All: split types into types, env, printer, core.
[jackhill/mal.git] / make / core.mk
CommitLineData
ea81a808
JM
1#
2# mal (Make a Lisp) Core functions
3#
4
5ifndef __mal_core_included
6__mal_core_included := true
7
8_TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
9include $(_TOP_DIR)util.mk
10include $(_TOP_DIR)types.mk
11include $(_TOP_DIR)printer.mk
12
13
14# Errors/Exceptions
15throw = $(eval __ERROR := $(1))
16
17
18# General functions
19
20# Return the type of the object (or "make" if it's not a object
21obj_type = $(call _string,$(call _obj_type,$(1)))
22
23equal? = $(if $(call _equal?,$(word 1,$(1)),$(word 2,$(1))),$(__true),$(__false))
24
25
26# Scalar functions
27nil? = $(if $(call _nil?,$(1)),$(__true),$(__false))
28true? = $(if $(call _true?,$(1)),$(__true),$(__false))
29false? = $(if $(call _false?,$(1)),$(__true),$(__false))
30
31
32# Symbol functions
33symbol? = $(if $(call _symbol?,$(1)),$(__true),$(__false))
34
35
36# Number functions
37number? = $(if $(call _number?,$(1)),$(__true),$(__false))
38
39number_lt = $(if $(call int_lt,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false))
40number_lte = $(if $(call int_lte,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false))
41number_gt = $(if $(call int_gt,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false))
42number_gte = $(if $(call int_gte,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false))
43
44number_plus = $(call _pnumber,$(call int_plus,$($(word 1,$(1))_value),$($(word 2,$(1))_value)))
45number_subtract = $(call _pnumber,$(call int_subtract,$($(word 1,$(1))_value),$($(word 2,$(1))_value)))
46number_multiply = $(call _pnumber,$(call int_multiply,$($(word 1,$(1))_value),$($(word 2,$(1))_value)))
47number_divide = $(call _pnumber,$(call int_divide,$($(word 1,$(1))_value),$($(word 2,$(1))_value)))
48
49
50# String functions
51
52pr_str = $(call _string,$(call _pr_str_mult,$(1),yes, ))
53str = $(call _string,$(call _pr_str_mult,$(1),,))
54prn = $(info $(call _pr_str_mult,$(1),yes, ))
55println = $(info $(subst \n,$(NEWLINE),$(call _pr_str_mult,$(1),, )))
56
57string? = $(if $(call _string?,$(1)),$(__true),$(__false))
58
59subs = $(strip \
60 $(foreach start,$(call gmsl_plus,1,$(call int_decode,$($(word 2,$(1))_value))),\
61 $(foreach end,$(if $(3),$(call int_decode,$($(3)_value)),$(words $($(word 1,$(1))_value))),\
62 $(call _string,$(wordlist $(start),$(end),$($(word 1,$(1))_value))))))
63
64
65
66# Function functions
67function? = $(if $(call _function?,$(1)),$(__true),$(__false))
68
69
70# List functions
71list? = $(if $(call _list?,$(1)),$(__true),$(__false))
72
73
74# Vector functions
75vector? = $(if $(call _vector?,$(1)),$(__true),$(__false))
76
77
78# Hash map (associative array) functions
79hash_map? = $(if $(call _hash_map?,$(1)),$(__true),$(__false))
80
81# set a key/value in a copy of the hash map
82assoc = $(word 1,\
83 $(foreach hm,$(call _clone_obj,$(word 1,$(1))),\
84 $(hm) \
85 $(call _assoc_seq!,$(hm),$(wordlist 2,$(words $(1)),$(1)))))
86
87# unset keys in a copy of the hash map
88# TODO: this could be made more efficient by copying only the
89# keys that not being removed.
90dissoc = $(word 1,\
91 $(foreach hm,$(call _clone_obj,$(word 1,$(1))),\
92 $(hm) \
93 $(foreach key,$(wordlist 2,$(words $(1)),$(1)),\
94 $(call _dissoc!,$(hm),$(call str_decode,$($(key)_value))))))
95
96keys = $(foreach new_list,$(call _list),$(new_list)$(eval $(new_list)_value := $(foreach v,$(call __get_obj_values,$(1)),$(call _string,$(word 4,$(subst _, ,$(v)))))))
97
98vals = $(foreach new_list,$(call _list),$(new_list)$(eval $(new_list)_value := $(foreach v,$(call __get_obj_values,$(1)),$($(v)))))
99
100# Hash map and vector functions
101
102# retrieve the value of a string key object from the hash map, or
103# retrive a vector by number object index
104get = $(strip \
105 $(if $(call _hash_map?,$(word 1,$(1))),\
106 $(call _get,$(word 1,$(1)),$(call str_decode,$($(word 2,$(1))_value))),\
107 $(call _get,$(word 1,$(1)),$(call int_decode,$($(word 2,$(1))_value)))))
108
109contains? = $(if $(call _contains?,$(word 1,$(1)),$(call str_decode,$($(word 2,$(1))_value))),$(__true),$(__false))
110
111
112# sequence operations
113
114sequential? = $(if $(call _sequential?,$(1)),$(__true),$(__false))
115
116cons = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $(strip $(word 1,$(1)) $(call __get_obj_values,$(word 2,$(1)))))))
117
118concat = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $(strip $(foreach lst,$1,$(call __get_obj_values,$(lst)))))))
119
120nth = $(word $(call gmsl_plus,1,$(call int_decode,$($(word 2,$(1))_value))),$($(word 1,$(1))_value))
121
122sfirst = $(word 1,$($(1)_value))
123
124slast = $(word $(words $($(1)_value)),$($(1)_value))
125
126empty? = $(if $(call _EQ,0,$(if $(call _hash_map?,$(1)),$($(1)_size),$(words $($(1)_value)))),$(__true),$(__false))
127
128count = $(call _number,$(call _count,$(1)))
129
130conj = $(word 1,$(foreach new_list,$(call __new_obj_like,$(word 1,$(1))),\
131 $(new_list) \
132 $(eval $(new_list)_value := $(strip $($(word 1,$(1))_value))) \
133 $(if $(call _list?,$(new_list)),\
134 $(foreach elem,$(wordlist 2,$(words $(1)),$(1)),\
135 $(eval $(new_list)_value := $(strip $(elem) $($(new_list)_value)))),\
136 $(eval $(new_list)_value := $(strip $($(new_list)_value) $(wordlist 2,$(words $(1)),$(1)))))))
137
138# Creates a new vector/list of the everything after but the first
139# element
140srest = $(word 1,$(foreach new_list,$(call _list),\
141 $(new_list) \
142 $(eval $(new_list)_value := $(wordlist 2,$(words $($(1)_value)),$($(1)_value)))))
143
144# Takes a space separated arguments and invokes the first argument
145# (function object) using the remaining arguments.
146sapply = $(call $(word 1,$(1))_value,\
147 $(strip \
148 $(wordlist 2,$(call gmsl_subtract,$(words $(1)),1),$(1)) \
149 $($(word $(words $(1)),$(1))_value)))
150
151# Map a function object over a list object
152smap = $(strip\
153 $(foreach func,$(word 1,$(1)),\
154 $(foreach lst,$(word 2,$(1)),\
155 $(foreach type,$(word 2,$(subst _, ,$(lst))),\
156 $(foreach new_hcode,$(call __new_obj_hash_code),\
157 $(foreach sz,$(words $(call __get_obj_values,$(lst))),\
158 $(eval $(__obj_magic)_$(type)_$(new_hcode)_value := $(strip \
159 $(foreach val,$(call __get_obj_values,$(lst)),\
160 $(call $(func)_value,$(val))))))\
161 $(__obj_magic)_$(type)_$(new_hcode))))))
162
163
164# Metadata functions
165
166with_meta = $(strip \
167 $(foreach new_obj,$(call _clone_obj,$(word 1,$(1))),\
168 $(eval $(new_obj)_meta := $(strip $(word 2,$(1))))\
169 $(new_obj)))
170
171meta = $(strip $($(1)_meta))
172
173
174# Atom functions
175
176atom = $(strip \
177 $(foreach hcode,$(call __new_obj_hash_code),\
178 $(foreach new_atom,$(__obj_magic)_atom_$(hcode),\
179 $(new_atom)\
180 $(eval $(new_atom)_value := $(1)))))
181atom? = $(if $(call _atom?,$(1)),$(__true),$(__false))
182
183deref = $($(1)_value)
184
185reset! = $(eval $(word 1,$(1))_value := $(word 2,$(1)))$(word 2,$(1))
186
187swap! = $(foreach resp,$(call $(word 2,$(1))_value,$($(word 1,$(1))_value) $(wordlist 3,$(words $(1)),$(1))),\
188 $(eval $(word 1,$(1))_value := $(resp))\
189 $(resp))
190
191
192
193
194# Namespace of core functions
195
196core_ns = type obj_type \
197 = equal? \
198 throw throw \
199 nil? nil? \
200 true? true? \
201 false? false? \
202 symbol _symbol \
203 symbol? symbol? \
204 function? function? \
205 string? string? \
206 pr-str pr_str \
207 str str \
208 prn prn \
209 println println \
210 subs subs \
211 number? number? \
212 < number_lt \
213 <= number_lte \
214 > number_gt \
215 >= number_gte \
216 + number_plus \
217 - number_subtract \
218 * number_multiply \
219 / number_divide \
220 \
221 list _list \
222 list? list? \
223 vector _vector \
224 vector? vector? \
225 hash-map _hash_map \
226 map? hash_map? \
227 assoc assoc \
228 dissoc dissoc \
229 get get \
230 contains? contains? \
231 keys keys \
232 vals vals \
233 \
234 sequential? sequential? \
235 cons cons \
236 concat concat \
237 nth nth \
238 first sfirst \
239 rest srest \
240 last slast \
241 empty? empty? \
242 count count \
243 conj conj \
244 apply sapply \
245 map smap \
246 \
247 with-meta with_meta \
248 meta meta \
249 atom atom \
250 atom? atom? \
251 deref deref \
252 reset! reset! \
253 swap! swap!
254
255endif