3 [![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal)
7 **1. Mal is a Clojure inspired Lisp interpreter**
9 **2. Mal is implemented in 75 languages (76 implementations total)**
11 | Language | Creator |
12 | -------- | ------- |
13 | [Ada](#ada) | [Chris Moore](https://github.com/zmower) |
14 | [Ada.2](#ada2) | [Nicolas Boulenguez](https://github.com/asarhaddon) |
15 | [GNU Awk](#gnu-awk) | [Miutsuru Kariya](https://github.com/kariya-mitsuru) |
16 | [Bash 4](#bash-4) | [Joel Martin](https://github.com/kanaka) |
17 | [BASIC](#basic-c64-and-qbasic) (C64 & QBasic) | [Joel Martin](https://github.com/kanaka) |
18 | [C](#c) | [Joel Martin](https://github.com/kanaka) |
19 | [C++](#c-1) | [Stephen Thirlwall](https://github.com/sdt) |
20 | [C#](#c-2) | [Joel Martin](https://github.com/kanaka) |
21 | [ChucK](#chuck) | [Vasilij Schneidermann](https://github.com/wasamasa) |
22 | [Clojure](#clojure) (Clojure & ClojureScript) | [Joel Martin](https://github.com/kanaka) |
23 | [CoffeeScript](#coffeescript) | [Joel Martin](https://github.com/kanaka) |
24 | [Common Lisp](#common-lisp) | [Iqbal Ansari](https://github.com/iqbalansari) |
25 | [Crystal](#crystal) | [Linda_pp](https://github.com/rhysd) |
26 | [D](#d) | [Dov Murik](https://github.com/dubek) |
27 | [Dart](#dart) | [Harry Terkelsen](https://github.com/hterkelsen) |
28 | [Elixir](#elixir) | [Martin Ek](https://github.com/ekmartin) |
29 | [Elm](#elm) | [Jos van Bakel](https://github.com/c0deaddict) |
30 | [Emacs Lisp](#emacs-lisp) | [Vasilij Schneidermann](https://github.com/wasamasa) |
31 | [Erlang](#erlang) | [Nathan Fiedler](https://github.com/nlfiedler) |
32 | [ES6](#es6-ecmascript-2015) (ECMAScript 2015) | [Joel Martin](https://github.com/kanaka) |
33 | [F#](#f) | [Peter Stephens](https://github.com/pstephens) |
34 | [Factor](#factor) | [Jordan Lewis](https://github.com/jordanlewis) |
35 | [Fantom](#fantom) | [Dov Murik](https://github.com/dubek) |
36 | [Forth](#forth) | [Chris Houser](https://github.com/chouser) |
37 | [GNU Guile](#gnu-guile-21) | [Mu Lei](https://github.com/NalaGinrut) |
38 | [GNU Smalltalk](#gnu-smalltalk) | [Vasilij Schneidermann](https://github.com/wasamasa) |
39 | [Go](#go) | [Joel Martin](https://github.com/kanaka) |
40 | [Groovy](#groovy) | [Joel Martin](https://github.com/kanaka) |
41 | [Haskell](#haskell) | [Joel Martin](https://github.com/kanaka) |
42 | [Haxe](#haxe-neko-python-c-and-javascript) (Neko, Python, C++, & JS) | [Joel Martin](https://github.com/kanaka) |
43 | [Hy](#hy) | [Joel Martin](https://github.com/kanaka) |
44 | [Io](#io) | [Dov Murik](https://github.com/dubek) |
45 | [Java](#java-17) | [Joel Martin](https://github.com/kanaka) |
46 | [JavaScript](#javascriptnode) ([Demo](http://kanaka.github.io/mal)) | [Joel Martin](https://github.com/kanaka) |
47 | [Julia](#julia) | [Joel Martin](https://github.com/kanaka) |
48 | [Kotlin](#kotlin) | [Javier Fernandez-Ivern](https://github.com/ivern) |
49 | [LiveScript](#livescript) | [Jos van Bakel](https://github.com/c0deaddict) |
50 | [Logo](#logo) | [Dov Murik](https://github.com/dubek) |
51 | [Lua](#lua) | [Joel Martin](https://github.com/kanaka) |
52 | [GNU Make](#gnu-make-381) | [Joel Martin](https://github.com/kanaka) |
53 | [mal itself](#mal) | [Joel Martin](https://github.com/kanaka) |
54 | [MATLAB](#matlab-gnu-octave-and-matlab) (GNU Octave & MATLAB) | [Joel Martin](https://github.com/kanaka) |
55 | [miniMAL](#minimal) ([Repo](https://github.com/kanaka/miniMAL), [Demo](https://kanaka.github.io/miniMAL/)) | [Joel Martin](https://github.com/kanaka) |
56 | [NASM](#nasm) | [Ben Dudson](https://github.com/bendudson) |
57 | [Nim](#nim-0170) | [Dennis Felsing](https://github.com/def-) |
58 | [Object Pascal](#object-pascal) | [Joel Martin](https://github.com/kanaka) |
59 | [Objective C](#objective-c) | [Joel Martin](https://github.com/kanaka) |
60 | [OCaml](#ocaml-4010) | [Chris Houser](https://github.com/chouser) |
61 | [Perl](#perl-58) | [Joel Martin](https://github.com/kanaka) |
62 | [Perl 6](#perl-6) | [Hinrik Örn Sigurðsson](https://github.com/hinrik) |
63 | [PHP](#php-53) | [Joel Martin](https://github.com/kanaka) |
64 | [Picolisp](#picolisp) | [Vasilij Schneidermann](https://github.com/wasamasa) |
65 | [PL/pgSQL](#plpgsql-postgres-sql-procedural-language) (Postgres) | [Joel Martin](https://github.com/kanaka) |
66 | [PL/SQL](#plsql-oracle-sql-procedural-language) (Oracle) | [Joel Martin](https://github.com/kanaka) |
67 | [PostScript](#postscript-level-23) | [Joel Martin](https://github.com/kanaka) |
68 | [PowerShell](#powershell) | [Joel Martin](https://github.com/kanaka) |
69 | [Python](#python-2x-and-3x) (2.X & 3.X) | [Joel Martin](https://github.com/kanaka) |
70 | [RPython](#rpython) | [Joel Martin](https://github.com/kanaka) |
71 | [R](#r) | [Joel Martin](https://github.com/kanaka) |
72 | [Racket](#racket-53) | [Joel Martin](https://github.com/kanaka) |
73 | [Rexx](#rexx) | [Dov Murik](https://github.com/dubek) |
74 | [Ruby](#ruby-19) | [Joel Martin](https://github.com/kanaka) |
75 | [Rust](#rust-100-nightly) | [Joel Martin](https://github.com/kanaka) |
76 | [Scala](#scala) | [Joel Martin](https://github.com/kanaka) |
77 | [Scheme (R7RS)](#scheme-r7rs) | [Vasilij Schneidermann](https://github.com/wasamasa) |
78 | [Skew](#skew) | [Dov Murik](https://github.com/dubek) |
79 | [Swift 2](#swift) | [Keith Rollin](https://github.com/keith-rollin) |
80 | [Swift 3](#swift-3) | [Joel Martin](https://github.com/kanaka) |
81 | [Swift 4](#swift-4) | [陆遥](https://github.com/LispLY) |
82 | [Tcl](#tcl-86) | [Dov Murik](https://github.com/dubek) |
83 | [TypeScript](#typescript) | [Masahiro Wakame](https://github.com/vvakame) |
84 | [VHDL](#vhdl) | [Dov Murik](https://github.com/dubek) |
85 | [Vimscript](#vimscript) | [Dov Murik](https://github.com/dubek) |
86 | [Visual Basic.NET](#visual-basicnet) | [Joel Martin](https://github.com/kanaka) |
87 | [WebAssembly](#webassembly-wasm) (wasm) | [Joel Martin](https://github.com/kanaka) |
88 | [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
91 **3. Mal is a learning tool**
93 Each implementation of mal is separated into
94 11 incremental, self-contained (and testable) steps that demonstrate
95 core concepts of Lisp. The last step is capable of self-hosting
96 (running the mal implementation of mal). See the [make-a-lisp process
97 guide](process/guide.md).
99 The make-a-lisp steps are:
101 * [step0_repl](process/guide.md#step0)
102 * [step1_read_print](process/guide.md#step1)
103 * [step2_eval](process/guide.md#step2)
104 * [step3_env](process/guide.md#step3)
105 * [step4_if_fn_do](process/guide.md#step4)
106 * [step5_tco](process/guide.md#step5)
107 * [step6_file](process/guide.md#step6)
108 * [step7_quote](process/guide.md#step7)
109 * [step8_macros](process/guide.md#step8)
110 * [step9_try](process/guide.md#step9)
111 * [stepA_mal](process/guide.md#stepA)
113 Each make-a-lisp step has an associated architectural diagram. That elements
114 that are new for that step are highlighted in red.
115 Here is the final diagram for [step A](process/guide.md#stepA):
117 ![stepA_mal architecture](process/stepA_mal.png)
119 If you are interesting in creating a mal implementation (or just
120 interested in using mal for something), please drop by the #mal
121 channel on freenode. In addition to the [make-a-lisp process
122 guide](process/guide.md) there is also a [mal/make-a-lisp
123 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
128 Mal was presented publicly for the first time in a lightning talk at
129 Clojure West 2014 (unfortunately there is no video). See
130 examples/clojurewest2014.mal for the presentation that was given at the
131 conference (yes, the presentation is a mal program).
133 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
134 "Achievement Unlocked: A Better Path to Language Learning".
135 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
136 [Slides](http://kanaka.github.io/midwest.io.mal/).
138 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
139 in 10 Incremental Steps" at LambdaConf 2016:
140 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
141 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
142 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
143 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
144 [Slides](http://kanaka.github.io/lambdaconf/).
146 ## Building/running implementations
148 The simplest way to run any given implementation is to use docker.
149 Every implementation has a docker image pre-built with language
150 dependencies installed. You can launch the REPL using a convenient
151 target in the top level Makefile (where IMPL is the implementation
152 directory name and stepX is the step to run):
155 make DOCKERIZE=1 "repl^IMPL^stepX"
156 # OR stepA is the default step:
157 make DOCKERIZE=1 "repl^IMPL"
163 The Ada implementation was developed with GNAT 4.9 on debian. It also
164 compiles unchanged on windows if you have windows versions of git,
165 GNAT and (optionally) make. There are no external dependencies
166 (readline not implemented).
176 The second Ada implementation was developed with GNAT 8 and links with
177 the GNU readline library.
187 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
191 gawk -O -f stepX_YYY.awk
201 ### BASIC (C64 and QBasic)
203 The BASIC implementation uses a preprocessor that can generate BASIC
204 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
205 C64 mode has been tested with
206 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
207 currently required to fix issues with line input) and the QBasic mode
208 has been tested with [qb64](http://www.qb64.net/).
210 Generate C64 code and run it using cbmbasic:
218 Generate QBasic code and load it into qb64:
222 make MODE=qbasic stepX_YYY.bas
226 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
227 inspiration for this implementation.
232 The C implementation of mal requires the following libraries (lib and
233 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
244 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
245 a readline compatible library to build. See the `cpp/README.md` for
259 The C# implementation of mal has been tested on Linux using the Mono
260 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
261 required to build and run the C# implementation.
271 The ChucK implementation has been tested with ChucK 1.3.5.2.
280 For the most part the Clojure implementation requires Clojure 1.5,
281 however, to pass all tests, Clojure 1.8.0-RC4 is required.
285 lein with-profile +stepX trampoline run
291 sudo npm install -g coffee-script
298 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
299 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
300 the [README](common-lisp/README.org) for more details. Provided you have the
301 dependencies mentioned installed, do the following to run the implementation
311 The Crystal implementation of mal has been tested with Crystal 0.26.1.
315 crystal run ./stepX_YYY.cr
317 make # needed to run tests
323 The D implementation of mal was tested with GDC 4.8. It requires the GNU
334 The Dart implementation has been tested with Dart 1.20.
343 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
344 and 24.5. While there is very basic readline editing (`<backspace>`
345 and `C-d` work, `C-c` cancels the process), it is recommended to use
350 emacs -Q --batch --load stepX_YYY.el
351 # with full readline support
352 rlwrap emacs -Q --batch --load stepX_YYY.el
357 The Elixir implementation of mal has been tested with Elixir 1.0.5.
362 # Or with readline/line editing functionality:
368 The Elm implementation of mal has been tested with Elm 0.18.0
378 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
379 and [rebar](https://github.com/rebar/rebar) to build.
385 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
389 ### ES6 (ECMAScript 2015)
391 The ES6 / ECMAScript 2015 implementation uses the
392 [babel](https://babeljs.io) compiler to generate ES5 compatible
393 JavaScript. The generated code has been tested with Node 0.12.4.
398 node build/stepX_YYY.js
404 The F# implementation of mal has been tested on Linux using the Mono
405 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
406 compiler (mcs) is also necessary to compile the readline dependency. All are
407 required to build and run the F# implementation.
417 The Factor implementation of mal has been tested with Factor 0.97
418 ([factorcode.org](http://factorcode.org)).
422 FACTOR_ROOTS=. factor -run=stepX_YYY
427 The Fantom implementation of mal has been tested with Fantom 1.0.70.
431 make lib/fan/stepX_YYY.pod
446 guile -L ./ stepX_YYY.scm
451 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
460 The Go implementation of mal requires that go is installed on on the
461 path. The implementation has been tested with Go 1.3.1.
472 The Groovy implementation of mal requires Groovy to run and has been
473 tested with Groovy 1.8.6.
478 groovy ./stepX_YYY.groovy
483 The Haskell implementation requires the ghc compiler version 7.10.1 or
484 later and also the Haskell parsec and readline (or editline) packages.
492 ### Haxe (Neko, Python, C++ and JavaScript)
494 The Haxe implementation of mal requires Haxe version 3.2 to compile.
495 Four different Haxe targets are supported: Neko, Python, C++, and
505 python3 ./stepX_YYY.py
516 The Hy implementation of mal has been tested with Hy 0.13.0.
525 The Io implementation of mal has been tested with Io version 20110905.
534 The Java implementation of mal requires maven2 to build.
539 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
541 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
554 The Julia implementation of mal requires Julia 0.4.
563 The Kotlin implementation of mal has been tested with Kotlin 1.0.
568 java -jar stepX_YYY.jar
573 The LiveScript implementation of mal has been tested with LiveScript 1.5.
578 node_modules/.bin/lsc stepX_YYY.ls
583 The Logo implementation of mal has been tested with UCBLogo 6.0.
592 The Lua implementation of mal has been tested with Lua 5.2. The
593 implementation requires that luarocks and the lua-rex-pcre library
598 make # to build and link linenoise.so
604 Running the mal implementation of mal involves running stepA of one of
605 the other implementations and passing the mal step to run as a command
610 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
623 The NASM implementation of mal is written for x86-64 Linux, and has been tested
624 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
634 The Nim implementation of mal has been tested with Nim 0.17.0.
646 The Object Pascal implementation of mal has been built and tested on
647 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
657 The Objective C implementation of mal has been built and tested on
658 Linux using clang/LLVM 3.6. It has also been built and tested on OS
675 ### MATLAB (GNU Octave and MATLAB)
677 The MatLab implementation has been tested with GNU Octave 4.2.1.
678 It has also been tested with MATLAB version R2014a on Linux. Note that
679 MATLAB is a commercial product.
684 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
685 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
686 # OR with command line arguments
687 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
688 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
693 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
694 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
695 implementation of mal you need to download/install the miniMAL
696 interpreter (which requires Node.js).
699 # Download miniMAL and dependencies
701 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
702 # Now run mal implementation in miniMAL
708 For readline line editing support, install Term::ReadLine::Perl or
709 Term::ReadLine::Gnu from CPAN.
718 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
727 The PHP implementation of mal requires the php command line interface
737 The Picolisp implementation requires libreadline and Picolisp 3.1.11
745 ### PL/pgSQL (Postgres SQL Procedural Language)
747 The PL/pgSQL implementation of mal requires a running Postgres server
748 (the "kanaka/mal-test-plpgsql" docker image automatically starts
749 a Postgres server). The implementation connects to the Postgres server
750 and create a database named "mal" to store tables and stored
751 procedures. The wrapper script uses the psql command to connect to the
752 server and defaults to the user "postgres" but this can be overridden
753 with the PSQL_USER environment variable. A password can be specified
754 using the PGPASSWORD environment variable. The implementation has been
755 tested with Postgres 9.4.
759 ./wrap.sh stepX_YYY.sql
761 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
764 ### PL/SQL (Oracle SQL Procedural Language)
766 The PL/pgSQL implementation of mal requires a running Oracle DB
767 server (the "kanaka/mal-test-plsql" docker image automatically
768 starts an Oracle Express server). The implementation connects to the
769 Oracle server to create types, tables and stored procedures. The
770 default SQL*Plus logon value (username/password@connect_identifier) is
771 "system/oracle" but this can be overridden with the ORACLE_LOGON
772 environment variable. The implementation has been tested with Oracle
773 Express Edition 11g Release 2. Note that any SQL*Plus connection
774 warnings (user password expiration, etc) will interfere with the
775 ability of the wrapper script to communicate with the DB.
779 ./wrap.sh stepX_YYY.sql
781 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
784 ### Postscript Level 2/3
786 The Postscript implementation of mal requires ghostscript to run. It
787 has been tested with ghostscript 9.10.
791 gs -q -dNODISPLAY -I./ stepX_YYY.ps
796 The PowerShell implementation of mal requires the PowerShell script
797 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
801 powershell ./stepX_YYY.ps1
804 ### Python (2.X and 3.X)
813 You must have [rpython](https://rpython.readthedocs.org/) on your path
814 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
818 make # this takes a very long time
824 The R implementation of mal requires R (r-base-core) to run.
828 make libs # to download and build rdyncall
834 The Racket implementation of mal requires the Racket
835 compiler/interpreter to run.
844 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
849 rexx -a ./stepX_YYY.rexxpp
859 ### Rust (1.0.0 nightly)
861 The rust implementation of mal requires the rust compiler and build
862 tool (cargo) to build.
866 cargo run --release --bin stepX_YYY
871 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
875 sbt 'run-main stepX_YYY'
878 scala -classpath target/scala*/classes stepX_YYY
881 ### Scheme (R7RS) ###
883 The Scheme implementation of mal has been tested with Chibi-Scheme
884 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
885 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
886 be able to get it running on other conforming R7RS implementations
887 after figuring out how libraries are loaded and adjusting the
888 `Makefile` and `run` script accordingly.
894 scheme_MODE=chibi ./run
897 scheme_MODE=kawa ./run
899 scheme_MODE=gauche ./run
902 scheme_MODE=chicken ./run
904 scheme_MODE=sagittarius ./run
907 scheme_MODE=cyclone ./run
909 scheme_MODE=foment ./run
914 The Skew implementation of mal has been tested with Skew 0.7.42.
925 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
926 7.0) to build. Older versions will not work due to changes in the
927 language and standard library.
937 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
938 has been tested with Swift 3 Preview 3.
948 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
949 has been tested with Swift 4.2.3 release.
959 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
960 editing support, install tclreadline.
964 tclsh ./stepX_YYY.tcl
969 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
970 It has been tested with Node.js v6.
980 The VHDL implementation of mal has been tested with GHDL 0.29.
985 ./run_vhdl.sh ./stepX_YYY
990 The Vimscript implementation of mal requires Vim 8.0 to run.
994 ./run_vimscript.sh ./stepX_YYY.vim
997 ### Visual Basic.NET ###
999 The VB.NET implementation of mal has been tested on Linux using the Mono
1000 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1001 required to build and run the VB.NET implementation.
1006 mono ./stepX_YYY.exe
1009 ### WebAssembly (wasm) ###
1011 The WebAssembly implementation is written in
1012 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1013 runs under the [wac/wace](https://github.com/kanaka/wac) WebAssembly
1019 wace ./stepX_YYY.wasm
1024 The Yorick implementation of mal was tested on Yorick 2.2.04.
1028 yorick -batch ./stepX_YYY.i
1035 The top level Makefile has a number of useful targets to assist with
1036 implementation development and testing. The `help` target provides
1037 a list of the targets and options:
1043 ### Functional tests
1045 The are over 600 generic functional tests (for all implementations)
1046 in the `tests/` directory. Each step has a corresponding test file
1047 containing tests specific to that step. The `runtest.py` test harness
1048 launches a Mal step implementation and then feeds the tests one at
1049 a time to the implementation and compares the output/return value to
1050 the expected output/return value.
1052 * To run all the tests across all implementations (be prepared to wait):
1058 * To run all tests against a single implementation:
1068 * To run tests for a single step against all implementations:
1078 * To run tests for a specific step against a single implementation:
1081 make "test^IMPL^stepX"
1084 make "test^ruby^step3"
1085 make "test^ps^step4"
1088 ### Self-hosted functional tests
1090 * To run the functional tests in self-hosted mode, you specify `mal`
1091 as the test implementation and use the `MAL_IMPL` make variable
1092 to change the underlying host language (default is JavaScript):
1094 make MAL_IMPL=IMPL "test^mal^step2"
1097 make "test^mal^step2" # js is default
1098 make MAL_IMPL=ruby "test^mal^step2"
1099 make MAL_IMPL=python "test^mal^step2"
1102 ### Starting the REPL
1104 * To start the REPL of an implementation in a specific step:
1107 make "repl^IMPL^stepX"
1110 make "repl^ruby^step3"
1111 make "repl^ps^step4"
1114 * If you omit the step, then `stepA` is used:
1124 * To start the REPL of the self-hosted implementation, specify `mal` as the
1125 REPL implementation and use the `MAL_IMPL` make variable to change the
1126 underlying host language (default is JavaScript):
1128 make MAL_IMPL=IMPL "repl^mal^stepX"
1131 make "repl^mal^step2" # js is default
1132 make MAL_IMPL=ruby "repl^mal^step2"
1133 make MAL_IMPL=python "repl^mal"
1136 ### Performance tests
1138 Warning: These performance tests are neither statistically valid nor
1139 comprehensive; runtime performance is a not a primary goal of mal. If
1140 you draw any serious conclusions from these performance tests, then
1141 please contact me about some amazing oceanfront property in Kansas
1142 that I'm willing to sell you for cheap.
1144 * To run performance tests against a single implementation:
1152 * To run performance tests against all implementations:
1157 ### Generating language statistics
1159 * To report line and byte statistics for a single implementation:
1167 * To report line and bytes statistics for general Lisp code (env, core
1170 make "stats-lisp^IMPL"
1173 make "stats-lisp^js"
1176 ## Dockerized testing
1178 Every implementation directory contains a Dockerfile to create
1179 a docker image containing all the dependencies for that
1180 implementation. In addition, the top-level Makefile contains support
1181 for running the tests target (and perf, stats, repl, etc) within
1182 a docker container for that implementation by passing *"DOCKERIZE=1"*
1183 on the make command line. For example:
1186 make DOCKERIZE=1 "test^js^step3"
1189 Existing implementations already have docker images built and pushed
1190 to the docker registry. However, if
1191 you wish to build or rebuild a docker image locally, the toplevel
1192 Makefile provides a rule for building docker images:
1195 make "docker-build^IMPL"
1200 * Docker images are named *"kanaka/mal-test-IMPL"*
1201 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1202 you will probably need to run this command once manually
1203 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1204 runtime dependencies need to be downloaded to avoid the tests timing
1205 out. These dependencies are downloaded to dot-files in the /mal
1206 directory so they will persist between runs.
1209 ## External Implementations
1211 The following implementations are maintained as separate projects:
1215 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
1219 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
1220 * [by vi](https://github.com/vi/mal-rust-vi) - using [Pest](https://pest.rs/) grammar, not using typical Mal infrastructure (cargo-ized steps and built-in converted tests).
1223 ## Other mal Projects
1225 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
1226 * [malcc](https://git.sr.ht/~tim/malcc) (@seven1m) - malcc is an incremental compiler implementation for the Mal language. It uses the Tiny C Compiler as the compiler backend and has full support for the Mal language, including macros, tail-call elimination, and even run-time eval. ["I Built a Lisp Compiler"](https://mpov.timmorgan.org/i-built-a-lisp-compiler/) post about the process.
1227 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
1231 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1232 License 2.0). See LICENSE.txt for more details.