├── .gitattributes ├── .github ├── pull_request_template.md └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── .travis.yml ├── IMPLS.yml ├── LICENSE ├── Makefile ├── Makefile.impls ├── README.md ├── ci.sh ├── docs ├── FAQ.md ├── Hints.md ├── TODO ├── cheatsheet.html ├── exercises.md ├── graph │ ├── README.md │ ├── all_data.json │ ├── base_data.yaml │ ├── collect_data.js │ ├── graph_languages.js │ ├── index.html │ ├── package-lock.json │ ├── package.json │ └── so-tags.csv ├── index.html ├── notes.md ├── step_notes.txt └── web │ ├── ansi.css │ ├── base.css │ ├── bg-body.png │ ├── bg-rule.png │ ├── console.css │ ├── fonts │ ├── exo-black-webfont.eot │ ├── exo-black-webfont.svg │ ├── exo-black-webfont.ttf │ ├── exo-black-webfont.woff │ ├── exo-bold-webfont.eot │ ├── exo-bold-webfont.svg │ ├── exo-bold-webfont.ttf │ ├── exo-bold-webfont.woff │ ├── exo-regular-webfont.eot │ ├── exo-regular-webfont.svg │ ├── exo-regular-webfont.ttf │ └── exo-regular-webfont.woff │ ├── github-icon.png │ ├── himera.css │ ├── jqconsole.min.js │ ├── layout.css │ ├── mal.js │ └── skeleton.css ├── examples ├── clojurewest2014.mal ├── exercises.mal ├── hello.mal └── presentation.mal ├── get-ci-matrix.py ├── impls ├── .gitignore ├── ada.2 │ ├── Dockerfile │ ├── Makefile │ ├── README │ ├── core.adb │ ├── core.ads │ ├── envs.adb │ ├── envs.ads │ ├── err.adb │ ├── err.ads │ ├── garbage_collected.adb │ ├── garbage_collected.ads │ ├── printer.adb │ ├── printer.ads │ ├── reader.adb │ ├── reader.ads │ ├── readline.adb │ ├── readline.ads │ ├── run │ ├── step0_repl.adb │ ├── step1_read_print.adb │ ├── step2_eval.adb │ ├── step3_env.adb │ ├── step4_if_fn_do.adb │ ├── step5_tco.adb │ ├── step6_file.adb │ ├── step7_quote.adb │ ├── step8_macros.adb │ ├── step9_try.adb │ ├── stepa_mal.adb │ ├── types-atoms.adb │ ├── types-atoms.ads │ ├── types-builtins.adb │ ├── types-builtins.ads │ ├── types-fns.adb │ ├── types-fns.ads │ ├── types-maps.adb │ ├── types-maps.ads │ ├── types-sequences.adb │ ├── types-sequences.ads │ ├── types-strings.adb │ ├── types-strings.ads │ ├── types.adb │ └── types.ads ├── ada │ ├── Dockerfile │ ├── Makefile │ ├── core.adb │ ├── core.ads │ ├── envs.adb │ ├── envs.ads │ ├── eval_callback.ads │ ├── printer.adb │ ├── printer.ads │ ├── reader.adb │ ├── reader.ads │ ├── run │ ├── smart_pointers.adb │ ├── smart_pointers.ads │ ├── step0_repl.adb │ ├── step1_read_print.adb │ ├── step2_eval.adb │ ├── step3_env.adb │ ├── step4_if_fn_do.adb │ ├── step5_tco.adb │ ├── step6_file.adb │ ├── step7_quote.adb │ ├── step8_macros.adb │ ├── step9_try.adb │ ├── stepa_mal.adb │ ├── types-hash_map.adb │ ├── types-hash_map.ads │ ├── types-vector.adb │ ├── types-vector.ads │ ├── types.adb │ └── types.ads ├── awk │ ├── Dockerfile │ ├── Makefile │ ├── core.awk │ ├── env.awk │ ├── printer.awk │ ├── reader.awk │ ├── run │ ├── step0_repl.awk │ ├── step1_read_print.awk │ ├── step2_eval.awk │ ├── step3_env.awk │ ├── step4_if_fn_do.awk │ ├── step5_tco.awk │ ├── step6_file.awk │ ├── step7_quote.awk │ ├── step8_macros.awk │ ├── step9_try.awk │ ├── stepA_mal.awk │ ├── tests │ │ └── step5_tco.mal │ └── types.awk ├── bash │ ├── Dockerfile │ ├── Makefile │ ├── core.sh │ ├── env.sh │ ├── printer.sh │ ├── reader.sh │ ├── run │ ├── step0_repl.sh │ ├── step1_read_print.sh │ ├── step2_eval.sh │ ├── step3_env.sh │ ├── step4_if_fn_do.sh │ ├── step5_tco.sh │ ├── step6_file.sh │ ├── step7_quote.sh │ ├── step8_macros.sh │ ├── step9_try.sh │ ├── stepA_mal.sh │ ├── tests │ │ └── stepA_mal.mal │ └── types.sh ├── basic │ ├── .args.mal │ ├── Dockerfile │ ├── Makefile │ ├── basicpp.py │ ├── cbmbasic_console.patch │ ├── core.in.bas │ ├── debug.in.bas │ ├── env.in.bas │ ├── mem.in.bas │ ├── printer.in.bas │ ├── reader.in.bas │ ├── readline.in.bas │ ├── run │ ├── step0_repl.in.bas │ ├── step1_read_print.in.bas │ ├── step2_eval.in.bas │ ├── step3_env.in.bas │ ├── step4_if_fn_do.in.bas │ ├── step5_tco.in.bas │ ├── step6_file.in.bas │ ├── step7_quote.in.bas │ ├── step8_macros.in.bas │ ├── step9_try.in.bas │ ├── stepA_mal.in.bas │ ├── types.in.bas │ └── variables.txt ├── bbc-basic │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── core │ ├── core.bas │ ├── env │ ├── env.bas │ ├── printer │ ├── printer.bas │ ├── reader │ ├── reader.bas │ ├── riscos │ │ ├── .gitignore │ │ ├── setup,feb │ │ └── tokenize,ffe │ ├── run │ ├── step0_repl.bas │ ├── step1_read_print.bas │ ├── step2_eval.bas │ ├── step3_env.bas │ ├── step4_if_fn_do.bas │ ├── step5_tco.bas │ ├── step6_file.bas │ ├── step7_quote.bas │ ├── step8_macros.bas │ ├── step9_try.bas │ ├── stepA_mal.bas │ ├── types │ └── types.bas ├── c.2 │ ├── Dockerfile │ ├── Makefile │ ├── core.c │ ├── core.h │ ├── env.c │ ├── env.h │ ├── libs │ │ ├── hashmap │ │ │ ├── hashmap.c │ │ │ └── hashmap.h │ │ └── linked_list │ │ │ ├── linked_list.c │ │ │ └── linked_list.h │ ├── printer.c │ ├── printer.h │ ├── reader.c │ ├── reader.h │ ├── run │ ├── step0_repl.c │ ├── step1_read_print.c │ ├── step2_eval.c │ ├── step3_env.c │ ├── step4_if_fn_do.c │ ├── step5_tco.c │ ├── step6_file.c │ ├── step7_quote.c │ ├── step8_macros.c │ ├── step9_try.c │ ├── stepA_mal.c │ ├── tests │ │ └── stepA_mal.mal │ ├── types.c │ └── types.h ├── c │ ├── Dockerfile │ ├── Makefile │ ├── core.c │ ├── core.h │ ├── env.c │ ├── interop.c │ ├── interop.h │ ├── printer.c │ ├── printer.h │ ├── reader.c │ ├── reader.h │ ├── readline.c │ ├── readline.h │ ├── run │ ├── step0_repl.c │ ├── step1_read_print.c │ ├── step2_eval.c │ ├── step3_env.c │ ├── step4_if_fn_do.c │ ├── step5_tco.c │ ├── step6_file.c │ ├── step7_quote.c │ ├── step8_macros.c │ ├── step9_try.c │ ├── stepA_mal.c │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ ├── types.c │ └── types.h ├── chuck │ ├── Dockerfile │ ├── Makefile │ ├── chuck.md │ ├── core.ck │ ├── env.ck │ ├── func.ck │ ├── notes.md │ ├── printer.ck │ ├── reader.ck │ ├── readline.ck │ ├── run │ ├── step0_repl.ck │ ├── step1_read_print.ck │ ├── step2_eval.ck │ ├── step3_env.ck │ ├── step4_if_fn_do.ck │ ├── step5_tco.ck │ ├── step6_file.ck │ ├── step7_quote.ck │ ├── step8_macros.ck │ ├── step9_try.ck │ ├── stepA_mal.ck │ ├── tests │ │ └── step5_tco.mal │ ├── types │ │ ├── MalObject.ck │ │ ├── MalSubr.ck │ │ ├── mal │ │ │ ├── MalAtom.ck │ │ │ ├── MalError.ck │ │ │ ├── MalFalse.ck │ │ │ ├── MalHashMap.ck │ │ │ ├── MalInt.ck │ │ │ ├── MalKeyword.ck │ │ │ ├── MalList.ck │ │ │ ├── MalNil.ck │ │ │ ├── MalString.ck │ │ │ ├── MalSymbol.ck │ │ │ ├── MalTrue.ck │ │ │ └── MalVector.ck │ │ └── subr │ │ │ ├── MalAdd.ck │ │ │ ├── MalApply.ck │ │ │ ├── MalAssoc.ck │ │ │ ├── MalAtomify.ck │ │ │ ├── MalConcat.ck │ │ │ ├── MalConj.ck │ │ │ ├── MalCons.ck │ │ │ ├── MalCount.ck │ │ │ ├── MalDeref.ck │ │ │ ├── MalDissoc.ck │ │ │ ├── MalDiv.ck │ │ │ ├── MalDoReset.ck │ │ │ ├── MalDoSwap.ck │ │ │ ├── MalEqual.ck │ │ │ ├── MalFirst.ck │ │ │ ├── MalGet.ck │ │ │ ├── MalGreater.ck │ │ │ ├── MalGreaterEqual.ck │ │ │ ├── MalHashMapify.ck │ │ │ ├── MalIsAtom.ck │ │ │ ├── MalIsContains.ck │ │ │ ├── MalIsEmpty.ck │ │ │ ├── MalIsFalse.ck │ │ │ ├── MalIsFn.ck │ │ │ ├── MalIsHashMap.ck │ │ │ ├── MalIsKeyword.ck │ │ │ ├── MalIsList.ck │ │ │ ├── MalIsMacro.ck │ │ │ ├── MalIsNil.ck │ │ │ ├── MalIsNumber.ck │ │ │ ├── MalIsString.ck │ │ │ ├── MalIsSymbol.ck │ │ │ ├── MalIsTrue.ck │ │ │ ├── MalIsVector.ck │ │ │ ├── MalKeys.ck │ │ │ ├── MalKeywordify.ck │ │ │ ├── MalLess.ck │ │ │ ├── MalLessEqual.ck │ │ │ ├── MalListify.ck │ │ │ ├── MalMap.ck │ │ │ ├── MalMeta.ck │ │ │ ├── MalMul.ck │ │ │ ├── MalNth.ck │ │ │ ├── MalPrStr.ck │ │ │ ├── MalPrintln.ck │ │ │ ├── MalPrn.ck │ │ │ ├── MalReadStr.ck │ │ │ ├── MalReadline.ck │ │ │ ├── MalRest.ck │ │ │ ├── MalSeq.ck │ │ │ ├── MalSequential.ck │ │ │ ├── MalSlurp.ck │ │ │ ├── MalStr.ck │ │ │ ├── MalSub.ck │ │ │ ├── MalSymbolify.ck │ │ │ ├── MalThrow.ck │ │ │ ├── MalTimeMs.ck │ │ │ ├── MalVals.ck │ │ │ ├── MalVec.ck │ │ │ ├── MalVectorify.ck │ │ │ └── MalWithMeta.ck │ └── util │ │ ├── Constants.ck │ │ ├── String.ck │ │ └── Util.ck ├── clojure │ ├── Dockerfile │ ├── Makefile │ ├── package.json │ ├── project.clj │ ├── run │ ├── src │ │ └── mal │ │ │ ├── core.cljc │ │ │ ├── env.cljc │ │ │ ├── node_readline.js │ │ │ ├── printer.cljc │ │ │ ├── reader.cljc │ │ │ ├── readline.clj │ │ │ ├── readline.cljs │ │ │ ├── step0_repl.cljc │ │ │ ├── step1_read_print.cljc │ │ │ ├── step2_eval.cljc │ │ │ ├── step3_env.cljc │ │ │ ├── step4_if_fn_do.cljc │ │ │ ├── step5_tco.cljc │ │ │ ├── step6_file.cljc │ │ │ ├── step7_quote.cljc │ │ │ ├── step8_macros.cljc │ │ │ ├── step9_try.cljc │ │ │ └── stepA_mal.cljc │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── coffee │ ├── Dockerfile │ ├── Makefile │ ├── core.coffee │ ├── env.coffee │ ├── node_readline.coffee │ ├── package.json │ ├── printer.coffee │ ├── reader.coffee │ ├── run │ ├── step0_repl.coffee │ ├── step1_read_print.coffee │ ├── step2_eval.coffee │ ├── step3_env.coffee │ ├── step4_if_fn_do.coffee │ ├── step5_tco.coffee │ ├── step6_file.coffee │ ├── step7_quote.coffee │ ├── step8_macros.coffee │ ├── step9_try.coffee │ ├── stepA_mal.coffee │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.coffee ├── common-lisp │ ├── Dockerfile │ ├── Makefile │ ├── README.org │ ├── fake-readline.lisp │ ├── hist │ │ └── .keepdir │ ├── run │ ├── run-abcl.lisp │ ├── run-mkcl.lisp │ ├── src │ │ ├── core.lisp │ │ ├── env.lisp │ │ ├── printer.lisp │ │ ├── reader.lisp │ │ ├── step0_repl.lisp │ │ ├── step1_read_print.lisp │ │ ├── step2_eval.lisp │ │ ├── step3_env.lisp │ │ ├── step4_if_fn_do.lisp │ │ ├── step5_tco.lisp │ │ ├── step6_file.lisp │ │ ├── step7_quote.lisp │ │ ├── step8_macros.lisp │ │ ├── step9_try.lisp │ │ ├── stepA_mal.lisp │ │ ├── types.lisp │ │ └── utils.lisp │ ├── step0_repl.asd │ ├── step1_read_print.asd │ ├── step2_eval.asd │ ├── step3_env.asd │ ├── step4_if_fn_do.asd │ ├── step5_tco.asd │ ├── step6_file.asd │ ├── step7_quote.asd │ ├── step8_macros.asd │ ├── step9_try.asd │ ├── stepA_mal.asd │ └── tests │ │ └── stepA_mal.mal ├── cpp │ ├── .gitignore │ ├── Core.cpp │ ├── Debug.h │ ├── Dockerfile │ ├── Environment.cpp │ ├── Environment.h │ ├── MAL.h │ ├── Makefile │ ├── README.md │ ├── ReadLine.cpp │ ├── ReadLine.h │ ├── Reader.cpp │ ├── RefCountedPtr.h │ ├── StaticList.h │ ├── String.cpp │ ├── String.h │ ├── Types.cpp │ ├── Types.h │ ├── Validation.cpp │ ├── Validation.h │ ├── docker.sh │ ├── run │ ├── step0_repl.cpp │ ├── step1_read_print.cpp │ ├── step2_eval.cpp │ ├── step3_env.cpp │ ├── step4_if_fn_do.cpp │ ├── step5_tco.cpp │ ├── step6_file.cpp │ ├── step7_quote.cpp │ ├── step8_macros.cpp │ ├── step9_try.cpp │ ├── stepA_mal.cpp │ └── tests │ │ └── step5_tco.mal ├── crystal │ ├── Dockerfile │ ├── Makefile │ ├── core.cr │ ├── env.cr │ ├── error.cr │ ├── printer.cr │ ├── reader.cr │ ├── run │ ├── shard.yml │ ├── step0_repl.cr │ ├── step1_read_print.cr │ ├── step2_eval.cr │ ├── step3_env.cr │ ├── step4_if_fn_do.cr │ ├── step5_tco.cr │ ├── step6_file.cr │ ├── step7_quote.cr │ ├── step8_macros.cr │ ├── step9_try.cr │ ├── stepA_mal.cr │ ├── tests │ │ └── step5_tco.mal │ └── types.cr ├── cs │ ├── Dockerfile │ ├── Makefile │ ├── core.cs │ ├── env.cs │ ├── getline.cs │ ├── interop.cs │ ├── printer.cs │ ├── reader.cs │ ├── readline.cs │ ├── run │ ├── step0_repl.cs │ ├── step1_read_print.cs │ ├── step2_eval.cs │ ├── step3_env.cs │ ├── step4_if_fn_do.cs │ ├── step5_tco.cs │ ├── step6_file.cs │ ├── step7_quote.cs │ ├── step8_macros.cs │ ├── step9_try.cs │ ├── stepA_mal.cs │ ├── tests │ │ └── step5_tco.mal │ └── types.cs ├── d │ ├── Dockerfile │ ├── Makefile │ ├── env.d │ ├── main.di │ ├── mal_core.d │ ├── printer.d │ ├── reader.d │ ├── readline.d │ ├── run │ ├── step0_repl.d │ ├── step1_read_print.d │ ├── step2_eval.d │ ├── step3_env.d │ ├── step4_if_fn_do.d │ ├── step5_tco.d │ ├── step6_file.d │ ├── step7_quote.d │ ├── step8_macros.d │ ├── step9_try.d │ ├── stepA_mal.d │ ├── tests │ │ └── step5_tco.mal │ └── types.d ├── dart │ ├── .analysis_options │ ├── .packages │ ├── Dockerfile │ ├── Makefile │ ├── core.dart │ ├── env.dart │ ├── printer.dart │ ├── pubspec.lock │ ├── pubspec.yaml │ ├── reader.dart │ ├── run │ ├── step0_repl.dart │ ├── step1_read_print.dart │ ├── step2_eval.dart │ ├── step3_env.dart │ ├── step4_if_fn_do.dart │ ├── step5_tco.dart │ ├── step6_file.dart │ ├── step7_quote.dart │ ├── step8_macros.dart │ ├── step9_try.dart │ ├── stepA_mal.dart │ └── types.dart ├── elisp │ ├── Dockerfile │ ├── Makefile │ ├── mal │ │ ├── core.el │ │ ├── env.el │ │ ├── printer.el │ │ ├── reader.el │ │ └── types.el │ ├── run │ ├── step0_repl.el │ ├── step1_read_print.el │ ├── step2_eval.el │ ├── step3_env.el │ ├── step4_if_fn_do.el │ ├── step5_tco.el │ ├── step6_file.el │ ├── step7_quote.el │ ├── step8_macros.el │ ├── step9_try.el │ ├── stepA_mal.el │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── elixir │ ├── Dockerfile │ ├── Makefile │ ├── lib │ │ ├── mal.ex │ │ ├── mal │ │ │ ├── atom.ex │ │ │ ├── core.ex │ │ │ ├── env.ex │ │ │ ├── printer.ex │ │ │ ├── reader.ex │ │ │ └── types.ex │ │ └── mix │ │ │ └── tasks │ │ │ ├── step0_repl.ex │ │ │ ├── step1_read_print.ex │ │ │ ├── step2_eval.ex │ │ │ ├── step3_env.ex │ │ │ ├── step4_if_fn_do.ex │ │ │ ├── step5_tco.ex │ │ │ ├── step6_file.ex │ │ │ ├── step7_quote.ex │ │ │ ├── step8_macros.ex │ │ │ ├── step9_try.ex │ │ │ └── stepA_mal.ex │ ├── mix.exs │ ├── run │ └── tests │ │ └── step5_tco.mal ├── elm │ ├── .dockerignore │ ├── Dockerfile │ ├── Makefile │ ├── bootstrap.js │ ├── elm.json │ ├── node_readline.js │ ├── package.json │ ├── run │ └── src │ │ ├── Core.elm │ │ ├── Env.elm │ │ ├── Eval.elm │ │ ├── IO.elm │ │ ├── Printer.elm │ │ ├── Reader.elm │ │ ├── Step0_repl.elm │ │ ├── Step1_read_print.elm │ │ ├── Step2_eval.elm │ │ ├── Step3_env.elm │ │ ├── Step4_if_fn_do.elm │ │ ├── Step5_tco.elm │ │ ├── Step6_file.elm │ │ ├── Step7_quote.elm │ │ ├── Step8_macros.elm │ │ ├── Step9_try.elm │ │ ├── StepA_mal.elm │ │ ├── Types.elm │ │ └── Utils.elm ├── erlang │ ├── Dockerfile │ ├── Makefile │ ├── rebar.config │ ├── rebar.config.script │ ├── run │ ├── src │ │ ├── atom.erl │ │ ├── core.erl │ │ ├── env.erl │ │ ├── mal.app.src │ │ ├── printer.erl │ │ ├── reader.erl │ │ ├── step0_repl.erl │ │ ├── step1_read_print.erl │ │ ├── step2_eval.erl │ │ ├── step3_env.erl │ │ ├── step4_if_fn_do.erl │ │ ├── step5_tco.erl │ │ ├── step6_file.erl │ │ ├── step7_quote.erl │ │ ├── step8_macros.erl │ │ ├── step9_try.erl │ │ ├── stepA_mal.erl │ │ └── types.erl │ └── tests │ │ └── step5_tco.mal ├── es6 │ ├── Dockerfile │ ├── Makefile │ ├── core.mjs │ ├── env.mjs │ ├── node_readline.js │ ├── package.json │ ├── printer.mjs │ ├── reader.mjs │ ├── run │ ├── step0_repl.mjs │ ├── step1_read_print.mjs │ ├── step2_eval.mjs │ ├── step3_env.mjs │ ├── step4_if_fn_do.mjs │ ├── step5_tco.mjs │ ├── step6_file.mjs │ ├── step7_quote.mjs │ ├── step8_macros.mjs │ ├── step9_try.mjs │ ├── stepA_mal.mjs │ ├── tests │ │ └── step5_tco.mal │ └── types.mjs ├── factor │ ├── Dockerfile │ ├── Makefile │ ├── lib │ │ ├── core │ │ │ ├── core-tests.factor │ │ │ └── core.factor │ │ ├── env │ │ │ ├── env-tests.factor │ │ │ └── env.factor │ │ ├── printer │ │ │ ├── printer-tests.factor │ │ │ └── printer.factor │ │ ├── reader │ │ │ ├── reader-tests.factor │ │ │ └── reader.factor │ │ └── types │ │ │ └── types.factor │ ├── run │ ├── step0_repl │ │ ├── deploy.factor │ │ └── step0_repl.factor │ ├── step1_read_print │ │ ├── deploy.factor │ │ └── step1_read_print.factor │ ├── step2_eval │ │ ├── deploy.factor │ │ └── step2_eval.factor │ ├── step3_env │ │ ├── deploy.factor │ │ └── step3_env.factor │ ├── step4_if_fn_do │ │ ├── deploy.factor │ │ └── step4_if_fn_do.factor │ ├── step5_tco │ │ ├── deploy.factor │ │ └── step5_tco.factor │ ├── step6_file │ │ ├── deploy.factor │ │ └── step6_file.factor │ ├── step7_quote │ │ ├── deploy.factor │ │ └── step7_quote.factor │ ├── step8_macros │ │ ├── deploy.factor │ │ └── step8_macros.factor │ ├── step9_try │ │ ├── deploy.factor │ │ └── step9_try.factor │ ├── stepA_mal │ │ ├── deploy.factor │ │ └── stepA_mal.factor │ └── tests │ │ └── step5_tco.mal ├── fantom │ ├── Dockerfile │ ├── Makefile │ ├── run │ ├── src │ │ ├── mallib │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ ├── core.fan │ │ │ │ ├── env.fan │ │ │ │ ├── interop.fan │ │ │ │ ├── reader.fan │ │ │ │ └── types.fan │ │ ├── step0_repl │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step1_read_print │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step2_eval │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step3_env │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step4_if_fn_do │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step5_tco │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step6_file │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step7_quote │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step8_macros │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ ├── step9_try │ │ │ ├── build.fan │ │ │ └── fan │ │ │ │ └── main.fan │ │ └── stepA_mal │ │ │ ├── build.fan │ │ │ └── fan │ │ │ └── main.fan │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── fennel │ ├── Dockerfile │ ├── Makefile │ ├── core.fnl │ ├── env.fnl │ ├── printer.fnl │ ├── reader.fnl │ ├── run │ ├── step0_repl.fnl │ ├── step1_read_print.fnl │ ├── step2_eval.fnl │ ├── step3_env.fnl │ ├── step4_if_fn_do.fnl │ ├── step5_tco.fnl │ ├── step6_file.fnl │ ├── step7_quote.fnl │ ├── step8_macros.fnl │ ├── step9_try.fnl │ ├── stepA_mal.fnl │ ├── types.fnl │ └── utils.fnl ├── forth │ ├── Dockerfile │ ├── Makefile │ ├── core.fs │ ├── env.fs │ ├── misc-tests.fs │ ├── printer.fs │ ├── reader.fs │ ├── run │ ├── step0_repl.fs │ ├── step1_read_print.fs │ ├── step2_eval.fs │ ├── step3_env.fs │ ├── step4_if_fn_do.fs │ ├── step5_tco.fs │ ├── step6_file.fs │ ├── step7_quote.fs │ ├── step8_macros.fs │ ├── step9_try.fs │ ├── stepA_mal.fs │ ├── str.fs │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.fs ├── fsharp │ ├── Dockerfile │ ├── Makefile │ ├── core.fs │ ├── env.fs │ ├── error.fs │ ├── node.fs │ ├── printer.fs │ ├── reader.fs │ ├── readline.fs │ ├── run │ ├── step0_repl.fs │ ├── step1_read_print.fs │ ├── step2_eval.fs │ ├── step3_env.fs │ ├── step4_if_fn_do.fs │ ├── step5_tco.fs │ ├── step6_file.fs │ ├── step7_quote.fs │ ├── step8_macros.fs │ ├── step9_try.fs │ ├── stepA_mal.fs │ ├── terminal.cs │ ├── tests │ │ └── step5_tco.mal │ ├── tokenizer.fs │ └── types.fs ├── gnu-smalltalk │ ├── Dockerfile │ ├── Makefile │ ├── core.st │ ├── env.st │ ├── func.st │ ├── printer.st │ ├── reader.st │ ├── readline.st │ ├── run │ ├── step0_repl.st │ ├── step1_read_print.st │ ├── step2_eval.st │ ├── step3_env.st │ ├── step4_if_fn_do.st │ ├── step5_tco.st │ ├── step6_file.st │ ├── step7_quote.st │ ├── step8_macros.st │ ├── step9_try.st │ ├── stepA_mal.st │ ├── tests │ │ └── stepA_mal.mal │ ├── types.st │ └── util.st ├── go │ ├── Dockerfile │ ├── Makefile │ ├── go.mod │ ├── run │ ├── src │ │ ├── core │ │ │ └── core.go │ │ ├── env │ │ │ └── env.go │ │ ├── printer │ │ │ └── printer.go │ │ ├── reader │ │ │ └── reader.go │ │ ├── readline │ │ │ └── readline.go │ │ ├── step0_repl │ │ │ └── step0_repl.go │ │ ├── step1_read_print │ │ │ └── step1_read_print.go │ │ ├── step2_eval │ │ │ └── step2_eval.go │ │ ├── step3_env │ │ │ └── step3_env.go │ │ ├── step4_if_fn_do │ │ │ └── step4_if_fn_do.go │ │ ├── step5_tco │ │ │ └── step5_tco.go │ │ ├── step6_file │ │ │ └── step6_file.go │ │ ├── step7_quote │ │ │ └── step7_quote.go │ │ ├── step8_macros │ │ │ └── step8_macros.go │ │ ├── step9_try │ │ │ └── step9_try.go │ │ ├── stepA_mal │ │ │ └── stepA_mal.go │ │ └── types │ │ │ └── types.go │ └── tests │ │ ├── step2_eval.mal │ │ ├── step4_if_fn_do.mal │ │ └── step5_tco.mal ├── groovy │ ├── Dockerfile │ ├── GroovyWrapper.groovy │ ├── Makefile │ ├── core.groovy │ ├── env.groovy │ ├── printer.groovy │ ├── reader.groovy │ ├── run │ ├── step0_repl.groovy │ ├── step1_read_print.groovy │ ├── step2_eval.groovy │ ├── step3_env.groovy │ ├── step4_if_fn_do.groovy │ ├── step5_tco.groovy │ ├── step6_file.groovy │ ├── step7_quote.groovy │ ├── step8_macros.groovy │ ├── step9_try.groovy │ ├── stepA_mal.groovy │ ├── tests │ │ └── step5_tco.mal │ └── types.groovy ├── guile │ ├── Dockerfile │ ├── Makefile │ ├── core.scm │ ├── env.scm │ ├── pcre.scm │ ├── printer.scm │ ├── reader.scm │ ├── readline.scm │ ├── run │ ├── step0_repl.scm │ ├── step1_read_print.scm │ ├── step2_eval.scm │ ├── step3_env.scm │ ├── step4_if_fn_do.scm │ ├── step5_tco.scm │ ├── step6_file.scm │ ├── step7_quote.scm │ ├── step8_macros.scm │ ├── step9_try.scm │ ├── stepA_mal.scm │ └── types.scm ├── hare │ ├── .gitignore │ ├── Dockerfile │ ├── makefile │ ├── mal │ │ ├── core.ha │ │ ├── env.ha │ │ ├── error.ha │ │ ├── gc.ha │ │ ├── hashmap.ha │ │ ├── printer.ha │ │ ├── reader.ha │ │ ├── tokenizer.ha │ │ └── types.ha │ ├── run │ ├── step0_repl.ha │ ├── step1_read_print.ha │ ├── step2_eval.ha │ ├── step3_env.ha │ ├── step4_if_fn_do.ha │ ├── step5_tco.ha │ ├── step6_file.ha │ ├── step7_quote.ha │ ├── step8_macros.ha │ ├── step9_try.ha │ └── stepA_mal.ha ├── haskell │ ├── Core.hs │ ├── Dockerfile │ ├── Env.hs │ ├── Makefile │ ├── Printer.hs │ ├── Reader.hs │ ├── Readline.hs │ ├── Types.hs │ ├── run │ ├── step0_repl.hs │ ├── step1_read_print.hs │ ├── step2_eval.hs │ ├── step3_env.hs │ ├── step4_if_fn_do.hs │ ├── step5_tco.hs │ ├── step6_file.hs │ ├── step7_quote.hs │ ├── step8_macros.hs │ ├── step9_try.hs │ ├── stepA_mal.hs │ └── tests │ │ └── step5_tco.mal ├── haxe │ ├── Compat.hx │ ├── Dockerfile │ ├── Makefile │ ├── Step0_repl.hx │ ├── Step1_read_print.hx │ ├── Step2_eval.hx │ ├── Step3_env.hx │ ├── Step4_if_fn_do.hx │ ├── Step5_tco.hx │ ├── Step6_file.hx │ ├── Step7_quote.hx │ ├── Step8_macros.hx │ ├── Step9_try.hx │ ├── StepA_mal.hx │ ├── core │ │ └── Core.hx │ ├── env │ │ └── Env.hx │ ├── node_readline.js │ ├── package.json │ ├── printer │ │ └── Printer.hx │ ├── reader │ │ ├── BlankLine.hx │ │ └── Reader.hx │ ├── run │ ├── tests │ │ └── step5_tco.mal │ └── types │ │ ├── MalException.hx │ │ └── Types.hx ├── hy │ ├── Dockerfile │ ├── Makefile │ ├── core.hy │ ├── env.hy │ ├── mal_types.hy │ ├── printer.hy │ ├── reader.hy │ ├── run │ ├── step0_repl.hy │ ├── step1_read_print.hy │ ├── step2_eval.hy │ ├── step3_env.hy │ ├── step4_if_fn_do.hy │ ├── step5_tco.hy │ ├── step6_file.hy │ ├── step7_quote.hy │ ├── step8_macros.hy │ ├── step9_try.hy │ ├── stepA_mal.hy │ └── tests │ │ └── step5_tco.mal ├── io │ ├── Dockerfile │ ├── Env.io │ ├── Makefile │ ├── MalCore.io │ ├── MalReader.io │ ├── MalReadline.io │ ├── MalTypes.io │ ├── run │ ├── step0_repl.io │ ├── step1_read_print.io │ ├── step2_eval.io │ ├── step3_env.io │ ├── step4_if_fn_do.io │ ├── step5_tco.io │ ├── step6_file.io │ ├── step7_quote.io │ ├── step8_macros.io │ ├── step9_try.io │ ├── stepA_mal.io │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── janet │ ├── Dockerfile │ ├── Makefile │ ├── core.janet │ ├── env.janet │ ├── printer.janet │ ├── reader.janet │ ├── run │ ├── step0_repl.janet │ ├── step1_read_print.janet │ ├── step2_eval.janet │ ├── step3_env.janet │ ├── step4_if_fn_do.janet │ ├── step5_tco.janet │ ├── step6_file.janet │ ├── step7_quote.janet │ ├── step8_macros.janet │ ├── step9_try.janet │ ├── stepA_mal.janet │ ├── tests │ │ └── stepA_mal.mal │ ├── types.janet │ └── utils.janet ├── java-truffle │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── build.gradle │ ├── make-native.sh │ ├── run │ ├── settings.gradle │ └── src │ │ └── main │ │ └── java │ │ └── truffle │ │ └── mal │ │ ├── Core.java │ │ ├── MalEnv.java │ │ ├── Printer.java │ │ ├── Reader.java │ │ ├── Types.java │ │ ├── step0_repl.java │ │ ├── step1_read_print.java │ │ ├── step2_eval.java │ │ ├── step3_env.java │ │ ├── step4_if_fn_do.java │ │ ├── step5_tco.java │ │ ├── step6_file.java │ │ ├── step7_quote.java │ │ ├── step8_macros.java │ │ ├── step9_try.java │ │ ├── stepA_mal.java │ │ ├── stepB_calls.java │ │ ├── stepC_slots.java │ │ ├── stepD_caching.java │ │ └── stepE_macros.java ├── java │ ├── Dockerfile │ ├── Makefile │ ├── pom.xml │ ├── run │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── mal │ │ │ ├── core.java │ │ │ ├── env.java │ │ │ ├── printer.java │ │ │ ├── reader.java │ │ │ ├── readline.java │ │ │ ├── step0_repl.java │ │ │ ├── step1_read_print.java │ │ │ ├── step2_eval.java │ │ │ ├── step3_env.java │ │ │ ├── step4_if_fn_do.java │ │ │ ├── step5_tco.java │ │ │ ├── step6_file.java │ │ │ ├── step7_quote.java │ │ │ ├── step8_macros.java │ │ │ ├── step9_try.java │ │ │ ├── stepA_mal.java │ │ │ └── types.java │ └── tests │ │ └── step5_tco.mal ├── jq │ ├── Dockerfile │ ├── Makefile │ ├── core.jq │ ├── docs │ │ └── impl-notes.md │ ├── env.jq │ ├── interp.jq │ ├── printer.jq │ ├── reader.jq │ ├── run │ ├── step0_repl.jq │ ├── step1_read_print.jq │ ├── step2_eval.jq │ ├── step3_env.jq │ ├── step4_if_fn_do.jq │ ├── step5_tco.jq │ ├── step6_file.jq │ ├── step7_quote.jq │ ├── step8_macros.jq │ ├── step9_try.jq │ ├── stepA_mal.jq │ └── utils.jq ├── js │ ├── Dockerfile │ ├── Makefile │ ├── core.js │ ├── env.js │ ├── interop.js │ ├── jq_readline.js │ ├── node_readline.js │ ├── package.json │ ├── printer.js │ ├── reader.js │ ├── run │ ├── step0_repl.js │ ├── step1_read_print.js │ ├── step2_eval.js │ ├── step3_env.js │ ├── step4_if_fn_do.js │ ├── step5_tco.js │ ├── step6_file.js │ ├── step7_quote.js │ ├── step8_macros.js │ ├── step9_try.js │ ├── stepA_mal.js │ ├── tests │ │ ├── common.js │ │ ├── node_modules │ │ ├── reader.js │ │ ├── step5_tco.mal │ │ ├── stepA_mal.mal │ │ └── types.js │ ├── types.js │ └── web ├── julia │ ├── Dockerfile │ ├── Makefile │ ├── core.jl │ ├── env.jl │ ├── printer.jl │ ├── reader.jl │ ├── readline_mod.jl │ ├── run │ ├── step0_repl.jl │ ├── step1_read_print.jl │ ├── step2_eval.jl │ ├── step3_env.jl │ ├── step4_if_fn_do.jl │ ├── step5_tco.jl │ ├── step6_file.jl │ ├── step7_quote.jl │ ├── step8_macros.jl │ ├── step9_try.jl │ ├── stepA_mal.jl │ ├── tests │ │ └── step5_tco.mal │ └── types.jl ├── kotlin │ ├── Dockerfile │ ├── Makefile │ ├── run │ ├── src │ │ └── mal │ │ │ ├── core.kt │ │ │ ├── env.kt │ │ │ ├── printer.kt │ │ │ ├── reader.kt │ │ │ ├── readline.kt │ │ │ ├── step0_repl.kt │ │ │ ├── step1_read_print.kt │ │ │ ├── step2_eval.kt │ │ │ ├── step3_env.kt │ │ │ ├── step4_if_fn_do.kt │ │ │ ├── step5_tco.kt │ │ │ ├── step6_file.kt │ │ │ ├── step7_quote.kt │ │ │ ├── step8_macros.kt │ │ │ ├── step9_try.kt │ │ │ ├── stepA_mal.kt │ │ │ └── types.kt │ └── tests │ │ └── step5_tco.mal ├── latex3 │ ├── Dockerfile │ ├── Makefile │ ├── core.sty │ ├── env.sty │ ├── printer.sty │ ├── reader.sty │ ├── run │ ├── step0_repl.tex │ ├── step1_read_print.tex │ ├── step2_eval.tex │ ├── step3_env.tex │ ├── step4_if_fn_do.tex │ ├── step6_file.tex │ ├── step7_quote.tex │ ├── step8_macros.tex │ ├── step9_try.tex │ ├── stepA_mal.tex │ └── types.sty ├── lib │ ├── README.md │ ├── alias-hacks.mal │ ├── benchmark.mal │ ├── equality.mal │ ├── load-file-once.mal │ ├── memoize.mal │ ├── perf.mal │ ├── pprint.mal │ ├── protocols.mal │ ├── reducers.mal │ ├── test_cascade.mal │ ├── threading.mal │ └── trivial.mal ├── livescript │ ├── Dockerfile │ ├── Makefile │ ├── core.ls │ ├── env.ls │ ├── error.ls │ ├── node_readline.js │ ├── package.json │ ├── printer.ls │ ├── reader.ls │ ├── run │ ├── step0_repl.ls │ ├── step1_read_print.ls │ ├── step2_eval.ls │ ├── step3_env.ls │ ├── step4_if_fn_do.ls │ ├── step5_tco.ls │ ├── step6_file.ls │ ├── step7_quote.ls │ ├── step8_macros.ls │ ├── step9_try.ls │ ├── stepA_mal.ls │ └── utils.ls ├── logo │ ├── Dockerfile │ ├── Makefile │ ├── core.lg │ ├── env.lg │ ├── examples │ │ └── tree.mal │ ├── printer.lg │ ├── reader.lg │ ├── readline.lg │ ├── run │ ├── step0_repl.lg │ ├── step1_read_print.lg │ ├── step2_eval.lg │ ├── step3_env.lg │ ├── step4_if_fn_do.lg │ ├── step5_tco.lg │ ├── step6_file.lg │ ├── step7_quote.lg │ ├── step8_macros.lg │ ├── step9_try.lg │ ├── stepA_mal.lg │ ├── tests │ │ └── stepA_mal.mal │ └── types.lg ├── lua │ ├── Dockerfile │ ├── Makefile │ ├── core.lua │ ├── env.lua │ ├── printer.lua │ ├── reader.lua │ ├── readline.lua │ ├── run │ ├── step0_repl.lua │ ├── step1_read_print.lua │ ├── step2_eval.lua │ ├── step3_env.lua │ ├── step4_if_fn_do.lua │ ├── step5_tco.lua │ ├── step6_file.lua │ ├── step7_quote.lua │ ├── step8_macros.lua │ ├── step9_try.lua │ ├── stepA_mal.lua │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ ├── types.lua │ └── utils.lua ├── make │ ├── Dockerfile │ ├── Makefile │ ├── README │ ├── core.mk │ ├── env.mk │ ├── gmsl.mk │ ├── numbers.mk │ ├── printer.mk │ ├── reader.mk │ ├── readline.mk │ ├── rules.mk │ ├── run │ ├── step0_repl.mk │ ├── step1_read_print.mk │ ├── step2_eval.mk │ ├── step3_env.mk │ ├── step4_if_fn_do.mk │ ├── step6_file.mk │ ├── step7_quote.mk │ ├── step8_macros.mk │ ├── step9_try.mk │ ├── stepA_mal.mk │ ├── tests │ │ └── stepA_mal.mal │ ├── types.mk │ └── util.mk ├── mal │ ├── Dockerfile │ ├── Makefile │ ├── core.mal │ ├── env.mal │ ├── run │ ├── step0_repl.mal │ ├── step1_read_print.mal │ ├── step2_eval.mal │ ├── step3_env.mal │ ├── step4_if_fn_do.mal │ ├── step6_file.mal │ ├── step7_quote.mal │ ├── step8_macros.mal │ ├── step9_try.mal │ └── stepA_mal.mal ├── matlab │ ├── +types │ │ ├── Atom.m │ │ ├── Function.m │ │ ├── HashMap.m │ │ ├── List.m │ │ ├── MalException.m │ │ ├── Nil.m │ │ ├── Reader.m │ │ ├── Symbol.m │ │ └── Vector.m │ ├── .dockerignore │ ├── Dict.m │ ├── Dockerfile │ ├── Env.m │ ├── Makefile │ ├── core.m │ ├── printer.m │ ├── reader.m │ ├── run │ ├── step0_repl.m │ ├── step1_read_print.m │ ├── step2_eval.m │ ├── step3_env.m │ ├── step4_if_fn_do.m │ ├── step5_tco.m │ ├── step6_file.m │ ├── step7_quote.m │ ├── step8_macros.m │ ├── step9_try.m │ ├── stepA_mal.m │ ├── type_utils.m │ └── types ├── miniMAL │ ├── Dockerfile │ ├── Makefile │ ├── core.json │ ├── env.json │ ├── miniMAL-core.json │ ├── node_readline.js │ ├── package.json │ ├── printer.json │ ├── reader.json │ ├── run │ ├── step0_repl.json │ ├── step1_read_print.json │ ├── step2_eval.json │ ├── step3_env.json │ ├── step4_if_fn_do.json │ ├── step5_tco.json │ ├── step6_file.json │ ├── step7_quote.json │ ├── step8_macros.json │ ├── step9_try.json │ ├── stepA_mal.json │ ├── tests │ │ └── step5_tco.mal │ └── types.json ├── nasm │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── core.asm │ ├── env.asm │ ├── exceptions.asm │ ├── macros.mac │ ├── printer.asm │ ├── reader.asm │ ├── run │ ├── step0_repl.asm │ ├── step1_read_print.asm │ ├── step2_eval.asm │ ├── step3_env.asm │ ├── step4_if_fn_do.asm │ ├── step5_tco.asm │ ├── step6_file.asm │ ├── step7_quote.asm │ ├── step8_macros.asm │ ├── step9_try.asm │ ├── stepA_mal.asm │ ├── system.asm │ └── types.asm ├── nim │ ├── Dockerfile │ ├── Makefile │ ├── core.nim │ ├── env.nim │ ├── mal.nimble │ ├── nim.cfg │ ├── printer.nim │ ├── reader.nim │ ├── run │ ├── step0_repl.nim │ ├── step1_read_print.nim │ ├── step2_eval.nim │ ├── step3_env.nim │ ├── step4_if_fn_do.nim │ ├── step5_tco.nim │ ├── step6_file.nim │ ├── step7_quote.nim │ ├── step8_macros.nim │ ├── step9_try.nim │ ├── stepA_mal.nim │ ├── tests │ │ └── step5_tco.mal │ └── types.nim ├── objc │ ├── Dockerfile │ ├── Makefile │ ├── core.h │ ├── core.m │ ├── env.h │ ├── env.m │ ├── mal_readline.c │ ├── mal_readline.h │ ├── malfunc.h │ ├── malfunc.m │ ├── printer.h │ ├── printer.m │ ├── reader.h │ ├── reader.m │ ├── run │ ├── step0_repl.m │ ├── step1_read_print.m │ ├── step2_eval.m │ ├── step3_env.m │ ├── step4_if_fn_do.m │ ├── step5_tco.m │ ├── step6_file.m │ ├── step7_quote.m │ ├── step8_macros.m │ ├── step9_try.m │ ├── stepA_mal.m │ ├── tests │ │ └── step5_tco.mal │ ├── types.h │ └── types.m ├── objpascal │ ├── Dockerfile │ ├── Makefile │ ├── core.pas │ ├── mal_env.pas │ ├── mal_func.pas │ ├── mal_readline.pas │ ├── mal_types.pas │ ├── printer.pas │ ├── reader.pas │ ├── regexpr │ │ └── Source │ │ │ └── RegExpr.pas │ ├── run │ ├── step0_repl.pas │ ├── step1_read_print.pas │ ├── step2_eval.pas │ ├── step3_env.pas │ ├── step4_if_fn_do.pas │ ├── step5_tco.pas │ ├── step6_file.pas │ ├── step7_quote.pas │ ├── step8_macros.pas │ ├── step9_try.pas │ ├── stepA_mal.pas │ └── tests │ │ └── step5_tco.mal ├── ocaml │ ├── Dockerfile │ ├── Makefile │ ├── core.ml │ ├── env.ml │ ├── printer.ml │ ├── reader.ml │ ├── run │ ├── step0_repl.ml │ ├── step1_read_print.ml │ ├── step2_eval.ml │ ├── step3_env.ml │ ├── step4_if_fn_do.ml │ ├── step5_tco.ml │ ├── step6_file.ml │ ├── step7_quote.ml │ ├── step8_macros.ml │ ├── step9_try.ml │ ├── stepA_mal.ml │ ├── tests │ │ └── step5_tco.mal │ └── types.ml ├── perl │ ├── Core.pm │ ├── Dockerfile │ ├── Env.pm │ ├── Interop.pm │ ├── Makefile │ ├── Printer.pm │ ├── README.md │ ├── Reader.pm │ ├── Readline.pm │ ├── Types.pm │ ├── run │ ├── step0_repl.pl │ ├── step1_read_print.pl │ ├── step2_eval.pl │ ├── step3_env.pl │ ├── step4_if_fn_do.pl │ ├── step5_tco.pl │ ├── step6_file.pl │ ├── step7_quote.pl │ ├── step8_macros.pl │ ├── step9_try.pl │ ├── stepA_mal.pl │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── perl6 │ ├── Dockerfile │ ├── Makefile │ ├── core.pm │ ├── env.pm │ ├── printer.pm │ ├── reader.pm │ ├── run │ ├── step0_repl.pl │ ├── step1_read_print.pl │ ├── step2_eval.pl │ ├── step3_env.pl │ ├── step4_if_fn_do.pl │ ├── step5_tco.pl │ ├── step6_file.pl │ ├── step7_quote.pl │ ├── step8_macros.pl │ ├── step9_try.pl │ ├── stepA_mal.pl │ ├── tests │ │ └── stepA_mal.mal │ └── types.pm ├── php │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── core.php │ ├── env.php │ ├── interop.php │ ├── printer.php │ ├── reader.php │ ├── readline.php │ ├── run │ ├── step0_repl.php │ ├── step1_read_print.php │ ├── step2_eval.php │ ├── step3_env.php │ ├── step4_if_fn_do.php │ ├── step5_tco.php │ ├── step6_file.php │ ├── step7_quote.php │ ├── step8_macros.php │ ├── step9_try.php │ ├── stepA_mal.php │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ ├── types.php │ └── webrunner.php ├── picolisp │ ├── Dockerfile │ ├── Makefile │ ├── core.l │ ├── env.l │ ├── func.l │ ├── printer.l │ ├── reader.l │ ├── readline.l │ ├── run │ ├── step0_repl.l │ ├── step1_read_print.l │ ├── step2_eval.l │ ├── step3_env.l │ ├── step4_if_fn_do.l │ ├── step5_tco.l │ ├── step6_file.l │ ├── step7_quote.l │ ├── step8_macros.l │ ├── step9_try.l │ ├── stepA_mal.l │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.l ├── pike │ ├── Core.pmod │ ├── Dockerfile │ ├── Env.pmod │ ├── Interop.pmod │ ├── Makefile │ ├── Printer.pmod │ ├── Reader.pmod │ ├── Readline.pmod │ ├── Types.pmod │ ├── run │ ├── step0_repl.pike │ ├── step1_read_print.pike │ ├── step2_eval.pike │ ├── step3_env.pike │ ├── step4_if_fn_do.pike │ ├── step5_tco.pike │ ├── step6_file.pike │ ├── step7_quote.pike │ ├── step8_macros.pike │ ├── step9_try.pike │ ├── stepA_mal.pike │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── plpgsql │ ├── Dockerfile │ ├── Makefile │ ├── core.sql │ ├── entrypoint.sh │ ├── envs.sql │ ├── init.sql │ ├── io.sql │ ├── printer.sql │ ├── reader.sql │ ├── run │ ├── step0_repl.sql │ ├── step1_read_print.sql │ ├── step2_eval.sql │ ├── step3_env.sql │ ├── step4_if_fn_do.sql │ ├── step5_tco.sql │ ├── step6_file.sql │ ├── step7_quote.sql │ ├── step8_macros.sql │ ├── step9_try.sql │ ├── stepA_mal.sql │ ├── types.sql │ └── wrap.sh ├── plsql │ ├── Dockerfile │ ├── Dockerfile-oracle │ ├── Dockerfile-postgres │ ├── Makefile │ ├── core.sql │ ├── entrypoint.sh │ ├── env.sql │ ├── io.sql │ ├── login.sql │ ├── printer.sql │ ├── reader.sql │ ├── run │ ├── step0_repl.sql │ ├── step1_read_print.sql │ ├── step2_eval.sql │ ├── step3_env.sql │ ├── step4_if_fn_do.sql │ ├── step5_tco.sql │ ├── step6_file.sql │ ├── step7_quote.sql │ ├── step8_macros.sql │ ├── step9_try.sql │ ├── stepA_mal.sql │ ├── types.sql │ └── wrap.sh ├── powershell │ ├── Dockerfile │ ├── Makefile │ ├── core.psm1 │ ├── env.psm1 │ ├── printer.psm1 │ ├── reader.psm1 │ ├── run │ ├── step0_repl.ps1 │ ├── step1_read_print.ps1 │ ├── step2_eval.ps1 │ ├── step3_env.ps1 │ ├── step4_if_fn_do.ps1 │ ├── step5_tco.ps1 │ ├── step6_file.ps1 │ ├── step7_quote.ps1 │ ├── step8_macros.ps1 │ ├── step9_try.ps1 │ ├── stepA_mal.ps1 │ └── types.psm1 ├── prolog │ ├── Dockerfile │ ├── Makefile │ ├── core.pl │ ├── env.pl │ ├── printer.pl │ ├── reader.pl │ ├── run │ ├── step0_repl.pl │ ├── step1_read_print.pl │ ├── step2_eval.pl │ ├── step3_env.pl │ ├── step4_if_fn_do.pl │ ├── step6_file.pl │ ├── step7_quote.pl │ ├── step8_macros.pl │ ├── step9_try.pl │ ├── stepA_mal.pl │ ├── tests │ │ └── stepA_mal.mal │ ├── types.pl │ └── utils.pl ├── ps │ ├── Dockerfile │ ├── Makefile │ ├── core.ps │ ├── env.ps │ ├── interop.ps │ ├── printer.ps │ ├── reader.ps │ ├── run │ ├── step0_repl.ps │ ├── step1_read_print.ps │ ├── step2_eval.ps │ ├── step3_env.ps │ ├── step4_if_fn_do.ps │ ├── step5_tco.ps │ ├── step6_file.ps │ ├── step7_quote.ps │ ├── step8_macros.ps │ ├── step9_try.ps │ ├── stepA_mal.ps │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.ps ├── purs │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── package.json │ ├── packages.dhall │ ├── run │ ├── spago.dhall │ └── src │ │ ├── Core.purs │ │ ├── Env.purs │ │ ├── Printer.purs │ │ ├── Reader.purs │ │ ├── Readline.js │ │ ├── Readline.purs │ │ ├── Types.purs │ │ ├── step0_repl.purs │ │ ├── step1_read_print.purs │ │ ├── step2_eval.purs │ │ ├── step3_env.purs │ │ ├── step4_if_fn_do.purs │ │ ├── step5_tco.purs │ │ ├── step6_file.purs │ │ ├── step7_quote.purs │ │ ├── step8_macros.purs │ │ ├── step9_try.purs │ │ └── stepA_mal.purs ├── python2 │ ├── Dockerfile │ ├── Makefile │ ├── core.py │ ├── env.py │ ├── mal_readline.py │ ├── mal_types.py │ ├── printer.py │ ├── reader.py │ ├── run │ ├── step0_repl.py │ ├── step1_read_print.py │ ├── step2_eval.py │ ├── step3_env.py │ ├── step4_if_fn_do.py │ ├── step5_tco.py │ ├── step6_file.py │ ├── step7_quote.py │ ├── step8_macros.py │ ├── step9_try.py │ ├── stepA_mal.py │ └── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal ├── python3 │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── core.py │ ├── env.py │ ├── mal_readline.py │ ├── mal_types.py │ ├── reader.py │ ├── run │ ├── step0_repl.py │ ├── step1_read_print.py │ ├── step2_eval.py │ ├── step3_env.py │ ├── step4_if_fn_do.py │ ├── step5_tco.py │ ├── step6_file.py │ ├── step7_quote.py │ ├── step8_macros.py │ ├── step9_try.py │ ├── stepA_mal.py │ └── tests │ │ ├── __init__.py │ │ ├── step5_tco.mal │ │ ├── stepA_mal.mal │ │ ├── test_step2.py │ │ ├── test_step3.py │ │ ├── test_step4.py │ │ ├── test_step5.py │ │ ├── test_step6.py │ │ ├── test_step7.py │ │ ├── test_step8.py │ │ ├── test_step9.py │ │ └── test_stepA.py ├── r │ ├── Dockerfile │ ├── Makefile │ ├── core.r │ ├── env.r │ ├── printer.r │ ├── reader.r │ ├── readline.r │ ├── run │ ├── step0_repl.r │ ├── step1_read_print.r │ ├── step2_eval.r │ ├── step3_env.r │ ├── step4_if_fn_do.r │ ├── step5_tco.r │ ├── step6_file.r │ ├── step7_quote.r │ ├── step8_macros.r │ ├── step9_try.r │ ├── stepA_mal.r │ ├── tests │ │ └── step5_tco.mal │ └── types.r ├── racket │ ├── Dockerfile │ ├── Makefile │ ├── core.rkt │ ├── env.rkt │ ├── printer.rkt │ ├── reader.rkt │ ├── readline.rkt │ ├── run │ ├── step0_repl.rkt │ ├── step1_read_print.rkt │ ├── step2_eval.rkt │ ├── step3_env.rkt │ ├── step4_if_fn_do.rkt │ ├── step5_tco.rkt │ ├── step6_file.rkt │ ├── step7_quote.rkt │ ├── step8_macros.rkt │ ├── step9_try.rkt │ ├── stepA_mal.rkt │ ├── tests │ │ └── step5_tco.mal │ └── types.rkt ├── rexx │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── core.rexx │ ├── env.rexx │ ├── printer.rexx │ ├── reader.rexx │ ├── readline.rexx │ ├── run │ ├── step0_repl.rexx │ ├── step1_read_print.rexx │ ├── step2_eval.rexx │ ├── step3_env.rexx │ ├── step4_if_fn_do.rexx │ ├── step5_tco.rexx │ ├── step6_file.rexx │ ├── step7_quote.rexx │ ├── step8_macros.rexx │ ├── step9_try.rexx │ ├── stepA_mal.rexx │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.rexx ├── rpython │ ├── Dockerfile │ ├── Makefile │ ├── core.py │ ├── env.py │ ├── mal_readline.py │ ├── mal_types.py │ ├── printer.py │ ├── reader.py │ ├── run │ ├── step0_repl.py │ ├── step1_read_print.py │ ├── step2_eval.py │ ├── step3_env.py │ ├── step4_if_fn_do.py │ ├── step5_tco.py │ ├── step6_file.py │ ├── step7_quote.py │ ├── step8_macros.py │ ├── step9_try.py │ ├── stepA_mal.py │ └── tests │ │ └── step5_tco.mal ├── ruby.2 │ ├── Dockerfile │ ├── Makefile │ ├── core.rb │ ├── env.rb │ ├── errors.rb │ ├── printer.rb │ ├── reader.rb │ ├── run │ ├── step0_repl.rb │ ├── step1_read_print.rb │ ├── step2_eval.rb │ ├── step3_env.rb │ ├── step4_if_fn_do.rb │ ├── step5_tco.rb │ ├── step6_file.rb │ ├── step7_quote.rb │ ├── step8_macros.rb │ ├── step9_try.rb │ ├── stepA_mal.rb │ └── types.rb ├── ruby │ ├── Dockerfile │ ├── Makefile │ ├── core.rb │ ├── env.rb │ ├── mal_readline.rb │ ├── printer.rb │ ├── reader.rb │ ├── run │ ├── step0_repl.rb │ ├── step1_read_print.rb │ ├── step2_eval.rb │ ├── step3_env.rb │ ├── step4_if_fn_do.rb │ ├── step5_tco.rb │ ├── step6_file.rb │ ├── step7_quote.rb │ ├── step8_macros.rb │ ├── step9_try.rb │ ├── stepA_mal.rb │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.rb ├── rust │ ├── .gitignore │ ├── Cargo.toml │ ├── Dockerfile │ ├── Makefile │ ├── core.rs │ ├── env.rs │ ├── printer.rs │ ├── reader.rs │ ├── run │ ├── step0_repl.rs │ ├── step1_read_print.rs │ ├── step2_eval.rs │ ├── step3_env.rs │ ├── step4_if_fn_do.rs │ ├── step5_tco.rs │ ├── step6_file.rs │ ├── step7_quote.rs │ ├── step8_macros.rs │ ├── step9_try.rs │ ├── stepA_mal.rs │ └── types.rs ├── scala │ ├── Dockerfile │ ├── Makefile │ ├── assembly.sbt │ ├── build.sbt │ ├── core.scala │ ├── env.scala │ ├── printer.scala │ ├── project │ │ └── assembly.sbt │ ├── reader.scala │ ├── run │ ├── step0_repl.scala │ ├── step1_read_print.scala │ ├── step2_eval.scala │ ├── step3_env.scala │ ├── step4_if_fn_do.scala │ ├── step5_tco.scala │ ├── step6_file.scala │ ├── step7_quote.scala │ ├── step8_macros.scala │ ├── step9_try.scala │ ├── stepA_mal.scala │ ├── tests │ │ └── step5_tco.mal │ └── types.scala ├── scheme │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── lib │ │ ├── core.sld │ │ ├── env.sld │ │ ├── printer.sld │ │ ├── reader.sld │ │ ├── types.sld │ │ └── util.sld │ ├── run │ ├── step0_repl.scm │ ├── step1_read_print.scm │ ├── step2_eval.scm │ ├── step3_env.scm │ ├── step4_if_fn_do.scm │ ├── step5_tco.scm │ ├── step6_file.scm │ ├── step7_quote.scm │ ├── step8_macros.scm │ ├── step9_try.scm │ ├── stepA_mal.scm │ └── tests │ │ └── stepA_mal.mal ├── skew │ ├── Dockerfile │ ├── Makefile │ ├── core.sk │ ├── env.sk │ ├── printer.sk │ ├── reader.sk │ ├── run │ ├── step0_repl.sk │ ├── step1_read_print.sk │ ├── step2_eval.sk │ ├── step3_env.sk │ ├── step4_if_fn_do.sk │ ├── step5_tco.sk │ ├── step6_file.sk │ ├── step7_quote.sk │ ├── step8_macros.sk │ ├── step9_try.sk │ ├── stepA_mal.sk │ ├── tests │ │ └── step5_tco.mal │ ├── types.sk │ └── util.sk ├── sml │ ├── .gitignore │ ├── Dockerfile │ ├── LargeInt.sml │ ├── Makefile │ ├── README.md │ ├── core.sml │ ├── env.sml │ ├── main.sml │ ├── printer.sml │ ├── reader.sml │ ├── run │ ├── step0_repl.mlb │ ├── step0_repl.sml │ ├── step1_read_print.mlb │ ├── step1_read_print.sml │ ├── step2_eval.mlb │ ├── step2_eval.sml │ ├── step3_env.mlb │ ├── step3_env.sml │ ├── step4_if_fn_do.mlb │ ├── step4_if_fn_do.sml │ ├── step6_file.mlb │ ├── step6_file.sml │ ├── step7_quote.mlb │ ├── step7_quote.sml │ ├── step8_macros.mlb │ ├── step8_macros.sml │ ├── step9_try.mlb │ ├── step9_try.sml │ ├── stepA_mal.mlb │ ├── stepA_mal.sml │ ├── types.sml │ └── util.sml ├── swift3 │ ├── Dockerfile │ ├── Makefile │ ├── Sources │ │ ├── core.swift │ │ ├── env.swift │ │ ├── printer.swift │ │ ├── reader.swift │ │ ├── step0_repl │ │ │ └── main.swift │ │ ├── step1_read_print │ │ │ └── main.swift │ │ ├── step2_eval │ │ │ └── main.swift │ │ ├── step3_env │ │ │ └── main.swift │ │ ├── step4_if_fn_do │ │ │ └── main.swift │ │ ├── step5_tco │ │ │ └── main.swift │ │ ├── step6_file │ │ │ └── main.swift │ │ ├── step7_quote │ │ │ └── main.swift │ │ ├── step8_macros │ │ │ └── main.swift │ │ ├── step9_try │ │ │ └── main.swift │ │ ├── stepA_mal │ │ │ └── main.swift │ │ └── types.swift │ ├── run │ └── tests │ │ └── step5_tco.mal ├── swift4 │ ├── Dockerfile │ ├── Makefile │ ├── Sources │ │ ├── core.swift │ │ ├── env.swift │ │ ├── printer.swift │ │ ├── reader.swift │ │ ├── step0_repl │ │ │ └── main.swift │ │ ├── step1_read_print │ │ │ └── main.swift │ │ ├── step2_eval │ │ │ └── main.swift │ │ ├── step3_env │ │ │ └── main.swift │ │ ├── step4_if_fn_do │ │ │ └── main.swift │ │ ├── step5_tco │ │ │ └── main.swift │ │ ├── step6_file │ │ │ └── main.swift │ │ ├── step7_quote │ │ │ └── main.swift │ │ ├── step8_macros │ │ │ └── main.swift │ │ ├── step9_try │ │ │ └── main.swift │ │ ├── stepA_mal │ │ │ └── main.swift │ │ └── types.swift │ └── run ├── swift6 │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── Package.swift │ ├── Sources │ │ ├── core │ │ │ ├── Core.swift │ │ │ ├── Env.swift │ │ │ ├── Errors.swift │ │ │ ├── Parser.swift │ │ │ ├── Printer.swift │ │ │ ├── Reader.swift │ │ │ ├── Types.swift │ │ │ └── Utils.swift │ │ ├── step0_repl │ │ │ └── main.swift │ │ ├── step1_read_print │ │ │ └── main.swift │ │ ├── step2_eval │ │ │ └── main.swift │ │ ├── step3_env │ │ │ └── main.swift │ │ ├── step4_if_fn_do │ │ │ └── main.swift │ │ ├── step5_tco │ │ │ └── main.swift │ │ ├── step6_file │ │ │ └── main.swift │ │ ├── step7_quote │ │ │ └── main.swift │ │ ├── step8_macros │ │ │ └── main.swift │ │ ├── step9_try │ │ │ └── main.swift │ │ └── stepA_mal │ │ │ └── main.swift │ └── run ├── tcl │ ├── Dockerfile │ ├── Makefile │ ├── core.tcl │ ├── env.tcl │ ├── mal_readline.tcl │ ├── printer.tcl │ ├── reader.tcl │ ├── run │ ├── step0_repl.tcl │ ├── step1_read_print.tcl │ ├── step2_eval.tcl │ ├── step3_env.tcl │ ├── step4_if_fn_do.tcl │ ├── step5_tco.tcl │ ├── step6_file.tcl │ ├── step7_quote.tcl │ ├── step8_macros.tcl │ ├── step9_try.tcl │ ├── stepA_mal.tcl │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ └── types.tcl ├── tests │ ├── busywork.mal │ ├── computations.mal │ ├── docker-build.sh │ ├── docker-run.sh │ ├── docker │ │ └── Dockerfile │ ├── fib.mal │ ├── inc.mal │ ├── incA.mal │ ├── incB.mal │ ├── incC.mal │ ├── lib │ │ ├── alias-hacks.mal │ │ ├── equality.mal │ │ ├── load-file-once-inc.mal │ │ ├── load-file-once.mal │ │ ├── memoize.mal │ │ ├── pprint.mal │ │ ├── protocols.mal │ │ ├── reducers.mal │ │ ├── test_cascade.mal │ │ ├── threading.mal │ │ └── trivial.mal │ ├── perf1.mal │ ├── perf2.mal │ ├── perf3.mal │ ├── print_argv.mal │ ├── run_argv_test.sh │ ├── step0_repl.mal │ ├── step1_read_print.mal │ ├── step2_eval.mal │ ├── step3_env.mal │ ├── step4_if_fn_do.mal │ ├── step5_tco.mal │ ├── step6_file.mal │ ├── step7_quote.mal │ ├── step8_macros.mal │ ├── step9_try.mal │ ├── stepA_mal.mal │ ├── test.txt │ └── travis_trigger.sh ├── ts │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── core.ts │ ├── env.ts │ ├── node_readline.ts │ ├── package.json │ ├── printer.ts │ ├── reader.ts │ ├── run │ ├── step0_repl.ts │ ├── step1_read_print.ts │ ├── step2_eval.ts │ ├── step3_env.ts │ ├── step4_if_fn_do.ts │ ├── step5_tco.ts │ ├── step6_file.ts │ ├── step7_quote.ts │ ├── step8_macros.ts │ ├── step9_try.ts │ ├── stepA_mal.ts │ ├── tsconfig.json │ └── types.ts ├── vala │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── core.vala │ ├── env.vala │ ├── gc.vala │ ├── printer.vala │ ├── reader.vala │ ├── run │ ├── step0_repl.vala │ ├── step1_read_print.vala │ ├── step2_eval.vala │ ├── step3_env.vala │ ├── step4_if_fn_do.vala │ ├── step5_tco.vala │ ├── step6_file.vala │ ├── step7_quote.vala │ ├── step8_macros.vala │ ├── step9_try.vala │ ├── stepA_mal.vala │ └── types.vala ├── vb │ ├── Dockerfile │ ├── Makefile │ ├── core.vb │ ├── env.vb │ ├── getline.cs │ ├── printer.vb │ ├── reader.vb │ ├── readline.vb │ ├── run │ ├── step0_repl.vb │ ├── step1_read_print.vb │ ├── step2_eval.vb │ ├── step3_env.vb │ ├── step4_if_fn_do.vb │ ├── step5_tco.vb │ ├── step6_file.vb │ ├── step7_quote.vb │ ├── step8_macros.vb │ ├── step9_try.vb │ ├── stepA_mal.vb │ ├── tests │ │ └── step5_tco.mal │ └── types.vb ├── vbs │ ├── Makefile │ ├── core.vbs │ ├── env.vbs │ ├── install.vbs │ ├── io.vbs │ ├── printer.vbs │ ├── reader.vbs │ ├── run │ ├── step0_repl.vbs │ ├── step1_read_print.vbs │ ├── step2_eval.vbs │ ├── step3_env.vbs │ ├── step4_if_fn_do.vbs │ ├── step5_tco.vbs │ ├── step6_file.vbs │ ├── step7_quote.vbs │ ├── step8_macros.vbs │ ├── step9_try.vbs │ ├── stepA_mal.vbs │ ├── tests │ │ ├── step4_if_fn_do.mal │ │ └── step9_try.mal │ └── types.vbs ├── vhdl │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── core.vhdl │ ├── env.vhdl │ ├── pkg_readline.vhdl │ ├── printer.vhdl │ ├── reader.vhdl │ ├── run │ ├── run_vhdl.sh │ ├── step0_repl.vhdl │ ├── step1_read_print.vhdl │ ├── step2_eval.vhdl │ ├── step3_env.vhdl │ ├── step4_if_fn_do.vhdl │ ├── step5_tco.vhdl │ ├── step6_file.vhdl │ ├── step7_quote.vhdl │ ├── step8_macros.vhdl │ ├── step9_try.vhdl │ ├── stepA_mal.vhdl │ └── types.vhdl ├── vimscript │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── core.vim │ ├── env.vim │ ├── printer.vim │ ├── reader.vim │ ├── readline.vim │ ├── run │ ├── run_vimscript.sh │ ├── step0_repl.vim │ ├── step1_read_print.vim │ ├── step2_eval.vim │ ├── step3_env.vim │ ├── step4_if_fn_do.vim │ ├── step5_tco.vim │ ├── step6_file.vim │ ├── step7_quote.vim │ ├── step8_macros.vim │ ├── step9_try.vim │ ├── stepA_mal.vim │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ ├── types.vim │ └── vimextras.c ├── wasm │ ├── Dockerfile │ ├── Makefile │ ├── core.wam │ ├── debug.wam │ ├── env.wam │ ├── mem.wam │ ├── node_readline.js │ ├── package.json │ ├── platform_direct.wam │ ├── platform_libc.wam │ ├── platform_wasi.wam │ ├── printer.wam │ ├── printf.wam │ ├── reader.wam │ ├── run │ ├── run.js │ ├── step0_repl.wam │ ├── step1_read_print.wam │ ├── step2_eval.wam │ ├── step3_env.wam │ ├── step4_if_fn_do.wam │ ├── step5_tco.wam │ ├── step6_file.wam │ ├── step7_quote.wam │ ├── step8_macros.wam │ ├── step9_try.wam │ ├── stepA_mal.wam │ ├── string.wam │ └── types.wam ├── wren │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── core.wren │ ├── env.wren │ ├── interop.wren │ ├── printer.wren │ ├── reader.wren │ ├── readline.wren │ ├── run │ ├── step0_repl.wren │ ├── step1_read_print.wren │ ├── step2_eval.wren │ ├── step3_env.wren │ ├── step4_if_fn_do.wren │ ├── step5_tco.wren │ ├── step6_file.wren │ ├── step7_quote.wren │ ├── step8_macros.wren │ ├── step9_try.wren │ ├── stepA_mal.wren │ ├── tests │ │ ├── step5_tco.mal │ │ └── stepA_mal.mal │ ├── types.wren │ └── wren-add-gettimeofday.patch ├── xslt │ ├── Dockerfile │ ├── Makefile │ ├── core.xslt │ ├── env.xslt │ ├── printer.xslt │ ├── reader.xslt │ ├── readline.xslt │ ├── run │ ├── step0_repl.inc.xslt │ ├── step0_repl.xslt │ ├── step1_read_print.inc.xslt │ ├── step1_read_print.xslt │ ├── step2_eval.inc.xslt │ ├── step2_eval.xslt │ ├── step3_env.inc.xslt │ ├── step3_env.xslt │ ├── step4_if_fn_do.inc.xslt │ ├── step4_if_fn_do.xslt │ ├── step6_file.inc.xslt │ ├── step6_file.xslt │ ├── step7_quote.inc.xslt │ ├── step7_quote.xslt │ ├── step8_macros.inc.xslt │ ├── step8_macros.xslt │ ├── step9_try.inc.xslt │ ├── step9_try.xslt │ ├── stepA_mal.inc.xslt │ ├── stepA_mal.xslt │ └── test.xslt ├── yorick │ ├── Dockerfile │ ├── Makefile │ ├── core.i │ ├── env.i │ ├── hash.i │ ├── printer.i │ ├── reader.i │ ├── run │ ├── step0_repl.i │ ├── step1_read_print.i │ ├── step2_eval.i │ ├── step3_env.i │ ├── step4_if_fn_do.i │ ├── step5_tco.i │ ├── step6_file.i │ ├── step7_quote.i │ ├── step8_macros.i │ ├── step9_try.i │ ├── stepA_mal.i │ ├── tests │ │ └── stepA_mal.mal │ └── types.i └── zig │ ├── Dockerfile │ ├── Makefile │ ├── README │ ├── build.zig │ ├── core.zig │ ├── env.zig │ ├── error.zig │ ├── hmap.zig │ ├── linked_list.zig │ ├── printer.zig │ ├── reader.zig │ ├── readline.zig │ ├── run │ ├── step0_repl.zig │ ├── step1_read_print.zig │ ├── step2_eval.zig │ ├── step3_env.zig │ ├── step4_if_fn_do.zig │ ├── step5_tco.zig │ ├── step6_file.zig │ ├── step7_quote.zig │ ├── step8_macros.zig │ ├── step9_try.zig │ ├── stepA_mal.zig │ └── types.zig ├── lib ├── process ├── guide.md ├── step0_repl.png ├── step0_repl.txt ├── step1_read_print.png ├── step1_read_print.txt ├── step2_eval.png ├── step2_eval.txt ├── step3_env.png ├── step3_env.txt ├── step4_if_fn_do.png ├── step4_if_fn_do.txt ├── step5_tco.png ├── step5_tco.txt ├── step6_file.png ├── step6_file.txt ├── step7_quote.png ├── step7_quote.txt ├── step8_macros.png ├── step8_macros.txt ├── step9_try.png ├── step9_try.txt ├── stepA_mal.png ├── stepA_mal.txt ├── steps.drawio └── steps.png ├── runtest.py ├── tests └── voom-like-version.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | impls/vbs/*.vbs text eol=crlf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .bash_history 3 | .cache 4 | .cargo 5 | .config 6 | .mal-history 7 | .mal_history 8 | .crystal 9 | .lein 10 | .local 11 | .m2 12 | .ivy2 13 | .sbt 14 | .npm 15 | .node-gyp 16 | */experiments 17 | node_modules 18 | */notes 19 | GPATH 20 | GTAGS 21 | GRTAGS 22 | logs 23 | old 24 | tmp/ 25 | .xslt_mal_history 26 | zig-cache/ 27 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/.gitmodules -------------------------------------------------------------------------------- /docs/graph/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal_graph", 3 | "version": "0.0.1", 4 | "description": "Graph Mal Languages", 5 | "dependencies": { 6 | "js-yaml": "3.13.1", 7 | "csvtojson": "2.0.8", 8 | "request": "2.88.0", 9 | "request-promise-native": "1.0.7" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/web/bg-body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/bg-body.png -------------------------------------------------------------------------------- /docs/web/bg-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/bg-rule.png -------------------------------------------------------------------------------- /docs/web/fonts/exo-black-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-black-webfont.eot -------------------------------------------------------------------------------- /docs/web/fonts/exo-black-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-black-webfont.ttf -------------------------------------------------------------------------------- /docs/web/fonts/exo-black-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-black-webfont.woff -------------------------------------------------------------------------------- /docs/web/fonts/exo-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-bold-webfont.eot -------------------------------------------------------------------------------- /docs/web/fonts/exo-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-bold-webfont.ttf -------------------------------------------------------------------------------- /docs/web/fonts/exo-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-bold-webfont.woff -------------------------------------------------------------------------------- /docs/web/fonts/exo-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-regular-webfont.eot -------------------------------------------------------------------------------- /docs/web/fonts/exo-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-regular-webfont.ttf -------------------------------------------------------------------------------- /docs/web/fonts/exo-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/fonts/exo-regular-webfont.woff -------------------------------------------------------------------------------- /docs/web/github-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/docs/web/github-icon.png -------------------------------------------------------------------------------- /examples/hello.mal: -------------------------------------------------------------------------------- 1 | (println "hello world\n\nanother line") 2 | (println "and another line") 3 | -------------------------------------------------------------------------------- /impls/ada.2/core.ads: -------------------------------------------------------------------------------- 1 | with Envs; 2 | 3 | package Core is 4 | 5 | procedure NS_Add_To_Repl (Repl : in Envs.Ptr); 6 | -- Add built-in functions. 7 | 8 | end Core; 9 | -------------------------------------------------------------------------------- /impls/ada.2/reader.ads: -------------------------------------------------------------------------------- 1 | with Types; 2 | 3 | package Reader is 4 | 5 | function Read_Str (Source : in String) return Types.T_Array; 6 | -- The language does not explicitly define what happens when the 7 | -- input string contains more than one expression. 8 | -- This implementation returns all of them. 9 | 10 | end Reader; 11 | -------------------------------------------------------------------------------- /impls/ada.2/readline.ads: -------------------------------------------------------------------------------- 1 | package Readline is 2 | 3 | function Input (Prompt : in String) return String; 4 | 5 | End_Of_File : exception; 6 | 7 | end Readline; 8 | -------------------------------------------------------------------------------- /impls/ada.2/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/ada/Makefile: -------------------------------------------------------------------------------- 1 | PROGS=step0_repl step1_read_print step2_eval step3_env step4_if_fn_do \ 2 | step5_tco step6_file step7_quote step8_macros step9_try 3 | 4 | all: ${PROGS} stepA_mal 5 | 6 | obj: 7 | mkdir -p $@ 8 | 9 | # stepA_mal is awkward because GNAT requires the filename to be lowercase 10 | ${PROGS} stepa_mal: force obj 11 | gnatmake -O3 -gnata $@.adb -D obj 12 | 13 | # so we make stepa_mal and just move it. 14 | stepA_mal: stepa_mal 15 | mv $< $@ 16 | 17 | clean: 18 | rm -f ${PROGS} 19 | rm -rf obj 20 | 21 | .PHONY: force 22 | 23 | force: 24 | -------------------------------------------------------------------------------- /impls/ada/core.ads: -------------------------------------------------------------------------------- 1 | with Envs; 2 | 3 | package Core is 4 | 5 | -- Init puts core functions into a new Env. 6 | procedure Init (Repl_Env : Envs.Env_Handle); 7 | 8 | Evaluation_Error : exception; 9 | 10 | end Core; 11 | -------------------------------------------------------------------------------- /impls/ada/eval_callback.ads: -------------------------------------------------------------------------------- 1 | with Envs; 2 | with Types; 3 | 4 | package Eval_Callback is 5 | 6 | type Eval_Func is access 7 | function (MH : Types.Mal_Handle; Env : Envs.Env_Handle) return Types.Mal_Handle; 8 | 9 | Eval : Eval_Func; 10 | 11 | end Eval_Callback; 12 | -------------------------------------------------------------------------------- /impls/ada/printer.adb: -------------------------------------------------------------------------------- 1 | package body Printer is 2 | 3 | function Pr_Str (M : Types.Mal_Handle) return String is 4 | begin 5 | if Types.Is_Null (M) then 6 | return ""; 7 | else 8 | return Types.To_String (Types.Deref (M).all); 9 | end if; 10 | end Pr_Str; 11 | 12 | end Printer; 13 | -------------------------------------------------------------------------------- /impls/ada/printer.ads: -------------------------------------------------------------------------------- 1 | with Types; 2 | 3 | package Printer is 4 | 5 | function Pr_Str (M : Types.Mal_Handle) return String; 6 | 7 | end Printer; 8 | -------------------------------------------------------------------------------- /impls/ada/reader.ads: -------------------------------------------------------------------------------- 1 | with Types; 2 | 3 | package Reader is 4 | 5 | -- This is the Parser (returns an AST) 6 | function Read_Str (S : String) return Types.Mal_Handle; 7 | 8 | private 9 | 10 | procedure Lex_Init (S : String); 11 | 12 | function Read_Form return Types.Mal_Handle; 13 | 14 | end Reader; 15 | -------------------------------------------------------------------------------- /impls/ada/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/awk/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = types.awk reader.awk printer.awk 2 | SOURCES_LISP = env.awk core.awk stepA_mal.awk 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.awk mal 9 | 10 | mal.awk: $(SOURCES) 11 | echo 'arbitrary_long_name==0 "exec" "/usr/bin/gawk" "-O" "-f" "$$0" "$$@"' > $@ 12 | cat $+ | grep -v "^@include " >> $@ 13 | 14 | mal: mal.awk 15 | echo '#!/bin/sh' > $@ 16 | cat $< >> $@ 17 | chmod +x $@ 18 | 19 | clean: 20 | rm -f mal.awk mal 21 | -------------------------------------------------------------------------------- /impls/awk/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec awk -O -f $(dirname $0)/${STEP:-stepA_mal}.awk "${@}" 3 | -------------------------------------------------------------------------------- /impls/awk/step0_repl.awk: -------------------------------------------------------------------------------- 1 | function READ(str) 2 | { 3 | return str 4 | } 5 | 6 | function EVAL(ast) 7 | { 8 | return ast 9 | } 10 | 11 | function PRINT(expr) 12 | { 13 | return expr 14 | } 15 | 16 | function rep(str) 17 | { 18 | return PRINT(EVAL(READ(str))) 19 | } 20 | 21 | function main(str) 22 | { 23 | while (1) { 24 | printf("user> ") 25 | if (getline str <= 0) { 26 | break 27 | } 28 | print rep(str) 29 | } 30 | } 31 | 32 | BEGIN { 33 | main() 34 | exit(0) 35 | } 36 | -------------------------------------------------------------------------------- /impls/awk/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; awk: skipping non-TCO recursion 2 | ;; Reason: completes up to 50,000 3 | -------------------------------------------------------------------------------- /impls/bash/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = types.sh reader.sh printer.sh 2 | SOURCES_LISP = env.sh core.sh stepA_mal.sh 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.sh mal 9 | 10 | mal.sh: $(SOURCES) 11 | cat $+ | grep -v "^source " > $@ 12 | 13 | mal: mal.sh 14 | echo "#!/usr/bin/env bash" > $@ 15 | cat $< >> $@ 16 | chmod +x $@ 17 | 18 | clean: 19 | rm -f mal.sh mal 20 | -------------------------------------------------------------------------------- /impls/bash/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec bash $(dirname $0)/${STEP:-stepA_mal}.sh "${@}" 3 | -------------------------------------------------------------------------------- /impls/bash/step0_repl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | READ () { 4 | read -u 0 -e -p "user> " r 5 | } 6 | 7 | EVAL () { 8 | r="${1}" 9 | } 10 | 11 | PRINT () { 12 | r="${1}" 13 | } 14 | 15 | while true; do 16 | READ 17 | EVAL "${r}" 18 | PRINT "${r}" 19 | echo "${r}" 20 | done 21 | -------------------------------------------------------------------------------- /impls/basic/.args.mal: -------------------------------------------------------------------------------- 1 | (def! -*ARGS*- (list )) 2 | -------------------------------------------------------------------------------- /impls/basic/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | (echo "(def! -*ARGS*- (list $(for a in "${@}"; do echo -n " \"${a}\""; done)))") > .args.mal 4 | case ${basic_MODE:-cbm} in 5 | cbm) exec cbmbasic ${STEP:-stepA_mal}.bas "${@}" ;; 6 | qbasic) exec ./${STEP:-stepA_mal} "${@}" ;; 7 | *) echo "Invalid basic_MODE: ${basic_MODE}"; exit 2 ;; 8 | esac 9 | -------------------------------------------------------------------------------- /impls/bbc-basic/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | .PHONY: clean 4 | 5 | clean: 6 | -------------------------------------------------------------------------------- /impls/bbc-basic/core: -------------------------------------------------------------------------------- 1 | core.bas -------------------------------------------------------------------------------- /impls/bbc-basic/env: -------------------------------------------------------------------------------- 1 | env.bas -------------------------------------------------------------------------------- /impls/bbc-basic/printer: -------------------------------------------------------------------------------- 1 | printer.bas -------------------------------------------------------------------------------- /impls/bbc-basic/reader: -------------------------------------------------------------------------------- 1 | reader.bas -------------------------------------------------------------------------------- /impls/bbc-basic/riscos/.gitignore: -------------------------------------------------------------------------------- 1 | *,ffb 2 | -------------------------------------------------------------------------------- /impls/bbc-basic/riscos/setup,feb: -------------------------------------------------------------------------------- 1 | | This Obey file sets up the environment for running mal on RISC OS. 2 | BASIC { < tokenize } 3 | -------------------------------------------------------------------------------- /impls/bbc-basic/run: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | exec "${BRANDY:-sbrandy}" -size 1024k \ 3 | -path ../bbc-basic -quit $(dirname $0)/${STEP:-stepA_mal}.bas "${@}" 4 | -------------------------------------------------------------------------------- /impls/bbc-basic/step0_repl.bas: -------------------------------------------------------------------------------- 1 | REM Step 0 of mal in BBC BASIC 2 | 3 | REPEAT 4 | PRINT "user> "; 5 | LINE INPUT "" line$ 6 | PRINT FNrep(line$) 7 | UNTIL FALSE 8 | 9 | END 10 | 11 | DEF FNREAD(a$) 12 | =a$ 13 | 14 | DEF FNEVAL(a$) 15 | =a$ 16 | 17 | DEF FNPRINT(a$) 18 | =a$ 19 | 20 | DEF FNrep(a$) 21 | =FNPRINT(FNEVAL(FNREAD(a$))) 22 | 23 | REM Local Variables: 24 | REM indent-tabs-mode: nil 25 | REM End: 26 | -------------------------------------------------------------------------------- /impls/bbc-basic/types: -------------------------------------------------------------------------------- 1 | types.bas -------------------------------------------------------------------------------- /impls/c.2/core.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAL_CORE_H 2 | #define _MAL_CORE_H 3 | 4 | #include "libs/hashmap/hashmap.h" 5 | #include "types.h" 6 | 7 | typedef struct ns_s ns; 8 | 9 | struct ns_s { 10 | 11 | hashmap mappings; 12 | 13 | }; 14 | 15 | ns* ns_make_core(); 16 | MalType* as_str(list args, int readably, char* separator); 17 | MalType* print(list args, int readably, char* separator); 18 | char* get_fn(gptr data); 19 | MalType* equal_lists(MalType* lst1, MalType* lst2); 20 | MalType* equal_hashmaps(MalType* map1, MalType* map2); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /impls/c.2/env.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAL_ENV_H 2 | #define _MAL_ENV_H 3 | 4 | #include "libs/linked_list/linked_list.h" 5 | #include "libs/hashmap/hashmap.h" 6 | #include "types.h" 7 | 8 | typedef struct Env_s Env; 9 | 10 | struct Env_s { 11 | 12 | struct Env_s* outer; 13 | hashmap data; 14 | 15 | }; 16 | 17 | Env* env_make(Env* outer, list binds, list exprs, MalType* variadic_symbol); 18 | void env_set(Env* current, char* symbol, MalType* value); 19 | MalType* env_get(Env* current, char* symbol); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /impls/c.2/libs/hashmap/hashmap.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAL_HASHMAP_H 2 | #define _MAL_HASHMAP_H 3 | 4 | #include "../linked_list/linked_list.h" 5 | 6 | /* a hashmap is just a list with alternating key/value pairs */ 7 | typedef list hashmap; 8 | 9 | hashmap hashmap_make(char* keystring, gptr data_ptr); 10 | hashmap hashmap_put(hashmap map, char* keystring, gptr data_ptr); 11 | gptr hashmap_get(hashmap map, char* keystring); 12 | gptr hashmap_getf(hashmap map, char* keystring, char*(*fn)(gptr)); 13 | hashmap hashmap_updatef(hashmap map, char* keystring, gptr value, char*(*fn)(gptr)); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /impls/c.2/printer.h: -------------------------------------------------------------------------------- 1 | #ifndef _PRINTER_H 2 | #define _PRINTER_H 3 | 4 | #include 5 | #include "types.h" 6 | 7 | #define UNREADABLY 0 8 | #define READABLY 1 9 | 10 | char* pr_str(MalType* mal_val, int readably); 11 | char* pr_str_list(list lst, int readably, char* start_delimiter, char* end_delimiter, char* separator); 12 | char* escape_string(char* str); 13 | char* snprintfbuf(long initial_size, char* fmt, ...); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /impls/c.2/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/c/core.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAL_CORE__ 2 | #define __MAL_CORE__ 3 | 4 | #include 5 | 6 | // namespace of type functions 7 | typedef struct { 8 | char *name; 9 | void *(*func)(void*); 10 | int arg_cnt; 11 | } core_ns_entry; 12 | 13 | extern core_ns_entry core_ns[62]; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /impls/c/interop.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAL_INTEROP__ 2 | #define __MAL_INTEROP__ 3 | 4 | MalVal *invoke_native(MalVal *call_data); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /impls/c/printer.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAL_PRINTER__ 2 | #define __MAL_PRINTER__ 3 | 4 | #include "types.h" 5 | 6 | char *_pr_str_args(MalVal *args, char *sep, int print_readably); 7 | char *_pr_str(MalVal *obj, int print_readably); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /impls/c/reader.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAL_READER__ 2 | #define __MAL_READER__ 3 | 4 | #include 5 | #include 6 | 7 | #include "types.h" 8 | 9 | typedef struct { 10 | GArray *array; 11 | int position; 12 | } Reader; 13 | 14 | Reader *reader_new(); 15 | int reader_append(Reader *reader, char* token); 16 | char *reader_peek(Reader *reader); 17 | char *reader_next(Reader *reader); 18 | void reader_free(Reader *reader); 19 | 20 | char *_readline (char prompt[]); 21 | MalVal *read_str (); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /impls/c/readline.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAL_READLINE__ 2 | #define __MAL_READLINE__ 3 | 4 | char *_readline (char prompt[]); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /impls/c/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/c/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; C: skipping non-TCO recursion 2 | ;; Reason: segfaults (unrecoverable) 3 | -------------------------------------------------------------------------------- /impls/chuck/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | 5 | .PHONY: all clean 6 | -------------------------------------------------------------------------------- /impls/chuck/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | regex_chugin=${REGEX_CHUGIN:-/usr/local/lib/chuck/1.5.2.5/RegEx.chug} 3 | if [[ ! -f "$regex_chugin" ]]; then 4 | echo "Set \$REGEX_CHUGIN to the absolute path of RegEx.chug"; exit 1 5 | fi 6 | 7 | imports=$(grep "^ *// *@import" "$(dirname $0)/${STEP:-stepA_mal}.ck" | awk '{print $3}') 8 | imports=$(for i in ${imports}; do ls $(dirname $0)/${i}; done) 9 | old_IFS="${IFS}"; IFS=$'\a'; export CHUCK_ARGS="${*}"; IFS="${old_IFS}" 10 | 11 | exec chuck --caution-to-the-wind --silent --chugin:"$regex_chugin" ${imports} $(dirname $-1)/${STEP:-stepA_mal}.ck 12 | -------------------------------------------------------------------------------- /impls/chuck/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; ChucK: skipping non-TCO recursion 2 | ;; Reason: stackoverflow (non-recoverable) 3 | -------------------------------------------------------------------------------- /impls/chuck/types/MalSubr.ck: -------------------------------------------------------------------------------- 1 | public class MalSubr extends MalObject 2 | { 3 | "subr" => type; 4 | string name; 5 | // HACK 6 | MalObject eval; 7 | 8 | fun MalObject call(MalObject args[]) 9 | { 10 | return new MalObject; 11 | } 12 | 13 | fun MalObject apply(MalObject f, MalObject args[]) 14 | { 15 | return new MalObject; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /impls/chuck/types/mal/MalError.ck: -------------------------------------------------------------------------------- 1 | public class MalError extends MalObject 2 | { 3 | "error" => type; 4 | 5 | fun void init(MalObject value) 6 | { 7 | value @=> object; 8 | } 9 | 10 | fun static MalError create(string value) 11 | { 12 | MalError m; 13 | m.init(MalString.create(value)); 14 | return m; 15 | } 16 | 17 | fun static MalError create(MalObject value) 18 | { 19 | MalError m; 20 | m.init(value); 21 | return m; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /impls/chuck/types/mal/MalFalse.ck: -------------------------------------------------------------------------------- 1 | public class MalFalse extends MalObject 2 | { 3 | "false" => type; 4 | 5 | fun void init() 6 | { 7 | 0 => intValue; 8 | } 9 | 10 | fun static MalFalse create() 11 | { 12 | MalFalse m; 13 | m.init(); 14 | return m; 15 | } 16 | 17 | fun MalObject clone() 18 | { 19 | MalFalse value; 20 | 21 | this.type => value.type; 22 | this.object @=> value.object; 23 | this.objects @=> value.objects; 24 | this.meta @=> value.meta; 25 | 26 | return value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /impls/chuck/types/mal/MalNil.ck: -------------------------------------------------------------------------------- 1 | public class MalNil extends MalObject 2 | { 3 | "nil" => type; 4 | 5 | fun void init() 6 | { 7 | -1 => intValue; 8 | } 9 | 10 | fun static MalNil create() 11 | { 12 | MalNil m; 13 | m.init(); 14 | return m; 15 | } 16 | 17 | fun MalObject clone() 18 | { 19 | MalNil value; 20 | 21 | this.type => value.type; 22 | this.object @=> value.object; 23 | this.objects @=> value.objects; 24 | this.meta @=> value.meta; 25 | 26 | return value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /impls/chuck/types/mal/MalTrue.ck: -------------------------------------------------------------------------------- 1 | public class MalTrue extends MalObject 2 | { 3 | "true" => type; 4 | 5 | fun void init() 6 | { 7 | 1 => intValue; 8 | } 9 | 10 | fun static MalTrue create() 11 | { 12 | MalTrue m; 13 | m.init(); 14 | return m; 15 | } 16 | 17 | fun MalObject clone() 18 | { 19 | MalTrue value; 20 | 21 | this.type => value.type; 22 | this.object @=> value.object; 23 | this.objects @=> value.objects; 24 | this.meta @=> value.meta; 25 | 26 | return value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalAdd.ck: -------------------------------------------------------------------------------- 1 | public class MalAdd extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalInt.create(args[0].intValue + args[1].intValue); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalApply.ck: -------------------------------------------------------------------------------- 1 | public class MalApply extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject f; 6 | MalObject.slice(args, 1, args.size()-1) @=> MalObject _args[]; 7 | args[args.size()-1].malObjectValues() @=> MalObject rest[]; 8 | 9 | MalObject.append(_args, rest) @=> _args; 10 | return (eval$MalSubr).apply(f, _args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalAtomify.ck: -------------------------------------------------------------------------------- 1 | public class MalAtomify extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject m; 6 | return MalAtom.create(m); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalConcat.ck: -------------------------------------------------------------------------------- 1 | public class MalConcat extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | MalObject value[0]; 6 | 7 | for( 0 => int i; i < args.size(); i++ ) 8 | { 9 | args[i].malObjectValues() @=> MalObject list[]; 10 | MalObject.append(value, list) @=> value; 11 | } 12 | 13 | return MalList.create(value); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalConj.ck: -------------------------------------------------------------------------------- 1 | public class MalConj extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].malObjectValues() @=> MalObject list[]; 6 | MalObject.slice(args, 1) @=> MalObject rest[]; 7 | 8 | if( args[0].type == "list" ) 9 | { 10 | return MalList.create(MalObject.append(MalObject.reverse(rest), list)); 11 | } 12 | else // args[0].type == "vector" 13 | { 14 | return MalVector.create(MalObject.append(list, rest)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalCons.ck: -------------------------------------------------------------------------------- 1 | public class MalCons extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | args[1].malObjectValues() @=> MalObject list[]; 7 | return MalList.create(MalObject.append([arg], list)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalCount.ck: -------------------------------------------------------------------------------- 1 | public class MalCount extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].type => string kind; 6 | if( kind == "list" || kind == "vector" ) 7 | { 8 | return MalInt.create(args[0].objects.size()); 9 | } 10 | else 11 | { 12 | return MalInt.create(0); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalDeref.ck: -------------------------------------------------------------------------------- 1 | public class MalDeref extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return args[0].malObjectValue(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalDiv.ck: -------------------------------------------------------------------------------- 1 | public class MalDiv extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalInt.create(args[0].intValue / args[1].intValue); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalDoReset.ck: -------------------------------------------------------------------------------- 1 | public class MalDoReset extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0]$MalAtom @=> MalAtom atom; 6 | args[1]$MalObject @=> MalObject value; 7 | 8 | value @=> atom.object; 9 | 10 | return value; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalDoSwap.ck: -------------------------------------------------------------------------------- 1 | public class MalDoSwap extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0]$MalAtom @=> MalAtom atom; 6 | atom.malObjectValue() @=> MalObject value; 7 | args[1] @=> MalObject f; 8 | MalObject.slice(args, 2) @=> MalObject _args[]; 9 | MalObject.append([value], _args) @=> _args; 10 | 11 | (eval$MalSubr).apply(f, _args) @=> value; 12 | value @=> atom.object; 13 | return value; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalFirst.ck: -------------------------------------------------------------------------------- 1 | public class MalFirst extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "nil" ) 8 | { 9 | return Constants.NIL; 10 | } 11 | 12 | arg.malObjectValues() @=> MalObject list[]; 13 | 14 | if( list.size() > 0 ) 15 | { 16 | return list[0]; 17 | } 18 | else 19 | { 20 | return Constants.NIL; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalGreater.ck: -------------------------------------------------------------------------------- 1 | public class MalGreater extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].intValue > args[1].intValue ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalGreaterEqual.ck: -------------------------------------------------------------------------------- 1 | public class MalGreaterEqual extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].intValue >= args[1].intValue ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalHashMapify.ck: -------------------------------------------------------------------------------- 1 | public class MalHashMapify extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalHashMap.create(args); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsAtom.ck: -------------------------------------------------------------------------------- 1 | public class MalIsAtom extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].type == "atom" ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsEmpty.ck: -------------------------------------------------------------------------------- 1 | public class MalIsEmpty extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].objects.size() == 0 ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsFalse.ck: -------------------------------------------------------------------------------- 1 | public class MalIsFalse extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "false" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsFn.ck: -------------------------------------------------------------------------------- 1 | public class MalIsFn extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].type == "subr" || ( args[0].type == "func" && 6 | !(args[0]$Func).isMacro ) ) 7 | { 8 | return Constants.TRUE; 9 | } 10 | else 11 | { 12 | return Constants.FALSE; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsHashMap.ck: -------------------------------------------------------------------------------- 1 | public class MalIsHashMap extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "hashmap" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsKeyword.ck: -------------------------------------------------------------------------------- 1 | public class MalIsKeyword extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "keyword" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsList.ck: -------------------------------------------------------------------------------- 1 | public class MalIsList extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].type == "list" ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsMacro.ck: -------------------------------------------------------------------------------- 1 | public class MalIsMacro extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].type == "func" && (args[0]$Func).isMacro ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsNil.ck: -------------------------------------------------------------------------------- 1 | public class MalIsNil extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "nil" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsNumber.ck: -------------------------------------------------------------------------------- 1 | public class MalIsNumber extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].type == "int" ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsString.ck: -------------------------------------------------------------------------------- 1 | public class MalIsString extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].type == "string" ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsSymbol.ck: -------------------------------------------------------------------------------- 1 | public class MalIsSymbol extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "symbol" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsTrue.ck: -------------------------------------------------------------------------------- 1 | public class MalIsTrue extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "true" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalIsVector.ck: -------------------------------------------------------------------------------- 1 | public class MalIsVector extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "vector" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalKeys.ck: -------------------------------------------------------------------------------- 1 | public class MalKeys extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].malObjectValues() @=> MalObject map[]; 6 | MalObject results[0]; 7 | 8 | for( 0 => int i; i < map.size(); 2 +=> i ) 9 | { 10 | results << map[i]; 11 | } 12 | 13 | return MalList.create(results); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalKeywordify.ck: -------------------------------------------------------------------------------- 1 | public class MalKeywordify extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalKeyword.create(args[0].stringValue); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalLess.ck: -------------------------------------------------------------------------------- 1 | public class MalLess extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].intValue < args[1].intValue ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalLessEqual.ck: -------------------------------------------------------------------------------- 1 | public class MalLessEqual extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if( args[0].intValue <= args[1].intValue ) 6 | { 7 | return Constants.TRUE; 8 | } 9 | else 10 | { 11 | return Constants.FALSE; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalListify.ck: -------------------------------------------------------------------------------- 1 | public class MalListify extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalList.create(args); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalMap.ck: -------------------------------------------------------------------------------- 1 | public class MalMap extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject f; 6 | args[1].malObjectValues() @=> MalObject list[]; 7 | 8 | for( 0 => int i; i < list.size(); i++ ) 9 | { 10 | (eval$MalSubr).apply(f, [list[i]]) @=> MalObject value; 11 | 12 | if( value.type == "error" ) 13 | { 14 | return value; 15 | } 16 | 17 | value @=> list[i]; 18 | } 19 | 20 | return MalList.create(list); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalMeta.ck: -------------------------------------------------------------------------------- 1 | public class MalMeta extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.meta == null ) 8 | { 9 | return Constants.NIL; 10 | } 11 | else 12 | { 13 | return (arg.meta)$MalObject; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalMul.ck: -------------------------------------------------------------------------------- 1 | public class MalMul extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalInt.create(args[0].intValue * args[1].intValue); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalNth.ck: -------------------------------------------------------------------------------- 1 | public class MalNth extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].malObjectValues() @=> MalObject list[]; 6 | args[1].intValue => int n; 7 | 8 | if( n < list.size() ) 9 | { 10 | return list[n]; 11 | } 12 | else 13 | { 14 | return MalError.create("out of bounds"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalPrStr.ck: -------------------------------------------------------------------------------- 1 | public class MalPrStr extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | string values[args.size()]; 6 | 7 | for( 0 => int i; i < values.size(); i++ ) 8 | { 9 | Printer.pr_str(args[i], true) => values[i]; 10 | } 11 | 12 | return MalString.create(String.join(values, " ")); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalPrintln.ck: -------------------------------------------------------------------------------- 1 | public class MalPrintln extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | string values[args.size()]; 6 | 7 | for( 0 => int i; i < values.size(); i++ ) 8 | { 9 | Printer.pr_str(args[i], false) => values[i]; 10 | } 11 | 12 | Util.println(String.join(values, " ")); 13 | return Constants.NIL; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalPrn.ck: -------------------------------------------------------------------------------- 1 | public class MalPrn extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | string values[args.size()]; 6 | 7 | for( 0 => int i; i < values.size(); i++ ) 8 | { 9 | Printer.pr_str(args[i], true) => values[i]; 10 | } 11 | 12 | Util.println(String.join(values, " ")); 13 | return Constants.NIL; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalReadStr.ck: -------------------------------------------------------------------------------- 1 | public class MalReadStr extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].stringValue => string input; 6 | return Reader.read_str(input); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalReadline.ck: -------------------------------------------------------------------------------- 1 | public class MalReadline extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].stringValue => string prompt; 6 | Readline.readline(prompt) => string input; 7 | 8 | if( input == null ) 9 | { 10 | return Constants.NIL; 11 | } 12 | else 13 | { 14 | return MalString.create(input); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalRest.ck: -------------------------------------------------------------------------------- 1 | public class MalRest extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | MalObject result[0]; 7 | 8 | if( arg.type == "nil" ) 9 | { 10 | return MalList.create(result); 11 | } 12 | 13 | args[0].malObjectValues() @=> MalObject list[]; 14 | 15 | if( list.size() > 0 ) 16 | { 17 | MalObject.slice(list, 1) @=> result; 18 | } 19 | 20 | return MalList.create(result); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalSequential.ck: -------------------------------------------------------------------------------- 1 | public class MalSequential extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | 7 | if( arg.type == "list" || arg.type == "vector" ) 8 | { 9 | return Constants.TRUE; 10 | } 11 | else 12 | { 13 | return Constants.FALSE; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalStr.ck: -------------------------------------------------------------------------------- 1 | public class MalStr extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | string values[args.size()]; 6 | 7 | for( 0 => int i; i < values.size(); i++ ) 8 | { 9 | Printer.pr_str(args[i], false) => values[i]; 10 | } 11 | 12 | return MalString.create(String.join(values, "")); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalSub.ck: -------------------------------------------------------------------------------- 1 | public class MalSub extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalInt.create(args[0].intValue - args[1].intValue); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalSymbolify.ck: -------------------------------------------------------------------------------- 1 | public class MalSymbolify extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].stringValue => string name; 6 | return MalSymbol.create(name); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalThrow.ck: -------------------------------------------------------------------------------- 1 | public class MalThrow extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalError.create(args[0]); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalTimeMs.ck: -------------------------------------------------------------------------------- 1 | public class MalTimeMs extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | // HACK: Std.system returns the status code only... 6 | "/tmp/chuck-date." + Std.rand2(1000,9999) => string temp_file; 7 | Std.system("date +%s%3N > " + temp_file); 8 | 9 | FileIO f; 10 | f.open(temp_file, FileIO.READ); 11 | f => int timestamp; 12 | f.close(); 13 | 14 | Std.system("rm " + temp_file); 15 | 16 | return MalInt.create(timestamp); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalVals.ck: -------------------------------------------------------------------------------- 1 | public class MalVals extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0].malObjectValues() @=> MalObject map[]; 6 | MalObject results[0]; 7 | 8 | for( 1 => int i; i < map.size(); 2 +=> i ) 9 | { 10 | results << map[i]; 11 | } 12 | 13 | return MalList.create(results); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalVec.ck: -------------------------------------------------------------------------------- 1 | public class MalVec extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | if (args.size() == 1) { 6 | args[0] @=> MalObject a0; 7 | if (a0.type == "vector") { 8 | return a0; 9 | } else if (a0.type == "list") { 10 | return MalVector.create(a0.malObjectValues()); 11 | } 12 | } 13 | return MalError.create("vec: wrong arguments"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalVectorify.ck: -------------------------------------------------------------------------------- 1 | public class MalVectorify extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | return MalVector.create(args); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/chuck/types/subr/MalWithMeta.ck: -------------------------------------------------------------------------------- 1 | public class MalWithMeta extends MalSubr 2 | { 3 | fun MalObject call(MalObject args[]) 4 | { 5 | args[0] @=> MalObject arg; 6 | args[1] @=> MalObject meta; 7 | 8 | MalObject value; 9 | arg.clone() @=> value; 10 | 11 | meta$Object @=> value.meta; 12 | 13 | return value; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /impls/chuck/util/Constants.ck: -------------------------------------------------------------------------------- 1 | public class Constants 2 | { 3 | static MalTrue @ TRUE; 4 | static MalFalse @ FALSE; 5 | static MalNil @ NIL; 6 | } 7 | 8 | MalTrue.create() @=> Constants.TRUE; 9 | MalFalse.create() @=> Constants.FALSE; 10 | MalNil.create() @=> Constants.NIL; 11 | -------------------------------------------------------------------------------- /impls/chuck/util/Util.ck: -------------------------------------------------------------------------------- 1 | public class Util 2 | { 3 | fun static void println(string message) 4 | { 5 | chout <= message + "\n"; 6 | } 7 | 8 | fun static void panic(string message) 9 | { 10 | println("This shouldn't happen because: " + message); 11 | Machine.crash(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /impls/clojure/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in ClojureScript", 5 | "dependencies": { 6 | "ffi-napi": "2.4.x", 7 | "lumo-cljs": "1.10.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /impls/clojure/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export PATH=$PATH:$(dirname $0)/node_modules/.bin 3 | STEP=${STEP:-stepA_mal} 4 | if [ "${clojure_MODE}" = "cljs" ]; then 5 | exec lumo -c $(dirname $0)/src -m mal.${STEP//_/-} "${@}" 6 | else 7 | exec java -jar $(dirname $0)/target/${STEP}.jar "${@}" 8 | fi 9 | -------------------------------------------------------------------------------- /impls/clojure/src/mal/readline.cljs: -------------------------------------------------------------------------------- 1 | (ns mal.readline) 2 | 3 | (def readline (.-readline (js/require "../src/mal/node_readline.js"))) 4 | -------------------------------------------------------------------------------- /impls/clojure/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/coffee/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in CoffeeScript", 5 | "dependencies": { 6 | "ffi-napi": "4.0.3", 7 | "coffeescript": "~1.8" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /impls/coffee/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec coffee $(dirname $0)/${STEP:-stepA_mal}.coffee "${@}" 3 | -------------------------------------------------------------------------------- /impls/coffee/step0_repl.coffee: -------------------------------------------------------------------------------- 1 | readline = require "./node_readline.coffee" 2 | 3 | # read 4 | READ = (str) -> str 5 | 6 | # eval 7 | EVAL = (ast, env) -> ast 8 | 9 | # print 10 | PRINT = (exp) -> exp 11 | 12 | # repl 13 | rep = (str) -> PRINT(EVAL(READ(str), {})) 14 | 15 | # repl loop 16 | while (line = readline.readline("user> ")) != null 17 | continue if line == "" 18 | console.log rep line 19 | 20 | # vim: ts=2:sw=2 21 | -------------------------------------------------------------------------------- /impls/coffee/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/coffee/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic bash interop 2 | 3 | (js* "7") 4 | ;=>7 5 | 6 | (js* "'7'") 7 | ;=>"7" 8 | 9 | (js* "[7,8,9]") 10 | ;=>(7 8 9) 11 | 12 | (js* "console.log('hello');") 13 | ;/hello 14 | ;=>nil 15 | 16 | (js* "foo=8;") 17 | (js* "foo;") 18 | ;=>8 19 | 20 | (js* "['a','b','c'].map(function(x){return 'X'+x+'Y'}).join(' ')") 21 | ;=>"XaY XbY XcY" 22 | 23 | (js* "[1,2,3].map(function(x){return 1+x})") 24 | ;=>(2 3 4) 25 | -------------------------------------------------------------------------------- /impls/common-lisp/hist/.keepdir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/impls/common-lisp/hist/.keepdir -------------------------------------------------------------------------------- /impls/common-lisp/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/common-lisp/run-abcl.lisp: -------------------------------------------------------------------------------- 1 | (require 'asdf) 2 | (push *default-pathname-defaults* asdf:*central-registry*) 3 | 4 | ;; Suppress compilation output 5 | (let ((*error-output* (make-broadcast-stream)) 6 | (*standard-output* (make-broadcast-stream))) 7 | (asdf:load-system (car ext:*command-line-argument-list*) :verbose nil)) 8 | 9 | (mal:main (cdr ext:*command-line-argument-list*)) 10 | (cl-user::quit) 11 | -------------------------------------------------------------------------------- /impls/cpp/.gitignore: -------------------------------------------------------------------------------- 1 | .deps 2 | *.o 3 | *.a 4 | step0_repl 5 | step1_read_print 6 | -------------------------------------------------------------------------------- /impls/cpp/ReadLine.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_READLINE_H 2 | #define INCLUDE_READLINE_H 3 | 4 | #include "String.h" 5 | 6 | class ReadLine { 7 | public: 8 | ReadLine(const String& historyFile); 9 | ~ReadLine(); 10 | 11 | bool get(const String& prompt, String& line); 12 | 13 | private: 14 | String m_historyPath; 15 | }; 16 | 17 | #endif // INCLUDE_READLINE_H 18 | -------------------------------------------------------------------------------- /impls/cpp/String.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_STRING_H 2 | #define INCLUDE_STRING_H 3 | 4 | #include 5 | #include 6 | 7 | typedef std::string String; 8 | typedef std::vector StringVec; 9 | 10 | #define STRF stringPrintf 11 | #define PLURAL(n) &("s"[(n)==1]) 12 | 13 | extern String stringPrintf(const char* fmt, ...); 14 | extern String copyAndFree(char* mallocedString); 15 | extern String escape(const String& s); 16 | extern String unescape(const String& s); 17 | 18 | #endif // INCLUDE_STRING_H 19 | -------------------------------------------------------------------------------- /impls/cpp/Validation.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_VALIDATION_H 2 | #define INCLUDE_VALIDATION_H 3 | 4 | #include "String.h" 5 | 6 | #define MAL_CHECK(condition, ...) \ 7 | if (!(condition)) { throw STRF(__VA_ARGS__); } else { } 8 | 9 | #define MAL_FAIL(...) MAL_CHECK(false, __VA_ARGS__) 10 | 11 | extern int checkArgsIs(const char* name, int expected, int got); 12 | extern int checkArgsBetween(const char* name, int min, int max, int got); 13 | extern int checkArgsAtLeast(const char* name, int min, int got); 14 | extern int checkArgsEven(const char* name, int got); 15 | 16 | #endif // INCLUDE_VALIDATION_H 17 | -------------------------------------------------------------------------------- /impls/cpp/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/cpp/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; C++: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, segfaults at 20,000 3 | -------------------------------------------------------------------------------- /impls/crystal/Makefile: -------------------------------------------------------------------------------- 1 | STEPS = step0_repl step1_read_print step2_eval step3_env \ 2 | step4_if_fn_do step5_tco step6_file step7_quote step8_macros \ 3 | step9_try stepA_mal 4 | all: $(STEPS) 5 | $(STEPS): 6 | shards build $@ --release 7 | clean: 8 | rm -rf .cache/crystal/ .cache/shards/ bin/ lib/ 9 | .PHONY: all clean $(STEPS) 10 | -------------------------------------------------------------------------------- /impls/crystal/error.cr: -------------------------------------------------------------------------------- 1 | require "./types" 2 | 3 | module Mal 4 | class ParseException < Exception 5 | end 6 | 7 | class EvalException < Exception 8 | end 9 | 10 | class RuntimeException < Exception 11 | getter :thrown 12 | 13 | def initialize(@thrown : Type) 14 | super() 15 | end 16 | end 17 | end 18 | 19 | def eval_error(msg) 20 | raise Mal::EvalException.new msg 21 | end 22 | 23 | def parse_error(msg) 24 | raise Mal::ParseException.new msg 25 | end 26 | -------------------------------------------------------------------------------- /impls/crystal/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec $(dirname $0)/bin/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/crystal/step0_repl.cr: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env crystal run 2 | 3 | require "readline" 4 | 5 | # Note: 6 | # Employed downcase names because Crystal prohibits uppercase names for methods 7 | 8 | def read(x) 9 | x 10 | end 11 | 12 | def eval(x) 13 | x 14 | end 15 | 16 | def print(x) 17 | x 18 | end 19 | 20 | def rep(x) 21 | read(eval(print(x))) 22 | end 23 | 24 | while line = Readline.readline("user> ") 25 | puts rep(line) 26 | end 27 | -------------------------------------------------------------------------------- /impls/crystal/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Crystal: skipping non-TCO recursion 2 | ;; Reason: completes at 1,000,000 3 | -------------------------------------------------------------------------------- /impls/cs/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec mono $(dirname $0)/${STEP:-stepA_mal}.exe ${RAW:+--raw} "${@}" 3 | -------------------------------------------------------------------------------- /impls/cs/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; C#: skipping non-TCO recursion 2 | ;; Reason: unrecoverable stack overflow at 10,000 3 | -------------------------------------------------------------------------------- /impls/d/main.di: -------------------------------------------------------------------------------- 1 | import types : MalType; 2 | import env : Env; 3 | 4 | MalType EVAL(MalType ast, Env env); 5 | -------------------------------------------------------------------------------- /impls/d/printer.d: -------------------------------------------------------------------------------- 1 | import types; 2 | 3 | string pr_str(MalType obj, bool readable = true) 4 | { 5 | return obj.print(readable); 6 | } 7 | -------------------------------------------------------------------------------- /impls/d/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/d/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; D: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, segfaults at 40,000 3 | -------------------------------------------------------------------------------- /impls/dart/.analysis_options: -------------------------------------------------------------------------------- 1 | analyzer: 2 | strong-mode: true 3 | exclude: 4 | - step2_eval.dart 5 | - step3_env.dart 6 | - step4_if_fn_do.dart 7 | - step5_tco.dart 8 | -------------------------------------------------------------------------------- /impls/dart/.packages: -------------------------------------------------------------------------------- 1 | # Generated by pub on 2016-08-20 13:39:08.695546. 2 | mal:lib/ 3 | -------------------------------------------------------------------------------- /impls/dart/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @true 3 | 4 | 5 | clean: 6 | -------------------------------------------------------------------------------- /impls/dart/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See http://pub.dartlang.org/doc/glossary.html#lockfile 3 | packages: {} 4 | sdk: any 5 | -------------------------------------------------------------------------------- /impls/dart/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mal 2 | author: Harry Terkelsen 3 | version: 0.0.1 4 | -------------------------------------------------------------------------------- /impls/dart/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec dart --checked $(dirname $0)/${STEP:-stepA_mal}.dart "${@}" 3 | -------------------------------------------------------------------------------- /impls/dart/step0_repl.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | String READ(String x) => x; 4 | 5 | String EVAL(String x) => x; 6 | 7 | String PRINT(String x) => x; 8 | 9 | String rep(String x) => PRINT(EVAL(READ(x))); 10 | 11 | const prompt = 'user> '; 12 | main() { 13 | while (true) { 14 | stdout.write(prompt); 15 | var input = stdin.readLineSync(); 16 | if (input == null) return; 17 | var output = rep(input); 18 | stdout.writeln(output); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /impls/elisp/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | emacs -Q --batch -L . --eval '(byte-recompile-directory "." 0)' 3 | 4 | # For debugging, it is sometimes useful to attempt a run without byte compation. 5 | nocompile: clean 6 | exec emacs -Q --batch -L . --eval "(setq text-quoting-style 'straight)" --load stepA_mal.el 7 | 8 | clean: 9 | rm -f *.elc *~ mal/*.elc mal/*~ 10 | -------------------------------------------------------------------------------- /impls/elisp/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | dir=$(dirname $0) 3 | exec emacs -Q --batch -L $dir --eval "(setq text-quoting-style 'straight)" --load $dir/${STEP:-stepA_mal}.elc "${@}" 4 | -------------------------------------------------------------------------------- /impls/elisp/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/elisp/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic elisp interop 2 | 3 | (elisp-eval "42") 4 | ;=>42 5 | 6 | (elisp-eval "(+ 1 1)") 7 | ;=>2 8 | 9 | (elisp-eval "[foo bar baz]") 10 | ;=>[foo bar baz] 11 | 12 | (elisp-eval "(mapcar '1+ (number-sequence 0 2))") 13 | ;=>(1 2 3) 14 | 15 | (elisp-eval "(progn (princ \"Hello World!\n\") nil)") 16 | ;/Hello World! 17 | ;=>nil 18 | 19 | (elisp-eval "(setq emacs-version-re (rx (+ digit) \".\" digit))") 20 | (elisp-eval "(and (string-match-p emacs-version-re emacs-version) t)") 21 | ;=>true 22 | -------------------------------------------------------------------------------- /impls/elixir/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = lib/mal/types.ex lib/mal/reader.ex lib/mal/printer.ex 2 | SOURCES_LISP = lib/mal/env.ex lib/mal/core.ex lib/mix/tasks/stepA_mal.ex 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | mix compile 7 | 8 | dist: mal 9 | 10 | mal: $(SOURCES) 11 | mix escript.build 12 | 13 | clean: 14 | mix clean 15 | rm -f mal 16 | 17 | .PHONY: clean 18 | -------------------------------------------------------------------------------- /impls/elixir/lib/mal.ex: -------------------------------------------------------------------------------- 1 | defmodule Mal do 2 | end 3 | -------------------------------------------------------------------------------- /impls/elixir/lib/mix/tasks/step0_repl.ex: -------------------------------------------------------------------------------- 1 | defmodule Mix.Tasks.Step0Repl do 2 | def run(_), do: loop() 3 | 4 | defp loop do 5 | Mal.Core.readline("user> ") 6 | |> read_eval_print 7 | |> IO.puts 8 | 9 | loop() 10 | end 11 | 12 | defp read(input) do 13 | input 14 | end 15 | 16 | defp eval(input) do 17 | input 18 | end 19 | 20 | defp print(input) do 21 | input 22 | end 23 | 24 | defp read_eval_print(:eof), do: exit(:normal) 25 | defp read_eval_print(line) do 26 | read(line) 27 | |> eval 28 | |> print 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /impls/elixir/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | exec mix ${STEP:-stepA_mal} "${@}" 4 | -------------------------------------------------------------------------------- /impls/elixir/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Elixir: skipping non-TCO recursion 2 | ;; Reason: Elixir has TCO, test always completes. 3 | -------------------------------------------------------------------------------- /impls/elm/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /impls/elm/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src" 5 | ], 6 | "elm-version": "0.19.1", 7 | "dependencies": { 8 | "direct": { 9 | "elm/core": "1.0.5", 10 | "elm/json": "1.1.3", 11 | "elm/parser": "1.1.0", 12 | "elm/regex": "1.0.0", 13 | "elm/time": "1.0.0" 14 | }, 15 | "indirect": {} 16 | }, 17 | "test-dependencies": { 18 | "direct": {}, 19 | "indirect": {} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /impls/elm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal-elm", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "bootstrap.js", 6 | "dependencies": { 7 | "ffi-napi": "4.0.3" 8 | }, 9 | "devDependencies": { 10 | "elm": "^0.19.1" 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "author": "", 16 | "license": "ISC" 17 | } 18 | -------------------------------------------------------------------------------- /impls/elm/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | exec node $(dirname $0)/bootstrap.js ${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/erlang/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% rebar configuration file (https://github.com/rebar/rebar) 3 | %% 4 | 5 | {erl_opts, [debug_info, fail_on_warning]}. 6 | 7 | {clean_files, [ 8 | "ebin", 9 | "src/*.beam", 10 | "mal", 11 | "step0_repl", 12 | "step1_read_print", 13 | "step2_eval", 14 | "step3_env", 15 | "step4_if_fn_do", 16 | "step5_tco", 17 | "step6_file", 18 | "step7_quote", 19 | "step8_macros", 20 | "step9_try", 21 | "stepA_mal" 22 | ]}. 23 | -------------------------------------------------------------------------------- /impls/erlang/rebar.config.script: -------------------------------------------------------------------------------- 1 | %% 2 | %% rebar dynamic configuration file 3 | %% (https://github.com/rebar/rebar/wiki/Dynamic-configuration) 4 | %% 5 | 6 | case os:getenv("MAL_STEP") of 7 | false -> CONFIG; % env var not defined 8 | [] -> CONFIG; % env var set to empty string 9 | Step -> CONFIG ++ [{escript_name, Step}]; 10 | mal -> CONFIG ++ [{escript_name, mal}] 11 | end. 12 | -------------------------------------------------------------------------------- /impls/erlang/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/erlang/src/mal.app.src: -------------------------------------------------------------------------------- 1 | {application, mal, [ 2 | {description, "Make-a-Lisp Erlang"}, 3 | {vsn, "1"}, 4 | {registered, []}, 5 | {applications, [ 6 | kernel, 7 | stdlib 8 | ]}, 9 | {mod, {mal_app, []}}, 10 | {env, []} 11 | ]}. 12 | -------------------------------------------------------------------------------- /impls/erlang/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Erlang: skipping non-TCO recursion 2 | ;; Reason: Erlang has TCO, test always completes. 3 | -------------------------------------------------------------------------------- /impls/es6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in ES6 (ECMAScript 6 / ECMAScript 2015)", 5 | "dependencies": { 6 | "esm": "3.1.x", 7 | "ffi-napi": "4.0.3" 8 | }, 9 | "esm": { 10 | "cjs": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /impls/es6/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec node -r esm $(dirname $0)/${STEP:-stepA_mal}.mjs "${@}" 3 | -------------------------------------------------------------------------------- /impls/es6/step0_repl.mjs: -------------------------------------------------------------------------------- 1 | import rl from './node_readline.js' 2 | const readline = rl.readline 3 | 4 | // read 5 | const READ = str => str 6 | 7 | // eval 8 | const EVAL = (ast, env) => ast 9 | 10 | // print 11 | const PRINT = exp => exp 12 | 13 | // repl 14 | const REP = str => PRINT(EVAL(READ(str), {})) 15 | 16 | while (true) { 17 | let line = readline('user> ') 18 | if (line == null) break 19 | if (line) { console.log(REP(line)) } 20 | } 21 | -------------------------------------------------------------------------------- /impls/es6/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/factor/lib/core/core-tests.factor: -------------------------------------------------------------------------------- 1 | USING: assocs effects kernel sequences stack-checker tools.test ; 2 | IN: lib.core 3 | 4 | { t } [ 5 | ns values [ 6 | infer ( x -- * ) ( x -- x ) [ effect= ] bi-curry@ bi or 7 | ] all? 8 | ] unit-test 9 | -------------------------------------------------------------------------------- /impls/factor/lib/reader/reader-tests.factor: -------------------------------------------------------------------------------- 1 | USING: lists lib.types tools.test ; 2 | IN: lib.reader 3 | 4 | { "foo" } [ "\"foo\"" read-atom ] unit-test 5 | { T{ malkeyword { name "foo" } } } [ ":foo" read-atom ] unit-test 6 | { f } [ "false" read-atom ] unit-test 7 | { t } [ "true" read-atom ] unit-test 8 | { +nil+ } [ "nil" read-atom ] unit-test 9 | { T{ malsymbol { name "foo" } } } [ "foo" read-atom ] unit-test 10 | { 14 } [ "14" read-atom ] unit-test 11 | { 1.5 } [ "1.5" read-atom ] unit-test 12 | { 2/3 } [ "2/3" read-atom ] unit-test 13 | -------------------------------------------------------------------------------- /impls/factor/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec factor $(dirname $0)/${STEP:-stepA_mal}/${STEP:-stepA_mal}.factor "${@}" 3 | -------------------------------------------------------------------------------- /impls/factor/step0_repl/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step0_repl" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step0_repl/step0_repl.factor: -------------------------------------------------------------------------------- 1 | ! Copyright (C) 2015 Jordan Lewis. 2 | ! See http://factorcode.org/license.txt for BSD license. 3 | USING: io kernel readline sequences ; 4 | IN: step0_repl 5 | 6 | : READ ( x -- x ) ; 7 | 8 | : EVAL ( x -- x ) ; 9 | 10 | : PRINT ( x -- x ) ; 11 | 12 | : REP ( x -- x ) READ EVAL PRINT ; 13 | 14 | : REPL ( -- ) 15 | [ 16 | "user> " readline [ 17 | [ REP print flush ] unless-empty 18 | ] keep 19 | ] loop ; 20 | 21 | MAIN: REPL 22 | -------------------------------------------------------------------------------- /impls/factor/step1_read_print/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step1_read_print" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step2_eval/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step2_eval" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step3_env/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step3_env" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step4_if_fn_do/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step4_if_fn_do" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step5_tco/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step5_tco" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step6_file/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step6_file" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step7_quote/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step7_quote" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step8_macros/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step8_macros" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/step9_try/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "step9_try" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/stepA_mal/deploy.factor: -------------------------------------------------------------------------------- 1 | USING: tools.deploy.config ; 2 | H{ 3 | { deploy-c-types? f } 4 | { deploy-help? f } 5 | { deploy-name "stepA_mal" } 6 | { "stop-after-last-window?" t } 7 | { deploy-unicode? f } 8 | { deploy-console? t } 9 | { deploy-io 3 } 10 | { deploy-reflection 1 } 11 | { deploy-ui? f } 12 | { deploy-word-defs? f } 13 | { deploy-threads? t } 14 | { deploy-math? t } 15 | { deploy-word-props? f } 16 | } 17 | -------------------------------------------------------------------------------- /impls/factor/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/fantom/Makefile: -------------------------------------------------------------------------------- 1 | all: dist 2 | 3 | dist: lib/fan/mal.pod 4 | 5 | lib/fan: 6 | mkdir -p $@ 7 | 8 | lib/fan/mal.pod: lib/fan/stepA_mal.pod 9 | cp -a $< $@ 10 | 11 | lib/fan/step%.pod: src/step%/build.fan src/step%/fan/*.fan lib/fan/mallib.pod 12 | FAN_ENV=util::PathEnv FAN_ENV_PATH=. fan $< 13 | 14 | lib/fan/mallib.pod: src/mallib/build.fan src/mallib/fan/*.fan lib/fan 15 | FAN_ENV=util::PathEnv FAN_ENV_PATH=. fan $< 16 | 17 | clean: 18 | rm -rf lib 19 | -------------------------------------------------------------------------------- /impls/fantom/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export FAN_ENV=util::PathEnv 3 | export FAN_ENV_PATH="$(dirname $0)" 4 | exec fan ${STEP:-stepA_mal} "$@" 5 | -------------------------------------------------------------------------------- /impls/fantom/src/mallib/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "mallib" 6 | summary = "mal library pod" 7 | depends = ["sys 1.0", "compiler 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step0_repl/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step0_repl" 6 | summary = "mal step0_repl pod" 7 | depends = ["sys 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step0_repl/fan/main.fan: -------------------------------------------------------------------------------- 1 | class Main 2 | { 3 | static Str READ(Str s) 4 | { 5 | return s 6 | } 7 | 8 | static Str EVAL(Str ast, Str env) 9 | { 10 | return ast 11 | } 12 | 13 | static Str PRINT(Str exp) 14 | { 15 | return exp 16 | } 17 | 18 | static Str REP(Str s, Str env) 19 | { 20 | return PRINT(EVAL(READ(s), env)) 21 | } 22 | 23 | static Void main() 24 | { 25 | while (true) { 26 | line := Env.cur.prompt("user> ") 27 | if (line == null) break 28 | if (line.isSpace) continue 29 | echo(REP(line, "")) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /impls/fantom/src/step1_read_print/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step1_read_print" 6 | summary = "mal step1_read_print pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step2_eval/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step2_eval" 6 | summary = "mal step2_eval pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step3_env/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step3_env" 6 | summary = "mal step3_env pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step4_if_fn_do/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step4_if_fn_do" 6 | summary = "mal step4_if_fn_do pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step5_tco/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step5_tco" 6 | summary = "mal step5_tco pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step6_file/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step6_file" 6 | summary = "mal step6_file pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step7_quote/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step7_quote" 6 | summary = "mal step7_quote pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step8_macros/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step8_macros" 6 | summary = "mal step8_macros pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/step9_try/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "step9_try" 6 | summary = "mal step9_try pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/src/stepA_mal/build.fan: -------------------------------------------------------------------------------- 1 | class Build : build::BuildPod 2 | { 3 | new make() 4 | { 5 | podName = "stepA_mal" 6 | summary = "mal stepA_mal pod" 7 | depends = ["sys 1.0", "mallib 1.0"] 8 | srcDirs = [`fan/`] 9 | outPodDir = `lib/fan/` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/fantom/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/fennel/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | true 3 | -------------------------------------------------------------------------------- /impls/fennel/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | exec fennel $(dirname $0)/${STEP:-stepA_mal}.fnl "${@}" 4 | -------------------------------------------------------------------------------- /impls/fennel/step0_repl.fnl: -------------------------------------------------------------------------------- 1 | (fn READ [code-str] 2 | code-str) 3 | 4 | (fn EVAL [ast] 5 | ast) 6 | 7 | (fn PRINT [ast] 8 | ast) 9 | 10 | (fn rep [code-str] 11 | (PRINT (EVAL (READ code-str)))) 12 | 13 | (var done false) 14 | 15 | (while (not done) 16 | (io.write "user> ") 17 | (io.flush) 18 | (let [input (io.read)] 19 | (if (not input) 20 | (set done true) 21 | (print (rep input))))) 22 | -------------------------------------------------------------------------------- /impls/forth/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = str.fs types.fs reader.fs printer.fs 2 | SOURCES_LISP = env.fs core.fs stepA_mal.fs 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.fs mal 9 | 10 | mal.fs: $(SOURCES) 11 | cat $+ | egrep -v "^require |^droprequire " > $@ 12 | 13 | mal: mal.fs 14 | echo "#! /usr/bin/env gforth" > $@ 15 | cat $< >> $@ 16 | chmod +x $@ 17 | 18 | clean: 19 | rm -f mal.fs mal 20 | -------------------------------------------------------------------------------- /impls/forth/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec gforth $(dirname $0)/${STEP:-stepA_mal}.fs "${@}" 3 | -------------------------------------------------------------------------------- /impls/forth/step0_repl.fs: -------------------------------------------------------------------------------- 1 | require types.fs 2 | 3 | : read ; 4 | : eval ; 5 | : print ; 6 | 7 | : rep 8 | read 9 | eval 10 | print ; 11 | 12 | create buff 128 allot 13 | 14 | : read-lines 15 | begin 16 | ." user> " 17 | buff 128 stdin read-line throw 18 | while ( num-bytes-read ) 19 | dup 0 <> if 20 | buff swap 21 | rep type cr 22 | endif 23 | repeat ; 24 | 25 | read-lines 26 | -------------------------------------------------------------------------------- /impls/forth/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/fsharp/readline.fs: -------------------------------------------------------------------------------- 1 | module Readline 2 | open System 3 | open Mono.Terminal 4 | 5 | type Mode = 6 | | Terminal 7 | | Raw 8 | 9 | let read prompt = function 10 | | Terminal 11 | -> let editor = LineEditor("Mal") 12 | editor.Edit(prompt, "") 13 | | Raw 14 | -> Console.Write(prompt) 15 | Console.Out.Flush() 16 | Console.ReadLine() 17 | -------------------------------------------------------------------------------- /impls/fsharp/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec mono $(dirname $0)/${STEP:-stepA_mal}.exe ${RAW:+--raw} "${@}" 3 | -------------------------------------------------------------------------------- /impls/fsharp/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; F#: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, unrecoverable segfault at 20,000 3 | -------------------------------------------------------------------------------- /impls/gnu-smalltalk/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | -------------------------------------------------------------------------------- /impls/gnu-smalltalk/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec gst -f $(dirname $0)/${STEP:-stepA_mal}.st "${@}" 3 | -------------------------------------------------------------------------------- /impls/gnu-smalltalk/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | (gst-eval "1 + 1") 2 | ;=>2 3 | 4 | (gst-eval "{1. 2. 3}") 5 | ;=>[1 2 3] 6 | 7 | (gst-eval "#('a' 'b' 'c') join: ' '") 8 | ;=>"a b c" 9 | 10 | (gst-eval "'Hello World!' displayNl") 11 | ;/Hello World! 12 | -------------------------------------------------------------------------------- /impls/go/go.mod: -------------------------------------------------------------------------------- 1 | module mal 2 | 3 | go 1.22.2 4 | -------------------------------------------------------------------------------- /impls/go/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/go/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Go: skipping non-TCO recursion 2 | ;; Reason: completes even at 100,000 3 | -------------------------------------------------------------------------------- /impls/groovy/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec groovy $(dirname $0)/${STEP:-stepA_mal}.groovy "${@}" 3 | -------------------------------------------------------------------------------- /impls/groovy/step0_repl.groovy: -------------------------------------------------------------------------------- 1 | // READ 2 | READ = { str -> 3 | str 4 | } 5 | 6 | // EVAL 7 | EVAL = { ast, env -> 8 | ast 9 | } 10 | 11 | // PRINT 12 | PRINT = { exp -> 13 | exp 14 | } 15 | 16 | // REPL 17 | REP = { str -> 18 | PRINT(EVAL(READ(str), [:])) 19 | } 20 | 21 | while (true) { 22 | line = System.console().readLine 'user> ' 23 | if (line == null) { 24 | break 25 | } 26 | try { 27 | println REP(line) 28 | } catch(ex) { 29 | println "Error: $ex" 30 | ex.printStackTrace() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /impls/groovy/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/guile/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = readline.scm types.scm reader.scm printer.scm 2 | SOURCES_LISP = env.scm core.scm stepA_mal.scm 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.scm 9 | 10 | mal.scm: $(SOURCES) 11 | echo "#! /usr/bin/env guile" > $@ 12 | echo "!#" >> $@ 13 | cat $+ | sed $(foreach f,$(+),-e 's/(readline)//') >> $@ 14 | chmod +x $@ 15 | 16 | clean: 17 | rm -f mal.scm 18 | -------------------------------------------------------------------------------- /impls/guile/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # XDG_CACHE_HOME is where guile stores the compiled files 3 | XDG_CACHE_HOME=.cache/ exec guile -L $(dirname $0) $(dirname $0)/${STEP:-stepA_mal}.scm "${@}" 4 | -------------------------------------------------------------------------------- /impls/hare/.gitignore: -------------------------------------------------------------------------------- 1 | !mal -------------------------------------------------------------------------------- /impls/hare/makefile: -------------------------------------------------------------------------------- 1 | CC= hare build 2 | 3 | BINS = step0_repl step1_read_print step2_eval step3_env step4_if_fn_do step5_tco step6_file step7_quote step8_macros step9_try stepA_mal 4 | 5 | .PHONY: all 6 | all: $(BINS) 7 | 8 | %: %.ha $(wildcard mal/*.ha) 9 | $(CC) -o $@ $< 10 | 11 | .PHONY: clean 12 | clean: 13 | rm $(BINS) 14 | -------------------------------------------------------------------------------- /impls/hare/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" -------------------------------------------------------------------------------- /impls/haskell/Makefile: -------------------------------------------------------------------------------- 1 | SRCS = step0_repl.hs step1_read_print.hs step2_eval.hs step3_env.hs \ 2 | step4_if_fn_do.hs step5_tco.hs step6_file.hs step7_quote.hs \ 3 | step8_macros.hs step9_try.hs stepA_mal.hs 4 | OTHER_SRCS = Readline.hs Types.hs Reader.hs Printer.hs Env.hs Core.hs 5 | BINS = $(SRCS:%.hs=%) 6 | ghc_flags = -Wall 7 | 8 | ##################### 9 | 10 | all: $(BINS) 11 | 12 | dist: mal 13 | 14 | mal: $(word $(words $(BINS)),$(BINS)) 15 | cp $< $@ 16 | 17 | $(BINS): %: %.hs $(OTHER_SRCS) 18 | ghc ${ghc_flags} --make $< -o $@ 19 | 20 | clean: 21 | rm -f $(BINS) mal *.hi *.o 22 | -------------------------------------------------------------------------------- /impls/haskell/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/haskell/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Haskell: skipping non-TCO recursion 2 | ;; Reason: completes up to 100,000, stackoverflow at 1,000,000 3 | -------------------------------------------------------------------------------- /impls/haxe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in Haxe/Javascript", 5 | "dependencies": { 6 | "ffi-napi": "4.0.3" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /impls/haxe/reader/BlankLine.hx: -------------------------------------------------------------------------------- 1 | package reader; 2 | 3 | class BlankLine { 4 | public function new() { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /impls/haxe/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | case ${haxe_MODE:-neko} in 3 | neko) exec neko $(dirname $0)/${STEP:-stepA_mal}.n "${@}" ;; 4 | python) exec python3 $(dirname $0)/${STEP:-stepA_mal}.py "${@}" ;; 5 | js) exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" ;; 6 | cpp) exec $(dirname $0)/cpp/${STEP:-stepA_mal} "${@}" ;; 7 | *) echo "Invalid haxe_MODE: ${haxe_MODE}"; exit 2 ;; 8 | esac 9 | -------------------------------------------------------------------------------- /impls/haxe/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 100000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/haxe/types/MalException.hx: -------------------------------------------------------------------------------- 1 | package types; 2 | 3 | import types.Types.MalType; 4 | 5 | class MalException { 6 | public var obj:MalType = null; 7 | public function new(obj:MalType) { 8 | this.obj = obj; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /impls/hy/Makefile: -------------------------------------------------------------------------------- 1 | all: mal.hy 2 | 3 | mal.hy: stepA_mal.hy 4 | cp $< $@ 5 | 6 | clean: 7 | rm -f mal.hy *.pyc 8 | -------------------------------------------------------------------------------- /impls/hy/mal_types.hy: -------------------------------------------------------------------------------- 1 | (import [types :as pytypes]) 2 | 3 | (defclass MalException [Exception] 4 | (defn --init-- [self val] (setv self.val val))) 5 | 6 | (defclass Atom [] 7 | (defn --init-- [self val] (setv self.val val))) 8 | 9 | (defn clone [obj] 10 | (if (= (type obj) pytypes.FunctionType) 11 | (pytypes.FunctionType obj.__code__ obj.__globals__ 12 | :name obj.__name__ 13 | :argdefs obj.__defaults__ 14 | :closure obj.__closure__) 15 | obj)) 16 | -------------------------------------------------------------------------------- /impls/hy/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal}.hy "${@}" 3 | -------------------------------------------------------------------------------- /impls/hy/step0_repl.hy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env hy 2 | 3 | (defn READ [str] 4 | str) 5 | 6 | (defn EVAL [ast env] 7 | ast) 8 | 9 | (defn PRINT [exp] 10 | exp) 11 | 12 | (defn REP [str] 13 | (PRINT (EVAL (READ str) {}))) 14 | 15 | (defmain [&rest args] 16 | ;; indented to match later steps 17 | (while True 18 | (try 19 | (do (setv line (raw_input "user> ")) 20 | (if (= "" line) (continue)) 21 | (print (REP line))) 22 | (except [EOFError] (break))))) 23 | -------------------------------------------------------------------------------- /impls/hy/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/io/Makefile: -------------------------------------------------------------------------------- 1 | STEPS = step0_repl.io step1_read_print.io step2_eval.io step3_env.io step4_if_fn_do.io step5_tco.io \ 2 | step6_file.io step7_quote.io step8_macros.io step9_try.io stepA_mal.io 3 | 4 | all: eerie 5 | 6 | eerie: 7 | ln -s /opt/.eerie eerie 8 | 9 | $(STEPS): eerie 10 | 11 | clean: 12 | -------------------------------------------------------------------------------- /impls/io/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | io $(dirname $0)/${STEP:-stepA_mal}.io "$@" 4 | -------------------------------------------------------------------------------- /impls/io/step0_repl.io: -------------------------------------------------------------------------------- 1 | Regex 2 | 3 | READ := method(str, str) 4 | 5 | EVAL := method(ast, env, ast) 6 | 7 | PRINT := method(exp, exp) 8 | 9 | RE := method(str, EVAL(READ(str), nil)) 10 | 11 | REP := method(str, PRINT(RE(str))) 12 | 13 | loop( 14 | line := MalReadline readLine("user> ") 15 | if(line isNil, break) 16 | if(line isEmpty, continue) 17 | REP(line) println 18 | ) 19 | -------------------------------------------------------------------------------- /impls/io/step1_read_print.io: -------------------------------------------------------------------------------- 1 | MalTypes 2 | MalReader 3 | 4 | READ := method(str, MalReader read_str(str)) 5 | 6 | EVAL := method(ast, env, ast) 7 | 8 | PRINT := method(exp, exp malPrint(true)) 9 | 10 | RE := method(str, EVAL(READ(str), nil)) 11 | 12 | REP := method(str, PRINT(RE(str))) 13 | 14 | loop( 15 | line := MalReadline readLine("user> ") 16 | if(line isNil, break) 17 | if(line isEmpty, continue) 18 | e := try(REP(line) println) 19 | e catch(Exception, 20 | ("Error: " .. (e error)) println 21 | ) 22 | ) 23 | -------------------------------------------------------------------------------- /impls/io/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Io: skipping non-TCO recursion 2 | ;; Reason: never completes, never segfaults 3 | -------------------------------------------------------------------------------- /impls/janet/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | true 3 | -------------------------------------------------------------------------------- /impls/janet/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec janet $(dirname $0)/${STEP:-stepA_mal}.janet "${@}" 3 | -------------------------------------------------------------------------------- /impls/janet/step0_repl.janet: -------------------------------------------------------------------------------- 1 | (defn READ 2 | [code-str] 3 | code-str) 4 | 5 | (defn EVAL 6 | [ast] 7 | ast) 8 | 9 | (defn PRINT 10 | [ast] 11 | ast) 12 | 13 | (defn rep 14 | [code-str] 15 | (PRINT (EVAL (READ code-str)))) 16 | 17 | # getline gives problems 18 | (defn getstdin [prompt buf] 19 | (file/write stdout prompt) 20 | (file/flush stdout) 21 | (file/read stdin :line buf)) 22 | 23 | (defn main 24 | [& args] 25 | (var buf nil) 26 | (while true 27 | (set buf @"") 28 | (getstdin "user> " buf) 29 | (if (< 0 (length buf)) 30 | (prin (rep buf)) 31 | (break)))) 32 | -------------------------------------------------------------------------------- /impls/janet/utils.janet: -------------------------------------------------------------------------------- 1 | (defn throw* 2 | [ast] 3 | (error ast)) 4 | -------------------------------------------------------------------------------- /impls/java-truffle/.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings 4 | target 5 | /.gradle/ 6 | /build/ 7 | .factorypath 8 | .apt_generated 9 | bin 10 | graal_dumps 11 | -------------------------------------------------------------------------------- /impls/java-truffle/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ghcr.io/graalvm/graalvm-ce:21.1.0 2 | 3 | RUN microdnf install python3 unzip && \ 4 | ln -sf /usr/bin/python3 /usr/bin/python && \ 5 | curl -o gradle.zip "https://downloads.gradle-dn.com/distributions/gradle-7.0.2-bin.zip" && \ 6 | mkdir /opt/gradle && \ 7 | unzip -d /opt/gradle gradle.zip 8 | 9 | RUN mkdir -p /mal 10 | WORKDIR /mal 11 | ENV GRADLE_USER_HOME=/tmp/.gradle 12 | ENV PATH="$PATH:/opt/gradle/gradle-7.0.2/bin" 13 | -------------------------------------------------------------------------------- /impls/java-truffle/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gradle build 3 | 4 | build/classes/java/main/truffle/mal/step%.class: src/main/java/truffle/mal/*.java 5 | gradle build 6 | 7 | clean: 8 | gradle clean 9 | -------------------------------------------------------------------------------- /impls/java-truffle/make-native.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | STEP=${1:-stepE_macros} 4 | 5 | CP=$(gradle -q --console plain printClasspath) 6 | native-image --macro:truffle --no-fallback --initialize-at-build-time \ 7 | -H:+TruffleCheckBlackListedMethods \ 8 | -cp "$CP" truffle.mal.$STEP build/$STEP 9 | -------------------------------------------------------------------------------- /impls/java-truffle/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | 5 | rootProject.name = 'truffle-mal' 6 | -------------------------------------------------------------------------------- /impls/java/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | args="" 3 | if [ "$#" -gt 0 ]; then 4 | args="-Dexec.args='$1'" 5 | for a in "${@:2}"; do 6 | args="$args '$a'" 7 | done 8 | fi 9 | exec mvn -quiet -e exec:java -Dexec.mainClass="mal.${STEP:-stepA_mal}" ${args:+"$args"} 10 | -------------------------------------------------------------------------------- /impls/java/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/jq/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | rm -fr .mypy_cache/ 5 | 6 | check: 7 | flake8 run 8 | pylint run 9 | mypy run 10 | 11 | .PHONY: all clean check 12 | -------------------------------------------------------------------------------- /impls/jq/step0_repl.jq: -------------------------------------------------------------------------------- 1 | include "utils"; 2 | 3 | def READ: 4 | .; 5 | 6 | def EVAL: 7 | .; 8 | 9 | def PRINT: 10 | .; 11 | 12 | def repl: 13 | # Infinite generator, interrupted by ./run. 14 | "user> " | __readline | 15 | READ | EVAL | 16 | PRINT, repl; 17 | 18 | repl 19 | -------------------------------------------------------------------------------- /impls/jq/step1_read_print.jq: -------------------------------------------------------------------------------- 1 | include "reader"; 2 | include "printer"; 3 | include "utils"; 4 | 5 | def READ: 6 | read_form; 7 | 8 | def EVAL: 9 | .; 10 | 11 | def PRINT: 12 | pr_str; 13 | 14 | def repl: 15 | # Infinite generator, interrupted by an exception or ./run. 16 | "user> " | __readline | 17 | try ( 18 | READ | EVAL | 19 | PRINT, repl 20 | ) catch if is_jqmal_error then 21 | ., repl 22 | else 23 | halt_error 24 | end; 25 | 26 | repl 27 | -------------------------------------------------------------------------------- /impls/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in Javascript", 5 | "dependencies": { 6 | "ffi-napi": "4.0.3" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /impls/js/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" 3 | -------------------------------------------------------------------------------- /impls/js/tests/common.js: -------------------------------------------------------------------------------- 1 | fs = require('fs'); 2 | assert = require('assert'); 3 | 4 | function assert_eq(a, b) { 5 | GLOBAL.assert.deepEqual(a, b, a + " !== " + b); 6 | } 7 | 8 | function load(file) { 9 | console.log(process.cwd()); 10 | //process.chdir('../'); 11 | eval(fs.readFileSync(file,'utf8')); 12 | } 13 | 14 | exports.assert_eq = assert_eq; 15 | exports.load = load; 16 | -------------------------------------------------------------------------------- /impls/js/tests/node_modules: -------------------------------------------------------------------------------- 1 | ../ -------------------------------------------------------------------------------- /impls/js/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/js/web: -------------------------------------------------------------------------------- 1 | ../docs/web -------------------------------------------------------------------------------- /impls/julia/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | 5 | -------------------------------------------------------------------------------- /impls/julia/readline_mod.jl: -------------------------------------------------------------------------------- 1 | module readline_mod 2 | 3 | export do_readline 4 | 5 | function do_readline(prompt) 6 | print(prompt) 7 | flush(STDOUT) 8 | line = readline(STDIN) 9 | if line == "" 10 | return nothing 11 | end 12 | chomp(line) 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /impls/julia/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec julia $(dirname $0)/${STEP:-stepA_mal}.jl "${@}" 3 | -------------------------------------------------------------------------------- /impls/julia/step0_repl.jl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env julia 2 | 3 | push!(LOAD_PATH, pwd(), "/usr/share/julia/base") 4 | import readline_mod 5 | 6 | # READ 7 | function READ(str) 8 | str 9 | end 10 | 11 | # EVAL 12 | function EVAL(ast, env) 13 | ast 14 | end 15 | 16 | # PRINT 17 | function PRINT(exp) 18 | exp 19 | end 20 | 21 | # REPL 22 | function REP(str) 23 | return PRINT(EVAL(READ(str), [])) 24 | end 25 | 26 | while true 27 | line = readline_mod.do_readline("user> ") 28 | if line === nothing break end 29 | println(REP(line)) 30 | end 31 | -------------------------------------------------------------------------------- /impls/julia/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 100000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/kotlin/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec java -jar $(dirname $0)/${STEP:-stepA_mal}.jar "${@}" 3 | -------------------------------------------------------------------------------- /impls/kotlin/src/mal/readline.kt: -------------------------------------------------------------------------------- 1 | package mal 2 | 3 | class EofException : Exception("EOF") 4 | 5 | fun readline(prompt: String): String { 6 | print(prompt) 7 | return readLine() ?: throw EofException() 8 | } 9 | -------------------------------------------------------------------------------- /impls/kotlin/src/mal/step0_repl.kt: -------------------------------------------------------------------------------- 1 | package mal 2 | 3 | fun main(args: Array) { 4 | fun read(input: String?): String? = input 5 | fun eval(expression: String?): String? = expression 6 | fun print(result: String?): String? = result 7 | 8 | while (true) { 9 | val input = readline("user> ") 10 | 11 | try { 12 | println(print(eval(read(input)))) 13 | } catch (e: EofException) { 14 | break 15 | } catch (t: Throwable) { 16 | println("Uncaught " + t + ": " + t.message) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /impls/kotlin/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/latex3/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | clean: 3 | rm -f *~ *.aux *.dvi *.log argv 4 | -------------------------------------------------------------------------------- /impls/lib/benchmark.mal: -------------------------------------------------------------------------------- 1 | ;; An alternative approach, to complement perf.mal 2 | (load-file "../lib/load-file-once.mal") 3 | (load-file-once "../lib/trivial.mal") ; gensym inc 4 | 5 | (def! benchmark* (fn* [f n results] 6 | (if (< 0 n) 7 | (let* [start-ms (time-ms) 8 | _ (f) 9 | end-ms (time-ms)] 10 | (benchmark* f (- n 1) (conj results (- end-ms start-ms)))) 11 | results))) 12 | 13 | (defmacro! benchmark (fn* [expr n] 14 | `(benchmark* (fn* [] ~expr) ~n []))) 15 | 16 | -------------------------------------------------------------------------------- /impls/lib/load-file-once.mal: -------------------------------------------------------------------------------- 1 | ;; Like load-file, but will never load the same path twice. 2 | 3 | ;; This file is normally loaded with `load-file`, so it needs a 4 | ;; different mechanism to neutralize multiple inclusions of 5 | ;; itself. Moreover, the file list should never be reset. 6 | 7 | (def! load-file-once 8 | (try* 9 | load-file-once 10 | (catch* _ 11 | (let* [seen (atom {"../lib/load-file-once.mal" nil})] 12 | (fn* [filename] 13 | (if (not (contains? @seen filename)) 14 | (do 15 | (swap! seen assoc filename nil) 16 | (load-file filename)))))))) 17 | -------------------------------------------------------------------------------- /impls/livescript/env.ls: -------------------------------------------------------------------------------- 1 | export class Env 2 | (outer = null, data = {}) -> 3 | @outer = outer 4 | @data = data 5 | 6 | set: (symbol, ast) -> 7 | @data[symbol] = ast 8 | 9 | get: (symbol) -> 10 | if symbol of @data then @data[symbol] 11 | else if @outer? then @outer.get symbol 12 | -------------------------------------------------------------------------------- /impls/livescript/error.ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/impls/livescript/error.ls -------------------------------------------------------------------------------- /impls/livescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "make-a-lisp", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "koffi": "^2.9.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /impls/livescript/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" 3 | -------------------------------------------------------------------------------- /impls/livescript/step1_read_print.ls: -------------------------------------------------------------------------------- 1 | readline = require './node_readline' 2 | {id} = require 'prelude-ls' 3 | {read_str, OnlyComment} = require './reader' 4 | {pr_str} = require './printer' 5 | 6 | 7 | EVAL = id 8 | 9 | rep = (line) -> pr_str EVAL read_str line 10 | 11 | loop 12 | line = readline.readline 'user> ' 13 | break if not line? or line == '' 14 | try 15 | console.log rep line 16 | catch {message}: ex 17 | if ex not instanceof OnlyComment 18 | console.log message 19 | -------------------------------------------------------------------------------- /impls/livescript/utils.ls: -------------------------------------------------------------------------------- 1 | {map} = require 'prelude-ls' 2 | 3 | 4 | export list-to-pairs = (list) -> 5 | [0 to (list.length - 2) by 2] \ 6 | |> map (idx) -> [list[idx], list[idx+1]] 7 | -------------------------------------------------------------------------------- /impls/logo/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = readline.lg types.lg reader.lg printer.lg 2 | SOURCES_LISP = env.lg core.lg stepA_mal.lg 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | .PHONY: all dist clean 6 | 7 | all: 8 | @true 9 | 10 | dist: mal.lg mal 11 | 12 | mal.lg: $(SOURCES) 13 | cat $+ | grep -v "^load " > $@ 14 | 15 | mal: mal.lg 16 | echo "#!/usr/bin/env logo" > $@ 17 | cat $< >> $@ 18 | chmod +x $@ 19 | 20 | clean: 21 | rm -f mal.lg mal 22 | -------------------------------------------------------------------------------- /impls/logo/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec ucblogo $(dirname $0)/${STEP:-stepA_mal}.lg - "${@}" 3 | -------------------------------------------------------------------------------- /impls/logo/step0_repl.lg: -------------------------------------------------------------------------------- 1 | load "../logo/readline.lg 2 | 3 | to _read :str 4 | output :str 5 | end 6 | 7 | to _eval :ast 8 | output :ast 9 | end 10 | 11 | to _print :exp 12 | output :exp 13 | end 14 | 15 | to rep :str 16 | output _print _eval _read :str 17 | end 18 | 19 | to repl 20 | do.until [ 21 | localmake "line readline "|user> | 22 | if not emptyp :line [ 23 | print rep :line 24 | ] 25 | ] [:line = []] 26 | (print) 27 | end 28 | 29 | repl 30 | bye 31 | -------------------------------------------------------------------------------- /impls/logo/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic Logo interop 2 | 3 | (logo-eval "7") 4 | ;=>7 5 | 6 | (logo-eval "\"hello") 7 | ;=>"hello" 8 | 9 | (logo-eval "[7 8 9]") 10 | ;=>(7 8 9) 11 | 12 | (logo-eval "123 = 123") 13 | ;=>true 14 | 15 | (logo-eval "not emptyp []") 16 | ;=>false 17 | 18 | (logo-eval "print [hello world]") 19 | ;/hello world 20 | ;=>nil 21 | 22 | (logo-eval "make \"foo 8") 23 | (logo-eval ":foo") 24 | ;=>8 25 | 26 | (logo-eval "apply \"word map \"reverse [Abc Abcd Abcde]") 27 | ;=>"cbAdcbAedcbA" 28 | 29 | (logo-eval "map [1 + ?] [1 2 3]") 30 | ;=>(2 3 4) 31 | -------------------------------------------------------------------------------- /impls/lua/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec lua $(dirname $0)/${STEP:-stepA_mal}.lua "${@}" 3 | -------------------------------------------------------------------------------- /impls/lua/step0_repl.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local readline = require('readline') 4 | 5 | function READ(str) 6 | return str 7 | end 8 | 9 | function EVAL(ast, any) 10 | return ast 11 | end 12 | 13 | function PRINT(exp) 14 | return exp 15 | end 16 | 17 | function rep(str) 18 | return PRINT(EVAL(READ(str),"")) 19 | end 20 | 21 | if #arg > 0 and arg[1] == "--raw" then 22 | readline.raw = true 23 | end 24 | 25 | while true do 26 | line = readline.readline("user> ") 27 | if not line then break end 28 | print(rep(line)) 29 | end 30 | -------------------------------------------------------------------------------- /impls/lua/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 100000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/make/README: -------------------------------------------------------------------------------- 1 | It is often useful to add $(warning /$0/ /$1/ /$2/ /$3/) at the very 2 | start of each interesting macro. 3 | 4 | Recal that foreach does nothing when the list only contains spaces, 5 | and adds spaces between the results even if some results are empty. 6 | 7 | If debugging the reader: 8 | # export READER_DEBUG=1 9 | 10 | In order to get the equivalent of DEBUG_EVAL in step2: 11 | # export EVAL_DEBUG=1 12 | -------------------------------------------------------------------------------- /impls/make/rules.mk: -------------------------------------------------------------------------------- 1 | # To load this file: 2 | # $(eval include rules.mk) 3 | 4 | # Usage: 5 | # (make* "$(eval $(call PRINT_RULE,abc,,@echo \"building $$@\"))") 6 | define PRINT_RULE 7 | $(1): $(2) 8 | $(3) 9 | endef 10 | 11 | # Usage: 12 | # (make* "$(eval $(call PRINT_LINES,abc:, @echo \"shell command\"))") 13 | define PRINT_LINES 14 | $(1) 15 | $(2) 16 | $(3) 17 | $(4) 18 | $(5) 19 | $(6) 20 | $(7) 21 | $(8) 22 | $(9) 23 | $(10) 24 | $(11) 25 | $(12) 26 | $(13) 27 | $(14) 28 | $(15) 29 | $(16) 30 | $(17) 31 | $(18) 32 | $(19) 33 | $(20) 34 | endef 35 | -------------------------------------------------------------------------------- /impls/make/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec make --no-print-directory -f $(dirname $0)/${STEP:-stepA_mal}.mk "${@}" 3 | -------------------------------------------------------------------------------- /impls/make/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic make interop 2 | 3 | (make* "7") 4 | ;=>"7" 5 | 6 | (make* "$(info foo)") 7 | ;/foo 8 | ;=>"" 9 | 10 | (make* "$(eval foo := 8)") 11 | (make* "$(foo)") 12 | ;=>"8" 13 | 14 | (make* "$(foreach v,a b c,X$(v)Y)") 15 | ;=>"XaY XbY XcY" 16 | 17 | (read-string (make* "($(foreach v,1 2 3,$(call int_add,1,$(v))))")) 18 | ;=>(2 3 4) 19 | 20 | -------------------------------------------------------------------------------- /impls/mal/Makefile: -------------------------------------------------------------------------------- 1 | all: mal.mal 2 | 3 | mal.mal: stepA_mal.mal 4 | cp $< $@ 5 | 6 | %.mal: 7 | @true 8 | 9 | clean: 10 | rm -f mal.mal 11 | -------------------------------------------------------------------------------- /impls/mal/core.mal: -------------------------------------------------------------------------------- 1 | (def! core_ns '[* + - / < <= = > >= apply assoc atom atom? concat conj 2 | cons contains? count deref dissoc empty? false? first fn? get 3 | hash-map keys keyword keyword? list list? macro? map map? meta nil? 4 | nth number? pr-str println prn read-string readline reset! rest seq 5 | sequential? slurp str string? swap! symbol symbol? throw time-ms 6 | true? vals vec vector vector? with-meta]) 7 | -------------------------------------------------------------------------------- /impls/mal/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | MAL_FILE=../mal/${STEP:-stepA_mal}.mal 3 | export STEP=stepA_mal # force MAL_IMPL to use stepA 4 | case ${MAL_IMPL} in 5 | *-mal) 6 | MAL_IMPL=${MAL_IMPL%%-mal} 7 | MAL_FILE="../mal/stepA_mal.mal ${MAL_FILE}" ;; 8 | esac 9 | exec ./../${MAL_IMPL:-js}/run ${MAL_FILE} "${@}" 10 | -------------------------------------------------------------------------------- /impls/mal/step0_repl.mal: -------------------------------------------------------------------------------- 1 | ;; read 2 | (def! READ (fn* [strng] 3 | strng)) 4 | 5 | ;; eval 6 | (def! EVAL (fn* [ast] 7 | ast)) 8 | 9 | ;; print 10 | (def! PRINT (fn* [exp] exp)) 11 | 12 | ;; repl 13 | (def! rep (fn* [strng] 14 | (PRINT (EVAL (READ strng))))) 15 | 16 | ;; repl loop 17 | (def! repl-loop (fn* [line] 18 | (if line 19 | (do 20 | (if (not (= "" line)) 21 | (println (rep line))) 22 | (repl-loop (readline "mal-user> ")))))) 23 | 24 | ;; main 25 | (repl-loop "") 26 | -------------------------------------------------------------------------------- /impls/mal/step1_read_print.mal: -------------------------------------------------------------------------------- 1 | ;; read 2 | (def! READ read-string) 3 | 4 | 5 | ;; eval 6 | (def! EVAL (fn* [ast] 7 | ast)) 8 | 9 | ;; print 10 | (def! PRINT pr-str) 11 | 12 | ;; repl 13 | (def! rep (fn* [strng] 14 | (PRINT (EVAL (READ strng))))) 15 | 16 | ;; repl loop 17 | (def! repl-loop (fn* [line] 18 | (if line 19 | (do 20 | (if (not (= "" line)) 21 | (try* 22 | (println (rep line)) 23 | (catch* exc 24 | (println "Uncaught exception:" exc)))) 25 | (repl-loop (readline "mal-user> ")))))) 26 | 27 | ;; main 28 | (repl-loop "") 29 | -------------------------------------------------------------------------------- /impls/matlab/+types/Atom.m: -------------------------------------------------------------------------------- 1 | classdef Atom < handle 2 | properties 3 | val 4 | end 5 | methods 6 | function atm = Atom(val) 7 | atm.val = val; 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /impls/matlab/+types/MalException.m: -------------------------------------------------------------------------------- 1 | classdef MalException < MException 2 | properties 3 | obj 4 | end 5 | methods 6 | function exc = MalException(obj) 7 | exc@MException('MalException:object', 'MalException'); 8 | exc.obj = obj; 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /impls/matlab/+types/Nil.m: -------------------------------------------------------------------------------- 1 | classdef Nil 2 | methods 3 | function len = length(obj) 4 | len = 0; 5 | end 6 | function ret = eq(a,b) 7 | ret = strcmp(class(b),'types.Nil'); 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /impls/matlab/+types/Symbol.m: -------------------------------------------------------------------------------- 1 | classdef Symbol 2 | properties 3 | name 4 | end 5 | methods 6 | function sym = Symbol(name) 7 | sym.name = name; 8 | end 9 | function ret = eq(a,b) 10 | ret = strcmp(a.name, b.name); 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /impls/matlab/.dockerignore: -------------------------------------------------------------------------------- 1 | octave-4.0.0* 2 | -------------------------------------------------------------------------------- /impls/matlab/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | 5 | -------------------------------------------------------------------------------- /impls/matlab/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | args= 4 | for x; do 5 | args="$args${args:+, }'$x'" 6 | done 7 | 8 | case "$matlab_MODE" in 9 | matlab) 10 | options='-nodisplay -nosplash -nodesktop -nojvm -r' 11 | ;; 12 | octave) 13 | options='-q --no-gui --no-history --eval' 14 | ;; 15 | *) 16 | echo "Bad matlab_MODE: $matlab_MODE" 17 | exit 1 18 | ;; 19 | esac 20 | 21 | exec $matlab_MODE $options "${STEP:-stepA_mal}($args);quit;" 22 | -------------------------------------------------------------------------------- /impls/matlab/step0_repl.m: -------------------------------------------------------------------------------- 1 | function step0_repl(varargin), main(varargin), end 2 | 3 | % read 4 | function ret = READ(str) 5 | ret = str; 6 | end 7 | 8 | % eval 9 | function ret = EVAL(ast, env) 10 | ret = ast; 11 | end 12 | 13 | % print 14 | function ret = PRINT(ast) 15 | ret = ast; 16 | end 17 | 18 | % REPL 19 | function ret = rep(str, env) 20 | ret = PRINT(EVAL(READ(str), env)); 21 | end 22 | 23 | function main(args) 24 | while (true) 25 | line = input('user> ', 's'); 26 | fprintf('%s\n', rep(line, '')); 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /impls/matlab/types: -------------------------------------------------------------------------------- 1 | +types/ -------------------------------------------------------------------------------- /impls/miniMAL/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal-miniMAL", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in miniMAL", 5 | "dependencies": { 6 | "minimal-lisp": "1.0.2", 7 | "ffi-napi": "4.0.3" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /impls/miniMAL/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | exec miniMAL ./${STEP:-stepA_mal}.json "${@}" 4 | -------------------------------------------------------------------------------- /impls/miniMAL/step0_repl.json: -------------------------------------------------------------------------------- 1 | ["do", 2 | 3 | 4 | ["load", ["`", "miniMAL-core.json"]], 5 | 6 | ["def", "READ", ["fn", ["strng"], 7 | "strng"]], 8 | 9 | ["def", "EVAL", ["fn", ["ast", "env"], 10 | "ast"]], 11 | 12 | ["def", "PRINT", ["fn", ["exp"], 13 | "exp"]], 14 | 15 | ["def", "rep", ["fn", ["strng"], 16 | ["PRINT", ["EVAL", ["READ", "strng"], null]]]], 17 | 18 | ["repl", ["`", "user> "], "rep"], 19 | 20 | null 21 | 22 | ] 23 | -------------------------------------------------------------------------------- /impls/miniMAL/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; miniMAL skipping non-TCO recursion 2 | ;; Reason: Unrecoverable stack overflow at 10,000 3 | -------------------------------------------------------------------------------- /impls/nasm/Makefile: -------------------------------------------------------------------------------- 1 | 2 | STEPS = step0_repl step1_read_print step2_eval step3_env step4_if_fn_do step5_tco step6_file step7_quote step8_macros step9_try stepA_mal 3 | 4 | COMPONENTS = env.asm core.asm reader.asm printer.asm types.asm system.asm exceptions.asm 5 | 6 | 7 | all: $(STEPS) 8 | 9 | %.o: %.asm $(COMPONENTS) 10 | nasm -felf64 $< 11 | 12 | %: %.o 13 | ld -o $@ $< 14 | 15 | .PHONY: clean 16 | clean: 17 | rm -f $(STEPS) $(STEPS:%=%.o) 18 | -------------------------------------------------------------------------------- /impls/nasm/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | 4 | -------------------------------------------------------------------------------- /impls/nim/mal.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | name = "mal" 3 | version = "1.1" 4 | author = "Dennis Felsing" 5 | description = "Mal code in Nim" 6 | license = "MIT" 7 | 8 | bin = "step0_repl, step1_read_print, step2_eval, step3_env, step4_if_fn_do, step5_tco, step6_file, step7_quote, step8_macros, step9_try, stepA_mal" 9 | 10 | [Deps] 11 | Requires = "nim >= 0.10.3" 12 | -------------------------------------------------------------------------------- /impls/nim/nim.cfg: -------------------------------------------------------------------------------- 1 | gc: markandsweep 2 | -------------------------------------------------------------------------------- /impls/nim/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/nim/step0_repl.nim: -------------------------------------------------------------------------------- 1 | import rdstdin 2 | 3 | proc read(str: string): string = str 4 | 5 | proc eval(ast: string): string = ast 6 | 7 | proc print(exp: string): string = exp 8 | 9 | while true: 10 | try: 11 | let line = readLineFromStdin("user> ") 12 | echo line.read.eval.print 13 | except IOError: quit() 14 | -------------------------------------------------------------------------------- /impls/nim/step1_read_print.nim: -------------------------------------------------------------------------------- 1 | import rdstdin, types, reader, printer 2 | 3 | proc read(str: string): MalType = str.read_str 4 | 5 | proc eval(ast: MalType): MalType = ast 6 | 7 | proc print(exp: MalType): string = exp.pr_str 8 | 9 | while true: 10 | try: 11 | let line = readLineFromStdin("user> ") 12 | echo line.read.eval.print 13 | except IOError: quit() 14 | except: 15 | echo getCurrentExceptionMsg() 16 | -------------------------------------------------------------------------------- /impls/nim/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Nim: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, unrecoverable segfault 20,000 3 | -------------------------------------------------------------------------------- /impls/objc/core.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface Core : NSObject 4 | 5 | + (NSDictionary *)ns; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /impls/objc/env.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | // See types.h for Env interface definition 4 | -------------------------------------------------------------------------------- /impls/objc/mal_readline.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAL_READLINE__ 2 | #define __MAL_READLINE__ 3 | 4 | char *_readline (char prompt[]); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /impls/objc/printer.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NSString * _pr_str(NSObject * obj, BOOL print_readably); 4 | -------------------------------------------------------------------------------- /impls/objc/reader.h: -------------------------------------------------------------------------------- 1 | NSArray * tokenize(NSString *str); 2 | NSObject * read_str(NSString *str); 3 | -------------------------------------------------------------------------------- /impls/objc/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/objc/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Objective C: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, unrecoverable segfault at 20,000 3 | -------------------------------------------------------------------------------- /impls/objpascal/regexpr/Source/RegExpr.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/impls/objpascal/regexpr/Source/RegExpr.pas -------------------------------------------------------------------------------- /impls/objpascal/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/objpascal/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Object Pascal: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, unrecoverable segfault at 20,000 3 | -------------------------------------------------------------------------------- /impls/ocaml/env.ml: -------------------------------------------------------------------------------- 1 | module T = Types.Types 2 | module Data = Map.Make (String) 3 | 4 | type env = { 5 | outer : env option; 6 | data : Types.mal_type Data.t ref; 7 | } 8 | 9 | let make outer = { outer = outer; data = ref Data.empty } 10 | 11 | let set env key value = 12 | env.data := Data.add key value !(env.data) 13 | 14 | let rec get env key = 15 | match Data.find_opt key !(env.data) with 16 | | Some value -> Some value 17 | | None -> match env.outer with 18 | | Some outer -> get outer key 19 | | None -> None 20 | -------------------------------------------------------------------------------- /impls/ocaml/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/ocaml/step0_repl.ml: -------------------------------------------------------------------------------- 1 | (* 2 | To try things at the ocaml repl: 3 | rlwrap ocaml 4 | 5 | To see type signatures of all functions: 6 | ocamlc -i step0_repl.ml 7 | 8 | To run the program: 9 | ocaml step0_repl.ml 10 | *) 11 | 12 | let read str = str 13 | let eval ast any = ast 14 | let print exp = exp 15 | let rep str = print (eval (read str) "") 16 | 17 | let rec main = 18 | try 19 | while true do 20 | print_string "user> "; 21 | print_endline (rep (read_line ())); 22 | done 23 | with End_of_file -> () 24 | -------------------------------------------------------------------------------- /impls/ocaml/step1_read_print.ml: -------------------------------------------------------------------------------- 1 | let read str = Reader.read_str str 2 | let eval ast any = ast 3 | let print exp = Printer.pr_str exp true 4 | let rep str = print (eval (read str) "") 5 | 6 | let rec main = 7 | try 8 | while true do 9 | print_string "user> "; 10 | let line = read_line () in 11 | try 12 | print_endline (rep line); 13 | with End_of_file -> () 14 | done 15 | with End_of_file -> () 16 | -------------------------------------------------------------------------------- /impls/ocaml/step5_tco.ml: -------------------------------------------------------------------------------- 1 | step4_if_fn_do.ml -------------------------------------------------------------------------------- /impls/ocaml/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Ocaml skipping non-TCO recursion 2 | ;; Reason: completes at 50,000, unrecoverable segfaul at 100,000 3 | -------------------------------------------------------------------------------- /impls/perl/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec perl $(dirname $0)/${STEP:-stepA_mal}.pl "${@}" 3 | -------------------------------------------------------------------------------- /impls/perl/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/perl/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing types returned from pl* 2 | 3 | (pl* "123") 4 | ;=>123 5 | 6 | (pl* "\"abc\"") 7 | ;=>"abc" 8 | 9 | (pl* "{'abc'=>123}") 10 | ;=>{"abc" 123} 11 | 12 | (pl* "['abc', 123]") 13 | ;=>("abc" 123) 14 | 15 | (pl* "2+3") 16 | ;=>5 17 | 18 | (pl* "undef") 19 | ;=>nil 20 | 21 | ;; Testing eval of print statement 22 | 23 | (pl* "print 'hello\n';") 24 | ;/hello 25 | ;=>1 26 | 27 | ;; Testing exceptions passing through pl* 28 | 29 | (try* (pl* "die \"pop!\\n\"") (catch* e e)) 30 | ;=>"pop!" 31 | -------------------------------------------------------------------------------- /impls/perl6/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @true 3 | 4 | clean: 5 | -------------------------------------------------------------------------------- /impls/perl6/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec perl6 $(dirname $0)/${STEP:-stepA_mal}.pl "${@}" 3 | -------------------------------------------------------------------------------- /impls/perl6/step0_repl.pl: -------------------------------------------------------------------------------- 1 | use v6; 2 | #use Linenoise; 3 | 4 | sub read ($str) { 5 | return $str; 6 | } 7 | 8 | sub eval ($ast) { 9 | return $ast; 10 | } 11 | 12 | sub print ($exp) { 13 | return $exp; 14 | } 15 | 16 | sub rep ($str) { 17 | return print(eval(read($str))); 18 | } 19 | 20 | sub MAIN { 21 | #while (my $line = linenoise('user> ')).defined { 22 | # say rep($line); 23 | #} 24 | while (my $line = prompt 'user> ').defined { 25 | say rep($line); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /impls/perl6/step1_read_print.pl: -------------------------------------------------------------------------------- 1 | use v6; 2 | use lib IO::Path.new($?FILE).dirname; 3 | use reader; 4 | use printer; 5 | use types; 6 | 7 | sub read ($str) { 8 | return read_str($str); 9 | } 10 | 11 | sub eval ($ast) { 12 | return $ast; 13 | } 14 | 15 | sub print ($exp) { 16 | return pr_str($exp, True); 17 | } 18 | 19 | sub rep ($str) { 20 | return print(eval(read($str))); 21 | } 22 | 23 | sub MAIN { 24 | while (my $line = prompt 'user> ').defined { 25 | say rep($line); 26 | CATCH { 27 | when X::MalException { .Str.say } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /impls/php/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec php $(dirname $0)/${STEP:-stepA_mal}.php "${@}" 3 | -------------------------------------------------------------------------------- /impls/php/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; PHP: skipping non-TCO recursion 2 | ;; Reason: completes at 10,000, unrecoverable segfault at 20,000 3 | -------------------------------------------------------------------------------- /impls/php/webrunner.php: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /impls/picolisp/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | -------------------------------------------------------------------------------- /impls/picolisp/env.l: -------------------------------------------------------------------------------- 1 | (class +Env) 2 | # data outer 3 | (dm T (Outer Binds Exprs) 4 | (=: data (new)) 5 | (=: outer Outer) 6 | (for (Binds Binds Binds) 7 | (if (<> (car Binds) '&) 8 | (set> This (pop 'Binds) (pop 'Exprs)) 9 | (pop 'Binds) 10 | (set> This (pop 'Binds) (MAL-list Exprs)) ) ) ) 11 | 12 | (de MAL-env (Outer Binds Exprs) 13 | (new '(+Env) Outer Binds Exprs) ) 14 | 15 | (dm set> (Key Value) 16 | (put (: data) Key Value) ) 17 | 18 | (dm get> (Key) 19 | (or (get (: data) Key) 20 | (and (: outer) (get> @ Key)) ) ) 21 | -------------------------------------------------------------------------------- /impls/picolisp/func.l: -------------------------------------------------------------------------------- 1 | (class +Func) 2 | # env ast params fn 3 | (dm T (Env Ast Params Fn) 4 | (=: type 'func) # HACK 5 | (=: env Env) 6 | (=: ast Ast) 7 | (=: params Params) 8 | (=: fn Fn) ) 9 | 10 | (de MAL-func (Env Ast Params Fn) 11 | (new '(+Func) Env Ast Params Fn) ) 12 | 13 | (de MAL-macro (MalFn) 14 | (let (env (get MalFn 'env) 15 | ast (get MalFn 'ast) 16 | params (get MalFn 'params) 17 | fn (get MalFn 'fn) 18 | clone (MAL-func env ast params fn)) 19 | (put clone 'is-macro T) 20 | clone)) 21 | -------------------------------------------------------------------------------- /impls/picolisp/readline.l: -------------------------------------------------------------------------------- 1 | (de load-history (File) 2 | (when (info File) 3 | (in File 4 | (until (eof) 5 | (native "libreadline.so" "add_history" NIL (line T)) ) ) ) ) 6 | 7 | (de save-to-history (Input) 8 | (when Input 9 | (native "libreadline.so" "add_history" NIL Input) 10 | (out "+.mal_history" 11 | (prinl Input) ) ) ) 12 | 13 | (de readline (Prompt) 14 | (let Input (native "libreadline.so" "readline" 'N Prompt) 15 | (if (=0 Input) 16 | 0 17 | (prog1 18 | (struct Input 'S) 19 | (save-to-history @) ) ) ) ) 20 | -------------------------------------------------------------------------------- /impls/picolisp/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec pil $(dirname $0)/${STEP:-stepA_mal}.l - "${@}" 3 | -------------------------------------------------------------------------------- /impls/picolisp/step0_repl.l: -------------------------------------------------------------------------------- 1 | (de load-relative (Path) 2 | (load (pack (car (file)) Path)) ) 3 | 4 | (load-relative "readline.l") 5 | 6 | (de READ (String) 7 | String) 8 | 9 | (de EVAL (Ast) 10 | Ast) 11 | 12 | (de PRINT (Ast) 13 | Ast) 14 | 15 | (de rep (String) 16 | (PRINT (EVAL (READ String))) ) 17 | 18 | (load-history ".mal_history") 19 | 20 | (use Eof 21 | (until Eof 22 | (let Input (readline "user> ") 23 | (if (=0 Input) 24 | (setq Eof T) 25 | (prinl (rep Input)) ) ) ) ) 26 | 27 | (prinl) 28 | (bye) 29 | -------------------------------------------------------------------------------- /impls/picolisp/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; PIL: skipping non-TCO recursion 2 | ;; Reason: segfault (unrecoverable) 3 | -------------------------------------------------------------------------------- /impls/picolisp/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic pil interop 2 | 3 | (pil-eval "T") 4 | ;=>true 5 | 6 | (pil-eval "NIL") 7 | ;=>nil 8 | 9 | (pil-eval "(+ 1 1)") 10 | ;=>2 11 | 12 | (pil-eval "(cons 1 2 3 NIL)") 13 | ;=>(1 2 3) 14 | 15 | (pil-eval "(use (@A @O) (match '(@A and @O) '(Alpha and Omega)) (prinl @A) (prinl @O))") 16 | Alpha 17 | Omega 18 | -------------------------------------------------------------------------------- /impls/pike/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = readline.pike types.pike reader.pike printer.pike 2 | SOURCES_LISP = env.pike core.pike stepA_mal.pike 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.pike mal 9 | 10 | mal.pike: $(SOURCES) 11 | cat $+ | grep -v "^#include" > $@ 12 | 13 | mal: mal.pike 14 | echo "#!/usr/bin/env pike" > $@ 15 | cat $< >> $@ 16 | chmod +x $@ 17 | 18 | clean: 19 | rm -f mal.pike mal 20 | -------------------------------------------------------------------------------- /impls/pike/Printer.pmod: -------------------------------------------------------------------------------- 1 | import .Types; 2 | 3 | string pr_str(Val ast, bool print_readably) 4 | { 5 | if(functionp(ast)) return "#"; 6 | return ast->to_string(print_readably); 7 | } 8 | -------------------------------------------------------------------------------- /impls/pike/Readline.pmod: -------------------------------------------------------------------------------- 1 | string readline(string prompt) { 2 | write(prompt); 3 | return Stdio.stdin->gets(); 4 | } 5 | -------------------------------------------------------------------------------- /impls/pike/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec pike $(dirname $0)/${STEP:-stepA_mal}.pike "${@}" 3 | -------------------------------------------------------------------------------- /impls/pike/step0_repl.pike: -------------------------------------------------------------------------------- 1 | import .Readline; 2 | 3 | string READ(string str) 4 | { 5 | return str; 6 | } 7 | 8 | string EVAL(string ast, string env) 9 | { 10 | return ast; 11 | } 12 | 13 | string PRINT(string exp) 14 | { 15 | return exp; 16 | } 17 | 18 | string rep(string str) 19 | { 20 | return PRINT(EVAL(READ(str), "")); 21 | } 22 | 23 | int main() 24 | { 25 | while(1) 26 | { 27 | string line = readline("user> "); 28 | if(!line) break; 29 | if(strlen(line) == 0) continue; 30 | write(({ rep(line), "\n" })); 31 | } 32 | write("\n"); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /impls/pike/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/plpgsql/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | -------------------------------------------------------------------------------- /impls/plpgsql/init.sql: -------------------------------------------------------------------------------- 1 | -- --------------------------------------------------------- 2 | -- init.sql 3 | 4 | -- Drop pre-existing schemas 5 | DROP SCHEMA IF EXISTS io, types, reader, printer, envs, core, mal CASCADE; 6 | 7 | -- Drop and recreate extensions 8 | DROP EXTENSION IF EXISTS hstore; 9 | CREATE EXTENSION hstore; 10 | 11 | DROP EXTENSION IF EXISTS dblink; 12 | CREATE EXTENSION dblink; 13 | 14 | -------------------------------------------------------------------------------- /impls/plpgsql/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/wrap.sh $(dirname $0)/${STEP:-stepA_mal}.sql "${@}" 3 | -------------------------------------------------------------------------------- /impls/plsql/Dockerfile-oracle: -------------------------------------------------------------------------------- 1 | FROM wnameless/oracle-xe-11g 2 | 3 | RUN apt-get -y update 4 | RUN apt-get -y install make cpp python 5 | 6 | RUN apt-get -y install rlwrap 7 | -------------------------------------------------------------------------------- /impls/plsql/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | 3 | clean: 4 | -------------------------------------------------------------------------------- /impls/plsql/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case ${1} in 4 | make*) 5 | echo "Skipping Oracle XE startup" 6 | ;; 7 | *) 8 | echo "Starting Oracle XE" 9 | sudo /usr/sbin/startup.sh 10 | ;; 11 | esac 12 | 13 | if [ "${*}" ]; then 14 | exec "${@}" 15 | else 16 | exec bash 17 | fi 18 | -------------------------------------------------------------------------------- /impls/plsql/login.sql: -------------------------------------------------------------------------------- 1 | -- PROMPT 'Start login.sql'; 2 | whenever sqlerror exit SQL.SQLCODE; 3 | whenever oserror exit 1; 4 | 5 | SET ECHO OFF; 6 | SET LINESIZE 32767; 7 | -- SET TRIMOUT ON; 8 | -- SET WRAP OFF; 9 | SET PAGESIZE 0; 10 | 11 | -- Do not format whitespace in terminaml output 12 | SET TAB OFF; 13 | 14 | -- Allow literal & in strings 15 | SET DEFINE OFF; 16 | 17 | -- Print DBMS_OUTPUT.PUT_LINE debugcommands 18 | SET SERVEROUTPUT ON SIZE 30000; 19 | 20 | -- Do not truncate or wrap CLOB output 21 | SET LONG 32767; 22 | SET LONGCHUNKSIZE 32767; 23 | 24 | -- PROMPT 'Finish login.sql'; 25 | 26 | -------------------------------------------------------------------------------- /impls/plsql/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/wrap.sh $(dirname $0)/${STEP:-stepA_mal}.sql "${@}" 3 | -------------------------------------------------------------------------------- /impls/powershell/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | true 3 | 4 | clean: 5 | -------------------------------------------------------------------------------- /impls/powershell/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec powershell $(dirname $0)/${STEP:-stepA_mal}.ps1 "${@}" 3 | -------------------------------------------------------------------------------- /impls/powershell/step0_repl.ps1: -------------------------------------------------------------------------------- 1 | while ($true) { 2 | Write-Host "user> " -NoNewline 3 | $line = [Console]::ReadLine() 4 | if ($line -eq $null) { 5 | break 6 | } 7 | "$line" 8 | } 9 | -------------------------------------------------------------------------------- /impls/prolog/Makefile: -------------------------------------------------------------------------------- 1 | # Stub Makefile to make Travis test mode happy. 2 | all clean: 3 | -------------------------------------------------------------------------------- /impls/prolog/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec swipl $(dirname $0)/${STEP:-stepA_mal}.pl "${@}" 3 | -------------------------------------------------------------------------------- /impls/ps/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = types.ps reader.ps printer.ps 2 | SOURCES_LISP = env.ps core.ps stepA_mal.ps 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.ps mal 9 | 10 | mal.ps: $(SOURCES) 11 | cat $+ | grep -v "runlibfile$$" > $@ 12 | 13 | mal: mal.ps 14 | echo "#!/bin/sh" > $@ 15 | echo "\":\" pop pop pop pop %#; exec gs -d'#!'=null -d'\":\"'=null -q -dNODISPLAY -- \"\$$0\" \"\$$@\"" >> $@ 16 | cat $< >> $@ 17 | chmod +x $@ 18 | 19 | clean: 20 | rm -f mal.ps mal 21 | -------------------------------------------------------------------------------- /impls/ps/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec gs -q -I$(dirname $0) -dNOSAFER -dNODISPLAY -- $(dirname $0)/${STEP:-stepA_mal}.ps "${@}" 3 | -------------------------------------------------------------------------------- /impls/ps/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/ps/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic ps interop 2 | 3 | (ps* "7") 4 | ;=>(7) 5 | 6 | (ps* "(7)") 7 | ;=>("7") 8 | 9 | (ps* "7 8 9 3 array astore") 10 | ;=>((7 8 9)) 11 | 12 | (ps* "1 1 eq") 13 | ;=>(true) 14 | 15 | (ps* "/sym") 16 | ;=>(sym) 17 | 18 | (ps* "1 1 eq { (yep) }{ (nope) } ifelse") 19 | ;=>("yep") 20 | 21 | (ps* "1 0 eq { (yep) }{ (nope) } ifelse") 22 | ;=>("nope") 23 | 24 | (ps* "1 2 3 pop pop pop") 25 | ;=>nil 26 | -------------------------------------------------------------------------------- /impls/purs/.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/ 5 | /generated-docs/ 6 | /.psc-package/ 7 | /.psc* 8 | /.purs* 9 | /.psa* 10 | /.spago 11 | 12 | /step*.js 13 | -------------------------------------------------------------------------------- /impls/purs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "readline-sync": "^1.4.10" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /impls/purs/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" -------------------------------------------------------------------------------- /impls/purs/src/Readline.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var readlineSync = require('readline-sync') 4 | 5 | exports.readLine = function (x) { 6 | return function () { 7 | const result = readlineSync.question(x); 8 | 9 | if(readlineSync.getRawInput() === String.fromCharCode(0)){ 10 | return ":q" 11 | } 12 | return result; 13 | } 14 | } 15 | 16 | 17 | exports.argv = process.argv; -------------------------------------------------------------------------------- /impls/purs/src/Readline.purs: -------------------------------------------------------------------------------- 1 | module Readline where 2 | 3 | import Prelude 4 | 5 | import Data.List (List, drop, fromFoldable) 6 | import Effect (Effect) 7 | 8 | 9 | 10 | foreign import readLine :: String -> Effect String 11 | 12 | 13 | foreign import argv :: Array String 14 | 15 | args :: List String 16 | args = drop 2 $ fromFoldable argv -------------------------------------------------------------------------------- /impls/python2/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = mal_readline.py mal_types.py reader.py printer.py 2 | SOURCES_LISP = env.py core.py stepA_mal.py 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.pyz mal 9 | 10 | SHELL := bash 11 | mal.pyz: $(SOURCES) 12 | cp stepA_mal.py __main__.py 13 | zip -q - __main__.py $+ > $@ 14 | rm __main__.py 15 | 16 | mal: mal.pyz 17 | echo '#!/usr/bin/env python' > $@ 18 | cat $< >> $@ 19 | chmod +x $@ 20 | 21 | clean: 22 | rm -f mal.pyz mal 23 | -------------------------------------------------------------------------------- /impls/python2/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec python2 $(dirname $0)/${STEP:-stepA_mal}.py "${@}" 3 | -------------------------------------------------------------------------------- /impls/python2/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/python2/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing Python interop 2 | 3 | ;; Testing Python expressions 4 | (py* "7") 5 | ;=>7 6 | (py* "'7'") 7 | ;=>"7" 8 | (py* "[7,8,9]") 9 | ;=>(7 8 9) 10 | (py* "' '.join(['X'+c+'Y' for c in ['a','b','c']])") 11 | ;=>"XaY XbY XcY" 12 | (py* "[1 + x for x in [1,2,3]]") 13 | ;=>(2 3 4) 14 | 15 | ;; Testing Python statements 16 | (py!* "print('hello')") 17 | ;/hello 18 | ;=>nil 19 | 20 | (py!* "foo = 19 % 4") 21 | ;=>nil 22 | (py* "foo") 23 | ;=>3 24 | -------------------------------------------------------------------------------- /impls/python3/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .mypy_cache/ 3 | .idea/ 4 | -------------------------------------------------------------------------------- /impls/python3/mal_readline.py: -------------------------------------------------------------------------------- 1 | # Importing this module is sufficient for the 'input' builtin command 2 | # to support readline. 3 | 4 | import atexit 5 | import os.path 6 | import readline 7 | 8 | histfile = os.path.join(os.path.expanduser('~'), '.mal-history') 9 | try: 10 | readline.read_history_file(histfile) 11 | except FileNotFoundError: 12 | pass 13 | readline.set_history_length(1000) 14 | atexit.register(readline.write_history_file, histfile) 15 | 16 | 17 | def input_(prompt: str) -> str: 18 | line = input(prompt) 19 | if line: 20 | readline.add_history(line) 21 | return line 22 | -------------------------------------------------------------------------------- /impls/python3/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec python3 $(dirname $0)/${STEP:-stepA_mal}.py "${@}" 3 | -------------------------------------------------------------------------------- /impls/python3/step0_repl.py: -------------------------------------------------------------------------------- 1 | import mal_readline 2 | 3 | 4 | def read(source: str) -> str: 5 | return source 6 | 7 | 8 | def eval_(ast: str) -> str: 9 | return ast 10 | 11 | 12 | def print_(form: str) -> str: 13 | return form 14 | 15 | 16 | def rep(source: str) -> str: 17 | return print_(eval_(read(source))) 18 | 19 | 20 | def main() -> None: 21 | while True: 22 | try: 23 | print(rep(mal_readline.input_('user> '))) 24 | except EOFError: 25 | break 26 | 27 | 28 | if __name__ == '__main__': 29 | main() 30 | -------------------------------------------------------------------------------- /impls/python3/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/impls/python3/tests/__init__.py -------------------------------------------------------------------------------- /impls/python3/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/python3/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | *host-language* 2 | ;=>"python3" 3 | 4 | ;; Testing Python interop 5 | 6 | ;; Testing Python expressions 7 | 8 | (py* "7") 9 | ;=>7 10 | 11 | (py* "'7'") 12 | ;=>"7" 13 | 14 | (py* "[7,8,9]") 15 | ;=>(7 8 9) 16 | 17 | (py* "' '.join(f'X{c}Y' for c in 'abc')") 18 | ;=>"XaY XbY XcY" 19 | 20 | (py* "list(1 + x for x in range(1, 4))") 21 | ;=>(2 3 4) 22 | 23 | ;; Testing Python statements 24 | 25 | (py!* "print('hello')") 26 | ;/hello 27 | ;=>nil 28 | 29 | (py!* "foo = 19 % 4") 30 | ;=>nil 31 | (py* "foo") 32 | ;=>3 33 | -------------------------------------------------------------------------------- /impls/python3/tests/test_step2.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import step2_eval 4 | 5 | 6 | class TestStep3(unittest.TestCase): 7 | def test_step3_let_multiple(self): 8 | self.assertEqual('{"a" 15}', step2_eval.rep('{"a" (+ 7 8)} ')) 9 | 10 | 11 | if __name__ == "__main__": 12 | unittest.main() 13 | -------------------------------------------------------------------------------- /impls/r/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec Rscript $(dirname $0)/${STEP:-stepA_mal}.r "${@}" 3 | -------------------------------------------------------------------------------- /impls/r/step0_repl.r: -------------------------------------------------------------------------------- 1 | source("readline.r") 2 | 3 | READ <- function(str) { 4 | return(str) 5 | } 6 | 7 | EVAL <- function(ast, env) { 8 | return(ast) 9 | } 10 | 11 | PRINT <- function(exp) { 12 | return(exp) 13 | } 14 | 15 | rep <- function(str) { 16 | return(PRINT(EVAL(READ(str), ""))) 17 | } 18 | 19 | repeat { 20 | line <- readline("user> ") 21 | if (is.null(line)) { cat("\n"); break } 22 | tryCatch({ 23 | cat(rep(line),"\n", sep="") 24 | }, error=function(err) { 25 | cat("Error: ", err$message,"\n", sep="") 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /impls/r/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/racket/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = types.rkt reader.rkt printer.rkt 2 | SOURCES_LISP = env.rkt core.rkt stepA_mal.rkt 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | 7 | dist: mal 8 | 9 | mal: $(SOURCES) 10 | raco exe stepA_mal.rkt 11 | mv stepA_mal $@ 12 | 13 | clean: 14 | rm -f mal 15 | -------------------------------------------------------------------------------- /impls/racket/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec racket $(dirname $0)/${STEP:-stepA_mal}.rkt "${@}" 3 | -------------------------------------------------------------------------------- /impls/racket/step0_repl.rkt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env racket 2 | #lang racket 3 | 4 | (require "readline.rkt" "types.rkt") 5 | 6 | ;; read 7 | (define (READ str) 8 | str) 9 | 10 | ;; eval 11 | (define (EVAL ast env) 12 | ast) 13 | 14 | ;; print 15 | (define (PRINT exp) 16 | exp) 17 | 18 | ;; repl 19 | (define (rep str) 20 | (PRINT (EVAL (READ str) ""))) 21 | 22 | (define (repl-loop) 23 | (let ([line (readline "user> ")]) 24 | (when (not (eq? nil line)) 25 | (printf "~a~n" (rep line)) 26 | (repl-loop)))) 27 | (repl-loop) 28 | -------------------------------------------------------------------------------- /impls/racket/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Racket: skipping non-TCO recursion 2 | ;; Reason: completes up to 1,000,000 3 | -------------------------------------------------------------------------------- /impls/rexx/.gitignore: -------------------------------------------------------------------------------- 1 | *.rexxpp 2 | -------------------------------------------------------------------------------- /impls/rexx/readline.rexx: -------------------------------------------------------------------------------- 1 | #ifndef __readline__ 2 | #define __readline__ 3 | 4 | readline: procedure /* readline(prompt) */ 5 | call charout , arg(1) 6 | return linein() 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /impls/rexx/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec rexx -a $(dirname $0)/${STEP:-stepA_mal}.rexxpp "${@}" 3 | -------------------------------------------------------------------------------- /impls/rexx/step0_repl.rexx: -------------------------------------------------------------------------------- 1 | call main 2 | exit 3 | 4 | #include "readline.rexx" 5 | 6 | read: procedure /* read(str) */ 7 | return arg(1) 8 | 9 | eval: procedure /* eval(exp, env) */ 10 | return arg(1) 11 | 12 | print: procedure /* print(exp) */ 13 | return arg(1) 14 | 15 | rep: procedure /* rep(str) */ 16 | return print(eval(read(arg(1), ""))) 17 | 18 | main: 19 | do while lines() > 0 /* 1 == 1 */ 20 | input_line = readline('user> ') 21 | if length(input_line) > 0 then 22 | call lineout , rep(input_line) 23 | end 24 | -------------------------------------------------------------------------------- /impls/rexx/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; REXX: skipping non-TCO recursion 2 | ;; Reason: regina rexx interpreter segfaults (unrecoverable) 3 | -------------------------------------------------------------------------------- /impls/rexx/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic Rexx interop 2 | ;; 3 | ;; Note that in Rexx "everything is a string". Numeric outputs are converted to 4 | ;; Mal numbers. 5 | 6 | (rexx-eval "3 ** 4") 7 | ;=>81 8 | 9 | (rexx-eval "words('a bb ' || 'ccc dddd')") 10 | ;=>4 11 | 12 | (rexx-eval "d2x(254)") 13 | ;=>"FE" 14 | 15 | (rexx-eval "say 'hello' 12.34 upper('rexx')" nil) 16 | ;/hello 12.34 REXX 17 | ;=>nil 18 | 19 | (rexx-eval "foo = 8" "foo + 3") 20 | ;=>11 21 | 22 | (rexx-eval "parse version s1 s2 s3 s4 s5" "'rexx_version=' || s2") 23 | ;=>"rexx_version=5.00" 24 | -------------------------------------------------------------------------------- /impls/rpython/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/rpython/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/ruby.2/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = errors.rb types.rb reader.rb printer.rb 2 | SOURCES_LISP = env.rb core.rb stepA_mal.rb 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.rb mal 9 | 10 | mal.rb: $(SOURCES) 11 | cat $+ | grep -v "^require_relative" > $@ 12 | 13 | mal: mal.rb 14 | echo "#!/usr/bin/env ruby" > $@ 15 | cat $< >> $@ 16 | chmod +x $@ 17 | 18 | clean: 19 | rm -f mal.rb mal 20 | -------------------------------------------------------------------------------- /impls/ruby.2/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec ruby $(dirname $0)/${STEP:-stepA_mal}.rb "${@}" 3 | -------------------------------------------------------------------------------- /impls/ruby.2/step0_repl.rb: -------------------------------------------------------------------------------- 1 | require "readline" 2 | 3 | module Mal 4 | extend self 5 | 6 | def READ(input) 7 | input 8 | end 9 | 10 | def EVAL(input) 11 | input 12 | end 13 | 14 | def PRINT(input) 15 | input 16 | end 17 | 18 | def rep(input) 19 | PRINT(EVAL(READ(input))) 20 | end 21 | end 22 | 23 | while input = Readline.readline("user> ") 24 | puts Mal.rep(input) 25 | end 26 | -------------------------------------------------------------------------------- /impls/ruby/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = mal_readline.rb types.rb reader.rb printer.rb 2 | SOURCES_LISP = env.rb core.rb stepA_mal.rb 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.rb mal 9 | 10 | mal.rb: $(SOURCES) 11 | cat $+ | grep -v "^require_relative" > $@ 12 | 13 | mal: mal.rb 14 | echo "#!/usr/bin/env ruby" > $@ 15 | cat $< >> $@ 16 | chmod +x $@ 17 | 18 | clean: 19 | rm -f mal.rb mal 20 | -------------------------------------------------------------------------------- /impls/ruby/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec ruby $(dirname $0)/${STEP:-stepA_mal}.rb "${@}" 3 | -------------------------------------------------------------------------------- /impls/ruby/step0_repl.rb: -------------------------------------------------------------------------------- 1 | require_relative "mal_readline" 2 | 3 | # read 4 | def READ(str) 5 | return str 6 | end 7 | 8 | # eval 9 | def EVAL(ast, env) 10 | return ast 11 | end 12 | 13 | # print 14 | def PRINT(exp) 15 | return exp 16 | end 17 | 18 | # repl 19 | def REP(str) 20 | return PRINT(EVAL(READ(str), {})) 21 | end 22 | 23 | # repl loop 24 | while line = _readline("user> ") 25 | puts REP(line) 26 | end 27 | -------------------------------------------------------------------------------- /impls/ruby/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/ruby/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic ruby interop 2 | 3 | (rb* "7") 4 | ;=>7 5 | 6 | (rb* "'7'") 7 | ;=>"7" 8 | 9 | (rb* "[7,8,9]") 10 | ;=>(7 8 9) 11 | 12 | (rb* "{\"abc\" => 789}") 13 | ;=>{"abc" 789} 14 | 15 | (rb* "print 'hello\n'") 16 | ;/hello 17 | ;=>nil 18 | 19 | (rb* "$foo=8;") 20 | (rb* "$foo") 21 | ;=>8 22 | 23 | (rb* "['a','b','c'].map{|x| 'X'+x+'Y'}.join(' ')") 24 | ;=>"XaY XbY XcY" 25 | 26 | (rb* "[1,2,3].map{|x| 1+x}") 27 | ;=>(2 3 4) 28 | -------------------------------------------------------------------------------- /impls/rust/.gitignore: -------------------------------------------------------------------------------- 1 | ./target 2 | -------------------------------------------------------------------------------- /impls/rust/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/target/release/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/scala/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = types.scala reader.scala printer.scala 2 | SOURCES_LISP = env.scala core.scala stepA_mal.scala 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | TARGET_DIR=target/scala-2.11 6 | 7 | all: $(TARGET_DIR)/mal.jar 8 | 9 | dist: mal 10 | 11 | mal: $(TARGET_DIR)/mal.jar 12 | cp $< $@ 13 | 14 | $(TARGET_DIR)/mal.jar: 15 | sbt assembly 16 | 17 | $(TARGET_DIR)/classes/step%.class: step%.scala $(SOURCES) 18 | sbt assembly 19 | 20 | clean: 21 | rm -rf mal target 22 | 23 | .PHONY: all dist clean 24 | -------------------------------------------------------------------------------- /impls/scala/assembly.sbt: -------------------------------------------------------------------------------- 1 | import sbtassembly.AssemblyPlugin.defaultShellScript 2 | 3 | test in assembly := {} 4 | assemblyJarName in assembly := "mal.jar" 5 | mainClass in assembly := Some("stepA_mal") 6 | assemblyOption in assembly ~= { _.copy(prependShellScript = Some(defaultShellScript)) } 7 | -------------------------------------------------------------------------------- /impls/scala/build.sbt: -------------------------------------------------------------------------------- 1 | lazy val root = (project in file(".")). 2 | settings( 3 | name := "mal", 4 | version := "0.1", 5 | scalaVersion := "2.11.4" 6 | ) 7 | -------------------------------------------------------------------------------- /impls/scala/project/assembly.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") 2 | -------------------------------------------------------------------------------- /impls/scala/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec java -classpath "$(dirname $0)/target/scala-2.11/mal.jar" "${STEP:-stepA_mal}" "$@" 3 | -------------------------------------------------------------------------------- /impls/scala/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/scheme/.gitignore: -------------------------------------------------------------------------------- 1 | lib/*.scm 2 | lib/*.so 3 | lib/*.c 4 | lib/*.o 5 | lib/*.meta 6 | lib.*.scm 7 | *.so 8 | *.c 9 | *.o 10 | out/ 11 | eggs/* -------------------------------------------------------------------------------- /impls/scheme/tests/stepA_mal.mal: -------------------------------------------------------------------------------- 1 | ;; Testing basic Scheme interop 2 | 3 | (scm-eval "(+ 1 1)") 4 | ;=>2 5 | 6 | (scm-eval "(begin (display \"Hello World!\") (newline) 7)") 7 | ;/Hello World! 8 | ;=>7 9 | 10 | (scm-eval "(string->list \"MAL\")") 11 | ;=>("M" "A" "L") 12 | 13 | (scm-eval "(map + '(1 2 3) '(4 5 6))") 14 | ;=>(5 7 9) 15 | 16 | (scm-eval "(string-map (lambda (c) (integer->char (+ 65 (modulo (+ (- (char->integer c) 65) 13) 26)))) \"ZNY\")") 17 | ;=>"MAL" 18 | -------------------------------------------------------------------------------- /impls/skew/printer.sk: -------------------------------------------------------------------------------- 1 | def pr_str(obj MalVal, readable bool) string { 2 | return obj.print(readable) 3 | } 4 | -------------------------------------------------------------------------------- /impls/skew/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" 3 | -------------------------------------------------------------------------------- /impls/skew/step0_repl.sk: -------------------------------------------------------------------------------- 1 | def READ(str string) string { 2 | return str 3 | } 4 | 5 | def EVAL(ast string, env StringMap) string { 6 | return ast 7 | } 8 | 9 | def PRINT(exp string) string { 10 | return exp 11 | } 12 | 13 | def REP(str string) string { 14 | return PRINT(EVAL(READ(str), {})) 15 | } 16 | 17 | @entry 18 | def main { 19 | var line string 20 | while (line = readLine("user> ")) != null { 21 | if line == "" { continue } 22 | printLn(REP(line)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /impls/skew/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/sml/.gitignore: -------------------------------------------------------------------------------- 1 | .smlmode 2 | .step* 3 | *.ui 4 | *.uo 5 | -------------------------------------------------------------------------------- /impls/sml/LargeInt.sml: -------------------------------------------------------------------------------- 1 | (* Moscow ML does not have the LargeInt structure, 2 | * but its Int is 64 bit on 64 bit systems. 3 | * We need 64 bit integers for the `time-ms` core function. 4 | *) 5 | 6 | structure LargeInt = Int 7 | -------------------------------------------------------------------------------- /impls/sml/env.sml: -------------------------------------------------------------------------------- 1 | fun set s v (NS d) = d := (s, v) :: (!d |> List.filter (not o eq s o #1)) 2 | 3 | fun get (NS d) s = !d |> List.find (eq s o #1) |> Option.map #2 4 | 5 | fun def s v (ENV ns) = set s v ns 6 | | def s v (INNER (ns, _)) = set s v ns 7 | 8 | fun lookup (ENV ns) s = get ns s 9 | | lookup (INNER (ns, outer)) s = optOrElse (get ns s) (fn () => lookup outer s) 10 | 11 | fun inside outer = INNER (NS (ref []), outer) 12 | -------------------------------------------------------------------------------- /impls/sml/main.sml: -------------------------------------------------------------------------------- 1 | val _ = main () 2 | -------------------------------------------------------------------------------- /impls/sml/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/sml/step0_repl.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | step0_repl.sml 4 | in 5 | main.sml 6 | end 7 | -------------------------------------------------------------------------------- /impls/sml/step0_repl.sml: -------------------------------------------------------------------------------- 1 | fun read s: string = 2 | s 3 | 4 | fun eval s: string = 5 | s 6 | 7 | fun print s: string = 8 | s 9 | 10 | fun rep s: string = 11 | (print o eval o read) s 12 | 13 | fun repl () = 14 | let open TextIO 15 | in ( 16 | print("user> "); 17 | case inputLine(stdIn) of 18 | SOME(line) => ( 19 | print(rep(line) ^ "\n"); 20 | repl () 21 | ) 22 | | NONE => () 23 | ) end 24 | 25 | fun main () = repl () 26 | -------------------------------------------------------------------------------- /impls/sml/step1_read_print.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | step1_read_print.sml 8 | in 9 | main.sml 10 | end 11 | -------------------------------------------------------------------------------- /impls/sml/step2_eval.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | step2_eval.sml 9 | in 10 | main.sml 11 | end 12 | -------------------------------------------------------------------------------- /impls/sml/step3_env.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | step3_env.sml 9 | in 10 | main.sml 11 | end 12 | -------------------------------------------------------------------------------- /impls/sml/step4_if_fn_do.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | core.sml 9 | step4_if_fn_do.sml 10 | in 11 | main.sml 12 | end 13 | -------------------------------------------------------------------------------- /impls/sml/step6_file.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | core.sml 9 | step6_file.sml 10 | in 11 | main.sml 12 | end 13 | -------------------------------------------------------------------------------- /impls/sml/step7_quote.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | core.sml 9 | step7_quote.sml 10 | in 11 | main.sml 12 | end 13 | -------------------------------------------------------------------------------- /impls/sml/step8_macros.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | core.sml 9 | step8_macros.sml 10 | in 11 | main.sml 12 | end 13 | -------------------------------------------------------------------------------- /impls/sml/step9_try.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | core.sml 9 | step9_try.sml 10 | in 11 | main.sml 12 | end 13 | -------------------------------------------------------------------------------- /impls/sml/stepA_mal.mlb: -------------------------------------------------------------------------------- 1 | local 2 | $(SML_LIB)/basis/basis.mlb 3 | util.sml 4 | types.sml 5 | printer.sml 6 | reader.sml 7 | env.sml 8 | core.sml 9 | stepA_mal.sml 10 | in 11 | main.sml 12 | end 13 | -------------------------------------------------------------------------------- /impls/swift3/Sources/step0_repl/main.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | while true { 4 | print("user> ", terminator: "") 5 | let line = readLine(strippingNewline: true) 6 | if line == nil { break } 7 | if line == "" { continue } 8 | 9 | print("\(line!)") 10 | } 11 | -------------------------------------------------------------------------------- /impls/swift3/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/swift3/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Swift 3: skipping non-TCO recursion 2 | ;; Reason: unrecoverable segfault at 10,000 3 | -------------------------------------------------------------------------------- /impls/swift4/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/swift6/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /out 4 | /Packages 5 | /*.xcodeproj 6 | xcuserdata/ 7 | .swiftpm 8 | -------------------------------------------------------------------------------- /impls/swift6/Makefile: -------------------------------------------------------------------------------- 1 | step%: 2 | swift build --product $@ 3 | [ -L .build/$@ ] || ln -s "$(shell swift build --show-bin-path)/$@" .build/$@ 4 | clean: 5 | rm -fr .build/ 6 | -------------------------------------------------------------------------------- /impls/swift6/Sources/core/Utils.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public func curry(_ function: @escaping (A, B) -> C) -> (A) -> (B) -> C { 4 | return { (a: A) -> (B) -> C in { (b: B) -> C in function(a, b) } } 5 | } 6 | 7 | public extension Collection { 8 | subscript (safe index: Index) -> Element? { 9 | return indices.contains(index) ? self[index] : nil 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /impls/swift6/Sources/step0_repl/main.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func READ(_ s: String) -> String { 4 | return s 5 | } 6 | 7 | func EVAL(_ s: String) -> String { 8 | return s 9 | } 10 | 11 | func PRINT(_ s: String) -> String { 12 | return s 13 | } 14 | 15 | func rep(_ s: String) -> String { 16 | return PRINT(EVAL(READ(s))) 17 | } 18 | 19 | while true { 20 | print("user> ", terminator: "") 21 | guard let s = readLine() else { break } 22 | print(rep(s)) 23 | } 24 | -------------------------------------------------------------------------------- /impls/swift6/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec $(dirname $0)/.build/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/tcl/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = mal_readline.tcl types.tcl reader.tcl printer.tcl 2 | SOURCES_LISP = env.tcl core.tcl stepA_mal.tcl 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | all: 6 | true 7 | 8 | dist: mal.tcl mal 9 | 10 | mal.tcl: $(SOURCES) 11 | cat $+ | grep -v "^source " > $@ 12 | 13 | mal: mal.tcl 14 | echo "#!/usr/bin/env tclsh" > $@ 15 | cat $< >> $@ 16 | chmod +x $@ 17 | 18 | clean: 19 | rm -f mal.tcl mal 20 | -------------------------------------------------------------------------------- /impls/tcl/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec tclsh $(dirname $0)/${STEP:-stepA_mal}.tcl ${RAW:+--raw} "${@}" 3 | -------------------------------------------------------------------------------- /impls/tcl/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/tests/computations.mal: -------------------------------------------------------------------------------- 1 | ;; Some inefficient arithmetic computations for benchmarking. 2 | 3 | ;; Unfortunately not yet available in tests of steps 4 and 5. 4 | 5 | ;; Compute n(n+1)/2 with a non tail-recursive call. 6 | (def! sumdown 7 | (fn* [n] ; non-negative number 8 | (if (= n 0) 9 | 0 10 | (+ n (sumdown (- n 1)))))) 11 | 12 | ;; Compute a Fibonacci number with two recursions. 13 | (def! fib 14 | (fn* [n] ; non-negative number 15 | (if (<= n 1) 16 | n 17 | (+ (fib (- n 1)) (fib (- n 2)))))) 18 | -------------------------------------------------------------------------------- /impls/tests/docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IMAGE_NAME=${IMAGE_NAME:-mal-test-ubuntu-utopic} 4 | GIT_TOP=$(git rev-parse --show-toplevel) 5 | 6 | docker build -t "${IMAGE_NAME}" "${GIT_TOP}/tests/docker" 7 | -------------------------------------------------------------------------------- /impls/tests/docker-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | IMAGE_NAME=${IMAGE_NAME:-mal-test-ubuntu-utopic} 4 | GIT_TOP=$(git rev-parse --show-toplevel) 5 | 6 | docker run -it --rm -u ${EUID} \ 7 | --volume=${GIT_TOP}:/mal \ 8 | ${IMAGE_NAME} \ 9 | "${@}" 10 | -------------------------------------------------------------------------------- /impls/tests/fib.mal: -------------------------------------------------------------------------------- 1 | (load-file "../lib/benchmark.mal") 2 | 3 | (def! fib (fn* [n] 4 | (if (= n 0) 5 | 1 6 | (if (= n 1) 7 | 1 8 | (+ (fib (- n 1)) 9 | (fib (- n 2))))))) 10 | 11 | (let* [n (read-string (first *ARGV*)) 12 | iters (read-string (first (rest *ARGV*)))] 13 | (println (str "Times (in ms) for (fib " n ") on " *host-language* ": ") 14 | (benchmark (fib n) iters))) 15 | -------------------------------------------------------------------------------- /impls/tests/inc.mal: -------------------------------------------------------------------------------- 1 | (def! inc1 (fn* (a) (+ 1 a))) 2 | (def! inc2 (fn* (a) (+ 2 a))) 3 | (def! inc3 (fn* (a) 4 | (+ 3 a))) 5 | -------------------------------------------------------------------------------- /impls/tests/incA.mal: -------------------------------------------------------------------------------- 1 | (def! inc4 (fn* (a) (+ 4 a))) 2 | 3 | (prn (inc4 5)) 4 | -------------------------------------------------------------------------------- /impls/tests/incB.mal: -------------------------------------------------------------------------------- 1 | ;; A comment in a file 2 | (def! inc4 (fn* (a) (+ 4 a))) 3 | (def! inc5 (fn* (a) ;; a comment after code 4 | (+ 5 a))) 5 | 6 | ;; ending comment without final new line -------------------------------------------------------------------------------- /impls/tests/incC.mal: -------------------------------------------------------------------------------- 1 | (def! mymap {"a" 2 | 1}) 3 | -------------------------------------------------------------------------------- /impls/tests/lib/load-file-once-inc.mal: -------------------------------------------------------------------------------- 1 | (swap! counter (fn* [x] (+ 1 x))) 2 | -------------------------------------------------------------------------------- /impls/tests/lib/memoize.mal: -------------------------------------------------------------------------------- 1 | (load-file "../lib/load-file-once.mal") 2 | (load-file-once "../tests/computations.mal") 3 | (load-file-once "../lib/memoize.mal") 4 | ;=>nil 5 | 6 | (def! N 32) 7 | 8 | ;; Benchmark naive 'fib' 9 | 10 | (def! r1 (fib N)) ; Should be slow 11 | 12 | ;; Benchmark memoized 'fib' 13 | 14 | (def! fib (memoize fib)) 15 | (def! r2 (fib N)) ; Should be quick 16 | 17 | (= r1 r2) 18 | ;=>true 19 | -------------------------------------------------------------------------------- /impls/tests/lib/threading.mal: -------------------------------------------------------------------------------- 1 | (load-file "../lib/load-file-once.mal") 2 | (load-file-once "../lib/threading.mal") 3 | ;=>nil 4 | 5 | ;; Testing -> macro 6 | (-> 7) 7 | ;=>7 8 | (-> (list 7 8 9) first) 9 | ;=>7 10 | (-> (list 7 8 9) (first)) 11 | ;=>7 12 | (-> (list 7 8 9) first (+ 7)) 13 | ;=>14 14 | (-> (list 7 8 9) rest (rest) first (+ 7)) 15 | ;=>16 16 | 17 | ;; Testing ->> macro 18 | (->> "L") 19 | ;=>"L" 20 | (->> "L" (str "A") (str "M")) 21 | ;=>"MAL" 22 | (->> [4] (concat [3]) (concat [2]) rest (concat [1])) 23 | ;=>(1 3 4) 24 | -------------------------------------------------------------------------------- /impls/tests/lib/trivial.mal: -------------------------------------------------------------------------------- 1 | (load-file "../lib/load-file-once.mal") 2 | (load-file-once "../lib/trivial.mal") 3 | ;=>nil 4 | 5 | (inc 12) 6 | ;=>13 7 | (dec 12) 8 | ;=>11 9 | (zero? 12) 10 | ;=>false 11 | (zero? 0) 12 | ;=>true 13 | (identity 12) 14 | ;=>12 15 | (= (gensym) (gensym)) 16 | ;=>false 17 | -------------------------------------------------------------------------------- /impls/tests/perf1.mal: -------------------------------------------------------------------------------- 1 | (load-file "../lib/load-file-once.mal") 2 | (load-file-once "../lib/threading.mal") ; -> 3 | (load-file-once "../lib/perf.mal") ; time 4 | (load-file-once "../lib/test_cascade.mal") ; or 5 | 6 | ;;(prn "Start: basic macros performance test") 7 | 8 | (time (do 9 | (or false nil false nil false nil false nil false nil 4) 10 | (cond false 1 nil 2 false 3 nil 4 false 5 nil 6 "else" 7) 11 | (-> (list 1 2 3 4 5 6 7 8 9) rest rest rest rest rest rest first))) 12 | 13 | ;;(prn "Done: basic macros performance test") 14 | -------------------------------------------------------------------------------- /impls/tests/perf2.mal: -------------------------------------------------------------------------------- 1 | (load-file "../lib/load-file-once.mal") 2 | (load-file-once "../tests/computations.mal") ; fib sumdown 3 | (load-file-once "../lib/perf.mal") ; time 4 | 5 | ;;(prn "Start: basic math/recursion test") 6 | 7 | (time (do 8 | (sumdown 10) 9 | (fib 12))) 10 | 11 | ;;(prn "Done: basic math/recursion test") 12 | -------------------------------------------------------------------------------- /impls/tests/print_argv.mal: -------------------------------------------------------------------------------- 1 | ; Used by the run_argv_test.sh test harness 2 | (prn *ARGV*) 3 | -------------------------------------------------------------------------------- /impls/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Testing recursive tail-call function 2 | 3 | (def! sum2 (fn* (n acc) (if (= n 0) acc (sum2 (- n 1) (+ n acc))))) 4 | 5 | ;; TODO: test let*, and do for TCO 6 | 7 | (sum2 10 0) 8 | ;=>55 9 | 10 | (def! res2 nil) 11 | ;=>nil 12 | (def! res2 (sum2 10000 0)) 13 | res2 14 | ;=>50005000 15 | 16 | 17 | ;; Test mutually recursive tail-call functions 18 | 19 | (def! foo (fn* (n) (if (= n 0) 0 (bar (- n 1))))) 20 | (def! bar (fn* (n) (if (= n 0) 0 (foo (- n 1))))) 21 | 22 | (foo 10000) 23 | ;=>0 24 | -------------------------------------------------------------------------------- /impls/tests/test.txt: -------------------------------------------------------------------------------- 1 | A line of text 2 | -------------------------------------------------------------------------------- /impls/ts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | npm-debug.log 4 | 5 | *.js 6 | -------------------------------------------------------------------------------- /impls/ts/Makefile: -------------------------------------------------------------------------------- 1 | STEPS = step0_repl step1_read_print step2_eval step3_env \ 2 | step4_if_fn_do step5_tco step6_file step7_quote \ 3 | step8_macros step9_try stepA_mal 4 | 5 | all: ts 6 | 7 | node_modules: 8 | npm install 9 | 10 | step%.js: node_modules types.ts reader.ts printer.ts env.ts core.ts step%.ts 11 | ./node_modules/.bin/tsc -p ./ 12 | 13 | 14 | .PHONY: ts clean 15 | 16 | ts: $(foreach s,$(STEPS),$(s).js) 17 | 18 | clean: 19 | rm -f *.js 20 | -------------------------------------------------------------------------------- /impls/ts/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec node $(dirname $0)/${STEP:-stepA_mal}.js "${@}" 3 | -------------------------------------------------------------------------------- /impls/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "lib": [ 6 | "es2015" 7 | ], 8 | "noImplicitAny": true, 9 | "noEmitOnError": true, 10 | "noImplicitReturns": true, 11 | "noImplicitThis": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "newLine": "LF", 15 | "strictNullChecks": true, 16 | "sourceMap": false 17 | }, 18 | "exclude": [ 19 | "node_modules" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /impls/vala/.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.h 3 | *.o 4 | -------------------------------------------------------------------------------- /impls/vala/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/vb/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec mono $(dirname $0)/${STEP:-stepA_mal}.exe ${RAW:+--raw} "${@}" 3 | -------------------------------------------------------------------------------- /impls/vb/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; VB: skipping non-TCO recursion 2 | ;; Reason: unrecoverable segfault at 10,000 3 | -------------------------------------------------------------------------------- /impls/vbs/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | true 3 | 4 | clean: 5 | -------------------------------------------------------------------------------- /impls/vbs/install.vbs: -------------------------------------------------------------------------------- 1 | On Error Resume Next 2 | CreateObject("System.Collections.ArrayList") -------------------------------------------------------------------------------- /impls/vbs/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | MAL_VBS_IMPL_NO_STDERR=1 MAL_VBS_IMPL_ECHO_STDIN=1 \ 3 | WSLENV=MAL_VBS_IMPL_NO_STDERR/w:MAL_VBS_IMPL_ECHO_STDIN/w \ 4 | cscript.exe -nologo "`wslpath -w "$(dirname $0)/${STEP:-stepA_mal}.vbs"`" "${@}" -------------------------------------------------------------------------------- /impls/vbs/tests/step4_if_fn_do.mal: -------------------------------------------------------------------------------- 1 | ((fn* [x] [x]) (list 1 2 3)) 2 | ;=>[(1 2 3)] 3 | 4 | ((fn* [x] [x]) [1 2 3]) 5 | ;=>[[1 2 3]] 6 | 7 | ((fn* [x] (list x)) (list 1 2 3)) 8 | ;=>((1 2 3)) 9 | 10 | ((fn* [x] (list x)) [1 2 3]) 11 | ;=>([1 2 3]) 12 | 13 | ((fn* [x] x) (list 1 2 3)) 14 | ;=>(1 2 3) 15 | 16 | ((fn* [x] x) [1 2 3]) 17 | ;=>[1 2 3] 18 | 19 | -------------------------------------------------------------------------------- /impls/vbs/tests/step9_try.mal: -------------------------------------------------------------------------------- 1 | (throw (list 1 2 3)) 2 | ;/.*([Ee][Rr][Rr][Oo][Rr]|[Ee]xception).*\(1 2 3\).* 3 | 4 | (try* (throw {}) (catch* e (do (throw e)))) 5 | ;/.*([Ee][Rr][Rr][Oo][Rr]|[Ee]xception).*{}.* 6 | 7 | (try* (throw (list 1 2 3)) (catch* exc (do 7))) 8 | ;=>7 9 | 10 | (try* (map throw (list "my err")) (catch* exc exc)) 11 | ;=>"my err" -------------------------------------------------------------------------------- /impls/vhdl/.gitignore: -------------------------------------------------------------------------------- 1 | work-obj93.cf 2 | -------------------------------------------------------------------------------- /impls/vhdl/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec $(dirname $0)/run_vhdl.sh $(dirname $0)/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /impls/vhdl/run_vhdl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ghdl doesn't allow passing command-line arguments to the VHDL program. To 4 | # circumvent that, we write the command-line arguments as lines in 5 | # vhdl_argv.tmp, and read the content of that file at the beginning of the VHDL 6 | # program. 7 | 8 | cleanup() { 9 | trap - TERM QUIT INT EXIT 10 | rm -f vhdl_argv.tmp 11 | } 12 | trap "cleanup" TERM QUIT INT EXIT 13 | 14 | bin="$1" 15 | shift 16 | 17 | for arg in "$@" ; do 18 | echo "$arg" 19 | done > vhdl_argv.tmp 20 | 21 | $bin 22 | -------------------------------------------------------------------------------- /impls/vimscript/.gitignore: -------------------------------------------------------------------------------- 1 | /*.o 2 | /*.so 3 | -------------------------------------------------------------------------------- /impls/vimscript/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | exec ./run_vimscript.sh ./${STEP:-stepA_mal}.vim "${@}" 4 | -------------------------------------------------------------------------------- /impls/vimscript/run_vimscript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Run Vim in ex mode (-e) and run the given script ($1) on startup. Our scripts 4 | # end with 'qall!' which causes actual Vim UI to never start up. 5 | # 6 | # Set environment variable DEBUG=1 to allow more verbose error output from Vim. 7 | # 8 | # See: http://vim.wikia.com/wiki/Vim_as_a_system_interpreter_for_vimscript 9 | 10 | rundir=`dirname $0` 11 | export LD_LIBRARY_PATH=`readlink -f $rundir` 12 | vimscriptfile="$1" 13 | shift 14 | if [ x$DEBUG = x ] ; then 15 | exec 2> /dev/null 16 | fi 17 | exec vim -i NONE -V1 -nNesS $vimscriptfile -- "$@" | cat 18 | -------------------------------------------------------------------------------- /impls/vimscript/step0_repl.vim: -------------------------------------------------------------------------------- 1 | source readline.vim 2 | 3 | function READ(str) 4 | return a:str 5 | endfunction 6 | 7 | function EVAL(ast, env) 8 | return a:ast 9 | endfunction 10 | 11 | function PRINT(exp) 12 | return a:exp 13 | endfunction 14 | 15 | function REP(str) 16 | return PRINT(EVAL(READ(a:str), {})) 17 | endfunction 18 | 19 | while 1 20 | let [eof, line] = Readline("user> ") 21 | if eof 22 | break 23 | endif 24 | if line == "" 25 | continue 26 | endif 27 | call PrintLn(REP(line)) 28 | endwhile 29 | qall! 30 | -------------------------------------------------------------------------------- /impls/vimscript/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Test recursive non-tail call function 2 | 3 | (def! sum-to (fn* (n) (if (= n 0) 0 (+ n (sum-to (- n 1)))))) 4 | 5 | (sum-to 10) 6 | ;=>55 7 | 8 | ;;; no try* yet, so test completion of side-effects 9 | (def! res1 nil) 10 | ;=>nil 11 | ;;; For implementations without their own TCO this should fail and 12 | ;;; leave res1 unchanged 13 | (def! res1 (sum-to 10000)) 14 | res1 15 | ;=>nil 16 | -------------------------------------------------------------------------------- /impls/wasm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mal", 3 | "version": "0.0.1", 4 | "description": "Make a Lisp (mal) language implemented in WebAssembly", 5 | "dependencies": { 6 | "@kanaka/wamp": "1.0.9", 7 | "ffi-napi": "^4.0.3", 8 | "text-encoding": "0.6.4" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /impls/wren/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES = types.wren env.wren printer.wren reader.wren readline.wren interop.wren core.wren stepA_mal.wren 2 | 3 | all: 4 | true 5 | 6 | dist: mal 7 | 8 | mal.wren: $(SOURCES) 9 | cat $+ | grep -v '^import "./' > $@ 10 | 11 | mal: mal.wren 12 | echo "#!/usr/bin/env wren" > $@ 13 | cat $< >> $@ 14 | chmod +x $@ 15 | 16 | .PHONY: clean 17 | 18 | clean: 19 | rm -f mal.wren mal 20 | -------------------------------------------------------------------------------- /impls/wren/README.md: -------------------------------------------------------------------------------- 1 | # Wren implementation 2 | 3 | ### Adding a time function 4 | 5 | Since Wren doesn't have a time function, we add a `System.gettimeofday` 6 | function which returns a float with the number of seconds since epoch (with 7 | fractions of seconds). 8 | 9 | This is done by applying the patch in `wren-add-gettimeofday.path` to Wren's 10 | source code before compiling it (see `Dockerfile`). 11 | 12 | ### Wren interop 13 | 14 | See examples in `tests/stepA_mal.mal` for usage of `wren-eval` to evaluate Wren 15 | expressions inside a Mal program. 16 | -------------------------------------------------------------------------------- /impls/wren/readline.wren: -------------------------------------------------------------------------------- 1 | import "io" for Stdin, Stdout 2 | 3 | class Readline { 4 | static readLine(prompt) { 5 | var line = null 6 | var fiber = Fiber.new { 7 | System.write(prompt) 8 | Stdout.flush() 9 | line = Stdin.readLine() 10 | } 11 | var error = fiber.try() 12 | return error ? null : line 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /impls/wren/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec wren $(dirname $0)/${STEP:-stepA_mal}.wren "${@}" 3 | -------------------------------------------------------------------------------- /impls/wren/step0_repl.wren: -------------------------------------------------------------------------------- 1 | import "./readline" for Readline 2 | 3 | class Mal { 4 | static read(str) { 5 | return str 6 | } 7 | 8 | static eval(ast, env) { 9 | return ast 10 | } 11 | 12 | static print(ast) { 13 | return ast 14 | } 15 | 16 | static rep(str) { 17 | return print(eval(read(str), null)) 18 | } 19 | 20 | static main() { 21 | while (true) { 22 | var line = Readline.readLine("user> ") 23 | if (line == null) break 24 | if (line != "") System.print(rep(line)) 25 | } 26 | System.print() 27 | } 28 | } 29 | 30 | Mal.main() 31 | -------------------------------------------------------------------------------- /impls/wren/tests/step5_tco.mal: -------------------------------------------------------------------------------- 1 | ;; Wren: skipping non-TCO recursion 2 | ;; Reason: completes up to 1,000,000 (with extended timeout) 3 | -------------------------------------------------------------------------------- /impls/xslt/Makefile: -------------------------------------------------------------------------------- 1 | .DEFAULT: 2 | echo 3 | 4 | .PHONY: clean 5 | 6 | all: 7 | echo "hello there general kenobi" 8 | -------------------------------------------------------------------------------- /impls/xslt/readline.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /impls/xslt/test.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /impls/yorick/Makefile: -------------------------------------------------------------------------------- 1 | SOURCES_BASE = hash.i types.i reader.i printer.i 2 | SOURCES_LISP = env.i core.i stepA_mal.i 3 | SOURCES = $(SOURCES_BASE) $(SOURCES_LISP) 4 | 5 | .PHONY: all dist clean 6 | 7 | all: dist 8 | 9 | dist: mal 10 | 11 | mal: $(SOURCES) 12 | echo "#!/usr/bin/yorick -batch" > $@ 13 | cat $+ | grep -v "^require," >> $@ 14 | chmod +x $@ 15 | 16 | clean: 17 | rm -f mal 18 | -------------------------------------------------------------------------------- /impls/yorick/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export YORICK_MAL_PATH="$(dirname $0)" 3 | exec yorick -batch "$YORICK_MAL_PATH/${STEP:-stepA_mal}.i" "${@}" 4 | -------------------------------------------------------------------------------- /impls/yorick/step0_repl.i: -------------------------------------------------------------------------------- 1 | func READ(str) 2 | { 3 | return str 4 | } 5 | 6 | func EVAL(exp, env) 7 | { 8 | return exp 9 | } 10 | 11 | func PRINT(exp) 12 | { 13 | return exp 14 | } 15 | 16 | func REP(str) 17 | { 18 | return PRINT(EVAL(READ(str), "")) 19 | } 20 | 21 | func main(void) 22 | { 23 | stdin_file = open("/dev/stdin", "r") 24 | while (1) { 25 | write, format="%s", "user> " 26 | line = rdline(stdin_file, prompt="") 27 | if (!line) break 28 | if (strlen(line) > 0) write, format="%s\n", REP(line) 29 | } 30 | write, "" 31 | } 32 | 33 | main; 34 | -------------------------------------------------------------------------------- /impls/zig/Makefile: -------------------------------------------------------------------------------- 1 | 2 | STEPS = step0_repl step1_read_print step2_eval step3_env step4_if_fn_do step5_tco step6_file step7_quote step8_macros step9_try stepA_mal 3 | 4 | all: $(STEPS) 5 | 6 | zig_opts += --release=safe 7 | zig_opts += -Doptimize=Debug 8 | $(STEPS): 9 | zig build $(zig_opts) -Dname=$@ -Droot_source_file=$@.zig 10 | 11 | .PHONY: all $(STEPS) clean 12 | 13 | clean: 14 | rm -fr .zig-cache/ zig-out/ 15 | rm -f *~ 16 | -------------------------------------------------------------------------------- /impls/zig/linked_list.zig: -------------------------------------------------------------------------------- 1 | const allocator = @import("std").heap.c_allocator; 2 | const ArrayListUnmanaged = @import("std").ArrayListUnmanaged; 3 | const MalType = @import("types.zig").MalType; 4 | 5 | // The name is poorly choosen but historical. 6 | 7 | pub const MalLinkedList = ArrayListUnmanaged(*MalType); 8 | 9 | pub fn list_destroy(ll: *MalLinkedList) void { 10 | for(ll.items) |x| 11 | x.decref(); 12 | ll.deinit(allocator); 13 | } 14 | -------------------------------------------------------------------------------- /impls/zig/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec $(dirname $0)/zig-out/bin/${STEP:-stepA_mal} "${@}" 3 | -------------------------------------------------------------------------------- /lib: -------------------------------------------------------------------------------- 1 | impls/lib -------------------------------------------------------------------------------- /process/step0_repl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step0_repl.png -------------------------------------------------------------------------------- /process/step0_repl.txt: -------------------------------------------------------------------------------- 1 | --- step0_repl ---------------------------------- 2 | READ(str): return str 3 | 4 | EVAL(ast,env): return ast 5 | 6 | PRINT(exp): return exp 7 | 8 | rep(str): return PRINT(EVAL(READ(str),"")) 9 | 10 | main loop: println(rep(readline("user> "))) 11 | 12 | -------------------------------------------------------------------------------- /process/step1_read_print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step1_read_print.png -------------------------------------------------------------------------------- /process/step1_read_print.txt: -------------------------------------------------------------------------------- 1 | --- step1_read_print ---------------------------- 2 | import reader, printer 3 | 4 | READ(str): return reader.read_str(str) 5 | 6 | EVAL(ast,env): return ast 7 | 8 | PRINT(exp): return printer.pr_str(exp) 9 | 10 | rep(str): return PRINT(EVAL(READ(str),"")) 11 | 12 | main loop: 13 | try: println(rep(readline("user> "))) 14 | catch e: println("Error: ", e) 15 | -------------------------------------------------------------------------------- /process/step2_eval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step2_eval.png -------------------------------------------------------------------------------- /process/step3_env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step3_env.png -------------------------------------------------------------------------------- /process/step4_if_fn_do.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step4_if_fn_do.png -------------------------------------------------------------------------------- /process/step5_tco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step5_tco.png -------------------------------------------------------------------------------- /process/step6_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step6_file.png -------------------------------------------------------------------------------- /process/step7_quote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step7_quote.png -------------------------------------------------------------------------------- /process/step8_macros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step8_macros.png -------------------------------------------------------------------------------- /process/step9_try.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/step9_try.png -------------------------------------------------------------------------------- /process/stepA_mal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/stepA_mal.png -------------------------------------------------------------------------------- /process/steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanaka/mal/178b7a88d22e92d16ef318c6830ea9f0973d0396/process/steps.png -------------------------------------------------------------------------------- /tests: -------------------------------------------------------------------------------- 1 | impls/tests -------------------------------------------------------------------------------- /voom-like-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | echo $(TZ=UTC git log -1 --pretty=%ad-g%h --date=format-local:"%Y%m%d_%H%M%S" -- "$@")$(test -z "$(git status --short -- "$@")" || echo _DIRTY) 4 | --------------------------------------------------------------------------------