Commit | Line | Data |
---|---|---|
31690700 JM |
1 | # |
2 | # mal (Make Lisp) | |
3 | # | |
4 | _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) | |
5 | include $(_TOP_DIR)types.mk | |
6 | include $(_TOP_DIR)reader.mk | |
ea81a808 JM |
7 | include $(_TOP_DIR)printer.mk |
8 | include $(_TOP_DIR)env.mk | |
9 | include $(_TOP_DIR)core.mk | |
31690700 JM |
10 | |
11 | SHELL := /bin/bash | |
12 | INTERACTIVE ?= yes | |
13 | EVAL_DEBUG ?= | |
14 | ||
15 | # READ: read and parse input | |
16 | define READ | |
17 | $(if $(READLINE_EOF)$(__ERROR),,$(call READ_STR,$(if $(1),$(1),$(call READLINE,"user> ")))) | |
18 | endef | |
19 | ||
20 | # EVAL: evaluate the parameter | |
21 | define LET | |
22 | $(strip \ | |
23 | $(word 1,$(2) \ | |
24 | $(foreach var,$(call _nth,$(1),0),\ | |
25 | $(foreach val,$(call _nth,$(1),1),\ | |
26 | $(call ENV_SET,$(2),$($(var)_value),$(call EVAL,$(val),$(2)))\ | |
27 | $(foreach left,$(call srest,$(call srest,$(1))), | |
28 | $(if $(call _EQ,0,$(call _count,$(left))),\ | |
29 | ,\ | |
30 | $(call LET,$(left),$(2)))))))) | |
31 | endef | |
32 | ||
33 | define EVAL_AST | |
34 | $(strip \ | |
35 | $(and $(EVAL_DEBUG),$(info EVAL_AST: $(call _pr_str,$(1))))\ | |
36 | $(if $(call _symbol?,$(1)),\ | |
37 | $(foreach key,$($(1)_value),\ | |
38 | $(call ENV_GET,$(2),$(key))),\ | |
39 | $(if $(call _list?,$(1)),\ | |
40 | $(call _smap,EVAL,$(1),$(2)),\ | |
41 | $(if $(call _vector?,$(1)),\ | |
42 | $(call _smap_vec,EVAL,$(1),$(2)),\ | |
43 | $(if $(call _hash_map?,$(1)),\ | |
44 | $(foreach new_hmap,$(call __new_obj,hmap),\ | |
45 | $(foreach v,$(call __get_obj_values,$(1)),\ | |
46 | $(eval $(v:$(1)_%=$(new_hmap)_%) := $(call EVAL,$($(v)),$(2))))\ | |
47 | $(eval $(new_hmap)_size := $($(1)_size))\ | |
48 | $(new_hmap)),\ | |
49 | $(1)))))) | |
50 | endef | |
51 | ||
52 | define EVAL_INVOKE | |
53 | $(if $(__ERROR),,\ | |
54 | $(and $(EVAL_DEBUG),$(info EVAL_INVOKE: $(call _pr_str,$(1)))) | |
55 | $(foreach a0,$(call _nth,$(1),0),\ | |
56 | $(if $(call _EQ,def!,$($(a0)_value)),\ | |
57 | $(foreach a1,$(call _nth,$(1),1),\ | |
58 | $(foreach a2,$(call _nth,$(1),2),\ | |
59 | $(foreach res,$(call EVAL,$(a2),$(2)),\ | |
b8ee29b2 JM |
60 | $(if $(__ERROR),,\ |
61 | $(if $(call ENV_SET,$(2),$($(a1)_value),$(res)),$(res),))))),\ | |
31690700 JM |
62 | $(if $(call _EQ,let*,$($(a0)_value)),\ |
63 | $(foreach a1,$(call _nth,$(1),1),\ | |
64 | $(foreach a2,$(call _nth,$(1),2),\ | |
65 | $(call EVAL,$(a2),$(call LET,$(a1),$(call ENV,$(2)))))),\ | |
66 | $(foreach el,$(call EVAL_AST,$(1),$(2)),\ | |
67 | $(call _apply,$(call sfirst,$(el)),$(call srest,$(el)))))))) | |
68 | endef | |
69 | ||
70 | define EVAL | |
71 | $(strip $(if $(__ERROR),,\ | |
72 | $(and $(EVAL_DEBUG),$(info EVAL: $(call _pr_str,$(1))))\ | |
73 | $(if $(call _list?,$(1)),\ | |
7730ef75 DM |
74 | $(if $(call _EQ,0,$(call _count,$(1))),\ |
75 | $(1),\ | |
76 | $(strip $(call EVAL_INVOKE,$(1),$(2)))),\ | |
31690700 JM |
77 | $(call EVAL_AST,$(1),$(2))))) |
78 | endef | |
79 | ||
80 | ||
81 | # PRINT: | |
82 | define PRINT | |
83 | $(if $(__ERROR),Error: $(call _pr_str,$(__ERROR),yes),$(if $(1),$(call _pr_str,$(1),yes)))$(if $(__ERROR),$(eval __ERROR :=),) | |
84 | endef | |
85 | ||
86 | # REPL: | |
87 | REPL_ENV := $(call ENV) | |
88 | REP = $(call PRINT,$(strip $(call EVAL,$(strip $(call READ,$(1))),$(REPL_ENV)))) | |
89 | REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call REPL)) | |
90 | ||
91 | # Setup the environment | |
8cb5cda4 JM |
92 | REPL_ENV := $(call ENV_SET,$(REPL_ENV),+,number_plus) |
93 | REPL_ENV := $(call ENV_SET,$(REPL_ENV),-,number_subtract) | |
94 | REPL_ENV := $(call ENV_SET,$(REPL_ENV),*,number_multiply) | |
95 | REPL_ENV := $(call ENV_SET,$(REPL_ENV),/,number_divide) | |
31690700 | 96 | |
86b689f3 | 97 | # repl loop |
31690700 | 98 | $(if $(strip $(INTERACTIVE)),$(call REPL)) |