2014-03-25 01:32:24 +04:00
|
|
|
#
|
|
|
|
# mal (Make Lisp)
|
|
|
|
#
|
|
|
|
_TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
include $(_TOP_DIR)readline.mk
|
|
|
|
include $(_TOP_DIR)util.mk
|
2014-03-25 01:32:24 +04:00
|
|
|
include $(_TOP_DIR)types.mk
|
|
|
|
include $(_TOP_DIR)reader.mk
|
2014-04-03 07:23:37 +04:00
|
|
|
include $(_TOP_DIR)printer.mk
|
|
|
|
include $(_TOP_DIR)env.mk
|
|
|
|
include $(_TOP_DIR)core.mk
|
2014-03-25 01:32:24 +04:00
|
|
|
|
|
|
|
SHELL := /bin/bash
|
|
|
|
|
|
|
|
# READ: read and parse input
|
|
|
|
define READ
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(READ_STR)
|
2014-03-25 01:32:24 +04:00
|
|
|
endef
|
|
|
|
|
|
|
|
# EVAL: evaluate the parameter
|
|
|
|
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
# If $1 is empty, `foreach` does no iteration at all.
|
|
|
|
starts_with? = $(foreach f,$(firstword $1)\
|
|
|
|
,$(and $(call _symbol?,$f),\
|
|
|
|
$(filter $2,$(call _symbol_val,$f))))
|
|
|
|
|
2020-07-21 19:01:48 +03:00
|
|
|
# elt, accumulator list -> new accumulator list
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
QQ_LOOP = $(if $(and $(_list?),\
|
|
|
|
$(call starts_with?,$(_seq_vals),splice-unquote))\
|
|
|
|
,$(call list,$(call _symbol,concat) $(lastword $(_seq_vals)) $2)$(rem \
|
|
|
|
),$(call list,$(call _symbol,cons) $(call QUASIQUOTE,$1) $2))
|
2020-07-21 19:01:48 +03:00
|
|
|
|
|
|
|
# list or vector source -> right folded list
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
QQ_FOLD = $(if $1\
|
|
|
|
,$(call QQ_LOOP,$(firstword $1),$(call QQ_FOLD,$(_rest)))$(rem \
|
|
|
|
),$(call list))
|
|
|
|
|
|
|
|
QUASIQUOTE = $(call QUASIQUOTE_$(_obj_type),$1)
|
|
|
|
QUASIQUOTE_nil = $1
|
|
|
|
QUASIQUOTE_true = $1
|
|
|
|
QUASIQUOTE_false = $1
|
|
|
|
QUASIQUOTE_string = $1
|
|
|
|
QUASIQUOTE_number = $1
|
|
|
|
QUASIQUOTE_keyword = $1
|
|
|
|
QUASIQUOTE_symbol = $(call list,$(call _symbol,quote) $1)
|
|
|
|
QUASIQUOTE_map = $(call list,$(call _symbol,quote) $1)
|
|
|
|
|
|
|
|
QUASIQUOTE_vector = $(call list,$(call _symbol,vec) $(call QQ_FOLD,$(_seq_vals)))
|
|
|
|
|
|
|
|
QUASIQUOTE_list = $(if $(call starts_with?,$(_seq_vals),unquote)\
|
|
|
|
,$(lastword $(_seq_vals))$(rem \
|
|
|
|
),$(call QQ_FOLD,$(_seq_vals)))
|
|
|
|
|
|
|
|
EVAL_special_quote = $1
|
|
|
|
|
|
|
|
EVAL_special_quasiquote = $(call EVAL,$(QUASIQUOTE),$2)
|
|
|
|
|
|
|
|
EVAL_nil = $1
|
|
|
|
EVAL_true = $1
|
|
|
|
EVAL_false = $1
|
|
|
|
EVAL_string = $1
|
|
|
|
EVAL_number = $1
|
|
|
|
EVAL_keyword = $1
|
|
|
|
|
|
|
|
EVAL_symbol = $(or $(call ENV_GET,$2,$1),$(call _error,'$(_symbol_val)' not found))
|
|
|
|
|
|
|
|
EVAL_vector = $(call vector,$(foreach e,$(_seq_vals),$(call EVAL,$e,$2)))
|
|
|
|
|
|
|
|
# First foreach defines a constant, second one loops on keys.
|
|
|
|
define EVAL_map
|
|
|
|
$(foreach obj,$(call _map_new)\
|
|
|
|
,$(obj)$(rem $(foreach k,$(_keys)\
|
|
|
|
,$(call _assoc!,$(obj),$k,$(call EVAL,$(call _get,$1,$k),$2)))))
|
|
|
|
endef
|
|
|
|
|
|
|
|
define EVAL_list
|
|
|
|
$(if $(_seq_vals)\
|
|
|
|
,$(foreach a0,$(firstword $(_seq_vals))\
|
|
|
|
,$(if $(call _symbol?,$(a0))\
|
|
|
|
,$(foreach dispatch,EVAL_special_$(call _symbol_val,$(a0))\
|
|
|
|
,$(if $(filter undefined,$(flavor $(dispatch)))\
|
|
|
|
,$(call EVAL_apply,$(_seq_vals),$2)$(rem \
|
|
|
|
),$(call $(dispatch),$(call _rest,$(_seq_vals)),$2)))$(rem \
|
|
|
|
),$(call EVAL_apply,$(_seq_vals),$2)))$(rem \
|
|
|
|
),$1)
|
|
|
|
endef
|
|
|
|
|
|
|
|
define EVAL_apply
|
|
|
|
$(foreach f,$(call EVAL,$(firstword $1),$2)\
|
|
|
|
,$(if $(__ERROR)\
|
|
|
|
,,$(if $(call _macro?,$f)\
|
|
|
|
,$(call EVAL,$(call _apply,$f,$(_rest)),$2)$(rem \
|
|
|
|
),$(call _apply,$f,$(foreach a,$(_rest),$(call EVAL,$a,$2))))))
|
2014-03-25 01:32:24 +04:00
|
|
|
endef
|
|
|
|
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
define EVAL_special_defmacro!
|
|
|
|
$(foreach res,$(call _as_macro,$(call EVAL,$(lastword $1),$2))\
|
|
|
|
,$(res)$(call ENV_SET,$2,$(firstword $1),$(res)))
|
2014-03-25 01:32:24 +04:00
|
|
|
endef
|
|
|
|
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
define EVAL_special_def!
|
|
|
|
$(foreach res,$(call EVAL,$(lastword $1),$2)\
|
|
|
|
,$(if $(__ERROR)\
|
|
|
|
,,$(res)$(call ENV_SET,$2,$(firstword $1),$(res))))
|
|
|
|
endef
|
|
|
|
|
|
|
|
define EVAL_special_let*
|
|
|
|
$(foreach let_env,$(call ENV,$2)\
|
|
|
|
,$(call _foreach2,$(call _seq_vals,$(firstword $1))\
|
|
|
|
,$$(call ENV_SET,$(let_env),$$k,$$(call EVAL,$$v,$(let_env))))$(rem \
|
|
|
|
)$(call EVAL,$(lastword $1),$(let_env)))
|
|
|
|
endef
|
|
|
|
|
|
|
|
EVAL_special_do = $(lastword $(foreach x,$1,$(call EVAL,$x,$2)))
|
|
|
|
|
|
|
|
define EVAL_special_if
|
|
|
|
$(if $(call truthy?,$(call EVAL,$(firstword $1),$2))\
|
|
|
|
,$(call EVAL,$(word 2,$1),$2)$(rem \
|
|
|
|
),$(if $(word 3,$1)\
|
|
|
|
,$(call EVAL,$(lastword $1),$2)$(rem \
|
|
|
|
),$(__nil)))
|
|
|
|
endef
|
|
|
|
|
|
|
|
EVAL_special_fn* = $(call _function,$(call _seq_vals,$(firstword $1)),$(lastword $1),$2)
|
|
|
|
|
2014-03-25 01:32:24 +04:00
|
|
|
define EVAL
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(if $(__ERROR)\
|
|
|
|
,,$(if $(call truthy?,$(call ENV_GET,$(2),$(call _symbol,DEBUG-EVAL)))\
|
|
|
|
,$(call print,EVAL: $(call _pr_str,$1,yes) env: $(call env_keys,$2)))$(rem \
|
|
|
|
)$(call EVAL_$(_obj_type),$1,$2))
|
2014-03-25 01:32:24 +04:00
|
|
|
endef
|
|
|
|
|
|
|
|
|
|
|
|
# PRINT:
|
|
|
|
define PRINT
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(if $(__ERROR)\
|
|
|
|
,Error$(encoded_colon)$(_SP)$(call _pr_str,$(__ERROR),yes)$(rem \
|
|
|
|
),$(call _pr_str,$1,yes))
|
2014-03-25 01:32:24 +04:00
|
|
|
endef
|
|
|
|
|
|
|
|
# REPL:
|
|
|
|
REPL_ENV := $(call ENV)
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
REP = $(call PRINT,$(call EVAL,$(READ),$(REPL_ENV)))
|
|
|
|
|
|
|
|
# The foreach does nothing when line is empty (EOF).
|
|
|
|
define REPL
|
|
|
|
$(foreach line,$(call READLINE,user>$(_SP))\
|
|
|
|
,$(eval __ERROR :=)$(rem \
|
|
|
|
)$(call print,$(call REP,$(line:ok=)))$(rem \
|
|
|
|
)$(call REPL))
|
|
|
|
endef
|
|
|
|
|
|
|
|
# Read and evaluate for side effects but ignore the result.
|
|
|
|
define RE
|
|
|
|
$(rem $(call EVAL,$(call READ,$(str_encode_nospace)),$(REPL_ENV)) \
|
|
|
|
)$(if $(__ERROR)\
|
|
|
|
,$(error during startup: $(call str_decode_nospace,$(call _pr_str,$(__ERROR),yes))))
|
|
|
|
endef
|
2014-03-25 01:32:24 +04:00
|
|
|
|
2014-04-17 08:57:50 +04:00
|
|
|
# core.mk: defined using Make
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(foreach f,$(core_ns)\
|
|
|
|
,$(call ENV_SET,$(REPL_ENV),$(call _symbol,$f),$(call _corefn,$f)))
|
|
|
|
|
|
|
|
core_eval = $(call EVAL,$1,$(REPL_ENV))
|
|
|
|
$(call ENV_SET,$(REPL_ENV),$(call _symbol,eval),$(call _corefn,core_eval))
|
|
|
|
|
|
|
|
$(call ENV_SET,$(REPL_ENV),$(call _symbol,*ARGV*),$(call list,$(foreach arg,\
|
|
|
|
$(call _rest,$(MAKECMDGOALS)),$(call _string,$(call str_encode_nospace,$(arg))))))
|
2014-03-25 01:32:24 +04:00
|
|
|
|
2014-04-17 08:57:50 +04:00
|
|
|
# core.mal: defined in terms of the language itself
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(call RE, (def! not (fn* (a) (if a false true))) )
|
|
|
|
$(call RE, (def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) "\nnil)"))))) )
|
|
|
|
$(call RE, (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw "odd number of forms to cond")) (cons 'cond (rest (rest xs))))))) )
|
2014-03-25 01:32:24 +04:00
|
|
|
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
ifneq (,$(MAKECMDGOALS))
|
2014-03-25 01:32:24 +04:00
|
|
|
# Load and eval any files specified on the command line
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(call RE, (load-file "$(firstword $(MAKECMDGOALS))") )
|
|
|
|
else
|
2014-04-19 22:04:09 +04:00
|
|
|
# repl loop
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
$(REPL)
|
|
|
|
endif
|
2014-04-28 02:58:48 +04:00
|
|
|
|
make: improve efficiency and encapsulation
Readability
* Use implicit parameter transmission ($(_list?) instead of $(call
_list?,$1),
first/lastword instead of word 1/words,
$1 instead of $(1).
* Use an undefined $(rem) macro and some automatic stripping (if,
foreach) to indent code with less calls to `strip` functions.
* Name the Make macro implementing a MAL core function exactly like the
function (modulo the encoding above) and simplify core_ns accordingly.
* Replace empty results representing `nil` with explicit MAL values.
* Implement large conditionals with a computed variable name, as already
done in printer.mk. For QUASIQUOTE and EVAL, this reduces a lot the
diff between steps.
* Represent the reader state as an explicit global variable instead of
passing the same name as argument again and again.
* Merge read-atom into read-form so that the switch on first character
is more visible.
Encapsulation
* Hide most representations into types.mk.
* Implement the type as a suffix in order to avoid a conditional in
_obj_type.
* Implement _error with throw.
* Create distinct types for keywords and macros.
* Move most metadata and atom stuff from core.mk to types.mk.
* Move parameter association from env to types because it hides more
about the representation of functions.
Representation
* Encode Make special characters in all strings/keywords/symbols, so
they can be used directly as spaced words and/or variable names for
map keys. (The encoding adding separating characters is kept for
read-string and seq).
* Change representation of numbers/strings/keywords/symbols, reducing
the number of Make variables.
Various
* Allow keyword argument for keyword core function.
* Shorten time-mes,slurp,readline...
* Remove obsolete stuff:
* `get` and `contains?` for vectors
* `count` for hash-maps
* `_join` from util.mk.
* `type` from core.mk.
* Add a function listing env_keys for DEBUG-EVAL.
* Fix some includes.
2022-02-01 20:06:57 +03:00
|
|
|
# Do not complain that there is no target.
|
2014-04-28 02:58:48 +04:00
|
|
|
.PHONY: none $(MAKECMDGOALS)
|
|
|
|
none $(MAKECMDGOALS):
|
|
|
|
@true
|