1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00
mal/make/env.mk
Joel Martin ea81a8087b All: split types into types, env, printer, core.
- 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.
2014-04-02 22:23:37 -05:00

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