diff options
Diffstat (limited to 'make')
| -rw-r--r-- | make/Makefile | 3 | ||||
| -rw-r--r-- | make/core.mk | 255 | ||||
| -rw-r--r-- | make/env.mk | 50 | ||||
| -rw-r--r-- | make/printer.mk | 45 | ||||
| -rwxr-xr-x | make/reader.mk | 20 | ||||
| -rw-r--r-- | make/step1_read_print.mk | 1 | ||||
| -rw-r--r-- | make/step2_eval.mk | 2 | ||||
| -rw-r--r-- | make/step3_env.mk | 3 | ||||
| -rw-r--r-- | make/step4_if_fn_do.mk | 13 | ||||
| -rw-r--r-- | make/step6_file.mk | 21 | ||||
| -rw-r--r-- | make/step7_quote.mk | 27 | ||||
| -rw-r--r-- | make/step8_macros.mk | 27 | ||||
| -rw-r--r-- | make/step9_interop.mk | 27 | ||||
| -rw-r--r-- | make/stepA_more.mk | 31 | ||||
| -rw-r--r-- | make/tests/types.mk | 10 | ||||
| -rw-r--r-- | make/types.mk | 420 |
16 files changed, 537 insertions, 418 deletions
diff --git a/make/Makefile b/make/Makefile index 1110397..2bb1e1e 100644 --- a/make/Makefile +++ b/make/Makefile @@ -1,7 +1,8 @@ TESTS = tests/types.mk tests/reader.mk tests/step9_interop.mk -SOURCES = util.mk readline.mk gmsl.mk types.mk reader.mk stepA_more.mk +SOURCES = util.mk readline.mk gmsl.mk types.mk reader.mk printer.mk \ + env.mk core.mk stepA_more.mk mal.mk: $(SOURCES) echo "#!/usr/bin/make -f" > $@ diff --git a/make/core.mk b/make/core.mk new file mode 100644 index 0000000..aaba3fd --- /dev/null +++ b/make/core.mk @@ -0,0 +1,255 @@ +# +# mal (Make a Lisp) Core functions +# + +ifndef __mal_core_included +__mal_core_included := true + +_TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(_TOP_DIR)util.mk +include $(_TOP_DIR)types.mk +include $(_TOP_DIR)printer.mk + + +# Errors/Exceptions +throw = $(eval __ERROR := $(1)) + + +# General functions + +# Return the type of the object (or "make" if it's not a object +obj_type = $(call _string,$(call _obj_type,$(1))) + +equal? = $(if $(call _equal?,$(word 1,$(1)),$(word 2,$(1))),$(__true),$(__false)) + + +# Scalar functions +nil? = $(if $(call _nil?,$(1)),$(__true),$(__false)) +true? = $(if $(call _true?,$(1)),$(__true),$(__false)) +false? = $(if $(call _false?,$(1)),$(__true),$(__false)) + + +# Symbol functions +symbol? = $(if $(call _symbol?,$(1)),$(__true),$(__false)) + + +# Number functions +number? = $(if $(call _number?,$(1)),$(__true),$(__false)) + +number_lt = $(if $(call int_lt,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) +number_lte = $(if $(call int_lte,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) +number_gt = $(if $(call int_gt,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) +number_gte = $(if $(call int_gte,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) + +number_plus = $(call _pnumber,$(call int_plus,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) +number_subtract = $(call _pnumber,$(call int_subtract,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) +number_multiply = $(call _pnumber,$(call int_multiply,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) +number_divide = $(call _pnumber,$(call int_divide,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) + + +# String functions + +pr_str = $(call _string,$(call _pr_str_mult,$(1),yes, )) +str = $(call _string,$(call _pr_str_mult,$(1),,)) +prn = $(info $(call _pr_str_mult,$(1),yes, )) +println = $(info $(subst \n,$(NEWLINE),$(call _pr_str_mult,$(1),, ))) + +string? = $(if $(call _string?,$(1)),$(__true),$(__false)) + +subs = $(strip \ + $(foreach start,$(call gmsl_plus,1,$(call int_decode,$($(word 2,$(1))_value))),\ + $(foreach end,$(if $(3),$(call int_decode,$($(3)_value)),$(words $($(word 1,$(1))_value))),\ + $(call _string,$(wordlist $(start),$(end),$($(word 1,$(1))_value)))))) + + + +# Function functions +function? = $(if $(call _function?,$(1)),$(__true),$(__false)) + + +# List functions +list? = $(if $(call _list?,$(1)),$(__true),$(__false)) + + +# Vector functions +vector? = $(if $(call _vector?,$(1)),$(__true),$(__false)) + + +# Hash map (associative array) functions +hash_map? = $(if $(call _hash_map?,$(1)),$(__true),$(__false)) + +# set a key/value in a copy of the hash map +assoc = $(word 1,\ + $(foreach hm,$(call _clone_obj,$(word 1,$(1))),\ + $(hm) \ + $(call _assoc_seq!,$(hm),$(wordlist 2,$(words $(1)),$(1))))) + +# unset keys in a copy of the hash map +# TODO: this could be made more efficient by copying only the +# keys that not being removed. +dissoc = $(word 1,\ + $(foreach hm,$(call _clone_obj,$(word 1,$(1))),\ + $(hm) \ + $(foreach key,$(wordlist 2,$(words $(1)),$(1)),\ + $(call _dissoc!,$(hm),$(call str_decode,$($(key)_value)))))) + +keys = $(foreach new_list,$(call _list),$(new_list)$(eval $(new_list)_value := $(foreach v,$(call __get_obj_values,$(1)),$(call _string,$(word 4,$(subst _, ,$(v))))))) + +vals = $(foreach new_list,$(call _list),$(new_list)$(eval $(new_list)_value := $(foreach v,$(call __get_obj_values,$(1)),$($(v))))) + +# Hash map and vector functions + +# retrieve the value of a string key object from the hash map, or +# retrive a vector by number object index +get = $(strip \ + $(if $(call _hash_map?,$(word 1,$(1))),\ + $(call _get,$(word 1,$(1)),$(call str_decode,$($(word 2,$(1))_value))),\ + $(call _get,$(word 1,$(1)),$(call int_decode,$($(word 2,$(1))_value))))) + +contains? = $(if $(call _contains?,$(word 1,$(1)),$(call str_decode,$($(word 2,$(1))_value))),$(__true),$(__false)) + + +# sequence operations + +sequential? = $(if $(call _sequential?,$(1)),$(__true),$(__false)) + +cons = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $(strip $(word 1,$(1)) $(call __get_obj_values,$(word 2,$(1))))))) + +concat = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $(strip $(foreach lst,$1,$(call __get_obj_values,$(lst))))))) + +nth = $(word $(call gmsl_plus,1,$(call int_decode,$($(word 2,$(1))_value))),$($(word 1,$(1))_value)) + +sfirst = $(word 1,$($(1)_value)) + +slast = $(word $(words $($(1)_value)),$($(1)_value)) + +empty? = $(if $(call _EQ,0,$(if $(call _hash_map?,$(1)),$($(1)_size),$(words $($(1)_value)))),$(__true),$(__false)) + +count = $(call _number,$(call _count,$(1))) + +conj = $(word 1,$(foreach new_list,$(call __new_obj_like,$(word 1,$(1))),\ + $(new_list) \ + $(eval $(new_list)_value := $(strip $($(word 1,$(1))_value))) \ + $(if $(call _list?,$(new_list)),\ + $(foreach elem,$(wordlist 2,$(words $(1)),$(1)),\ + $(eval $(new_list)_value := $(strip $(elem) $($(new_list)_value)))),\ + $(eval $(new_list)_value := $(strip $($(new_list)_value) $(wordlist 2,$(words $(1)),$(1))))))) + +# Creates a new vector/list of the everything after but the first +# element +srest = $(word 1,$(foreach new_list,$(call _list),\ + $(new_list) \ + $(eval $(new_list)_value := $(wordlist 2,$(words $($(1)_value)),$($(1)_value))))) + +# Takes a space separated arguments and invokes the first argument +# (function object) using the remaining arguments. +sapply = $(call $(word 1,$(1))_value,\ + $(strip \ + $(wordlist 2,$(call gmsl_subtract,$(words $(1)),1),$(1)) \ + $($(word $(words $(1)),$(1))_value))) + +# Map a function object over a list object +smap = $(strip\ + $(foreach func,$(word 1,$(1)),\ + $(foreach lst,$(word 2,$(1)),\ + $(foreach type,$(word 2,$(subst _, ,$(lst))),\ + $(foreach new_hcode,$(call __new_obj_hash_code),\ + $(foreach sz,$(words $(call __get_obj_values,$(lst))),\ + $(eval $(__obj_magic)_$(type)_$(new_hcode)_value := $(strip \ + $(foreach val,$(call __get_obj_values,$(lst)),\ + $(call $(func)_value,$(val))))))\ + $(__obj_magic)_$(type)_$(new_hcode)))))) + + +# Metadata functions + +with_meta = $(strip \ + $(foreach new_obj,$(call _clone_obj,$(word 1,$(1))),\ + $(eval $(new_obj)_meta := $(strip $(word 2,$(1))))\ + $(new_obj))) + +meta = $(strip $($(1)_meta)) + + +# Atom functions + +atom = $(strip \ + $(foreach hcode,$(call __new_obj_hash_code),\ + $(foreach new_atom,$(__obj_magic)_atom_$(hcode),\ + $(new_atom)\ + $(eval $(new_atom)_value := $(1))))) +atom? = $(if $(call _atom?,$(1)),$(__true),$(__false)) + +deref = $($(1)_value) + +reset! = $(eval $(word 1,$(1))_value := $(word 2,$(1)))$(word 2,$(1)) + +swap! = $(foreach resp,$(call $(word 2,$(1))_value,$($(word 1,$(1))_value) $(wordlist 3,$(words $(1)),$(1))),\ + $(eval $(word 1,$(1))_value := $(resp))\ + $(resp)) + + + + +# Namespace of core functions + +core_ns = type obj_type \ + = equal? \ + throw throw \ + nil? nil? \ + true? true? \ + false? false? \ + symbol _symbol \ + symbol? symbol? \ + function? function? \ + string? string? \ + pr-str pr_str \ + str str \ + prn prn \ + println println \ + subs subs \ + number? number? \ + < number_lt \ + <= number_lte \ + > number_gt \ + >= number_gte \ + + number_plus \ + - number_subtract \ + * number_multiply \ + / number_divide \ + \ + list _list \ + list? list? \ + vector _vector \ + vector? vector? \ + hash-map _hash_map \ + map? hash_map? \ + assoc assoc \ + dissoc dissoc \ + get get \ + contains? contains? \ + keys keys \ + vals vals \ + \ + sequential? sequential? \ + cons cons \ + concat concat \ + nth nth \ + first sfirst \ + rest srest \ + last slast \ + empty? empty? \ + count count \ + conj conj \ + apply sapply \ + map smap \ + \ + with-meta with_meta \ + meta meta \ + atom atom \ + atom? atom? \ + deref deref \ + reset! reset! \ + swap! swap! + +endif diff --git a/make/env.mk b/make/env.mk new file mode 100644 index 0000000..d508283 --- /dev/null +++ b/make/env.mk @@ -0,0 +1,50 @@ +# +# mal (Make Lisp) Object Types and Functions +# + +ifndef __mal_env_included +__mal_env_included := true + +_TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(_TOP_DIR)types.mk + +# +# ENV +# + +# An ENV environment is a hash-map with an __outer__ reference to an +# outer environment +define BIND_ARGS +$(strip \ + $(word 1,$(1) \ + $(foreach fparam,$(call _nth,$(2),0),\ + $(if $(call _EQ,&,$($(fparam)_value)), + $(call ENV_SET,$(1),$($(call _nth,$(2),1)_value),$(strip \ + $(foreach new_list,$(call _list), + $(word 1,$(new_list) \ + $(foreach val,$(3),$(call _conj!,$(new_list),$(val))))))),\ + $(foreach val,$(word 1,$(3)),\ + $(call ENV_SET,$(1),$($(fparam)_value),$(val))\ + $(foreach left,$(call srest,$(2)),\ + $(if $(call _EQ,0,$(call _count,$(left))),\ + ,\ + $(call BIND_ARGS,$(1),$(left),$(wordlist 2,$(words $(3)),$(3)))))))))) +endef + +# Create a new ENV and optional bind values in it +# $(1): outer environment (set as a key named __outer__) +# $(2): list/vector object of bind forms +# $(3): space separated list of expressions to bind +ENV = $(strip $(foreach new_env,$(call _assoc!,$(call _hash_map),__outer__,$(if $(1),$(1),$(__nil))),$(if $(2),$(call BIND_ARGS,$(new_env),$(2),$(3)),$(new_env)))) +ENV_FIND = $(strip \ + $(if $(call _contains?,$(1),$(subst =,$(__equal),$(2))),\ + $(1),\ + $(if $(call _EQ,$(__nil),$(call _get,$(1),__outer__)),\ + ,\ + $(call ENV_FIND,$(call _get,$(1),__outer__),$(2))))) + +ENV_GET = $(foreach env,|$(call ENV_FIND,$(1),$(2))|,$(if $(call _EQ,||,$(env)),$(call _error,'$(2)' not found),$(call _get,$(strip $(subst |,,$(env))),$(subst =,$(__equal),$(2))))) + +ENV_SET = $(if $(call _assoc!,$(1),$(subst =,$(__equal),$(2)),$(3)),$(1),) + +endif diff --git a/make/printer.mk b/make/printer.mk new file mode 100644 index 0000000..a1f2559 --- /dev/null +++ b/make/printer.mk @@ -0,0 +1,45 @@ +# +# mal (Make a Lisp) printer +# + +ifndef __mal_printer_included +__mal_printer_included := true + +_TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(_TOP_DIR)util.mk +include $(_TOP_DIR)types.mk + +# return a printable form of the argument, the second parameter is +# 'print_readably' which backslashes quotes in string values +_pr_str = $(if $(1),$(foreach ot,$(call _obj_type,$(1)),$(if $(call _EQ,make,$(ot)),$(call _error,_pr_str failed on $(1)),$(call $(ot)_pr_str,$(1),$(2)))),) + +# Like _pr_str but takes multiple values in first argument, the second +# parameter is 'print_readably' which backslashes quotes in string +# values, the third parameter is the delimeter to use between each +# _pr_str'd value +_pr_str_mult = $(call _pr_str,$(word 1,$(1)),$(2))$(if $(word 2,$(1)),$(3)$(call _pr_str_mult,$(wordlist 2,$(words $(1)),$(1)),$(2),$(3)),) + + +# Type specific printing + +nil_pr_str = nil +true_pr_str = true +false_pr_str = false + +number_pr_str = $(call int_decode,$($(1)_value)) + +symbol_pr_str = $($(1)_value) + +string_pr_str = $(if $(2),"$(subst $(DQUOTE),$(ESC_DQUOTE),$(subst $(SLASH),$(SLASH)$(SLASH),$(call str_decode,$($(1)_value))))",$(call str_decode,$($(1)_value))) + +function_pr_str = <$(if $(word 6,$(value $(1)_value)),$(wordlist 1,5,$(value $(1)_value))...,$(value $(1)_value))> + +list_pr_str = ($(foreach v,$(call __get_obj_values,$(1)),$(call _pr_str,$(v),$(2)))) + +vector_pr_str = [$(foreach v,$(call __get_obj_values,$(1)),$(call _pr_str,$(v),$(2)))] + +hash_map_pr_str = {$(foreach v,$(call __get_obj_values,$(1)),"$(foreach hcode,$(word 3,$(subst _, ,$(1))),$(patsubst $(1)_%,%,$(v:%_value=%)))" $(call _pr_str,$($(v)),$(2)))} + +atom_pr_str = (atom $(call _pr_str,$($(1)_value),$(2))) + +endif diff --git a/make/reader.mk b/make/reader.mk index ce3b078..8d04596 100755 --- a/make/reader.mk +++ b/make/reader.mk @@ -55,10 +55,10 @@ endef define READ_ATOM $(foreach ch,$(word 1,$($(1))),\ $(if $(filter $(NUMBERS),$(ch)),\ - $(call number,$(call READ_NUMBER,$(1))),\ + $(call _number,$(call READ_NUMBER,$(1))),\ $(if $(filter $(DQUOTE),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(call _string,$(strip $(call READ_STRING,$(1))))\ + $(call __string,$(strip $(call READ_STRING,$(1))))\ $(eval $(if $(filter $(DQUOTE),$(word 1,$($(1)))),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1)))),\ $(call _error,Expected '$(DQUOTE)' in; $($(1))))),\ @@ -69,7 +69,7 @@ $(foreach ch,$(word 1,$($(1))),\ $(__true),\ $(if $(call _EQ,false,$(sym)),\ $(__false),\ - $(call symbol,$(sym))))))))) + $(call _symbol,$(sym))))))))) endef # read and return tokens until $(2) found @@ -111,28 +111,28 @@ $(foreach ch,$(word 1,$($(1))),\ $(call DROP_UNTIL,$(1),$(_NL)),\ $(if $(filter $(SQUOTE),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(call list,$(call symbol,quote) $(strip $(call READ_FORM,$(1)))),\ + $(call _list,$(call _symbol,quote) $(strip $(call READ_FORM,$(1)))),\ $(if $(filter $(QQUOTE),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(call list,$(call symbol,quasiquote) $(strip $(call READ_FORM,$(1)))),\ + $(call _list,$(call _symbol,quasiquote) $(strip $(call READ_FORM,$(1)))),\ $(if $(filter $(UNQUOTE),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(call list,$(call symbol,unquote) $(strip $(call READ_FORM,$(1)))),\ + $(call _list,$(call _symbol,unquote) $(strip $(call READ_FORM,$(1)))),\ $(if $(filter $(_SUQ),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(call list,$(call symbol,splice-unquote) $(strip $(call READ_FORM,$(1)))),\ + $(call _list,$(call _symbol,splice-unquote) $(strip $(call READ_FORM,$(1)))),\ $(if $(filter $(CARET),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ $(foreach meta,$(strip $(call READ_FORM,$(1))),\ - $(call list,$(call symbol,with-meta) $(strip $(call READ_FORM,$(1))) $(meta))),\ + $(call _list,$(call _symbol,with-meta) $(strip $(call READ_FORM,$(1))) $(meta))),\ $(if $(filter $(ATSIGN),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(call list,$(call symbol,deref) $(strip $(call READ_FORM,$(1)))),\ + $(call _list,$(call _symbol,deref) $(strip $(call READ_FORM,$(1)))),\ $(if $(filter $(_RC),$(ch)),\ $(call _error,Unexpected '$(RCURLY)'),\ $(if $(filter $(_LC),$(ch)),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1))))\ - $(foreach thm,$(call hash_map),\ + $(foreach thm,$(call _hash_map),\ $(call do,$(call _assoc_seq!,$(thm),$(strip $(call READ_UNTIL,$(1),$(_RC),$(RCURLY)))))\ $(eval $(if $(filter $(_RC),$(word 1,$($(1)))),\ $(eval $(1) := $(wordlist 2,$(words $($(1))),$($(1)))),\ diff --git a/make/step1_read_print.mk b/make/step1_read_print.mk index 710cd1d..a5fe2d2 100644 --- a/make/step1_read_print.mk +++ b/make/step1_read_print.mk @@ -4,6 +4,7 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk SHELL := /bin/bash INTERACTIVE ?= yes diff --git a/make/step2_eval.mk b/make/step2_eval.mk index 62cd415..96cd98f 100644 --- a/make/step2_eval.mk +++ b/make/step2_eval.mk @@ -4,6 +4,8 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes diff --git a/make/step3_env.mk b/make/step3_env.mk index 4f3f070..7c505cf 100644 --- a/make/step3_env.mk +++ b/make/step3_env.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes diff --git a/make/step4_if_fn_do.mk b/make/step4_if_fn_do.mk index d08998d..f45cfa9 100644 --- a/make/step4_if_fn_do.mk +++ b/make/step4_if_fn_do.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes @@ -71,7 +74,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,fn*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach a2,$(call _nth,$(1),2),\ - $(call function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ + $(call _function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ $(foreach el,$(call EVAL_AST,$(1),$(2)),\ $(and $(EVAL_DEBUG),$(info invoke: $(call _pr_str,$(el))))\ $(foreach f,$(call sfirst,$(el)),\ @@ -99,11 +102,11 @@ REP = $(call PRINT,$(strip $(call EVAL,$(strip $(call READ,$(1))),$(REPL_ENV)))) REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call REPL)) # Setup the environment -_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call function,$$(call $(2),$$1)))) +_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call _function,$$(call $(2),$$1)))) -# Import types functions -_import_types = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_types,$(wordlist 3,$(words $(1)),$(1))),) -$(call _import_types,$(types_ns)) +# Import core namespace +_import_core = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_core,$(wordlist 3,$(words $(1)),$(1))),) +$(call _import_core,$(core_ns)) # Defined in terms of the language itself $(call do,$(call REP, (def! not (fn* (a) (if a false true))) )) diff --git a/make/step6_file.mk b/make/step6_file.mk index 0c72a9c..c791b33 100644 --- a/make/step6_file.mk +++ b/make/step6_file.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes @@ -71,7 +74,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,fn*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach a2,$(call _nth,$(1),2),\ - $(call function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ + $(call _function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ $(foreach el,$(call EVAL_AST,$(1),$(2)),\ $(and $(EVAL_DEBUG),$(info invoke: $(call _pr_str,$(el))))\ $(foreach f,$(call sfirst,$(el)),\ @@ -100,17 +103,17 @@ REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call # Setup the environment _ref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(if $(2),$(2),$(1)))) -_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call function,$$(call $(2),$$1)))) +_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call _function,$$(call $(2),$$1)))) -# Import types functions -_import_types = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_types,$(wordlist 3,$(words $(1)),$(1))),) -$(call _import_types,$(types_ns)) +# Import core namespace +_import_core = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_core,$(wordlist 3,$(words $(1)),$(1))),) +$(call _import_core,$(core_ns)) -$(call _ref,read-string,$(call function,$$(call READ_STR,$$(1)))) -$(call _ref,eval,$(call function,$$(call EVAL,$$(1),$$(REPL_ENV)))) +$(call _ref,read-string,$(call _function,$$(call READ_STR,$$(1)))) +$(call _ref,eval,$(call _function,$$(call EVAL,$$(1),$$(REPL_ENV)))) -_slurp = $(call string,$(call _read_file,$(1))) -$(call _ref,slurp,$(call function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) +_slurp = $(call _string,$(call _read_file,$(1))) +$(call _ref,slurp,$(call _function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) # Defined in terms of the language itself $(call do,$(call REP, (def! not (fn* (a) (if a false true))) )) diff --git a/make/step7_quote.mk b/make/step7_quote.mk index 2a14c11..46e5130 100644 --- a/make/step7_quote.mk +++ b/make/step7_quote.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes @@ -20,12 +23,12 @@ IS_PAIR = $(if $(call _EQ,list,$(call _obj_type,$(1))),$(if $(call _EQ,0,$(call define QUASIQUOTE $(strip \ $(if $(call _NOT,$(call IS_PAIR,$(1))),\ - $(call list,$(call symbol,quote) $(1)),\ + $(call _list,$(call _symbol,quote) $(1)),\ $(if $(call _EQ,unquote,$($(call _nth,$(1),0)_value)),\ $(call _nth,$(1),1),\ $(if $(and $(call IS_PAIR,$(call _nth,$(1),0)),$(call _EQ,splice-unquote,$($(call _nth,$(call _nth,$(1),0),0)_value))),\ - $(call list,$(call symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ - $(call list,$(call symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) + $(call _list,$(call _symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ + $(call _list,$(call _symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) endef define LET @@ -88,7 +91,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,fn*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach a2,$(call _nth,$(1),2),\ - $(call function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ + $(call _function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ $(foreach el,$(call EVAL_AST,$(1),$(2)),\ $(and $(EVAL_DEBUG),$(info invoke: $(call _pr_str,$(el))))\ $(foreach f,$(call sfirst,$(el)),\ @@ -117,17 +120,17 @@ REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call # Setup the environment _ref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(if $(2),$(2),$(1)))) -_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call function,$$(call $(2),$$1)))) +_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call _function,$$(call $(2),$$1)))) -# Import types functions -_import_types = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_types,$(wordlist 3,$(words $(1)),$(1))),) -$(call _import_types,$(types_ns)) +# Import core namespace +_import_core = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_core,$(wordlist 3,$(words $(1)),$(1))),) +$(call _import_core,$(core_ns)) -$(call _ref,read-string,$(call function,$$(call READ_STR,$$(1)))) -$(call _ref,eval,$(call function,$$(call EVAL,$$(1),$$(REPL_ENV)))) +$(call _ref,read-string,$(call _function,$$(call READ_STR,$$(1)))) +$(call _ref,eval,$(call _function,$$(call EVAL,$$(1),$$(REPL_ENV)))) -_slurp = $(call string,$(call _read_file,$(1))) -$(call _ref,slurp,$(call function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) +_slurp = $(call _string,$(call _read_file,$(1))) +$(call _ref,slurp,$(call _function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) # Defined in terms of the language itself $(call do,$(call REP, (def! not (fn* (a) (if a false true))) )) diff --git a/make/step8_macros.mk b/make/step8_macros.mk index 910acb0..fee4bb0 100644 --- a/make/step8_macros.mk +++ b/make/step8_macros.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes @@ -20,12 +23,12 @@ IS_PAIR = $(if $(call _EQ,list,$(call _obj_type,$(1))),$(if $(call _EQ,0,$(call define QUASIQUOTE $(strip \ $(if $(call _NOT,$(call IS_PAIR,$(1))),\ - $(call list,$(call symbol,quote) $(1)),\ + $(call _list,$(call _symbol,quote) $(1)),\ $(if $(call _EQ,unquote,$($(call _nth,$(1),0)_value)),\ $(call _nth,$(1),1),\ $(if $(and $(call IS_PAIR,$(call _nth,$(1),0)),$(call _EQ,splice-unquote,$($(call _nth,$(call _nth,$(1),0),0)_value))),\ - $(call list,$(call symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ - $(call list,$(call symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) + $(call _list,$(call _symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ + $(call _list,$(call _symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) endef define IS_MACRO_CALL @@ -108,7 +111,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,fn*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach a2,$(call _nth,$(1),2),\ - $(call function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ + $(call _function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ $(foreach el,$(call EVAL_AST,$(1),$(2)),\ $(and $(EVAL_DEBUG),$(info invoke: $(call _pr_str,$(el))))\ $(foreach f,$(call sfirst,$(el)),\ @@ -140,17 +143,17 @@ REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call # Setup the environment _ref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(if $(2),$(2),$(1)))) -_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call function,$$(call $(2),$$1)))) +_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call _function,$$(call $(2),$$1)))) -# Import types functions -_import_types = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_types,$(wordlist 3,$(words $(1)),$(1))),) -$(call _import_types,$(types_ns)) +# Import core namespace +_import_core = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_core,$(wordlist 3,$(words $(1)),$(1))),) +$(call _import_core,$(core_ns)) -$(call _ref,read-string,$(call function,$$(call READ_STR,$$(1)))) -$(call _ref,eval,$(call function,$$(call EVAL,$$(1),$$(REPL_ENV)))) +$(call _ref,read-string,$(call _function,$$(call READ_STR,$$(1)))) +$(call _ref,eval,$(call _function,$$(call EVAL,$$(1),$$(REPL_ENV)))) -_slurp = $(call string,$(call _read_file,$(1))) -$(call _ref,slurp,$(call function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) +_slurp = $(call _string,$(call _read_file,$(1))) +$(call _ref,slurp,$(call _function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) # Defined in terms of the language itself $(call do,$(call REP, (def! not (fn* (a) (if a false true))) )) diff --git a/make/step9_interop.mk b/make/step9_interop.mk index 6de228d..4b7eaff 100644 --- a/make/step9_interop.mk +++ b/make/step9_interop.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes @@ -20,12 +23,12 @@ IS_PAIR = $(if $(call _EQ,list,$(call _obj_type,$(1))),$(if $(call _EQ,0,$(call define QUASIQUOTE $(strip \ $(if $(call _NOT,$(call IS_PAIR,$(1))),\ - $(call list,$(call symbol,quote) $(1)),\ + $(call _list,$(call _symbol,quote) $(1)),\ $(if $(call _EQ,unquote,$($(call _nth,$(1),0)_value)),\ $(call _nth,$(1),1),\ $(if $(and $(call IS_PAIR,$(call _nth,$(1),0)),$(call _EQ,splice-unquote,$($(call _nth,$(call _nth,$(1),0),0)_value))),\ - $(call list,$(call symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ - $(call list,$(call symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) + $(call _list,$(call _symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ + $(call _list,$(call _symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) endef define IS_MACRO_CALL @@ -112,7 +115,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,fn*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach a2,$(call _nth,$(1),2),\ - $(call function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ + $(call _function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ $(foreach el,$(call EVAL_AST,$(1),$(2)),\ $(and $(EVAL_DEBUG),$(info invoke: $(call _pr_str,$(el))))\ $(foreach f,$(call sfirst,$(el)),\ @@ -144,17 +147,17 @@ REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call # Setup the environment _ref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(if $(2),$(2),$(1)))) -_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call function,$$(call $(2),$$1)))) +_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call _function,$$(call $(2),$$1)))) -# Import types functions -_import_types = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_types,$(wordlist 3,$(words $(1)),$(1))),) -$(call _import_types,$(types_ns)) +# Import core namespace +_import_core = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_core,$(wordlist 3,$(words $(1)),$(1))),) +$(call _import_core,$(core_ns)) -$(call _ref,read-string,$(call function,$$(call READ_STR,$$(1)))) -$(call _ref,eval,$(call function,$$(call EVAL,$$(1),$$(REPL_ENV)))) +$(call _ref,read-string,$(call _function,$$(call READ_STR,$$(1)))) +$(call _ref,eval,$(call _function,$$(call EVAL,$$(1),$$(REPL_ENV)))) -_slurp = $(call string,$(call _read_file,$(1))) -$(call _ref,slurp,$(call function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) +_slurp = $(call _string,$(call _read_file,$(1))) +$(call _ref,slurp,$(call _function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) # Defined in terms of the language itself $(call do,$(call REP, (def! not (fn* (a) (if a false true))) )) diff --git a/make/stepA_more.mk b/make/stepA_more.mk index 48c0cb2..3cd0d2a 100644 --- a/make/stepA_more.mk +++ b/make/stepA_more.mk @@ -4,6 +4,9 @@ _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)types.mk include $(_TOP_DIR)reader.mk +include $(_TOP_DIR)printer.mk +include $(_TOP_DIR)env.mk +include $(_TOP_DIR)core.mk SHELL := /bin/bash INTERACTIVE ?= yes @@ -20,12 +23,12 @@ IS_PAIR = $(if $(call _EQ,list,$(call _obj_type,$(1))),$(if $(call _EQ,0,$(call define QUASIQUOTE $(strip \ $(if $(call _NOT,$(call IS_PAIR,$(1))),\ - $(call list,$(call symbol,quote) $(1)),\ + $(call _list,$(call _symbol,quote) $(1)),\ $(if $(call _EQ,unquote,$($(call _nth,$(1),0)_value)),\ $(call _nth,$(1),1),\ $(if $(and $(call IS_PAIR,$(call _nth,$(1),0)),$(call _EQ,splice-unquote,$($(call _nth,$(call _nth,$(1),0),0)_value))),\ - $(call list,$(call symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ - $(call list,$(call symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) + $(call _list,$(call _symbol,concat) $(call _nth,$(call _nth,$(1),0),1) $(call QUASIQUOTE,$(call srest,$(1)))),\ + $(call _list,$(call _symbol,cons) $(call QUASIQUOTE,$(call _nth,$(1),0)) $(call QUASIQUOTE,$(call srest,$(1)))))))) endef define IS_MACRO_CALL @@ -109,7 +112,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,catch*,$($(a20)_value)),\ $(foreach a21,$(call _nth,$(a2),1),\ $(foreach a22,$(call _nth,$(a2),2),\ - $(foreach binds,$(call list,$(a21)),\ + $(foreach binds,$(call _list,$(a21)),\ $(foreach catch_env,$(call ENV,$(2),$(binds),$(__ERROR)),\ $(eval __ERROR :=)\ $(call EVAL,$(a22),$(catch_env)))))),\ @@ -127,7 +130,7 @@ $(if $(__ERROR),,\ $(if $(call _EQ,fn*,$($(a0)_value)),\ $(foreach a1,$(call _nth,$(1),1),\ $(foreach a2,$(call _nth,$(1),2),\ - $(call function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ + $(call _function,$$(call EVAL,$(a2),$$(call ENV,$(2),$(a1),$$1))))),\ $(foreach el,$(call EVAL_AST,$(1),$(2)),\ $(and $(EVAL_DEBUG),$(info invoke: $(call _pr_str,$(el))))\ $(foreach f,$(call sfirst,$(el)),\ @@ -159,18 +162,18 @@ REPL = $(info $(call REP,$(call READLINE,"user> ")))$(if $(READLINE_EOF),,$(call # Setup the environment _ref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(if $(2),$(2),$(1)))) -_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call function,$$(call $(2),$$1)))) +_fref = $(eval REPL_ENV := $(call ENV_SET,$(REPL_ENV),$(1),$(call _function,$$(call $(2),$$1)))) -# Import types functions -_import_types = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_types,$(wordlist 3,$(words $(1)),$(1))),) -$(call _import_types,$(types_ns)) +# Import core namespace +_import_core = $(if $(strip $(1)),$(call _fref,$(word 1,$(1)),$(word 2,$(1)))$(call _import_core,$(wordlist 3,$(words $(1)),$(1))),) +$(call _import_core,$(core_ns)) -$(call _ref,readline,$(call function,$$(foreach res,$$(call string,$$(call READLINE,"$$(call str_decode,$$($$(1)_value))")),$$(if $$(READLINE_EOF),$$(__nil),$$(res))))) -$(call _ref,read-string,$(call function,$$(call READ_STR,$$(1)))) -$(call _ref,eval,$(call function,$$(call EVAL,$$(1),$$(REPL_ENV)))) +$(call _ref,readline,$(call _function,$$(foreach res,$$(call _string,$$(call READLINE,"$$(call str_decode,$$($$(1)_value))")),$$(if $$(READLINE_EOF),$$(__nil),$$(res))))) +$(call _ref,read-string,$(call _function,$$(call READ_STR,$$(1)))) +$(call _ref,eval,$(call _function,$$(call EVAL,$$(1),$$(REPL_ENV)))) -_slurp = $(call string,$(call _read_file,$(1))) -$(call _ref,slurp,$(call function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) +_slurp = $(call _string,$(call _read_file,$(1))) +$(call _ref,slurp,$(call _function,$$(call _slurp,$$(call str_decode,$$($$(1)_value))))) # Defined in terms of the language itself $(call do,$(call REP, (def! not (fn* (a) (if a false true))) )) diff --git a/make/tests/types.mk b/make/tests/types.mk index c1c1849..a100afe 100644 --- a/make/tests/types.mk +++ b/make/tests/types.mk @@ -63,9 +63,9 @@ $(call assert_eq,a string value - a string (with parens),$(call str_decode,$($(c $(info Testing function objects) -$(call assert_eq,function,$(call _obj_type,$(call function,abc)),\ +$(call assert_eq,function,$(call _obj_type,$(call _function,abc)),\ (type (function abc)) is not 'function') -FN1 := $(call function,arg1:'$$(word 1,$$(1))' arg2:'$$(word 2,$$(1))') +FN1 := $(call _function,arg1:'$$(word 1,$$(1))' arg2:'$$(word 2,$$(1))') $(call assert_eq,$(__true),$(call function?,$(FN1))) $(call assert_eq,arg1:'A' arg2:'B',$(call apply,$(FN1),$(call list,A B))) @@ -113,7 +113,7 @@ $(call assert_eq,A,$(call sfirst,$(call _nth,$(L4),1)),\ $(info Testing hash_maps) -X := $(call hash_map) +X := $(call _hash_map) $(call assert_eq,$(__true),$(call hash_map?,$(X)),\ (hash_map? $$(X))) $(call assert_eq,$(__false),$(call vector?,$(X)),\ @@ -130,7 +130,7 @@ $(call assert_eq,value of X a,$(call _get,$(X),a),\ $(call assert_eq,$(__true),$(call contains?,$(X) $(mykey)),\ (contains? $$(X),a)) -Y := $(call hash_map) +Y := $(call _hash_map) $(call assert_eq,0,$(call _count,$(Y)),\ (_count $$(Y))) $(call do,$(call _assoc!,$(Y),a,value of Y a)) @@ -241,7 +241,7 @@ $(info Testing smap function) L5 := $(call _conj!,$(call list),$(call number,1) $(call number,2) $(call number,3)) inc = $(call number_plus,$(call number,1) $(1)) $(call assert_eq,(2 3 4),$(call _pr_str,$(call _smap,inc,$(L5)))) -inc_func := $(call function,$$(call number_plus,$$(call number,1) $$(1))) +inc_func := $(call _function,$$(call number_plus,$$(call number,1) $$(1))) $(call assert_eq,(2 3 4),$(call _pr_str,$(call smap,$(inc_func) $(L5)))) diff --git a/make/types.mk b/make/types.mk index 9f03530..b971fb1 100644 --- a/make/types.mk +++ b/make/types.mk @@ -1,5 +1,5 @@ # -# mal (Make Lisp) Object Types and Functions +# mal (Make a Lisp) object types # ifndef __mal_types_included @@ -8,6 +8,9 @@ __mal_types_included := true _TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(_TOP_DIR)util.mk + +# Low-level type implemenation + # magic is \u2344 \u204a __obj_magic = ⍄⁊ # \u2256 @@ -25,11 +28,54 @@ __get_obj_values = $(strip \ $(sort $(foreach v,$(filter %_value,$(filter $(1)_%,$(.VARIABLES))),$(if $(call _undefined?,$(v)),,$(v)))),\ $($(1)_value))) + +# Visualize Objects in memory +__var_name = $(word 2,$(subst _, ,$(1)))_$(word 3,$(subst _, ,$(1))) +__var_idx := 0 +__var_print = $(foreach v,$(1),\ + $(foreach var,$(call __var_name,$(v)),\ + $(if $(or $(call _list?,$(v)),$(call _vector?,$(v))),\ + $(info $(2)$(var):)\ + $(eval __var_idx := $(call gmsl_plus,1,$(__var_idx)))\ + $(foreach lidx,__lidx_$(__var_idx),\ + $(eval $(lidx) := 0)\ + $(foreach val,$($(v)_value),\ + $(call __var_print,$(val),$(2)$(SPACE)$(SPACE)$($(lidx)): )\ + $(eval $(lidx) := $(call gmsl_plus,1,$($(lidx)))))),\ + $(if $(call _hash_map?,$(v)),\ + $(info $(2)$(var):)\ + $(foreach vkey,$(filter $(v)_%,$(.VARIABLES)),\ + $(foreach key,$(word 4,$(subst _, ,$(vkey))),\ + $(info $(2)$(SPACE)$(SPACE)$(subst $(__equal),=,$(key)): )\ + $(call __var_print,$($(vkey)),$(2)$(SPACE)$(SPACE)$(SPACE)$(SPACE)))),\ + $(if $(call _symbol?,$(v)),\ + $(info $(2)$(var): $($(v)_value)),\ + $(if $(call _number?,$(v)),\ + $(info $(2)$(var): $(call int_decode,$($(v)_value))),\ + $(if $(call _nil?,$(v)),\ + $(info $(2)nil),\ + $(if $(call _function?,$(v)),\ + $(if $(word 6,$(value $(v)_value)),\ + $(info $(2)$(var): $(wordlist 1,5,$(value $(v)_value))...),\ + $(info $(2)$(var): $(value $(v)_value))),\ + $(info $(2)$(var): ...))))))))) + +_visualize_memory = $(foreach var,$(sort $(foreach vv,$(filter $(__obj_magic)_%,$(.VARIABLES)),$(call __var_name,$(vv)))),$(call __var_print,$(__obj_magic)_$(var))) + + +# Errors/Exceptions __ERROR := +_error = $(eval __ERROR := $(call _string,$(1))) + + +# Constant atomic values +__undefined = $(__obj_magic)_undf_0 +__nil = $(__obj_magic)__nil_0 +__true = $(__obj_magic)_true_0 +__false = $(__obj_magic)_fals_0 + -# # General functions -# # Return the type of the object (or "make" if it's not a object _obj_type = $(strip \ @@ -46,22 +92,6 @@ _obj_type = $(strip \ $(if $(filter $(__obj_magic)_hmap_%,$(1)),hash_map,\ $(if $(filter $(__obj_magic)_undf_%,$(1)),undefined,\ make))))))))))))) -obj_type = $(call string,$(call _obj_type,$(1))) - -# return a printable form of the argument, the second parameter is -# 'print_readably' which backslashes quotes in string values -_pr_str = $(if $(1),$(foreach ot,$(call _obj_type,$(1)),$(if $(call _EQ,make,$(ot)),$(call _error,_pr_str failed on $(1)),$(call $(ot)_pr_str,$(1),$(2)))),) - -# Like _pr_str but takes multiple values in first argument, the second -# parameter is 'print_readably' which backslashes quotes in string -# values, the third parameter is the delimeter to use between each -# _pr_str'd value -_pr_str_mult = $(call _pr_str,$(word 1,$(1)),$(2))$(if $(word 2,$(1)),$(3)$(call _pr_str_mult,$(wordlist 2,$(words $(1)),$(1)),$(2),$(3)),) - -pr_str = $(call string,$(call _pr_str_mult,$(1),yes, )) -str = $(call string,$(call _pr_str_mult,$(1),,)) -prn = $(info $(call _pr_str_mult,$(1),yes, )) -println = $(info $(subst \n,$(NEWLINE),$(call _pr_str_mult,$(1),, ))) _clone_obj = $(strip \ $(foreach new_hcode,$(call __new_obj_hash_code),\ @@ -75,101 +105,50 @@ _clone_obj = $(strip \ $(eval $(new_obj)_value := $(strip $($(1)_value)))))\ $(new_obj)))) -with_meta = $(strip \ - $(foreach new_obj,$(call _clone_obj,$(word 1,$(1))),\ - $(eval $(new_obj)_meta := $(strip $(word 2,$(1))))\ - $(new_obj))) - -meta = $(strip $($(1)_meta)) - - -# -# Special atomic values -# -__undefined = $(__obj_magic)_undf_0 -__nil = $(__obj_magic)__nil_0 -__true = $(__obj_magic)_true_0 -__false = $(__obj_magic)_fals_0 +_equal? = $(strip \ + $(foreach ot1,$(call _obj_type,$(1)),$(foreach ot2,$(call _obj_type,$(2)),\ + $(if $(or $(call _EQ,$(ot1),$(ot2)),\ + $(and $(call _sequential?,$(1)),$(call _sequential?,$(2)))),\ + $(if $(or $(call _string?,$(1)),$(call _symbol?,$(1)),$(call _number?,$(1))),\ + $(call _EQ,$($(1)_value),$($(2)_value)),\ + $(if $(or $(call _vector?,$(1)),$(call _list?,$(1)),$(call _hash_map?,$(1))),\ + $(if $(and $(call _EQ,$(call _count,$(1)),$(call _count,$(2))),\ + $(call _EQ,$(call _count,$(1)),$(words $(call gmsl_pairmap,_equal?,$(call __get_obj_values,$(1)),$(call __get_obj_values,$(2)))))),$(__true),),\ + $(call _EQ,$(1),$(2)))))))) _undefined? = $(or $(call _EQ,undefined,$(origin $(1))),$(filter $(__undefined),$($(1)))) -undefined? = $(if $(call _undefined?,$(1)),$(__true),$(__false)) _nil? = $(if $(filter $(__obj_magic)__nil_%,$(1)),$(__true),) -nil? = $(if $(call _nil?,$(1)),$(__true),$(__false)) -nil_pr_str = nil _true? = $(if $(filter $(__obj_magic)_true_%,$(1)),$(__true),) -true? = $(if $(call _true?,$(1)),$(__true),$(__false)) -true_pr_str = true _false? = $(if $(filter $(__obj_magic)_fals_%,$(1)),$(__true),) -false? = $(if $(call _false?,$(1)),$(__true),$(__false)) -false_pr_str = false -# -# Numbers -# +# Symbols +_symbol = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_symb_$(hcode)$(eval $(__obj_magic)_symb_$(hcode)_value := $(1))) +_symbol? = $(if $(filter $(__obj_magic)_symb_%,$(1)),$(__true),) -_pnumber = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_numb_$(hcode)$(eval $(__obj_magic)_numb_$(hcode)_value := $(1))) -number = $(call _pnumber,$(call int_encode,$(1))) +# Numbers +_pnumber = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_numb_$(hcode)$(eval $(__obj_magic)_numb_$(hcode)_value := $(1))) +_number = $(call _pnumber,$(call int_encode,$(1))) _number? = $(if $(filter $(__obj_magic)_numb_%,$(1)),$(__true),) -number? = $(if $(call _number?,$(1)),$(__true),$(__false)) - -number_pr_str = $(call int_decode,$($(1)_value)) - -number_plus = $(call _pnumber,$(call int_plus,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) -number_subtract = $(call _pnumber,$(call int_subtract,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) -number_multiply = $(call _pnumber,$(call int_multiply,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) -number_divide = $(call _pnumber,$(call int_divide,$($(word 1,$(1))_value),$($(word 2,$(1))_value))) -number_gt = $(if $(call int_gt,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) -number_gte = $(if $(call int_gte,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) -number_lt = $(if $(call int_lt,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) -number_lte = $(if $(call int_lte,$($(word 1,$(1))_value),$($(word 2,$(1))_value)),$(__true),$(__false)) - -# -# Symbols -# -symbol = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_symb_$(hcode)$(eval $(__obj_magic)_symb_$(hcode)_value := $(1))) - -_symbol? = $(if $(filter $(__obj_magic)_symb_%,$(1)),$(__true),) -symbol? = $(if $(call _symbol?,$(1)),$(__true),$(__false)) - -symbol_pr_str = $($(1)_value) - -# # Strings -# -_string = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(1))) -string = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(call str_encode,$(1)))) - +__string = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(1))) +_string = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_strn_$(hcode)$(eval $(__obj_magic)_strn_$(hcode)_value := $(call str_encode,$(1)))) _string? = $(if $(filter $(__obj_magic)_strn_%,$(1)),$(__true),) -string? = $(if $(call _string?,$(1)),$(__true),$(__false)) - -string_pr_str = $(if $(2),"$(subst $(DQUOTE),$(ESC_DQUOTE),$(subst $(SLASH),$(SLASH)$(SLASH),$(call str_decode,$($(1)_value))))",$(call str_decode,$($(1)_value))) - -subs = $(strip \ - $(foreach start,$(call gmsl_plus,1,$(call int_decode,$($(word 2,$(1))_value))),\ - $(foreach end,$(if $(3),$(call int_decode,$($(3)_value)),$(words $($(word 1,$(1))_value))),\ - $(call _string,$(wordlist $(start),$(end),$($(word 1,$(1))_value)))))) -# -# Function objects -# +# Functions # Return a function object. The first parameter is the # function/macro 'source'. Note that any $ must be escaped as $$ to be # preserved and become positional arguments for when the # function/macro is later invoked. -function = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_func_$(hcode)$(eval $(__obj_magic)_func_$(hcode)_value = $(1))) - +_function = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_func_$(hcode)$(eval $(__obj_magic)_func_$(hcode)_value = $(1))) _function? = $(if $(filter $(__obj_magic)_func_%,$(1)),$(__true),) -function? = $(if $(call _function?,$(1)),$(__true),$(__false)) - -function_pr_str = <$(if $(word 6,$(value $(1)_value)),$(wordlist 1,5,$(value $(1)_value))...,$(value $(1)_value))> # Takes a function name and a list object of arguments and invokes # the function with space separated arguments @@ -179,25 +158,20 @@ _apply = $(call $(1),$($(2)_value)) # the function with space separated arguments apply = $(call $(1)_value,$($(2)_value)) -# Takes a space separated arguments and invokes the first argument -# (function object) using the remaining arguments. -sapply = $(call $(word 1,$(1))_value,\ - $(strip \ - $(wordlist 2,$(call gmsl_subtract,$(words $(1)),1),$(1)) \ - $($(word $(words $(1)),$(1))_value))) -# -# hash maps (associative arrays) -# +# Lists +_list = $(word 1,$(foreach new_list,$(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_list_$(hcode)),$(new_list) $(eval $(new_list)_value := $1))) +_list? = $(if $(filter $(__obj_magic)_list_%,$(1)),$(__true),) -# create a new anonymous empty hash map -_hash_map = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_hmap_$(hcode)$(eval $(__obj_magic)_hmap_$(hcode)_size := 0)) -hash_map = $(word 1,$(foreach new_hmap,$(call _hash_map),$(new_hmap) $(if $(1),$(call _assoc_seq!,$(new_hmap),$(1))))) -_hash_map? = $(if $(filter $(__obj_magic)_hmap_%,$(1)),$(__true),) -hash_map? = $(if $(call _hash_map?,$(1)),$(__true),$(__false)) +# Vectors (same as lists for now) +_vector = $(word 1,$(foreach new_vect,$(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_vect_$(hcode)),$(new_vect) $(eval $(new_vect)_value := $1))) +_vector? = $(if $(filter $(__obj_magic)_vect_%,$(1)),$(__true),) + -hash_map_pr_str = {$(foreach v,$(call __get_obj_values,$(1)),"$(foreach hcode,$(word 3,$(subst _, ,$(1))),$(patsubst $(1)_%,%,$(v:%_value=%)))" $(call _pr_str,$($(v)),$(2)))} +# Hash maps (associative arrays) +_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)))))) +_hash_map? = $(if $(filter $(__obj_magic)_hmap_%,$(1)),$(__true),) # Set multiple key/values in a map _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))),) @@ -205,30 +179,9 @@ _assoc_seq! = $(call _assoc!,$(1),$(call str_decode,$($(word 1,$(2))_value)),$(w # set a key/value in the hash map _assoc! = $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),$(eval $(1)_size := $(call gmsl_plus,$($(1)_size),1)),)$(eval $(1)_$(k)_value := $(3))$(1)) -# set a key/value in a copy of the hash map -assoc = $(word 1,\ - $(foreach hm,$(call _clone_obj,$(word 1,$(1))),\ - $(hm) \ - $(call _assoc_seq!,$(hm),$(wordlist 2,$(words $(1)),$(1))))) - # unset a key in the hash map _dissoc! = $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),,$(eval $(1)_$(k)_value := $(__undefined))$(eval $(1)_size := $(call gmsl_subtract,$($(1)_size),1))))$(1) -# unset keys in a copy of the hash map -# TODO: this could be made more efficient by copying only the -# keys that not being removed. -dissoc = $(word 1,\ - $(foreach hm,$(call _clone_obj,$(word 1,$(1))),\ - $(hm) \ - $(foreach key,$(wordlist 2,$(words $(1)),$(1)),\ - $(call _dissoc!,$(hm),$(call str_decode,$($(key)_value)))))) - -keys = $(foreach new_list,$(call _list),$(new_list)$(eval $(new_list)_value := $(foreach v,$(call __get_obj_values,$(1)),$(call string,$(word 4,$(subst _, ,$(v))))))) - -vals = $(foreach new_list,$(call _list),$(new_list)$(eval $(new_list)_value := $(foreach v,$(call __get_obj_values,$(1)),$($(v))))) - - - # Hash map and vector functions # retrieve the value of a plain string key from the hash map, or @@ -240,104 +193,20 @@ _get = $(strip \ $(word $(call gmsl_plus,1,$(2)),$($(1)_value)),\ ,))) -# retrieve the value of a string key object from the hash map, or -# retrive a vector by number object index -get = $(strip \ - $(if $(call _hash_map?,$(word 1,$(1))),\ - $(call _get,$(word 1,$(1)),$(call str_decode,$($(word 2,$(1))_value))),\ - $(call _get,$(word 1,$(1)),$(call number_pr_str,$(word 2,$(1)))))) - _contains? = $(strip \ $(if $(call _hash_map?,$(1)),\ $(foreach k,$(subst =,$(__equal),$(2)),$(if $(call _undefined?,$(1)_$(k)_value),,$(__true))),\ $(if $(call _vector?,$(1)),\ $(if $(word $(call gmsl_plus,1,$(2)),$($(1)_value)),$(__true),),\ ,))) -contains? = $(if $(call _contains?,$(word 1,$(1)),$(call str_decode,$($(word 2,$(1))_value))),$(__true),$(__false)) - - -# -# Errors/Exceptions -# -_error = $(eval __ERROR := $(call string,$(1))) -throw = $(eval __ERROR := $(1)) - - -# -# vectors -# - -_vector = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_vect_$(hcode)) -vector = $(word 1,$(foreach new_vect,$(call _vector),$(new_vect) $(eval $(new_vect)_value := $1))) - -_vector? = $(if $(filter $(__obj_magic)_vect_%,$(1)),$(__true),) -vector? = $(if $(call _vector?,$(1)),$(__true),$(__false)) - -vector_pr_str = [$(foreach v,$(call __get_obj_values,$(1)),$(call _pr_str,$(v),$(2)))] - -# -# list (same as vectors for now) -# - -_list = $(foreach hcode,$(call __new_obj_hash_code),$(__obj_magic)_list_$(hcode)) -list = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $1))) - -_list? = $(if $(filter $(__obj_magic)_list_%,$(1)),$(__true),) -list? = $(if $(call _list?,$(1)),$(__true),$(__false)) - -list_pr_str = ($(foreach v,$(call __get_obj_values,$(1)),$(call _pr_str,$(v),$(2)))) - -cons = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $(strip $(word 1,$(1)) $(call __get_obj_values,$(word 2,$(1))))))) -# -# atoms -# -atom = $(strip \ - $(foreach hcode,$(call __new_obj_hash_code),\ - $(foreach new_atom,$(__obj_magic)_atom_$(hcode),\ - $(new_atom)\ - $(eval $(new_atom)_value := $(1))))) - -_atom? = $(if $(filter $(__obj_magic)_atom_%,$(1)),$(__true),) -atom? = $(if $(call _atom?,$(1)),$(__true),$(__false)) - -atom_pr_str = (atom $(call _pr_str,$($(1)_value),$(2))) - -deref = $($(1)_value) - -reset! = $(eval $(word 1,$(1))_value := $(word 2,$(1)))$(word 2,$(1)) - -swap! = $(foreach resp,$(call $(word 2,$(1))_value,$($(word 1,$(1))_value) $(wordlist 3,$(words $(1)),$(1))),\ - $(eval $(word 1,$(1))_value := $(resp))\ - $(resp)) - - -# # sequence operations -# _sequential? = $(if $(filter $(__obj_magic)_list_% $(__obj_magic)_vect_%,$(1)),$(__true),) -sequential? = $(if $(call _sequential?,$(1)),$(__true),$(__false)) - -raw_flat = $(foreach val,$(call __get_obj_values,$(1)),$($(val))) _nth = $(word $(call gmsl_plus,1,$(2)),$($(1)_value)) -nth = $(word $(call gmsl_plus,1,$(call int_decode,$($(word 2,$(1))_value))),$($(word 1,$(1))_value)) - -empty? = $(if $(call _EQ,0,$(if $(call _hash_map?,$(1)),$($(1)_size),$(words $($(1)_value)))),$(__true),$(__false)) - -concat = $(word 1,$(foreach new_list,$(call _list),$(new_list) $(eval $(new_list)_value := $(strip $(foreach lst,$1,$(call __get_obj_values,$(lst))))))) - -conj = $(word 1,$(foreach new_list,$(call __new_obj_like,$(word 1,$(1))),\ - $(new_list) \ - $(eval $(new_list)_value := $(strip $($(word 1,$(1))_value))) \ - $(if $(call _list?,$(new_list)),\ - $(foreach elem,$(wordlist 2,$(words $(1)),$(1)),\ - $(eval $(new_list)_value := $(strip $(elem) $($(new_list)_value)))),\ - $(eval $(new_list)_value := $(strip $($(new_list)_value) $(wordlist 2,$(words $(1)),$(1))))))) - # conj that mutates a sequence in-place to append the call arguments _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) @@ -345,11 +214,6 @@ _count = $(strip \ $(if $(call _hash_map?,$(1)),\ $($(1)_size),\ $(words $($(1)_value)))) -count = $(call number,$(call _count,$(1))) - -sfirst = $(word 1,$($(1)_value)) - -slast = $(word $(words $($(1)_value)),$($(1)_value)) # Creates a new vector/list of the everything after but the first # element @@ -366,135 +230,15 @@ _smap = $(word 1,\ # Same as _smap but returns a vector _smap_vec = $(word 1,\ - $(foreach new_vector,$(call vector),\ + $(foreach new_vector,$(call _vector),\ $(new_vector)\ $(foreach v,$(call __get_obj_values,$(2)),\ $(call _conj!,$(new_vector),$(call $(1),$(v),$(3),$(4)))))) -# Map a function object over a list object -smap = $(strip\ - $(foreach func,$(word 1,$(1)),\ - $(foreach lst,$(word 2,$(1)),\ - $(foreach type,$(word 2,$(subst _, ,$(lst))),\ - $(foreach new_hcode,$(call __new_obj_hash_code),\ - $(foreach sz,$(words $(call __get_obj_values,$(lst))),\ - $(eval $(__obj_magic)_$(type)_$(new_hcode)_value := $(strip \ - $(foreach val,$(call __get_obj_values,$(lst)),\ - $(call $(func)_value,$(val))))))\ - $(__obj_magic)_$(type)_$(new_hcode)))))) - - - -_equal? = $(strip \ - $(foreach ot1,$(call _obj_type,$(1)),$(foreach ot2,$(call _obj_type,$(2)),\ - $(if $(or $(call _EQ,$(ot1),$(ot2)),\ - $(and $(call _sequential?,$(1)),$(call _sequential?,$(2)))),\ - $(if $(or $(call _string?,$(1)),$(call _symbol?,$(1)),$(call _number?,$(1))),\ - $(call _EQ,$($(1)_value),$($(2)_value)),\ - $(if $(or $(call _vector?,$(1)),$(call _list?,$(1)),$(call _hash_map?,$(1))),\ - $(if $(and $(call _EQ,$(call _count,$(1)),$(call _count,$(2))),\ - $(call _EQ,$(call _count,$(1)),$(words $(call gmsl_pairmap,_equal?,$(call __get_obj_values,$(1)),$(call __get_obj_values,$(2)))))),$(__true),),\ - $(call _EQ,$(1),$(2)))))))) - -equal? = $(if $(call _equal?,$(word 1,$(1)),$(word 2,$(1))),$(__true),$(__false)) - -# -# ENV -# - -# An ENV environment is a hash-map with an __outer__ reference to an -# outer environment -define BIND_ARGS -$(strip \ - $(word 1,$(1) \ - $(foreach fparam,$(call _nth,$(2),0),\ - $(if $(call _EQ,&,$($(fparam)_value)), - $(call ENV_SET,$(1),$($(call _nth,$(2),1)_value),$(strip \ - $(foreach new_list,$(call _list), - $(word 1,$(new_list) \ - $(foreach val,$(3),$(call _conj!,$(new_list),$(val))))))),\ - $(foreach val,$(word 1,$(3)),\ - $(call ENV_SET,$(1),$($(fparam)_value),$(val))\ - $(foreach left,$(call srest,$(2)),\ - $(if $(call _EQ,0,$(call _count,$(left))),\ - ,\ - $(call BIND_ARGS,$(1),$(left),$(wordlist 2,$(words $(3)),$(3)))))))))) -endef - -# Create a new ENV and optional bind values in it -# $(1): outer environment (set as a key named __outer__) -# $(2): list/vector object of bind forms -# $(3): space separated list of expressions to bind -ENV = $(strip $(foreach new_env,$(call _assoc!,$(call _hash_map),__outer__,$(if $(1),$(1),$(__nil))),$(if $(2),$(call BIND_ARGS,$(new_env),$(2),$(3)),$(new_env)))) -ENV_FIND = $(strip \ - $(if $(call _contains?,$(1),$(subst =,$(__equal),$(2))),\ - $(1),\ - $(if $(call _EQ,$(__nil),$(call _get,$(1),__outer__)),\ - ,\ - $(call ENV_FIND,$(call _get,$(1),__outer__),$(2))))) - -ENV_GET = $(foreach env,|$(call ENV_FIND,$(1),$(2))|,$(if $(call _EQ,||,$(env)),$(call _error,'$(2)' not found),$(call _get,$(strip $(subst |,,$(env))),$(subst =,$(__equal),$(2))))) - -ENV_SET = $(if $(call _assoc!,$(1),$(subst =,$(__equal),$(2)),$(3)),$(1),) - -# -# Visualize Objects in memory -# - -__var_name = $(word 2,$(subst _, ,$(1)))_$(word 3,$(subst _, ,$(1))) -__var_idx := 0 -__var_print = $(foreach v,$(1),\ - $(foreach var,$(call __var_name,$(v)),\ - $(if $(or $(call _list?,$(v)),$(call _vector?,$(v))),\ - $(info $(2)$(var):)\ - $(eval __var_idx := $(call gmsl_plus,1,$(__var_idx)))\ - $(foreach lidx,__lidx_$(__var_idx),\ - $(eval $(lidx) := 0)\ - $(foreach val,$($(v)_value),\ - $(call __var_print,$(val),$(2)$(SPACE)$(SPACE)$($(lidx)): )\ - $(eval $(lidx) := $(call gmsl_plus,1,$($(lidx)))))),\ - $(if $(call _hash_map?,$(v)),\ - $(info $(2)$(var):)\ - $(foreach vkey,$(filter $(v)_%,$(.VARIABLES)),\ - $(foreach key,$(word 4,$(subst _, ,$(vkey))),\ - $(info $(2)$(SPACE)$(SPACE)$(subst $(__equal),=,$(key)): )\ - $(call __var_print,$($(vkey)),$(2)$(SPACE)$(SPACE)$(SPACE)$(SPACE)))),\ - $(if $(call _symbol?,$(v)),\ - $(info $(2)$(var): $($(v)_value)),\ - $(if $(call _number?,$(v)),\ - $(info $(2)$(var): $(call int_decode,$($(v)_value))),\ - $(if $(call _nil?,$(v)),\ - $(info $(2)nil),\ - $(if $(call _function?,$(v)),\ - $(if $(word 6,$(value $(v)_value)),\ - $(info $(2)$(var): $(wordlist 1,5,$(value $(v)_value))...),\ - $(info $(2)$(var): $(value $(v)_value))),\ - $(info $(2)$(var): ...))))))))) +# atoms -visualize_memory = $(foreach var,$(sort $(foreach vv,$(filter $(__obj_magic)_%,$(.VARIABLES)),$(call __var_name,$(vv)))),$(call __var_print,$(__obj_magic)_$(var))) +_atom? = $(if $(filter $(__obj_magic)_atom_%,$(1)),$(__true),) -# -# Namespace of type functions -# -types_ns = pr-str pr_str str str prn prn println println \ - with-meta with_meta meta meta \ - type obj_type = equal? \ - nil? nil? true? true? false? false? \ - number? number? \ - > number_gt >= number_gte < number_lt <= number_lte \ - + number_plus - number_subtract * number_multiply / number_divide \ - symbol? symbol? function? function? \ - string? string? subs subs \ - hash-map hash_map map? hash_map? assoc assoc dissoc dissoc \ - get get contains? contains? keys keys vals vals \ - throw throw \ - list list list? list? \ - vector vector vector? vector? \ - atom atom atom? atom? deref deref reset! reset! swap! swap! \ - sequential? sequential? \ - cons cons nth nth empty? empty? count count concat concat \ - conj conj first sfirst last slast rest srest \ - apply sapply map smap \ endif |
