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 78 languages (80 different implementations and 101 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 | [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
95 **3. Mal is a learning tool**
97 Each implementation of mal is separated into
98 11 incremental, self-contained (and testable) steps that demonstrate
99 core concepts of Lisp. The last step is capable of self-hosting
100 (running the mal implementation of mal). See the [make-a-lisp process
101 guide](process/guide.md).
103 The make-a-lisp steps are:
105 * [step0_repl](process/guide.md#step0)
106 * [step1_read_print](process/guide.md#step1)
107 * [step2_eval](process/guide.md#step2)
108 * [step3_env](process/guide.md#step3)
109 * [step4_if_fn_do](process/guide.md#step4)
110 * [step5_tco](process/guide.md#step5)
111 * [step6_file](process/guide.md#step6)
112 * [step7_quote](process/guide.md#step7)
113 * [step8_macros](process/guide.md#step8)
114 * [step9_try](process/guide.md#step9)
115 * [stepA_mal](process/guide.md#stepA)
117 Each make-a-lisp step has an associated architectural diagram. That elements
118 that are new for that step are highlighted in red.
119 Here is the final diagram for [step A](process/guide.md#stepA):
121 ![stepA_mal architecture](process/stepA_mal.png)
123 If you are interested in creating a mal implementation (or just
124 interested in using mal for something), please drop by the #mal
125 channel on freenode. In addition to the [make-a-lisp process
126 guide](process/guide.md) there is also a [mal/make-a-lisp
127 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
132 Mal was presented publicly for the first time in a lightning talk at
133 Clojure West 2014 (unfortunately there is no video). See
134 examples/clojurewest2014.mal for the presentation that was given at the
135 conference (yes, the presentation is a mal program).
137 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
138 "Achievement Unlocked: A Better Path to Language Learning".
139 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
140 [Slides](http://kanaka.github.io/midwest.io.mal/).
142 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
143 in 10 Incremental Steps" at LambdaConf 2016:
144 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
145 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
146 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
147 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
148 [Slides](http://kanaka.github.io/lambdaconf/).
150 ## Building/running implementations
152 The simplest way to run any given implementation is to use docker.
153 Every implementation has a docker image pre-built with language
154 dependencies installed. You can launch the REPL using a convenient
155 target in the top level Makefile (where IMPL is the implementation
156 directory name and stepX is the step to run):
159 make DOCKERIZE=1 "repl^IMPL^stepX"
160 # OR stepA is the default step:
161 make DOCKERIZE=1 "repl^IMPL"
164 ## External Implementations
166 The following implementations are maintained as separate projects:
170 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
174 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
175 * [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).
178 ## Other mal Projects
180 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
181 * [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.
182 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
185 ## Implementation Details
189 The Ada implementation was developed with GNAT 4.9 on debian. It also
190 compiles unchanged on windows if you have windows versions of git,
191 GNAT and (optionally) make. There are no external dependencies
192 (readline not implemented).
202 The second Ada implementation was developed with GNAT 8 and links with
203 the GNU readline library.
213 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
217 gawk -O -f stepX_YYY.awk
227 ### BASIC (C64 and QBasic)
229 The BASIC implementation uses a preprocessor that can generate BASIC
230 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
231 C64 mode has been tested with
232 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
233 currently required to fix issues with line input) and the QBasic mode
234 has been tested with [qb64](http://www.qb64.net/).
236 Generate C64 code and run it using cbmbasic:
244 Generate QBasic code and load it into qb64:
248 make MODE=qbasic stepX_YYY.bas
252 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
253 inspiration for this implementation.
257 The BBC BASIC V implementation can run in the Brandy interpreter:
261 brandy -quit stepX_YYY.bbc
264 Or in ARM BBC BASIC V under RISC OS 3 or later:
267 *Dir bbc-basic.riscos
274 The C implementation of mal requires the following libraries (lib and
275 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
286 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
287 a readline compatible library to build. See the `cpp/README.md` for
301 The C# implementation of mal has been tested on Linux using the Mono
302 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
303 required to build and run the C# implementation.
313 The ChucK implementation has been tested with ChucK 1.3.5.2.
322 For the most part the Clojure implementation requires Clojure 1.5,
323 however, to pass all tests, Clojure 1.8.0-RC4 is required.
327 lein with-profile +stepX trampoline run
333 sudo npm install -g coffee-script
340 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
341 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
342 the [README](common-lisp/README.org) for more details. Provided you have the
343 dependencies mentioned installed, do the following to run the implementation
353 The Crystal implementation of mal has been tested with Crystal 0.26.1.
357 crystal run ./stepX_YYY.cr
359 make # needed to run tests
365 The D implementation of mal was tested with GDC 4.8. It requires the GNU
376 The Dart implementation has been tested with Dart 1.20.
385 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
386 and 24.5. While there is very basic readline editing (`<backspace>`
387 and `C-d` work, `C-c` cancels the process), it is recommended to use
392 emacs -Q --batch --load stepX_YYY.el
393 # with full readline support
394 rlwrap emacs -Q --batch --load stepX_YYY.el
399 The Elixir implementation of mal has been tested with Elixir 1.0.5.
404 # Or with readline/line editing functionality:
410 The Elm implementation of mal has been tested with Elm 0.18.0
420 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
421 and [rebar](https://github.com/rebar/rebar) to build.
427 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
431 ### ES6 (ECMAScript 2015)
433 The ES6 / ECMAScript 2015 implementation uses the
434 [babel](https://babeljs.io) compiler to generate ES5 compatible
435 JavaScript. The generated code has been tested with Node 0.12.4.
440 node build/stepX_YYY.js
446 The F# implementation of mal has been tested on Linux using the Mono
447 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
448 compiler (mcs) is also necessary to compile the readline dependency. All are
449 required to build and run the F# implementation.
459 The Factor implementation of mal has been tested with Factor 0.97
460 ([factorcode.org](http://factorcode.org)).
464 FACTOR_ROOTS=. factor -run=stepX_YYY
469 The Fantom implementation of mal has been tested with Fantom 1.0.70.
473 make lib/fan/stepX_YYY.pod
488 guile -L ./ stepX_YYY.scm
493 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
502 The Go implementation of mal requires that go is installed on on the
503 path. The implementation has been tested with Go 1.3.1.
514 The Groovy implementation of mal requires Groovy to run and has been
515 tested with Groovy 1.8.6.
520 groovy ./stepX_YYY.groovy
525 The Haskell implementation requires the ghc compiler version 7.10.1 or
526 later and also the Haskell parsec and readline (or editline) packages.
534 ### Haxe (Neko, Python, C++ and JavaScript)
536 The Haxe implementation of mal requires Haxe version 3.2 to compile.
537 Four different Haxe targets are supported: Neko, Python, C++, and
547 python3 ./stepX_YYY.py
558 The Hy implementation of mal has been tested with Hy 0.13.0.
567 The Io implementation of mal has been tested with Io version 20110905.
576 The Java implementation of mal requires maven2 to build.
581 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
583 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
596 The Julia implementation of mal requires Julia 0.4.
605 The Kotlin implementation of mal has been tested with Kotlin 1.0.
610 java -jar stepX_YYY.jar
615 The LiveScript implementation of mal has been tested with LiveScript 1.5.
620 node_modules/.bin/lsc stepX_YYY.ls
625 The Logo implementation of mal has been tested with UCBLogo 6.0.
634 The Lua implementation of mal has been tested with Lua 5.2. The
635 implementation requires that luarocks and the lua-rex-pcre library
640 make # to build and link linenoise.so
646 Running the mal implementation of mal involves running stepA of one of
647 the other implementations and passing the mal step to run as a command
652 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
665 The NASM implementation of mal is written for x86-64 Linux, and has been tested
666 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
676 The Nim implementation of mal has been tested with Nim 0.17.0.
688 The Object Pascal implementation of mal has been built and tested on
689 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
699 The Objective C implementation of mal has been built and tested on
700 Linux using clang/LLVM 3.6. It has also been built and tested on OS
717 ### MATLAB (GNU Octave and MATLAB)
719 The MatLab implementation has been tested with GNU Octave 4.2.1.
720 It has also been tested with MATLAB version R2014a on Linux. Note that
721 MATLAB is a commercial product.
726 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
727 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
728 # OR with command line arguments
729 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
730 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
735 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
736 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
737 implementation of mal you need to download/install the miniMAL
738 interpreter (which requires Node.js).
741 # Download miniMAL and dependencies
743 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
744 # Now run mal implementation in miniMAL
750 The Perl 5 implementation should work with perl 5.19.3 and later.
752 For readline line editing support, install Term::ReadLine::Perl or
753 Term::ReadLine::Gnu from CPAN.
762 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
771 The PHP implementation of mal requires the php command line interface
781 The Picolisp implementation requires libreadline and Picolisp 3.1.11
791 The Pike implementation was tested on Pike 8.0.
798 ### PL/pgSQL (PostgreSQL SQL Procedural Language)
800 The PL/pgSQL implementation of mal requires a running PostgreSQL server
801 (the "kanaka/mal-test-plpgsql" docker image automatically starts
802 a PostgreSQL server). The implementation connects to the PostgreSQL server
803 and create a database named "mal" to store tables and stored
804 procedures. The wrapper script uses the psql command to connect to the
805 server and defaults to the user "postgres" but this can be overridden
806 with the PSQL_USER environment variable. A password can be specified
807 using the PGPASSWORD environment variable. The implementation has been
808 tested with PostgreSQL 9.4.
812 ./wrap.sh stepX_YYY.sql
814 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
817 ### PL/SQL (Oracle SQL Procedural Language)
819 The PL/SQL implementation of mal requires a running Oracle DB
820 server (the "kanaka/mal-test-plsql" docker image automatically
821 starts an Oracle Express server). The implementation connects to the
822 Oracle server to create types, tables and stored procedures. The
823 default SQL\*Plus logon value (username/password@connect_identifier) is
824 "system/oracle" but this can be overridden with the ORACLE_LOGON
825 environment variable. The implementation has been tested with Oracle
826 Express Edition 11g Release 2. Note that any SQL\*Plus connection
827 warnings (user password expiration, etc) will interfere with the
828 ability of the wrapper script to communicate with the DB.
832 ./wrap.sh stepX_YYY.sql
834 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
837 ### PostScript Level 2/3
839 The PostScript implementation of mal requires Ghostscript to run. It
840 has been tested with Ghostscript 9.10.
844 gs -q -dNODISPLAY -I./ stepX_YYY.ps
849 The PowerShell implementation of mal requires the PowerShell script
850 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
854 powershell ./stepX_YYY.ps1
857 ### Python (2.X and 3.X)
866 The second Python implementation makes heavy use of type annotations and uses the Arpeggio parser library.
869 # Recommended: do these steps in a Python virtual environment.
870 pip3 install Arpeggio==1.9.0
876 You must have [rpython](https://rpython.readthedocs.org/) on your path
877 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
881 make # this takes a very long time
887 The R implementation of mal requires R (r-base-core) to run.
891 make libs # to download and build rdyncall
897 The Racket implementation of mal requires the Racket
898 compiler/interpreter to run.
907 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
912 rexx -a ./stepX_YYY.rexxpp
922 ### Rust (1.0.0 nightly)
924 The rust implementation of mal requires the rust compiler and build
925 tool (cargo) to build.
929 cargo run --release --bin stepX_YYY
934 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
938 sbt 'run-main stepX_YYY'
941 scala -classpath target/scala*/classes stepX_YYY
944 ### Scheme (R7RS) ###
946 The Scheme implementation of mal has been tested with Chibi-Scheme
947 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
948 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
949 be able to get it running on other conforming R7RS implementations
950 after figuring out how libraries are loaded and adjusting the
951 `Makefile` and `run` script accordingly.
957 scheme_MODE=chibi ./run
960 scheme_MODE=kawa ./run
962 scheme_MODE=gauche ./run
965 scheme_MODE=chicken ./run
967 scheme_MODE=sagittarius ./run
970 scheme_MODE=cyclone ./run
972 scheme_MODE=foment ./run
977 The Skew implementation of mal has been tested with Skew 0.7.42.
988 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
989 7.0) to build. Older versions will not work due to changes in the
990 language and standard library.
1000 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
1001 has been tested with Swift 3 Preview 3.
1011 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
1012 has been tested with Swift 4.2.3 release.
1022 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
1023 editing support, install tclreadline.
1027 tclsh ./stepX_YYY.tcl
1032 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
1033 It has been tested with Node.js v6.
1043 The Vala implementation of mal has been tested with the Vala 0.40.8
1044 compiler. You will need to install `valac` and `libreadline-dev` or
1055 The VHDL implementation of mal has been tested with GHDL 0.29.
1060 ./run_vhdl.sh ./stepX_YYY
1065 The Vimscript implementation of mal requires Vim 8.0 to run.
1069 ./run_vimscript.sh ./stepX_YYY.vim
1072 ### Visual Basic.NET ###
1074 The VB.NET implementation of mal has been tested on Linux using the Mono
1075 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1076 required to build and run the VB.NET implementation.
1081 mono ./stepX_YYY.exe
1084 ### WebAssembly (wasm) ###
1086 The WebAssembly implementation is written in
1087 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1088 runs under several different non-web embeddings (runtimes):
1089 [node](https://nodejs.org),
1090 [wasmtime](https://github.com/CraneStation/wasmtime),
1091 [wasmer](https://wasmer.io),
1092 [lucet](https://github.com/fastly/lucet),
1093 [wax](https://github.com/kanaka/wac),
1094 [wace](https://github.com/kanaka/wac),
1095 [warpy](https://github.com/kanaka/warpy).
1101 ./run.js ./stepX_YYY.wasm
1103 make wasm_MODE=wasmtime
1104 wasmtime --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1106 make wasm_MODE=wasmer
1107 wasmer run --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1109 make wasm_MODE=lucet
1110 lucet-wasi --dir=./:./ --dir=../:../ --dir=/:/ ./stepX_YYY.so
1113 wax ./stepX_YYY.wasm
1115 make wasm_MODE=wace_libc
1116 wace ./stepX_YYY.wasm
1118 make wasm_MODE=warpy
1119 warpy --argv --memory-pages 256 ./stepX_YYY.wasm
1124 The Yorick implementation of mal was tested on Yorick 2.2.04.
1128 yorick -batch ./stepX_YYY.i
1135 The top level Makefile has a number of useful targets to assist with
1136 implementation development and testing. The `help` target provides
1137 a list of the targets and options:
1143 ### Functional tests
1145 The are almost 800 generic functional tests (for all implementations)
1146 in the `tests/` directory. Each step has a corresponding test file
1147 containing tests specific to that step. The `runtest.py` test harness
1148 launches a Mal step implementation and then feeds the tests one at
1149 a time to the implementation and compares the output/return value to
1150 the expected output/return value.
1152 * To run all the tests across all implementations (be prepared to wait):
1158 * To run all tests against a single implementation:
1168 * To run tests for a single step against all implementations:
1178 * To run tests for a specific step against a single implementation:
1181 make "test^IMPL^stepX"
1184 make "test^ruby^step3"
1185 make "test^ps^step4"
1188 ### Self-hosted functional tests
1190 * To run the functional tests in self-hosted mode, you specify `mal`
1191 as the test implementation and use the `MAL_IMPL` make variable
1192 to change the underlying host language (default is JavaScript):
1194 make MAL_IMPL=IMPL "test^mal^step2"
1197 make "test^mal^step2" # js is default
1198 make MAL_IMPL=ruby "test^mal^step2"
1199 make MAL_IMPL=python "test^mal^step2"
1202 ### Starting the REPL
1204 * To start the REPL of an implementation in a specific step:
1207 make "repl^IMPL^stepX"
1210 make "repl^ruby^step3"
1211 make "repl^ps^step4"
1214 * If you omit the step, then `stepA` is used:
1224 * To start the REPL of the self-hosted implementation, specify `mal` as the
1225 REPL implementation and use the `MAL_IMPL` make variable to change the
1226 underlying host language (default is JavaScript):
1228 make MAL_IMPL=IMPL "repl^mal^stepX"
1231 make "repl^mal^step2" # js is default
1232 make MAL_IMPL=ruby "repl^mal^step2"
1233 make MAL_IMPL=python "repl^mal"
1236 ### Performance tests
1238 Warning: These performance tests are neither statistically valid nor
1239 comprehensive; runtime performance is a not a primary goal of mal. If
1240 you draw any serious conclusions from these performance tests, then
1241 please contact me about some amazing oceanfront property in Kansas
1242 that I'm willing to sell you for cheap.
1244 * To run performance tests against a single implementation:
1252 * To run performance tests against all implementations:
1257 ### Generating language statistics
1259 * To report line and byte statistics for a single implementation:
1267 ## Dockerized testing
1269 Every implementation directory contains a Dockerfile to create
1270 a docker image containing all the dependencies for that
1271 implementation. In addition, the top-level Makefile contains support
1272 for running the tests target (and perf, stats, repl, etc) within
1273 a docker container for that implementation by passing *"DOCKERIZE=1"*
1274 on the make command line. For example:
1277 make DOCKERIZE=1 "test^js^step3"
1280 Existing implementations already have docker images built and pushed
1281 to the docker registry. However, if
1282 you wish to build or rebuild a docker image locally, the toplevel
1283 Makefile provides a rule for building docker images:
1286 make "docker-build^IMPL"
1291 * Docker images are named *"kanaka/mal-test-IMPL"*
1292 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1293 you will probably need to run this command once manually
1294 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1295 runtime dependencies need to be downloaded to avoid the tests timing
1296 out. These dependencies are downloaded to dot-files in the /mal
1297 directory so they will persist between runs.
1302 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1303 License 2.0). See LICENSE.txt for more details.