Commit | Line | Data |
---|---|---|
31690700 | 1 | # |
ea81a808 | 2 | # mal (Make a Lisp) object types |
31690700 JM |
3 | # |
4 | ||
5 | ifndef __mal_types_included | |
6 | __mal_types_included := true | |
7 | ||
8 | _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) | |
f4c8a091 | 9 | include $(_TOP_DIR)gmsl.mk |
31690700 | 10 | include $(_TOP_DIR)util.mk |
f4c8a091 | 11 | include $(_TOP_DIR)numbers.mk |
31690700 | 12 | |
ea81a808 JM |
13 | |
14 | # Low-level type implemenation | |
15 | ||
31690700 JM |
16 | # magic is \u2344 \u204a |
17 | __obj_magic = ⍄⁊ | |
18 | # \u2256 | |
19 | __equal = ≛ | |
b8ee29b2 | 20 | __keyword = ʞ |
31690700 JM |
21 | __obj_hash_code = 0 |
22 | ||
f4c8a091 | 23 | __new_obj_hash_code = $(eval __obj_hash_code := $(call int_add,1,$(__obj_hash_code)))$(__obj_hash_code) |
31690700 JM |
24 | |
25 | __new_obj = $(__obj_magic)_$(1)_$(call __new_obj_hash_code) | |
26 | ||
27 | __new_obj_like = $(foreach type,$(word 2,$(subst _, ,$(1))),$(__obj_magic)_$(type)_$(__new_obj_hash_code)) | |
28 | ||
29 | __get_obj_values = $(strip \ | |
30 | $(if $(filter $(__obj_magic)_hmap_%,$(1)),\ | |
31 | $(sort $(foreach v,$(filter %_value,$(filter $(1)_%,$(.VARIABLES))),$(if $(call _undefined?,$(v)),,$(v)))),\ | |
32 | $($(1)_value))) | |
33 | ||
ea81a808 JM |
34 | |
35 | # Visualize Objects in memory | |
36 | __var_name = $(word 2,$(subst _, ,$(1)))_$(word 3,$(subst _, ,$(1))) | |
37 | __var_idx := 0 | |
38 | __var_print = $(foreach v,$(1),\ | |
39 | $(foreach var,$(call __var_name,$(v)),\ | |
40 | $(if $(or $(call _list?,$(v)),$(call _vector?,$(v))),\ | |
41 | $(info $(2)$(var):)\ | |
f4c8a091 | 42 | $(eval __var_idx := $(call int_add,1,$(__var_idx)))\ |
ea81a808 JM |
43 | $(foreach lidx,__lidx_$(__var_idx),\ |
44 | $(eval $(lidx) := 0)\ | |
45 | $(foreach val,$($(v)_value),\ | |
46 | $(call __var_print,$(val),$(2)$(SPACE)$(SPACE)$($(lidx)): )\ | |
f4c8a091 | 47 | $(eval $(lidx) := $(call int_add,1,$($(lidx)))))),\ |
ea81a808 JM |
48 | $(if $(call _hash_map?,$(v)),\ |
49 | $(info $(2)$(var):)\ | |
50 | $(foreach vkey,$(filter $(v)_%,$(.VARIABLES)),\ | |
51 | $(foreach key,$(word 4,$(subst _, ,$(vkey))),\ | |
52 | $(info $(2)$(SPACE)$(SPACE)$(subst $(__equal),=,$(key)): )\ | |
53 | $(call __var_print,$($(vkey)),$(2)$(SPACE)$(SPACE)$(SPACE)$(SPACE)))),\ | |
54 | $(if $(call _symbol?,$(v)),\ | |
55 | $(info $(2)$(var): $($(v)_value)),\ | |
b8ee29b2 JM |
56 | $(if $(call _keyword?,$(v)),\ |
57 | $(info $(2)$(var): $($(v)_value)),\ | |
ea81a808 JM |
58 | $(if $(call _number?,$(v)),\ |
59 | $(info $(2)$(var): $(call int_decode,$($(v)_value))),\ | |
60 | $(if $(call _nil?,$(v)),\ | |
61 | $(info $(2)nil),\ | |
62 | $(if $(call _function?,$(v)),\ | |
63 | $(if $(word 6,$(value $(v)_value)),\ | |
64 | $(info $(2)$(var): $(wordlist 1,5,$(value $(v)_value))...),\ | |
65 | $(info $(2)$(var): $(value $(v)_value))),\ | |
b8ee29b2 | 66 | $(info $(2)$(var): ...)))))))))) |
ea81a808 JM |
67 | |
68 | _visualize_memory = $(foreach var,$(sort $(foreach vv,$(filter $(__obj_magic)_%,$(.VARIABLES)),$(call __var_name,$(vv)))),$(call __var_print,$(__obj_magic)_$(var))) | |
69 | ||
70 | ||
71 | # Errors/Exceptions | |
31690700 | 72 | __ERROR := |
ea81a808 JM |
73 | _error = $(eval __ERROR := $(call _string,$(1))) |
74 | ||
75 | ||
76 | # Constant atomic values | |
77 | __undefined = $(__obj_magic)_undf_0 | |
78 | __nil = $(__obj_magic)__nil_0 | |
79 | __true = $(__obj_magic)_true_0 | |
80 | __false = $(__obj_magic)_fals_0 | |
81 | ||
31690700 | 82 | |
31690700 | 83 | # General functions |
31690700 JM |
84 | |
85 | # Return the type of the object (or "make" if it's not a object | |
86 | _obj_type = $(strip \ | |
87 | $(if $(filter $(__obj_magic)_symb_%,$(1)),symbol,\ | |
88 | $(if $(filter $(__obj_magic)_list_%,$(1)),list,\ | |
89 | $(if $(filter $(__obj_magic)_numb_%,$(1)),number,\ | |
90 | $(if $(filter $(__obj_magic)_func_%,$(1)),function,\ | |
b8ee29b2 JM |
91 | $(if $(filter $(__obj_magic)_strn_%,$(1)),\ |
92 | $(if $(filter $(__keyword)%,$($(1)_value)),keyword,string),\ | |
31690700 JM |
93 | $(if $(filter $(__obj_magic)__nil_%,$(1)),nil,\ |
94 | $(if $(filter $(__obj_magic)_true_%,$(1)),true,\ | |
95 | $(if $(filter $(__obj_magic)_fals_%,$(1)),false,\ | |
96 | $(if $(filter $(__obj_magic)_vect_%,$(1)),vector,\ | |
97 | $(if $(filter $(__obj_magic)_atom_%,$(1)),atom,\ | |
98 | $(if $(filter $(__obj_magic)_hmap_%,$(1)),hash_map,\ | |
99 | $(if $(filter $(__obj_magic)_undf_%,$(1)),undefined,\ | |
100 | make))))))))))))) | |
31690700 JM |
101 | |
102 | _clone_obj = $(strip \ | |
103 | $(foreach new_hcode,$(call __new_obj_hash_code),\ | |
104 | $(foreach new_obj,$(foreach type,$(word 2,$(subst _, ,$(1))),$(__obj_magic)_$(type)_$(new_hcode)),\ | |
105 | $(if $(filter $(__obj_magic)_hmap_%,$(1)),\ | |
106 | $(foreach v,$(call __get_obj_values,$(1)),\ | |
107 | $(eval $(v:$(1)_%=$(new_obj)_%) := $($(v))))\ | |
108 | $(eval $(new_obj)_size := $($(1)_size)),\ | |
109 | $(if $(filter $(__obj_magic)_func_%,$(1)),\ | |
110 | $(eval $(new_obj)_value = $(value $(1)_value)),\ | |
111 | $(eval $(new_obj)_value := $(strip $($(1)_value)))))\ | |
112 | $(new_obj)))) | |
113 | ||
ea81a808 JM |
114 | _equal? = $(strip \ |
115 | $(foreach ot1,$(call _obj_type,$(1)),$(foreach ot2,$(call _obj_type,$(2)),\ | |
116 | $(if $(or $(call _EQ,$(ot1),$(ot2)),\ | |
117 | $(and $(call _sequential?,$(1)),$(call _sequential?,$(2)))),\ | |
b8ee29b2 | 118 | $(if $(or $(call _string?,$(1)),$(call _symbol?,$(1)),$(call _keyword?,$(1)),$(call _number?,$(1))),\ |
ea81a808 JM |
119 | $(call _EQ,$($(1)_value),$($(2)_value)),\ |
120 | $(if $(or $(call _vector?,$(1)),$(call _list?,$(1)),$(call _hash_map?,$(1))),\ | |
121 | $(if $(and $(call _EQ,$(call _count,$(1)),$(call _count,$(2))),\ | |
122 | $(call _EQ,$(call _count,$(1)),$(words $(call gmsl_pairmap,_equal?,$(call __get_obj_values,$(1)),$(call __get_obj_values,$(2)))))),$(__true),),\ | |
123 | $(call _EQ,$(1),$(2)))))))) | |
31690700 JM |
124 | |
125 | _undefined? = $(or $(call _EQ,undefined,$(origin $(1))),$(filter $(__undefined),$($(1)))) | |
31690700 JM |
126 | |
127 | _nil? = $(if $(filter $(__obj_magic)__nil_%,$(1)),$(__true),) | |
31690700 JM |
128 | |
129 | _true? = $(if $(filter $(__obj_magic)_true_%,$(1)),$(__true),) | |
31690700 JM |
130 | |
131 | _false? = $(if $(filter $(__obj_magic)_fals_%,$(1)),$(__true),) | |
31690700 JM |
132 | |
133 | ||
ea81a808 JM |
134 | # Symbols |
135 | _symbol = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_symb_$(hcode)$(eval $(__obj_magic)_symb_$(hcode)_value := $(1))) | |
136 | _symbol? = $(if $(filter $(__obj_magic)_symb_%,$(1)),$(__true),) | |
31690700 | 137 | |
31690700 | 138 | |
b8ee29b2 JM |
139 | # Keywords |
140 | _keyword = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(__keyword)$(1))) | |
141 | _keyword? = $(if $(filter $(__obj_magic)_strn_%,$(1)),$(if $(filter $(__keyword)%,$($(1)_value)),$(__true),)) | |
142 | ||
143 | ||
ea81a808 JM |
144 | # Numbers |
145 | _pnumber = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_numb_$(hcode)$(eval $(__obj_magic)_numb_$(hcode)_value := $(1))) | |
146 | _number = $(call _pnumber,$(call int_encode,$(1))) | |
31690700 | 147 | _number? = $(if $(filter $(__obj_magic)_numb_%,$(1)),$(__true),) |
31690700 | 148 | |
31690700 | 149 | |
31690700 | 150 | # Strings |
ea81a808 JM |
151 | __string = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(1))) |
152 | _string = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(call str_encode,$(1)))) | |
31690700 | 153 | _string? = $(if $(filter $(__obj_magic)_strn_%,$(1)),$(__true),) |
31690700 | 154 | |
ea81a808 | 155 | # Functions |
31690700 JM |
156 | |
157 | # Return a function object. The first parameter is the | |
158 | # function/macro 'source'. Note that any $ must be escaped as $$ to be | |
159 | # preserved and become positional arguments for when the | |
160 | # function/macro is later invoked. | |
ea81a808 | 161 | _function = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_func_$(hcode)$(eval $(__obj_magic)_func_$(hcode)_value = $(1))) |
31690700 | 162 | _function? = $(if $(filter $(__obj_magic)_func_%,$(1)),$(__true),) |
31690700 JM |
163 | |
164 | # Takes a function name and a list object of arguments and invokes | |
165 | # the function with space separated arguments | |
166 | _apply = $(call $(1),$($(2)_value)) | |
167 | ||
168 | # Takes a function object and a list object of arguments and invokes | |
169 | # the function with space separated arguments | |
170 | apply = $(call $(1)_value,$($(2)_value)) | |
171 | ||
31690700 | 172 | |
ea81a808 JM |
173 | # Lists |
174 | _list = $(word 1,$(foreach new_list,$(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_list_$(hcode)),$(new_list) $(eval $(new_list)_value := $1))) | |
175 | _list? = $(if $(filter $(__obj_magic)_list_%,$(1)),$(__true),) | |
31690700 | 176 | |
31690700 | 177 | |
ea81a808 JM |
178 | # Vectors (same as lists for now) |
179 | _vector = $(word 1,$(foreach new_vect,$(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_vect_$(hcode)),$(new_vect) $(eval $(new_vect)_value := $1))) | |
180 | _vector? = $(if $(filter $(__obj_magic)_vect_%,$(1)),$(__true),) | |
181 | ||
31690700 | 182 | |
ea81a808 JM |
183 | # Hash maps (associative arrays) |
184 | _hash_map = $(word 1,$(foreach hcode,$(call __new_obj_hash_code),$(foreach new_hmap,$(__obj_magic)_hmap_$(hcode),$(new_hmap) $(eval $(new_hmap)_size := 0) $(if $(1),$(call _assoc_seq!,$(new_hmap),$(1)))))) | |
185 | _hash_map? = $(if $(filter $(__obj_magic)_hmap_%,$(1)),$(__true),) | |
31690700 JM |
186 | |
187 | # Set multiple key/values in a map | |
188 | _assoc_seq! = $(call _assoc!,$(1),$(call str_decode,$($(word 1,$(2))_value)),$(word 2,$(2)))$(if $(word 3,$(2)),$(call _assoc_seq!,$(1),$(wordlist 3,$(words $(2)),$(2))),) | |
189 | ||
b8ee29b2 JM |
190 | _dissoc_seq! = $(foreach key,$(2),\ |
191 | $(call _dissoc!,$(1),$(call str_decode,$($(key)_value)))) | |
192 | ||
31690700 | 193 | # set a key/value in the hash map |
f4c8a091 | 194 | _assoc! = $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),$(eval $(1)_size := $(call int_add,$($(1)_size),1)),)$(eval $(1)_$(k)_value := $(3))$(1)) |
31690700 | 195 | |
31690700 | 196 | # unset a key in the hash map |
f4c8a091 | 197 | _dissoc! = $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),,$(eval $(1)_$(k)_value := $(__undefined))$(eval $(1)_size := $(call int_sub,$($(1)_size),1))))$(1) |
31690700 | 198 | |
31690700 JM |
199 | # Hash map and vector functions |
200 | ||
201 | # retrieve the value of a plain string key from the hash map, or | |
202 | # retrive a vector by plain index | |
203 | _get = $(strip \ | |
204 | $(if $(call _hash_map?,$(1)),\ | |
205 | $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),,$($(1)_$(k)_value))),\ | |
206 | $(if $(call _vector?,$(1)),\ | |
f4c8a091 | 207 | $(word $(call int_add,1,$(2)),$($(1)_value)),\ |
31690700 JM |
208 | ,))) |
209 | ||
31690700 JM |
210 | _contains? = $(strip \ |
211 | $(if $(call _hash_map?,$(1)),\ | |
212 | $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),,$(__true))),\ | |
213 | $(if $(call _vector?,$(1)),\ | |
f4c8a091 | 214 | $(if $(word $(call int_add,1,$(2)),$($(1)_value)),$(__true),),\ |
31690700 | 215 | ,))) |
31690700 JM |
216 | |
217 | ||
31690700 | 218 | # sequence operations |
31690700 JM |
219 | |
220 | _sequential? = $(if $(filter $(__obj_magic)_list_% $(__obj_magic)_vect_%,$(1)),$(__true),) | |
31690700 | 221 | |
f4c8a091 | 222 | _nth = $(word $(call int_add,1,$(2)),$($(1)_value)) |
31690700 | 223 | |
31690700 JM |
224 | # conj that mutates a sequence in-place to append the call arguments |
225 | _conj! = $(eval $(1)_value := $(strip $($(1)_value) $2 $3 $4 $5 $6 $7 $8 $9 $(10) $(11) $(12) $(13) $(14) $(15) $(16) $(17) $(18) $(19) $(20)))$(1) | |
226 | ||
227 | _count = $(strip \ | |
228 | $(if $(call _hash_map?,$(1)),\ | |
229 | $($(1)_size),\ | |
230 | $(words $($(1)_value)))) | |
31690700 JM |
231 | |
232 | # Creates a new vector/list of the everything after but the first | |
233 | # element | |
9528bb14 JM |
234 | srest = $(word 1,$(foreach new_list,$(call _list),\ |
235 | $(new_list) \ | |
236 | $(eval $(new_list)_value := $(wordlist 2,$(words $($(1)_value)),$($(1)_value))))) | |
31690700 JM |
237 | |
238 | # maps a make function over a list object, using mutating _conj! | |
239 | _smap = $(word 1,\ | |
240 | $(foreach new_list,$(call _list),\ | |
241 | $(new_list)\ | |
242 | $(foreach v,$(call __get_obj_values,$(2)),\ | |
243 | $(call _conj!,$(new_list),$(call $(1),$(v),$(3),$(4)))))) | |
244 | ||
245 | # Same as _smap but returns a vector | |
246 | _smap_vec = $(word 1,\ | |
ea81a808 | 247 | $(foreach new_vector,$(call _vector),\ |
31690700 JM |
248 | $(new_vector)\ |
249 | $(foreach v,$(call __get_obj_values,$(2)),\ | |
250 | $(call _conj!,$(new_vector),$(call $(1),$(v),$(3),$(4)))))) | |
251 | ||
31690700 | 252 | |
ea81a808 | 253 | # atoms |
31690700 | 254 | |
ea81a808 | 255 | _atom? = $(if $(filter $(__obj_magic)_atom_%,$(1)),$(__true),) |
31690700 | 256 | |
31690700 JM |
257 | |
258 | endif |