# Settings
#
-IMPLS = awk bash c clojure coffee cpp crystal cs erlang elixir es6 factor forth fsharp go groovy \
- guile haskell java julia js lua make mal ocaml matlab miniMAL nim \
- perl php ps python r racket rpython ruby rust scala swift vb vimscript
+IMPLS = awk bash c d clojure coffee cpp crystal cs erlang elixir es6 factor forth fsharp go groovy \
+ guile haskell java julia js kotlin lua make mal ocaml matlab miniMAL nim \
+ perl php ps python r racket rpython ruby rust scala swift tcl vb vimscript
step0 = step0_repl
step1 = step1_read_print
EXCLUDE_TESTS += test^c^step5 # segfault
EXCLUDE_TESTS += test^cpp^step5 # completes at 10,000
EXCLUDE_TESTS += test^cs^step5 # fatal stack overflow fault
+EXCLUDE_TESTS += test^d^step5 # completes at 10,000, fatal stack overflow at 1,000,000
EXCLUDE_TESTS += test^erlang^step5 # erlang is TCO, test passes
EXCLUDE_TESTS += test^elixir^step5 # elixir is TCO, test passes
EXCLUDE_TESTS += test^fsharp^step5 # completes at 10,000, fatal stack overflow at 100,000
awk_STEP_TO_PROG = awk/$($(1)).awk
bash_STEP_TO_PROG = bash/$($(1)).sh
c_STEP_TO_PROG = c/$($(1))
+d_STEP_TO_PROG = d/$($(1))
clojure_STEP_TO_PROG = clojure/src/$($(1)).clj
coffee_STEP_TO_PROG = coffee/$($(1)).coffee
cpp_STEP_TO_PROG = cpp/$($(1))
elixir_STEP_TO_PROG = elixir/lib/mix/tasks/$($(1)).ex
erlang_STEP_TO_PROG = erlang/$($(1))
es6_STEP_TO_PROG = es6/build/$($(1)).js
-factor_STEP_TO_PROG = factor/src/$($(1))/$($(1)).factor
+factor_STEP_TO_PROG = factor/$($(1))/$($(1)).factor
forth_STEP_TO_PROG = forth/$($(1)).fs
fsharp_STEP_TO_PROG = fsharp/$($(1)).exe
go_STEP_TO_PROG = go/$($(1))
haskell_STEP_TO_PROG = haskell/$($(1))
julia_STEP_TO_PROG = julia/$($(1)).jl
js_STEP_TO_PROG = js/$($(1)).js
+kotlin_STEP_TO_PROG = kotlin/$($(1)).jar
lua_STEP_TO_PROG = lua/$($(1)).lua
make_STEP_TO_PROG = make/$($(1)).mk
mal_STEP_TO_PROG = mal/$($(1)).mal
rust_STEP_TO_PROG = rust/target/release/$($(1))
scala_STEP_TO_PROG = scala/$($(1)).scala
swift_STEP_TO_PROG = swift/$($(1))
+tcl_STEP_TO_PROG = tcl/$($(1)).tcl
vb_STEP_TO_PROG = vb/$($(1)).exe
vimscript_STEP_TO_PROG = vimscript/$($(1)).vim
guile_STEP_TO_PROG = guile/$($(1)).scm
COMMA = ,
noop =
SPACE = $(noop) $(noop)
-export FACTOR_ROOTS := src
+export FACTOR_ROOTS := .
awk_RUNSTEP = awk -O -f ../$(2) $(3)
bash_RUNSTEP = bash ../$(2) $(3)
c_RUNSTEP = ../$(2) $(3)
+d_RUNSTEP = ../$(2) $(3)
clojure_RUNSTEP = lein with-profile +$(1) trampoline run $(3)
coffee_RUNSTEP = coffee ../$(2) $(3)
cpp_RUNSTEP = ../$(2) $(3)
java_RUNSTEP = mvn -quiet exec:java -Dexec.mainClass="mal.$($(1))" $(if $(3), -Dexec.args="$(3)",)
julia_RUNSTEP = ../$(2) $(3)
js_RUNSTEP = node ../$(2) $(3)
+kotlin_RUNSTEP = java -jar ../$(2) $(3)
lua_RUNSTEP = ../$(2) $(3)
make_RUNSTEP = make -f ../$(2) $(3)
mal_RUNSTEP = $(call $(MAL_IMPL)_RUNSTEP,stepA,$(call $(MAL_IMPL)_STEP_TO_PROG,stepA),../$(2),") #"
rust_RUNSTEP = ../$(2) $(3)
scala_RUNSTEP = sbt 'run-main $($(1))$(if $(3), $(3),)'
swift_RUNSTEP = ../$(2) $(3)
+tcl_RUNSTEP = tclsh ../$(2) --raw $(3)
vb_RUNSTEP = mono ../$(2) --raw $(3)
vimscript_RUNSTEP = ./run_vimscript.sh ../$(2) $(3)
# needs TERM=dumb to work with readline
IMPL_PERF = $(filter-out $(EXCLUDE_PERFS),$(foreach impl,$(DO_IMPLS),perf^$(impl)))
+IMPL_REPL = $(foreach impl,$(DO_IMPLS),repl^$(impl))
+ALL_REPL = $(strip $(sort \
+ $(foreach impl,$(DO_IMPLS),\
+ $(foreach step,$(STEPS),repl^$(impl)^$(step)))))
+
#
# Build rules
#
# Build a program in an implementation directory
+# Make sure we always try and build first because the dependencies are
+# encoded in the implementation Makefile not here
+.PHONY: $(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(call $(i)_STEP_TO_PROG,$(s))))
$(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(call $(i)_STEP_TO_PROG,$(s)))):
- $(MAKE) -C $(dir $(@)) $(notdir $(@))
+ $(foreach impl,$(word 1,$(subst /, ,$(@))),\
+ $(MAKE) -C $(impl) $(subst $(impl)/,,$(@)))
# Allow test, test^STEP, test^IMPL, and test^IMPL^STEP
.SECONDEXPANSION:
$(call $(impl)_RUNSTEP,stepA,$(call $(impl)_STEP_TO_PROG,stepA),../tests/perf2.mal); \
echo 'Running: $(call $(impl)_RUNSTEP,stepA,$(call $(impl)_STEP_TO_PROG,stepA),../tests/perf3.mal)'; \
$(call $(impl)_RUNSTEP,stepA,$(call $(impl)_STEP_TO_PROG,stepA),../tests/perf3.mal))
+
+# REPL invocation rules
+# Allow repl^IMPL^STEP and repl^IMPL (which starts REPL of stepA)
+
+.SECONDEXPANSION:
+$(IMPL_REPL): $$@^stepA
+
+.SECONDEXPANSION:
+$(ALL_REPL): $$(call $$(word 2,$$(subst ^, ,$$(@)))_STEP_TO_PROG,$$(word 3,$$(subst ^, ,$$(@))))
+ @$(foreach impl,$(word 2,$(subst ^, ,$(@))),\
+ $(foreach step,$(word 3,$(subst ^, ,$(@))),\
+ cd $(if $(filter mal,$(impl)),$(MAL_IMPL),$(impl)); \
+ echo 'REPL implementation $(impl), step file: $+'; \
+ echo 'Running: $(call $(impl)_RUNSTEP,$(step),$(+))'; \
+ $(call $(impl)_RUNSTEP,$(step),$(+));))