mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 00:52:44 +03:00
ea81a8087b
- types: low-level mapping to the implementation language. - core: functions on types that are exposed directly to mal. - printer: implementation called by pr-str, str, prn, println. - env: the environment implementation - Also, unindent all TCO while loops so that the diff of step4 and step5 are minimized.
51 lines
1.8 KiB
Makefile
51 lines
1.8 KiB
Makefile
#
|
|
# 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
|