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 79 languages (81 different implementations and 102 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 | [BBC BASIC V](#bbc-basic-v) | [Ben Harris](https://github.com/bjh21) |
19 | [C](#c) | [Joel Martin](https://github.com/kanaka) |
20 | [C++](#c-1) | [Stephen Thirlwall](https://github.com/sdt) |
21 | [C#](#c-2) | [Joel Martin](https://github.com/kanaka) |
22 | [ChucK](#chuck) | [Vasilij Schneidermann](https://github.com/wasamasa) |
23 | [Clojure](#clojure) (Clojure & ClojureScript) | [Joel Martin](https://github.com/kanaka) |
24 | [CoffeeScript](#coffeescript) | [Joel Martin](https://github.com/kanaka) |
25 | [Common Lisp](#common-lisp) | [Iqbal Ansari](https://github.com/iqbalansari) |
26 | [Crystal](#crystal) | [Linda_pp](https://github.com/rhysd) |
27 | [D](#d) | [Dov Murik](https://github.com/dubek) |
28 | [Dart](#dart) | [Harry Terkelsen](https://github.com/hterkelsen) |
29 | [Elixir](#elixir) | [Martin Ek](https://github.com/ekmartin) |
30 | [Elm](#elm) | [Jos van Bakel](https://github.com/c0deaddict) |
31 | [Emacs Lisp](#emacs-lisp) | [Vasilij Schneidermann](https://github.com/wasamasa) |
32 | [Erlang](#erlang) | [Nathan Fiedler](https://github.com/nlfiedler) |
33 | [ES6](#es6-ecmascript-2015) (ECMAScript 2015) | [Joel Martin](https://github.com/kanaka) |
34 | [F#](#f) | [Peter Stephens](https://github.com/pstephens) |
35 | [Factor](#factor) | [Jordan Lewis](https://github.com/jordanlewis) |
36 | [Fantom](#fantom) | [Dov Murik](https://github.com/dubek) |
37 | [Forth](#forth) | [Chris Houser](https://github.com/chouser) |
38 | [GNU Guile](#gnu-guile-21) | [Mu Lei](https://github.com/NalaGinrut) |
39 | [GNU Smalltalk](#gnu-smalltalk) | [Vasilij Schneidermann](https://github.com/wasamasa) |
40 | [Go](#go) | [Joel Martin](https://github.com/kanaka) |
41 | [Groovy](#groovy) | [Joel Martin](https://github.com/kanaka) |
42 | [Haskell](#haskell) | [Joel Martin](https://github.com/kanaka) |
43 | [Haxe](#haxe-neko-python-c-and-javascript) (Neko, Python, C++, & JS) | [Joel Martin](https://github.com/kanaka) |
44 | [Hy](#hy) | [Joel Martin](https://github.com/kanaka) |
45 | [Io](#io) | [Dov Murik](https://github.com/dubek) |
46 | [Java](#java-17) | [Joel Martin](https://github.com/kanaka) |
47 | [JavaScript](#javascriptnode) ([Demo](http://kanaka.github.io/mal)) | [Joel Martin](https://github.com/kanaka) |
48 | [Julia](#julia) | [Joel Martin](https://github.com/kanaka) |
49 | [Kotlin](#kotlin) | [Javier Fernandez-Ivern](https://github.com/ivern) |
50 | [LiveScript](#livescript) | [Jos van Bakel](https://github.com/c0deaddict) |
51 | [Logo](#logo) | [Dov Murik](https://github.com/dubek) |
52 | [Lua](#lua) | [Joel Martin](https://github.com/kanaka) |
53 | [GNU Make](#gnu-make-381) | [Joel Martin](https://github.com/kanaka) |
54 | [mal itself](#mal) | [Joel Martin](https://github.com/kanaka) |
55 | [MATLAB](#matlab-gnu-octave-and-matlab) (GNU Octave & MATLAB) | [Joel Martin](https://github.com/kanaka) |
56 | [miniMAL](#minimal) ([Repo](https://github.com/kanaka/miniMAL), [Demo](https://kanaka.github.io/miniMAL/)) | [Joel Martin](https://github.com/kanaka) |
57 | [NASM](#nasm) | [Ben Dudson](https://github.com/bendudson) |
58 | [Nim](#nim-0170) | [Dennis Felsing](https://github.com/def-) |
59 | [Object Pascal](#object-pascal) | [Joel Martin](https://github.com/kanaka) |
60 | [Objective C](#objective-c) | [Joel Martin](https://github.com/kanaka) |
61 | [OCaml](#ocaml-4010) | [Chris Houser](https://github.com/chouser) |
62 | [Perl](#perl-5) | [Joel Martin](https://github.com/kanaka) |
63 | [Perl 6](#perl-6) | [Hinrik Örn Sigurðsson](https://github.com/hinrik) |
64 | [PHP](#php-53) | [Joel Martin](https://github.com/kanaka) |
65 | [Picolisp](#picolisp) | [Vasilij Schneidermann](https://github.com/wasamasa) |
66 | [Pike](#pike) | [Dov Murik](https://github.com/dubek) |
67 | [PL/pgSQL](#plpgsql-postgresql-sql-procedural-language) (PostgreSQL) | [Joel Martin](https://github.com/kanaka) |
68 | [PL/SQL](#plsql-oracle-sql-procedural-language) (Oracle) | [Joel Martin](https://github.com/kanaka) |
69 | [PostScript](#postscript-level-23) | [Joel Martin](https://github.com/kanaka) |
70 | [PowerShell](#powershell) | [Joel Martin](https://github.com/kanaka) |
71 | [Python](#python-2x-and-3x) (2.X & 3.X) | [Joel Martin](https://github.com/kanaka) |
72 | [Python #2](#python2-3x) (3.X) | [Gavin Lewis](https://github.com/epylar) |
73 | [RPython](#rpython) | [Joel Martin](https://github.com/kanaka) |
74 | [R](#r) | [Joel Martin](https://github.com/kanaka) |
75 | [Racket](#racket-53) | [Joel Martin](https://github.com/kanaka) |
76 | [Rexx](#rexx) | [Dov Murik](https://github.com/dubek) |
77 | [Ruby](#ruby-19) | [Joel Martin](https://github.com/kanaka) |
78 | [Rust](#rust-100-nightly) | [Joel Martin](https://github.com/kanaka) |
79 | [Scala](#scala) | [Joel Martin](https://github.com/kanaka) |
80 | [Scheme (R7RS)](#scheme-r7rs) | [Vasilij Schneidermann](https://github.com/wasamasa) |
81 | [Skew](#skew) | [Dov Murik](https://github.com/dubek) |
82 | [Swift 2](#swift) | [Keith Rollin](https://github.com/keith-rollin) |
83 | [Swift 3](#swift-3) | [Joel Martin](https://github.com/kanaka) |
84 | [Swift 4](#swift-4) | [陆遥](https://github.com/LispLY) |
85 | [Tcl](#tcl-86) | [Dov Murik](https://github.com/dubek) |
86 | [TypeScript](#typescript) | [Masahiro Wakame](https://github.com/vvakame) |
87 | [Vala](#vala) | [Simon Tatham](https://github.com/sgtatham) |
88 | [VHDL](#vhdl) | [Dov Murik](https://github.com/dubek) |
89 | [Vimscript](#vimscript) | [Dov Murik](https://github.com/dubek) |
90 | [Visual Basic.NET](#visual-basicnet) | [Joel Martin](https://github.com/kanaka) |
91 | [WebAssembly](#webassembly-wasm) (wasm) | [Joel Martin](https://github.com/kanaka) |
92 | [Wren](#wren) | [Dov Murik](https://github.com/dubek) |
93 | [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
96 **3. Mal is a learning tool**
98 Each implementation of mal is separated into
99 11 incremental, self-contained (and testable) steps that demonstrate
100 core concepts of Lisp. The last step is capable of self-hosting
101 (running the mal implementation of mal). See the [make-a-lisp process
102 guide](process/guide.md).
104 The make-a-lisp steps are:
106 * [step0_repl](process/guide.md#step0)
107 * [step1_read_print](process/guide.md#step1)
108 * [step2_eval](process/guide.md#step2)
109 * [step3_env](process/guide.md#step3)
110 * [step4_if_fn_do](process/guide.md#step4)
111 * [step5_tco](process/guide.md#step5)
112 * [step6_file](process/guide.md#step6)
113 * [step7_quote](process/guide.md#step7)
114 * [step8_macros](process/guide.md#step8)
115 * [step9_try](process/guide.md#step9)
116 * [stepA_mal](process/guide.md#stepA)
118 Each make-a-lisp step has an associated architectural diagram. That elements
119 that are new for that step are highlighted in red.
120 Here is the final diagram for [step A](process/guide.md#stepA):
122 ![stepA_mal architecture](process/stepA_mal.png)
124 If you are interested in creating a mal implementation (or just
125 interested in using mal for something), please drop by the #mal
126 channel on freenode. In addition to the [make-a-lisp process
127 guide](process/guide.md) there is also a [mal/make-a-lisp
128 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
133 Mal was presented publicly for the first time in a lightning talk at
134 Clojure West 2014 (unfortunately there is no video). See
135 examples/clojurewest2014.mal for the presentation that was given at the
136 conference (yes, the presentation is a mal program).
138 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
139 "Achievement Unlocked: A Better Path to Language Learning".
140 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
141 [Slides](http://kanaka.github.io/midwest.io.mal/).
143 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
144 in 10 Incremental Steps" at LambdaConf 2016:
145 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
146 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
147 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
148 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
149 [Slides](http://kanaka.github.io/lambdaconf/).
151 ## Building/running implementations
153 The simplest way to run any given implementation is to use docker.
154 Every implementation has a docker image pre-built with language
155 dependencies installed. You can launch the REPL using a convenient
156 target in the top level Makefile (where IMPL is the implementation
157 directory name and stepX is the step to run):
160 make DOCKERIZE=1 "repl^IMPL^stepX"
161 # OR stepA is the default step:
162 make DOCKERIZE=1 "repl^IMPL"
165 ## External Implementations
167 The following implementations are maintained as separate projects:
171 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
175 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
176 * [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).
179 ## Other mal Projects
181 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
182 * [malcc](https://github.com/seven1m/malcc) - 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.
183 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
186 ## Implementation Details
190 The Ada implementation was developed with GNAT 4.9 on debian. It also
191 compiles unchanged on windows if you have windows versions of git,
192 GNAT and (optionally) make. There are no external dependencies
193 (readline not implemented).
203 The second Ada implementation was developed with GNAT 8 and links with
204 the GNU readline library.
214 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
218 gawk -O -f stepX_YYY.awk
228 ### BASIC (C64 and QBasic)
230 The BASIC implementation uses a preprocessor that can generate BASIC
231 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
232 C64 mode has been tested with
233 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
234 currently required to fix issues with line input) and the QBasic mode
235 has been tested with [qb64](http://www.qb64.net/).
237 Generate C64 code and run it using cbmbasic:
245 Generate QBasic code and load it into qb64:
249 make MODE=qbasic stepX_YYY.bas
253 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
254 inspiration for this implementation.
258 The BBC BASIC V implementation can run in the Brandy interpreter:
262 brandy -quit stepX_YYY.bbc
265 Or in ARM BBC BASIC V under RISC OS 3 or later:
268 *Dir bbc-basic.riscos
275 The C implementation of mal requires the following libraries (lib and
276 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
287 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
288 a readline compatible library to build. See the `cpp/README.md` for
302 The C# implementation of mal has been tested on Linux using the Mono
303 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
304 required to build and run the C# implementation.
314 The ChucK implementation has been tested with ChucK 1.3.5.2.
323 For the most part the Clojure implementation requires Clojure 1.5,
324 however, to pass all tests, Clojure 1.8.0-RC4 is required.
328 lein with-profile +stepX trampoline run
334 sudo npm install -g coffee-script
341 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
342 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
343 the [README](common-lisp/README.org) for more details. Provided you have the
344 dependencies mentioned installed, do the following to run the implementation
354 The Crystal implementation of mal has been tested with Crystal 0.26.1.
358 crystal run ./stepX_YYY.cr
360 make # needed to run tests
366 The D implementation of mal was tested with GDC 4.8. It requires the GNU
377 The Dart implementation has been tested with Dart 1.20.
386 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
387 and 24.5. While there is very basic readline editing (`<backspace>`
388 and `C-d` work, `C-c` cancels the process), it is recommended to use
393 emacs -Q --batch --load stepX_YYY.el
394 # with full readline support
395 rlwrap emacs -Q --batch --load stepX_YYY.el
400 The Elixir implementation of mal has been tested with Elixir 1.0.5.
405 # Or with readline/line editing functionality:
411 The Elm implementation of mal has been tested with Elm 0.18.0
421 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
422 and [rebar](https://github.com/rebar/rebar) to build.
428 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
432 ### ES6 (ECMAScript 2015)
434 The ES6 / ECMAScript 2015 implementation uses the
435 [babel](https://babeljs.io) compiler to generate ES5 compatible
436 JavaScript. The generated code has been tested with Node 0.12.4.
441 node build/stepX_YYY.js
447 The F# implementation of mal has been tested on Linux using the Mono
448 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
449 compiler (mcs) is also necessary to compile the readline dependency. All are
450 required to build and run the F# implementation.
460 The Factor implementation of mal has been tested with Factor 0.97
461 ([factorcode.org](http://factorcode.org)).
465 FACTOR_ROOTS=. factor -run=stepX_YYY
470 The Fantom implementation of mal has been tested with Fantom 1.0.70.
474 make lib/fan/stepX_YYY.pod
489 guile -L ./ stepX_YYY.scm
494 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
503 The Go implementation of mal requires that go is installed on on the
504 path. The implementation has been tested with Go 1.3.1.
515 The Groovy implementation of mal requires Groovy to run and has been
516 tested with Groovy 1.8.6.
521 groovy ./stepX_YYY.groovy
526 The Haskell implementation requires the ghc compiler version 7.10.1 or
527 later and also the Haskell parsec and readline (or editline) packages.
535 ### Haxe (Neko, Python, C++ and JavaScript)
537 The Haxe implementation of mal requires Haxe version 3.2 to compile.
538 Four different Haxe targets are supported: Neko, Python, C++, and
548 python3 ./stepX_YYY.py
559 The Hy implementation of mal has been tested with Hy 0.13.0.
568 The Io implementation of mal has been tested with Io version 20110905.
577 The Java implementation of mal requires maven2 to build.
582 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
584 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
597 The Julia implementation of mal requires Julia 0.4.
606 The Kotlin implementation of mal has been tested with Kotlin 1.0.
611 java -jar stepX_YYY.jar
616 The LiveScript implementation of mal has been tested with LiveScript 1.5.
621 node_modules/.bin/lsc stepX_YYY.ls
626 The Logo implementation of mal has been tested with UCBLogo 6.0.
635 The Lua implementation of mal has been tested with Lua 5.2. The
636 implementation requires that luarocks and the lua-rex-pcre library
641 make # to build and link linenoise.so
647 Running the mal implementation of mal involves running stepA of one of
648 the other implementations and passing the mal step to run as a command
653 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
666 The NASM implementation of mal is written for x86-64 Linux, and has been tested
667 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
677 The Nim implementation of mal has been tested with Nim 0.17.0.
689 The Object Pascal implementation of mal has been built and tested on
690 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
700 The Objective C implementation of mal has been built and tested on
701 Linux using clang/LLVM 3.6. It has also been built and tested on OS
718 ### MATLAB (GNU Octave and MATLAB)
720 The MatLab implementation has been tested with GNU Octave 4.2.1.
721 It has also been tested with MATLAB version R2014a on Linux. Note that
722 MATLAB is a commercial product.
727 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
728 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
729 # OR with command line arguments
730 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
731 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
736 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
737 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
738 implementation of mal you need to download/install the miniMAL
739 interpreter (which requires Node.js).
742 # Download miniMAL and dependencies
744 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
745 # Now run mal implementation in miniMAL
751 The Perl 5 implementation should work with perl 5.19.3 and later.
753 For readline line editing support, install Term::ReadLine::Perl or
754 Term::ReadLine::Gnu from CPAN.
763 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
772 The PHP implementation of mal requires the php command line interface
782 The Picolisp implementation requires libreadline and Picolisp 3.1.11
792 The Pike implementation was tested on Pike 8.0.
799 ### PL/pgSQL (PostgreSQL SQL Procedural Language)
801 The PL/pgSQL implementation of mal requires a running PostgreSQL server
802 (the "kanaka/mal-test-plpgsql" docker image automatically starts
803 a PostgreSQL server). The implementation connects to the PostgreSQL server
804 and create a database named "mal" to store tables and stored
805 procedures. The wrapper script uses the psql command to connect to the
806 server and defaults to the user "postgres" but this can be overridden
807 with the PSQL_USER environment variable. A password can be specified
808 using the PGPASSWORD environment variable. The implementation has been
809 tested with PostgreSQL 9.4.
813 ./wrap.sh stepX_YYY.sql
815 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
818 ### PL/SQL (Oracle SQL Procedural Language)
820 The PL/SQL implementation of mal requires a running Oracle DB
821 server (the "kanaka/mal-test-plsql" docker image automatically
822 starts an Oracle Express server). The implementation connects to the
823 Oracle server to create types, tables and stored procedures. The
824 default SQL\*Plus logon value (username/password@connect_identifier) is
825 "system/oracle" but this can be overridden with the ORACLE_LOGON
826 environment variable. The implementation has been tested with Oracle
827 Express Edition 11g Release 2. Note that any SQL\*Plus connection
828 warnings (user password expiration, etc) will interfere with the
829 ability of the wrapper script to communicate with the DB.
833 ./wrap.sh stepX_YYY.sql
835 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
838 ### PostScript Level 2/3
840 The PostScript implementation of mal requires Ghostscript to run. It
841 has been tested with Ghostscript 9.10.
845 gs -q -dNODISPLAY -I./ stepX_YYY.ps
850 The PowerShell implementation of mal requires the PowerShell script
851 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
855 powershell ./stepX_YYY.ps1
858 ### Python (2.X and 3.X)
867 The second Python implementation makes heavy use of type annotations and uses the Arpeggio parser library.
870 # Recommended: do these steps in a Python virtual environment.
871 pip3 install Arpeggio==1.9.0
877 You must have [rpython](https://rpython.readthedocs.org/) on your path
878 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
882 make # this takes a very long time
888 The R implementation of mal requires R (r-base-core) to run.
892 make libs # to download and build rdyncall
898 The Racket implementation of mal requires the Racket
899 compiler/interpreter to run.
908 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
913 rexx -a ./stepX_YYY.rexxpp
923 ### Rust (1.0.0 nightly)
925 The rust implementation of mal requires the rust compiler and build
926 tool (cargo) to build.
930 cargo run --release --bin stepX_YYY
935 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
939 sbt 'run-main stepX_YYY'
942 scala -classpath target/scala*/classes stepX_YYY
945 ### Scheme (R7RS) ###
947 The Scheme implementation of mal has been tested with Chibi-Scheme
948 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
949 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
950 be able to get it running on other conforming R7RS implementations
951 after figuring out how libraries are loaded and adjusting the
952 `Makefile` and `run` script accordingly.
958 scheme_MODE=chibi ./run
961 scheme_MODE=kawa ./run
963 scheme_MODE=gauche ./run
966 scheme_MODE=chicken ./run
968 scheme_MODE=sagittarius ./run
971 scheme_MODE=cyclone ./run
973 scheme_MODE=foment ./run
978 The Skew implementation of mal has been tested with Skew 0.7.42.
989 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
990 7.0) to build. Older versions will not work due to changes in the
991 language and standard library.
1001 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
1002 has been tested with Swift 3 Preview 3.
1012 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
1013 has been tested with Swift 4.2.3 release.
1023 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
1024 editing support, install tclreadline.
1028 tclsh ./stepX_YYY.tcl
1033 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
1034 It has been tested with Node.js v6.
1044 The Vala implementation of mal has been tested with the Vala 0.40.8
1045 compiler. You will need to install `valac` and `libreadline-dev` or
1056 The VHDL implementation of mal has been tested with GHDL 0.29.
1061 ./run_vhdl.sh ./stepX_YYY
1066 The Vimscript implementation of mal requires Vim 8.0 to run.
1070 ./run_vimscript.sh ./stepX_YYY.vim
1073 ### Visual Basic.NET ###
1075 The VB.NET implementation of mal has been tested on Linux using the Mono
1076 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1077 required to build and run the VB.NET implementation.
1082 mono ./stepX_YYY.exe
1085 ### WebAssembly (wasm) ###
1087 The WebAssembly implementation is written in
1088 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1089 runs under several different non-web embeddings (runtimes):
1090 [node](https://nodejs.org),
1091 [wasmtime](https://github.com/CraneStation/wasmtime),
1092 [wasmer](https://wasmer.io),
1093 [lucet](https://github.com/fastly/lucet),
1094 [wax](https://github.com/kanaka/wac),
1095 [wace](https://github.com/kanaka/wac),
1096 [warpy](https://github.com/kanaka/warpy).
1102 ./run.js ./stepX_YYY.wasm
1104 make wasm_MODE=wasmtime
1105 wasmtime --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1107 make wasm_MODE=wasmer
1108 wasmer run --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1110 make wasm_MODE=lucet
1111 lucet-wasi --dir=./:./ --dir=../:../ --dir=/:/ ./stepX_YYY.so
1114 wax ./stepX_YYY.wasm
1116 make wasm_MODE=wace_libc
1117 wace ./stepX_YYY.wasm
1119 make wasm_MODE=warpy
1120 warpy --argv --memory-pages 256 ./stepX_YYY.wasm
1125 The Wren implementation of mal was tested on Wren 0.2.0.
1129 wren ./stepX_YYY.wren
1134 The Yorick implementation of mal was tested on Yorick 2.2.04.
1138 yorick -batch ./stepX_YYY.i
1145 The top level Makefile has a number of useful targets to assist with
1146 implementation development and testing. The `help` target provides
1147 a list of the targets and options:
1153 ### Functional tests
1155 The are almost 800 generic functional tests (for all implementations)
1156 in the `tests/` directory. Each step has a corresponding test file
1157 containing tests specific to that step. The `runtest.py` test harness
1158 launches a Mal step implementation and then feeds the tests one at
1159 a time to the implementation and compares the output/return value to
1160 the expected output/return value.
1162 * To run all the tests across all implementations (be prepared to wait):
1168 * To run all tests against a single implementation:
1178 * To run tests for a single step against all implementations:
1188 * To run tests for a specific step against a single implementation:
1191 make "test^IMPL^stepX"
1194 make "test^ruby^step3"
1195 make "test^ps^step4"
1198 ### Self-hosted functional tests
1200 * To run the functional tests in self-hosted mode, you specify `mal`
1201 as the test implementation and use the `MAL_IMPL` make variable
1202 to change the underlying host language (default is JavaScript):
1204 make MAL_IMPL=IMPL "test^mal^step2"
1207 make "test^mal^step2" # js is default
1208 make MAL_IMPL=ruby "test^mal^step2"
1209 make MAL_IMPL=python "test^mal^step2"
1212 ### Starting the REPL
1214 * To start the REPL of an implementation in a specific step:
1217 make "repl^IMPL^stepX"
1220 make "repl^ruby^step3"
1221 make "repl^ps^step4"
1224 * If you omit the step, then `stepA` is used:
1234 * To start the REPL of the self-hosted implementation, specify `mal` as the
1235 REPL implementation and use the `MAL_IMPL` make variable to change the
1236 underlying host language (default is JavaScript):
1238 make MAL_IMPL=IMPL "repl^mal^stepX"
1241 make "repl^mal^step2" # js is default
1242 make MAL_IMPL=ruby "repl^mal^step2"
1243 make MAL_IMPL=python "repl^mal"
1246 ### Performance tests
1248 Warning: These performance tests are neither statistically valid nor
1249 comprehensive; runtime performance is a not a primary goal of mal. If
1250 you draw any serious conclusions from these performance tests, then
1251 please contact me about some amazing oceanfront property in Kansas
1252 that I'm willing to sell you for cheap.
1254 * To run performance tests against a single implementation:
1262 * To run performance tests against all implementations:
1267 ### Generating language statistics
1269 * To report line and byte statistics for a single implementation:
1277 ## Dockerized testing
1279 Every implementation directory contains a Dockerfile to create
1280 a docker image containing all the dependencies for that
1281 implementation. In addition, the top-level Makefile contains support
1282 for running the tests target (and perf, stats, repl, etc) within
1283 a docker container for that implementation by passing *"DOCKERIZE=1"*
1284 on the make command line. For example:
1287 make DOCKERIZE=1 "test^js^step3"
1290 Existing implementations already have docker images built and pushed
1291 to the docker registry. However, if
1292 you wish to build or rebuild a docker image locally, the toplevel
1293 Makefile provides a rule for building docker images:
1296 make "docker-build^IMPL"
1301 * Docker images are named *"kanaka/mal-test-IMPL"*
1302 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1303 you will probably need to run this command once manually
1304 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1305 runtime dependencies need to be downloaded to avoid the tests timing
1306 out. These dependencies are downloaded to dot-files in the /mal
1307 directory so they will persist between runs.
1312 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1313 License 2.0). See LICENSE.txt for more details.