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 76 languages (77 different implementations and 98 runtime modes)**
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 | [Vala](#vala) | [Simon Tatham](https://github.com/sgtatham) |
85 | [VHDL](#vhdl) | [Dov Murik](https://github.com/dubek) |
86 | [Vimscript](#vimscript) | [Dov Murik](https://github.com/dubek) |
87 | [Visual Basic.NET](#visual-basicnet) | [Joel Martin](https://github.com/kanaka) |
88 | [WebAssembly](#webassembly-wasm) (wasm) | [Joel Martin](https://github.com/kanaka) |
89 | [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
92 **3. Mal is a learning tool**
94 Each implementation of mal is separated into
95 11 incremental, self-contained (and testable) steps that demonstrate
96 core concepts of Lisp. The last step is capable of self-hosting
97 (running the mal implementation of mal). See the [make-a-lisp process
98 guide](process/guide.md).
100 The make-a-lisp steps are:
102 * [step0_repl](process/guide.md#step0)
103 * [step1_read_print](process/guide.md#step1)
104 * [step2_eval](process/guide.md#step2)
105 * [step3_env](process/guide.md#step3)
106 * [step4_if_fn_do](process/guide.md#step4)
107 * [step5_tco](process/guide.md#step5)
108 * [step6_file](process/guide.md#step6)
109 * [step7_quote](process/guide.md#step7)
110 * [step8_macros](process/guide.md#step8)
111 * [step9_try](process/guide.md#step9)
112 * [stepA_mal](process/guide.md#stepA)
114 Each make-a-lisp step has an associated architectural diagram. That elements
115 that are new for that step are highlighted in red.
116 Here is the final diagram for [step A](process/guide.md#stepA):
118 ![stepA_mal architecture](process/stepA_mal.png)
120 If you are interesting in creating a mal implementation (or just
121 interested in using mal for something), please drop by the #mal
122 channel on freenode. In addition to the [make-a-lisp process
123 guide](process/guide.md) there is also a [mal/make-a-lisp
124 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
129 Mal was presented publicly for the first time in a lightning talk at
130 Clojure West 2014 (unfortunately there is no video). See
131 examples/clojurewest2014.mal for the presentation that was given at the
132 conference (yes, the presentation is a mal program).
134 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
135 "Achievement Unlocked: A Better Path to Language Learning".
136 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
137 [Slides](http://kanaka.github.io/midwest.io.mal/).
139 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
140 in 10 Incremental Steps" at LambdaConf 2016:
141 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
142 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
143 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
144 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
145 [Slides](http://kanaka.github.io/lambdaconf/).
147 ## Building/running implementations
149 The simplest way to run any given implementation is to use docker.
150 Every implementation has a docker image pre-built with language
151 dependencies installed. You can launch the REPL using a convenient
152 target in the top level Makefile (where IMPL is the implementation
153 directory name and stepX is the step to run):
156 make DOCKERIZE=1 "repl^IMPL^stepX"
157 # OR stepA is the default step:
158 make DOCKERIZE=1 "repl^IMPL"
161 ## External Implementations
163 The following implementations are maintained as separate projects:
167 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
171 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
172 * [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).
175 ## Other mal Projects
177 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
178 * [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.
179 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
182 ## Implementation Details
186 The Ada implementation was developed with GNAT 4.9 on debian. It also
187 compiles unchanged on windows if you have windows versions of git,
188 GNAT and (optionally) make. There are no external dependencies
189 (readline not implemented).
199 The second Ada implementation was developed with GNAT 8 and links with
200 the GNU readline library.
210 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
214 gawk -O -f stepX_YYY.awk
224 ### BASIC (C64 and QBasic)
226 The BASIC implementation uses a preprocessor that can generate BASIC
227 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
228 C64 mode has been tested with
229 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
230 currently required to fix issues with line input) and the QBasic mode
231 has been tested with [qb64](http://www.qb64.net/).
233 Generate C64 code and run it using cbmbasic:
241 Generate QBasic code and load it into qb64:
245 make MODE=qbasic stepX_YYY.bas
249 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
250 inspiration for this implementation.
255 The C implementation of mal requires the following libraries (lib and
256 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
267 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
268 a readline compatible library to build. See the `cpp/README.md` for
282 The C# implementation of mal has been tested on Linux using the Mono
283 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
284 required to build and run the C# implementation.
294 The ChucK implementation has been tested with ChucK 1.3.5.2.
303 For the most part the Clojure implementation requires Clojure 1.5,
304 however, to pass all tests, Clojure 1.8.0-RC4 is required.
308 lein with-profile +stepX trampoline run
314 sudo npm install -g coffee-script
321 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
322 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
323 the [README](common-lisp/README.org) for more details. Provided you have the
324 dependencies mentioned installed, do the following to run the implementation
334 The Crystal implementation of mal has been tested with Crystal 0.26.1.
338 crystal run ./stepX_YYY.cr
340 make # needed to run tests
346 The D implementation of mal was tested with GDC 4.8. It requires the GNU
357 The Dart implementation has been tested with Dart 1.20.
366 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
367 and 24.5. While there is very basic readline editing (`<backspace>`
368 and `C-d` work, `C-c` cancels the process), it is recommended to use
373 emacs -Q --batch --load stepX_YYY.el
374 # with full readline support
375 rlwrap emacs -Q --batch --load stepX_YYY.el
380 The Elixir implementation of mal has been tested with Elixir 1.0.5.
385 # Or with readline/line editing functionality:
391 The Elm implementation of mal has been tested with Elm 0.18.0
401 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
402 and [rebar](https://github.com/rebar/rebar) to build.
408 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
412 ### ES6 (ECMAScript 2015)
414 The ES6 / ECMAScript 2015 implementation uses the
415 [babel](https://babeljs.io) compiler to generate ES5 compatible
416 JavaScript. The generated code has been tested with Node 0.12.4.
421 node build/stepX_YYY.js
427 The F# implementation of mal has been tested on Linux using the Mono
428 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
429 compiler (mcs) is also necessary to compile the readline dependency. All are
430 required to build and run the F# implementation.
440 The Factor implementation of mal has been tested with Factor 0.97
441 ([factorcode.org](http://factorcode.org)).
445 FACTOR_ROOTS=. factor -run=stepX_YYY
450 The Fantom implementation of mal has been tested with Fantom 1.0.70.
454 make lib/fan/stepX_YYY.pod
469 guile -L ./ stepX_YYY.scm
474 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
483 The Go implementation of mal requires that go is installed on on the
484 path. The implementation has been tested with Go 1.3.1.
495 The Groovy implementation of mal requires Groovy to run and has been
496 tested with Groovy 1.8.6.
501 groovy ./stepX_YYY.groovy
506 The Haskell implementation requires the ghc compiler version 7.10.1 or
507 later and also the Haskell parsec and readline (or editline) packages.
515 ### Haxe (Neko, Python, C++ and JavaScript)
517 The Haxe implementation of mal requires Haxe version 3.2 to compile.
518 Four different Haxe targets are supported: Neko, Python, C++, and
528 python3 ./stepX_YYY.py
539 The Hy implementation of mal has been tested with Hy 0.13.0.
548 The Io implementation of mal has been tested with Io version 20110905.
557 The Java implementation of mal requires maven2 to build.
562 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
564 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
577 The Julia implementation of mal requires Julia 0.4.
586 The Kotlin implementation of mal has been tested with Kotlin 1.0.
591 java -jar stepX_YYY.jar
596 The LiveScript implementation of mal has been tested with LiveScript 1.5.
601 node_modules/.bin/lsc stepX_YYY.ls
606 The Logo implementation of mal has been tested with UCBLogo 6.0.
615 The Lua implementation of mal has been tested with Lua 5.2. The
616 implementation requires that luarocks and the lua-rex-pcre library
621 make # to build and link linenoise.so
627 Running the mal implementation of mal involves running stepA of one of
628 the other implementations and passing the mal step to run as a command
633 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
646 The NASM implementation of mal is written for x86-64 Linux, and has been tested
647 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
657 The Nim implementation of mal has been tested with Nim 0.17.0.
669 The Object Pascal implementation of mal has been built and tested on
670 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
680 The Objective C implementation of mal has been built and tested on
681 Linux using clang/LLVM 3.6. It has also been built and tested on OS
698 ### MATLAB (GNU Octave and MATLAB)
700 The MatLab implementation has been tested with GNU Octave 4.2.1.
701 It has also been tested with MATLAB version R2014a on Linux. Note that
702 MATLAB is a commercial product.
707 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
708 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
709 # OR with command line arguments
710 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
711 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
716 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
717 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
718 implementation of mal you need to download/install the miniMAL
719 interpreter (which requires Node.js).
722 # Download miniMAL and dependencies
724 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
725 # Now run mal implementation in miniMAL
731 For readline line editing support, install Term::ReadLine::Perl or
732 Term::ReadLine::Gnu from CPAN.
741 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
750 The PHP implementation of mal requires the php command line interface
760 The Picolisp implementation requires libreadline and Picolisp 3.1.11
768 ### PL/pgSQL (Postgres SQL Procedural Language)
770 The PL/pgSQL implementation of mal requires a running Postgres server
771 (the "kanaka/mal-test-plpgsql" docker image automatically starts
772 a Postgres server). The implementation connects to the Postgres server
773 and create a database named "mal" to store tables and stored
774 procedures. The wrapper script uses the psql command to connect to the
775 server and defaults to the user "postgres" but this can be overridden
776 with the PSQL_USER environment variable. A password can be specified
777 using the PGPASSWORD environment variable. The implementation has been
778 tested with Postgres 9.4.
782 ./wrap.sh stepX_YYY.sql
784 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
787 ### PL/SQL (Oracle SQL Procedural Language)
789 The PL/pgSQL implementation of mal requires a running Oracle DB
790 server (the "kanaka/mal-test-plsql" docker image automatically
791 starts an Oracle Express server). The implementation connects to the
792 Oracle server to create types, tables and stored procedures. The
793 default SQL*Plus logon value (username/password@connect_identifier) is
794 "system/oracle" but this can be overridden with the ORACLE_LOGON
795 environment variable. The implementation has been tested with Oracle
796 Express Edition 11g Release 2. Note that any SQL*Plus connection
797 warnings (user password expiration, etc) will interfere with the
798 ability of the wrapper script to communicate with the DB.
802 ./wrap.sh stepX_YYY.sql
804 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
807 ### Postscript Level 2/3
809 The Postscript implementation of mal requires ghostscript to run. It
810 has been tested with ghostscript 9.10.
814 gs -q -dNODISPLAY -I./ stepX_YYY.ps
819 The PowerShell implementation of mal requires the PowerShell script
820 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
824 powershell ./stepX_YYY.ps1
827 ### Python (2.X and 3.X)
836 You must have [rpython](https://rpython.readthedocs.org/) on your path
837 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
841 make # this takes a very long time
847 The R implementation of mal requires R (r-base-core) to run.
851 make libs # to download and build rdyncall
857 The Racket implementation of mal requires the Racket
858 compiler/interpreter to run.
867 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
872 rexx -a ./stepX_YYY.rexxpp
882 ### Rust (1.0.0 nightly)
884 The rust implementation of mal requires the rust compiler and build
885 tool (cargo) to build.
889 cargo run --release --bin stepX_YYY
894 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
898 sbt 'run-main stepX_YYY'
901 scala -classpath target/scala*/classes stepX_YYY
904 ### Scheme (R7RS) ###
906 The Scheme implementation of mal has been tested with Chibi-Scheme
907 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
908 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
909 be able to get it running on other conforming R7RS implementations
910 after figuring out how libraries are loaded and adjusting the
911 `Makefile` and `run` script accordingly.
917 scheme_MODE=chibi ./run
920 scheme_MODE=kawa ./run
922 scheme_MODE=gauche ./run
925 scheme_MODE=chicken ./run
927 scheme_MODE=sagittarius ./run
930 scheme_MODE=cyclone ./run
932 scheme_MODE=foment ./run
937 The Skew implementation of mal has been tested with Skew 0.7.42.
948 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
949 7.0) to build. Older versions will not work due to changes in the
950 language and standard library.
960 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
961 has been tested with Swift 3 Preview 3.
971 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
972 has been tested with Swift 4.2.3 release.
982 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
983 editing support, install tclreadline.
987 tclsh ./stepX_YYY.tcl
992 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
993 It has been tested with Node.js v6.
1003 The Vala implementation of mal has been tested with the Vala 0.40.8
1004 compiler. You will need to install `valac` and `libreadline-dev` or
1015 The VHDL implementation of mal has been tested with GHDL 0.29.
1020 ./run_vhdl.sh ./stepX_YYY
1025 The Vimscript implementation of mal requires Vim 8.0 to run.
1029 ./run_vimscript.sh ./stepX_YYY.vim
1032 ### Visual Basic.NET ###
1034 The VB.NET implementation of mal has been tested on Linux using the Mono
1035 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1036 required to build and run the VB.NET implementation.
1041 mono ./stepX_YYY.exe
1044 ### WebAssembly (wasm) ###
1046 The WebAssembly implementation is written in
1047 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1048 runs under several different non-web embeddings (runtimes):
1050 [wasmtime](https://github.com/CraneStation/wasmtime),
1051 [wax](https://github.com/kanaka/wac),
1052 [wace](https://github.com/kanaka/wac),
1053 [warpy](https://github.com/kanaka/warpy).
1059 ./run.js ./stepX_YYY.wasm
1061 make wasm_MODE=wasmtime
1062 wasmtime --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1065 wace ./stepX_YYY.wasm
1067 make wasm_MODE=wace_libc
1068 wace ./stepX_YYY.wasm
1070 make wasm_MODE=warpy
1071 warpy --argv --memory-pages 256 ./stepX_YYY.wasm
1076 The Yorick implementation of mal was tested on Yorick 2.2.04.
1080 yorick -batch ./stepX_YYY.i
1087 The top level Makefile has a number of useful targets to assist with
1088 implementation development and testing. The `help` target provides
1089 a list of the targets and options:
1095 ### Functional tests
1097 The are over 600 generic functional tests (for all implementations)
1098 in the `tests/` directory. Each step has a corresponding test file
1099 containing tests specific to that step. The `runtest.py` test harness
1100 launches a Mal step implementation and then feeds the tests one at
1101 a time to the implementation and compares the output/return value to
1102 the expected output/return value.
1104 * To run all the tests across all implementations (be prepared to wait):
1110 * To run all tests against a single implementation:
1120 * To run tests for a single step against all implementations:
1130 * To run tests for a specific step against a single implementation:
1133 make "test^IMPL^stepX"
1136 make "test^ruby^step3"
1137 make "test^ps^step4"
1140 ### Self-hosted functional tests
1142 * To run the functional tests in self-hosted mode, you specify `mal`
1143 as the test implementation and use the `MAL_IMPL` make variable
1144 to change the underlying host language (default is JavaScript):
1146 make MAL_IMPL=IMPL "test^mal^step2"
1149 make "test^mal^step2" # js is default
1150 make MAL_IMPL=ruby "test^mal^step2"
1151 make MAL_IMPL=python "test^mal^step2"
1154 ### Starting the REPL
1156 * To start the REPL of an implementation in a specific step:
1159 make "repl^IMPL^stepX"
1162 make "repl^ruby^step3"
1163 make "repl^ps^step4"
1166 * If you omit the step, then `stepA` is used:
1176 * To start the REPL of the self-hosted implementation, specify `mal` as the
1177 REPL implementation and use the `MAL_IMPL` make variable to change the
1178 underlying host language (default is JavaScript):
1180 make MAL_IMPL=IMPL "repl^mal^stepX"
1183 make "repl^mal^step2" # js is default
1184 make MAL_IMPL=ruby "repl^mal^step2"
1185 make MAL_IMPL=python "repl^mal"
1188 ### Performance tests
1190 Warning: These performance tests are neither statistically valid nor
1191 comprehensive; runtime performance is a not a primary goal of mal. If
1192 you draw any serious conclusions from these performance tests, then
1193 please contact me about some amazing oceanfront property in Kansas
1194 that I'm willing to sell you for cheap.
1196 * To run performance tests against a single implementation:
1204 * To run performance tests against all implementations:
1209 ### Generating language statistics
1211 * To report line and byte statistics for a single implementation:
1219 ## Dockerized testing
1221 Every implementation directory contains a Dockerfile to create
1222 a docker image containing all the dependencies for that
1223 implementation. In addition, the top-level Makefile contains support
1224 for running the tests target (and perf, stats, repl, etc) within
1225 a docker container for that implementation by passing *"DOCKERIZE=1"*
1226 on the make command line. For example:
1229 make DOCKERIZE=1 "test^js^step3"
1232 Existing implementations already have docker images built and pushed
1233 to the docker registry. However, if
1234 you wish to build or rebuild a docker image locally, the toplevel
1235 Makefile provides a rule for building docker images:
1238 make "docker-build^IMPL"
1243 * Docker images are named *"kanaka/mal-test-IMPL"*
1244 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1245 you will probably need to run this command once manually
1246 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1247 runtime dependencies need to be downloaded to avoid the tests timing
1248 out. These dependencies are downloaded to dot-files in the /mal
1249 directory so they will persist between runs.
1254 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1255 License 2.0). See LICENSE.txt for more details.