mirror of
https://github.com/kanaka/mal.git
synced 2024-10-05 18:08:55 +03:00
88 lines
1.8 KiB
Makefile
88 lines
1.8 KiB
Makefile
#
|
|
# mal (Make Lisp)
|
|
#
|
|
_TOP_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
|
include $(_TOP_DIR)readline.mk
|
|
include $(_TOP_DIR)util.mk
|
|
include $(_TOP_DIR)types.mk
|
|
include $(_TOP_DIR)reader.mk
|
|
include $(_TOP_DIR)printer.mk
|
|
include $(_TOP_DIR)core.mk
|
|
|
|
SHELL := /bin/bash
|
|
EVAL_DEBUG ?=
|
|
|
|
# READ: read and parse input
|
|
define READ
|
|
$(READ_STR)
|
|
endef
|
|
|
|
# EVAL: evaluate the parameter
|
|
|
|
EVAL_nil = $1
|
|
EVAL_true = $1
|
|
EVAL_false = $1
|
|
EVAL_string = $1
|
|
EVAL_number = $1
|
|
EVAL_keyword = $1
|
|
|
|
EVAL_symbol = $(or $(call _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)\
|
|
,$(call EVAL_apply,$(_seq_vals),$2)$(rem \
|
|
),$1)
|
|
endef
|
|
|
|
define EVAL_apply
|
|
$(foreach f,$(call EVAL,$(firstword $1),$2)\
|
|
,$(if $(__ERROR)\
|
|
,,$(call _apply,$f,$(foreach a,$(_rest),$(call EVAL,$a,$2)))))
|
|
endef
|
|
|
|
define EVAL
|
|
$(if $(__ERROR)\
|
|
,,$(if $(EVAL_DEBUG),\
|
|
$(call print,EVAL: $(call _pr_str,$1,yes)))$(rem \
|
|
)$(call EVAL_$(_obj_type),$1,$2))
|
|
endef
|
|
|
|
|
|
# PRINT:
|
|
define PRINT
|
|
$(if $(__ERROR)\
|
|
,Error$(encoded_colon)$(_SP)$(call _pr_str,$(__ERROR),yes)$(rem \
|
|
),$(call _pr_str,$1,yes))
|
|
endef
|
|
|
|
# REPL:
|
|
REPL_ENV := $(call hash-map,$(foreach f,+ - * /\
|
|
,$(call _symbol,$f) $(call _corefn,$f)))
|
|
|
|
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
|
|
|
|
# repl loop
|
|
$(REPL)
|
|
|
|
# Do not complain that there is no target.
|
|
.PHONY: none
|
|
none:
|
|
@true
|