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 a learning tool**
11 Each implementation of mal is separated into
12 11 incremental, self-contained (and testable) steps that demonstrate
13 core concepts of Lisp. The last step is capable of self-hosting
14 (running the mal implementation of mal). See the [make-a-lisp process
15 guide](process/guide.md).
17 The make-a-lisp steps are:
19 * [step0_repl](process/guide.md#step0)
20 * [step1_read_print](process/guide.md#step1)
21 * [step2_eval](process/guide.md#step2)
22 * [step3_env](process/guide.md#step3)
23 * [step4_if_fn_do](process/guide.md#step4)
24 * [step5_tco](process/guide.md#step5)
25 * [step6_file](process/guide.md#step6)
26 * [step7_quote](process/guide.md#step7)
27 * [step8_macros](process/guide.md#step8)
28 * [step9_try](process/guide.md#step9)
29 * [stepA_mal](process/guide.md#stepA)
31 Each make-a-lisp step has an associated architectural diagram. That elements
32 that are new for that step are highlighted in red.
33 Here is the final diagram for [step A](process/guide.md#stepA):
35 ![stepA_mal architecture](process/stepA_mal.png)
37 If you are interested in creating a mal implementation (or just
38 interested in using mal for something), please drop by the #mal
39 channel on freenode. In addition to the [make-a-lisp process
40 guide](process/guide.md) there is also a [mal/make-a-lisp
41 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
44 **3. Mal is implemented in 82 languages (85 different implementations and 105 runtime modes)**
46 | Language | Creator |
47 | -------- | ------- |
48 | [Ada](#ada) | [Chris Moore](https://github.com/zmower) |
49 | [Ada #2](#ada2) | [Nicolas Boulenguez](https://github.com/asarhaddon) |
50 | [GNU Awk](#gnu-awk) | [Miutsuru Kariya](https://github.com/kariya-mitsuru) |
51 | [Bash 4](#bash-4) | [Joel Martin](https://github.com/kanaka) |
52 | [BASIC](#basic-c64-and-qbasic) (C64 & QBasic) | [Joel Martin](https://github.com/kanaka) |
53 | [BBC BASIC V](#bbc-basic-v) | [Ben Harris](https://github.com/bjh21) |
54 | [C](#c) | [Joel Martin](https://github.com/kanaka) |
55 | [C++](#c-1) | [Stephen Thirlwall](https://github.com/sdt) |
56 | [C#](#c-2) | [Joel Martin](https://github.com/kanaka) |
57 | [ChucK](#chuck) | [Vasilij Schneidermann](https://github.com/wasamasa) |
58 | [Clojure](#clojure) (Clojure & ClojureScript) | [Joel Martin](https://github.com/kanaka) |
59 | [CoffeeScript](#coffeescript) | [Joel Martin](https://github.com/kanaka) |
60 | [Common Lisp](#common-lisp) | [Iqbal Ansari](https://github.com/iqbalansari) |
61 | [Crystal](#crystal) | [Linda_pp](https://github.com/rhysd) |
62 | [D](#d) | [Dov Murik](https://github.com/dubek) |
63 | [Dart](#dart) | [Harry Terkelsen](https://github.com/hterkelsen) |
64 | [Elixir](#elixir) | [Martin Ek](https://github.com/ekmartin) |
65 | [Elm](#elm) | [Jos van Bakel](https://github.com/c0deaddict) |
66 | [Emacs Lisp](#emacs-lisp) | [Vasilij Schneidermann](https://github.com/wasamasa) |
67 | [Erlang](#erlang) | [Nathan Fiedler](https://github.com/nlfiedler) |
68 | [ES6](#es6-ecmascript-2015) (ECMAScript 2015) | [Joel Martin](https://github.com/kanaka) |
69 | [F#](#f) | [Peter Stephens](https://github.com/pstephens) |
70 | [Factor](#factor) | [Jordan Lewis](https://github.com/jordanlewis) |
71 | [Fantom](#fantom) | [Dov Murik](https://github.com/dubek) |
72 | [Forth](#forth) | [Chris Houser](https://github.com/chouser) |
73 | [GNU Guile](#gnu-guile-21) | [Mu Lei](https://github.com/NalaGinrut) |
74 | [GNU Smalltalk](#gnu-smalltalk) | [Vasilij Schneidermann](https://github.com/wasamasa) |
75 | [Go](#go) | [Joel Martin](https://github.com/kanaka) |
76 | [Groovy](#groovy) | [Joel Martin](https://github.com/kanaka) |
77 | [Haskell](#haskell) | [Joel Martin](https://github.com/kanaka) |
78 | [Haxe](#haxe-neko-python-c-and-javascript) (Neko, Python, C++, & JS) | [Joel Martin](https://github.com/kanaka) |
79 | [Hy](#hy) | [Joel Martin](https://github.com/kanaka) |
80 | [Io](#io) | [Dov Murik](https://github.com/dubek) |
81 | [Java](#java-17) | [Joel Martin](https://github.com/kanaka) |
82 | [JavaScript](#javascriptnode) ([Demo](http://kanaka.github.io/mal)) | [Joel Martin](https://github.com/kanaka) |
83 | [jq](#jq) | [Ali MohammadPur](https://github.com/alimpfard) |
84 | [Julia](#julia) | [Joel Martin](https://github.com/kanaka) |
85 | [Kotlin](#kotlin) | [Javier Fernandez-Ivern](https://github.com/ivern) |
86 | [LiveScript](#livescript) | [Jos van Bakel](https://github.com/c0deaddict) |
87 | [Logo](#logo) | [Dov Murik](https://github.com/dubek) |
88 | [Lua](#lua) | [Joel Martin](https://github.com/kanaka) |
89 | [GNU Make](#gnu-make-381) | [Joel Martin](https://github.com/kanaka) |
90 | [mal itself](#mal) | [Joel Martin](https://github.com/kanaka) |
91 | [MATLAB](#matlab-gnu-octave-and-matlab) (GNU Octave & MATLAB) | [Joel Martin](https://github.com/kanaka) |
92 | [miniMAL](#minimal) ([Repo](https://github.com/kanaka/miniMAL), [Demo](https://kanaka.github.io/miniMAL/)) | [Joel Martin](https://github.com/kanaka) |
93 | [NASM](#nasm) | [Ben Dudson](https://github.com/bendudson) |
94 | [Nim](#nim-104) | [Dennis Felsing](https://github.com/def-) |
95 | [Object Pascal](#object-pascal) | [Joel Martin](https://github.com/kanaka) |
96 | [Objective C](#objective-c) | [Joel Martin](https://github.com/kanaka) |
97 | [OCaml](#ocaml-4010) | [Chris Houser](https://github.com/chouser) |
98 | [Perl](#perl-5) | [Joel Martin](https://github.com/kanaka) |
99 | [Perl 6](#perl-6) | [Hinrik Örn Sigurðsson](https://github.com/hinrik) |
100 | [PHP](#php-53) | [Joel Martin](https://github.com/kanaka) |
101 | [Picolisp](#picolisp) | [Vasilij Schneidermann](https://github.com/wasamasa) |
102 | [Pike](#pike) | [Dov Murik](https://github.com/dubek) |
103 | [PL/pgSQL](#plpgsql-postgresql-sql-procedural-language) (PostgreSQL) | [Joel Martin](https://github.com/kanaka) |
104 | [PL/SQL](#plsql-oracle-sql-procedural-language) (Oracle) | [Joel Martin](https://github.com/kanaka) |
105 | [PostScript](#postscript-level-23) | [Joel Martin](https://github.com/kanaka) |
106 | [PowerShell](#powershell) | [Joel Martin](https://github.com/kanaka) |
107 | [Python](#python-2x-and-3x) (2.X & 3.X) | [Joel Martin](https://github.com/kanaka) |
108 | [Python #2](#python2-3x) (3.X) | [Gavin Lewis](https://github.com/epylar) |
109 | [RPython](#rpython) | [Joel Martin](https://github.com/kanaka) |
110 | [R](#r) | [Joel Martin](https://github.com/kanaka) |
111 | [Racket](#racket-53) | [Joel Martin](https://github.com/kanaka) |
112 | [Rexx](#rexx) | [Dov Murik](https://github.com/dubek) |
113 | [Ruby](#ruby-19) | [Joel Martin](https://github.com/kanaka) |
114 | [Rust](#rust-138) | [Joel Martin](https://github.com/kanaka) |
115 | [Scala](#scala) | [Joel Martin](https://github.com/kanaka) |
116 | [Scheme (R7RS)](#scheme-r7rs) | [Vasilij Schneidermann](https://github.com/wasamasa) |
117 | [Skew](#skew) | [Dov Murik](https://github.com/dubek) |
118 | [Swift 2](#swift) | [Keith Rollin](https://github.com/keith-rollin) |
119 | [Swift 3](#swift-3) | [Joel Martin](https://github.com/kanaka) |
120 | [Swift 4](#swift-4) | [陆遥](https://github.com/LispLY) |
121 | [Swift 5](#swift-5) | [Oleg Montak](https://github.com/MontakOleg) |
122 | [Tcl](#tcl-86) | [Dov Murik](https://github.com/dubek) |
123 | [TypeScript](#typescript) | [Masahiro Wakame](https://github.com/vvakame) |
124 | [Vala](#vala) | [Simon Tatham](https://github.com/sgtatham) |
125 | [VHDL](#vhdl) | [Dov Murik](https://github.com/dubek) |
126 | [Vimscript](#vimscript) | [Dov Murik](https://github.com/dubek) |
127 | [Visual Basic.NET](#visual-basicnet) | [Joel Martin](https://github.com/kanaka) |
128 | [WebAssembly](#webassembly-wasm) (wasm) | [Joel Martin](https://github.com/kanaka) |
129 | [Wren](#wren) | [Dov Murik](https://github.com/dubek) |
130 | [XSLT](#xslt) | [Ali MohammadPur](https://github.com/alimpfard) |
131 | [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
132 | [Zig](#zig) | [Josh Tobin](https://github.com/rjtobin) |
137 Mal was presented publicly for the first time in a lightning talk at
138 Clojure West 2014 (unfortunately there is no video). See
139 examples/clojurewest2014.mal for the presentation that was given at the
140 conference (yes, the presentation is a mal program).
142 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
143 "Achievement Unlocked: A Better Path to Language Learning".
144 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
145 [Slides](http://kanaka.github.io/midwest.io.mal/).
147 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
148 in 10 Incremental Steps" at LambdaConf 2016:
149 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
150 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
151 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
152 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
153 [Slides](http://kanaka.github.io/lambdaconf/).
155 ## Building/running implementations
157 The simplest way to run any given implementation is to use docker.
158 Every implementation has a docker image pre-built with language
159 dependencies installed. You can launch the REPL using a convenient
160 target in the top level Makefile (where IMPL is the implementation
161 directory name and stepX is the step to run):
164 make DOCKERIZE=1 "repl^IMPL^stepX"
165 # OR stepA is the default step:
166 make DOCKERIZE=1 "repl^IMPL"
169 ## External Implementations
171 The following implementations are maintained as separate projects:
175 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
179 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
180 * [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).
183 ## Other mal Projects
185 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
186 * [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.
187 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
188 * [flk](https://github.com/chr15m/flk) - A LISP that runs wherever Bash is
189 * [glisp](https://github.com/baku89/glisp) - Self-bootstrapping graphic design tool on Lisp. [Live Demo](https://baku89.com/glisp/)
192 ## Implementation Details
196 The Ada implementation was developed with GNAT 4.9 on debian. It also
197 compiles unchanged on windows if you have windows versions of git,
198 GNAT and (optionally) make. There are no external dependencies
199 (readline not implemented).
209 The second Ada implementation was developed with GNAT 8 and links with
210 the GNU readline library.
220 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
224 gawk -O -f stepX_YYY.awk
234 ### BASIC (C64 and QBasic)
236 The BASIC implementation uses a preprocessor that can generate BASIC
237 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
238 C64 mode has been tested with
239 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
240 currently required to fix issues with line input) and the QBasic mode
241 has been tested with [qb64](http://www.qb64.net/).
243 Generate C64 code and run it using cbmbasic:
251 Generate QBasic code and load it into qb64:
255 make MODE=qbasic stepX_YYY.bas
259 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
260 inspiration for this implementation.
264 The BBC BASIC V implementation can run in the Brandy interpreter:
268 brandy -quit stepX_YYY.bbc
271 Or in ARM BBC BASIC V under RISC OS 3 or later:
274 *Dir bbc-basic.riscos
281 The C implementation of mal requires the following libraries (lib and
282 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
293 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
294 a readline compatible library to build. See the `cpp/README.md` for
308 The C# implementation of mal has been tested on Linux using the Mono
309 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
310 required to build and run the C# implementation.
320 The ChucK implementation has been tested with ChucK 1.3.5.2.
329 For the most part the Clojure implementation requires Clojure 1.5,
330 however, to pass all tests, Clojure 1.8.0-RC4 is required.
334 lein with-profile +stepX trampoline run
340 sudo npm install -g coffee-script
347 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
348 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
349 the [README](common-lisp/README.org) for more details. Provided you have the
350 dependencies mentioned installed, do the following to run the implementation
360 The Crystal implementation of mal has been tested with Crystal 0.26.1.
364 crystal run ./stepX_YYY.cr
366 make # needed to run tests
372 The D implementation of mal was tested with GDC 4.8. It requires the GNU
383 The Dart implementation has been tested with Dart 1.20.
392 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
393 and 24.5. While there is very basic readline editing (`<backspace>`
394 and `C-d` work, `C-c` cancels the process), it is recommended to use
399 emacs -Q --batch --load stepX_YYY.el
400 # with full readline support
401 rlwrap emacs -Q --batch --load stepX_YYY.el
406 The Elixir implementation of mal has been tested with Elixir 1.0.5.
411 # Or with readline/line editing functionality:
417 The Elm implementation of mal has been tested with Elm 0.18.0
427 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
428 and [rebar](https://github.com/rebar/rebar) to build.
434 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
438 ### ES6 (ECMAScript 2015)
440 The ES6 / ECMAScript 2015 implementation uses the
441 [babel](https://babeljs.io) compiler to generate ES5 compatible
442 JavaScript. The generated code has been tested with Node 0.12.4.
447 node build/stepX_YYY.js
453 The F# implementation of mal has been tested on Linux using the Mono
454 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
455 compiler (mcs) is also necessary to compile the readline dependency. All are
456 required to build and run the F# implementation.
466 The Factor implementation of mal has been tested with Factor 0.97
467 ([factorcode.org](http://factorcode.org)).
471 FACTOR_ROOTS=. factor -run=stepX_YYY
476 The Fantom implementation of mal has been tested with Fantom 1.0.70.
480 make lib/fan/stepX_YYY.pod
495 guile -L ./ stepX_YYY.scm
500 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
503 cd impls/gnu-smalltalk
509 The Go implementation of mal requires that go is installed on on the
510 path. The implementation has been tested with Go 1.3.1.
521 The Groovy implementation of mal requires Groovy to run and has been
522 tested with Groovy 1.8.6.
527 groovy ./stepX_YYY.groovy
532 The Haskell implementation requires the ghc compiler version 7.10.1 or
533 later and also the Haskell parsec and readline (or editline) packages.
541 ### Haxe (Neko, Python, C++ and JavaScript)
543 The Haxe implementation of mal requires Haxe version 3.2 to compile.
544 Four different Haxe targets are supported: Neko, Python, C++, and
554 python3 ./stepX_YYY.py
565 The Hy implementation of mal has been tested with Hy 0.13.0.
574 The Io implementation of mal has been tested with Io version 20110905.
583 The Java implementation of mal requires maven2 to build.
588 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
590 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
603 The Julia implementation of mal requires Julia 0.4.
612 Tested against version 1.6, with a lot of cheating in the IO department
618 DEBUG=true STEP=stepA_YYY ./run
623 The Kotlin implementation of mal has been tested with Kotlin 1.0.
628 java -jar stepX_YYY.jar
633 The LiveScript implementation of mal has been tested with LiveScript 1.5.
638 node_modules/.bin/lsc stepX_YYY.ls
643 The Logo implementation of mal has been tested with UCBLogo 6.0.
652 The Lua implementation of mal has been tested with Lua 5.3.5 The
653 implementation requires luarocks to be installed.
657 make # to build and link linenoise.so and rex_pcre.so
663 Running the mal implementation of mal involves running stepA of one of
664 the other implementations and passing the mal step to run as a command
669 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
682 The NASM implementation of mal is written for x86-64 Linux, and has been tested
683 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
693 The Nim implementation of mal has been tested with Nim 1.0.4.
705 The Object Pascal implementation of mal has been built and tested on
706 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
716 The Objective C implementation of mal has been built and tested on
717 Linux using clang/LLVM 3.6. It has also been built and tested on OS
734 ### MATLAB (GNU Octave and MATLAB)
736 The MatLab implementation has been tested with GNU Octave 4.2.1.
737 It has also been tested with MATLAB version R2014a on Linux. Note that
738 MATLAB is a commercial product.
743 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
744 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
745 # OR with command line arguments
746 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
747 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
752 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
753 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
754 implementation of mal you need to download/install the miniMAL
755 interpreter (which requires Node.js).
758 # Download miniMAL and dependencies
760 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
761 # Now run mal implementation in miniMAL
767 The Perl 5 implementation should work with perl 5.19.3 and later.
769 For readline line editing support, install Term::ReadLine::Perl or
770 Term::ReadLine::Gnu from CPAN.
779 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
788 The PHP implementation of mal requires the php command line interface
798 The Picolisp implementation requires libreadline and Picolisp 3.1.11
808 The Pike implementation was tested on Pike 8.0.
815 ### PL/pgSQL (PostgreSQL SQL Procedural Language)
817 The PL/pgSQL implementation of mal requires a running PostgreSQL server
818 (the "kanaka/mal-test-plpgsql" docker image automatically starts
819 a PostgreSQL server). The implementation connects to the PostgreSQL server
820 and create a database named "mal" to store tables and stored
821 procedures. The wrapper script uses the psql command to connect to the
822 server and defaults to the user "postgres" but this can be overridden
823 with the PSQL_USER environment variable. A password can be specified
824 using the PGPASSWORD environment variable. The implementation has been
825 tested with PostgreSQL 9.4.
829 ./wrap.sh stepX_YYY.sql
831 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
834 ### PL/SQL (Oracle SQL Procedural Language)
836 The PL/SQL implementation of mal requires a running Oracle DB
837 server (the "kanaka/mal-test-plsql" docker image automatically
838 starts an Oracle Express server). The implementation connects to the
839 Oracle server to create types, tables and stored procedures. The
840 default SQL\*Plus logon value (username/password@connect_identifier) is
841 "system/oracle" but this can be overridden with the ORACLE_LOGON
842 environment variable. The implementation has been tested with Oracle
843 Express Edition 11g Release 2. Note that any SQL\*Plus connection
844 warnings (user password expiration, etc) will interfere with the
845 ability of the wrapper script to communicate with the DB.
849 ./wrap.sh stepX_YYY.sql
851 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
854 ### PostScript Level 2/3
856 The PostScript implementation of mal requires Ghostscript to run. It
857 has been tested with Ghostscript 9.10.
861 gs -q -dNODISPLAY -I./ stepX_YYY.ps
866 The PowerShell implementation of mal requires the PowerShell script
867 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
871 powershell ./stepX_YYY.ps1
874 ### Python (2.X and 3.X)
883 The second Python implementation makes heavy use of type annotations and uses the Arpeggio parser library.
886 # Recommended: do these steps in a Python virtual environment.
887 pip3 install Arpeggio==1.9.0
893 You must have [rpython](https://rpython.readthedocs.org/) on your path
894 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
898 make # this takes a very long time
904 The R implementation of mal requires R (r-base-core) to run.
908 make libs # to download and build rdyncall
914 The Racket implementation of mal requires the Racket
915 compiler/interpreter to run.
924 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
929 rexx -a ./stepX_YYY.rexxpp
941 The rust implementation of mal requires the rust compiler and build
942 tool (cargo) to build.
946 cargo run --release --bin stepX_YYY
951 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
955 sbt 'run-main stepX_YYY'
958 scala -classpath target/scala*/classes stepX_YYY
961 ### Scheme (R7RS) ###
963 The Scheme implementation of mal has been tested with Chibi-Scheme
964 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
965 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
966 be able to get it running on other conforming R7RS implementations
967 after figuring out how libraries are loaded and adjusting the
968 `Makefile` and `run` script accordingly.
974 scheme_MODE=chibi ./run
977 scheme_MODE=kawa ./run
979 scheme_MODE=gauche ./run
982 scheme_MODE=chicken ./run
984 scheme_MODE=sagittarius ./run
987 scheme_MODE=cyclone ./run
989 scheme_MODE=foment ./run
994 The Skew implementation of mal has been tested with Skew 0.7.42.
1005 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
1006 7.0) to build. Older versions will not work due to changes in the
1007 language and standard library.
1017 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
1018 has been tested with Swift 3 Preview 3.
1028 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
1029 has been tested with Swift 4.2.3 release.
1039 The Swift 5 implementation of mal requires the Swift 5.0 compiler. It
1040 has been tested with Swift 5.1.1 release.
1049 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
1050 editing support, install tclreadline.
1054 tclsh ./stepX_YYY.tcl
1059 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
1060 It has been tested with Node.js v6.
1070 The Vala implementation of mal has been tested with the Vala 0.40.8
1071 compiler. You will need to install `valac` and `libreadline-dev` or
1082 The VHDL implementation of mal has been tested with GHDL 0.29.
1087 ./run_vhdl.sh ./stepX_YYY
1092 The Vimscript implementation of mal requires Vim 8.0 to run.
1096 ./run_vimscript.sh ./stepX_YYY.vim
1099 ### Visual Basic.NET ###
1101 The VB.NET implementation of mal has been tested on Linux using the Mono
1102 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1103 required to build and run the VB.NET implementation.
1108 mono ./stepX_YYY.exe
1111 ### WebAssembly (wasm) ###
1113 The WebAssembly implementation is written in
1114 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1115 runs under several different non-web embeddings (runtimes):
1116 [node](https://nodejs.org),
1117 [wasmtime](https://github.com/CraneStation/wasmtime),
1118 [wasmer](https://wasmer.io),
1119 [lucet](https://github.com/fastly/lucet),
1120 [wax](https://github.com/kanaka/wac),
1121 [wace](https://github.com/kanaka/wac),
1122 [warpy](https://github.com/kanaka/warpy).
1128 ./run.js ./stepX_YYY.wasm
1130 make wasm_MODE=wasmtime
1131 wasmtime --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1133 make wasm_MODE=wasmer
1134 wasmer run --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1136 make wasm_MODE=lucet
1137 lucet-wasi --dir=./:./ --dir=../:../ --dir=/:/ ./stepX_YYY.so
1140 wax ./stepX_YYY.wasm
1142 make wasm_MODE=wace_libc
1143 wace ./stepX_YYY.wasm
1145 make wasm_MODE=warpy
1146 warpy --argv --memory-pages 256 ./stepX_YYY.wasm
1151 The XSLT implementation of mal is written with XSLT 3 and tested on Saxon 9.9.1.6 Home Edition.
1160 The Wren implementation of mal was tested on Wren 0.2.0.
1164 wren ./stepX_YYY.wren
1169 The Yorick implementation of mal was tested on Yorick 2.2.04.
1173 yorick -batch ./stepX_YYY.i
1178 The Zig implementation of mal was tested on Zig 0.5.
1189 The top level Makefile has a number of useful targets to assist with
1190 implementation development and testing. The `help` target provides
1191 a list of the targets and options:
1197 ### Functional tests
1199 The are almost 800 generic functional tests (for all implementations)
1200 in the `tests/` directory. Each step has a corresponding test file
1201 containing tests specific to that step. The `runtest.py` test harness
1202 launches a Mal step implementation and then feeds the tests one at
1203 a time to the implementation and compares the output/return value to
1204 the expected output/return value.
1206 * To run all the tests across all implementations (be prepared to wait):
1212 * To run all tests against a single implementation:
1222 * To run tests for a single step against all implementations:
1232 * To run tests for a specific step against a single implementation:
1235 make "test^IMPL^stepX"
1238 make "test^ruby^step3"
1239 make "test^ps^step4"
1242 ### Self-hosted functional tests
1244 * To run the functional tests in self-hosted mode, you specify `mal`
1245 as the test implementation and use the `MAL_IMPL` make variable
1246 to change the underlying host language (default is JavaScript):
1248 make MAL_IMPL=IMPL "test^mal^step2"
1251 make "test^mal^step2" # js is default
1252 make MAL_IMPL=ruby "test^mal^step2"
1253 make MAL_IMPL=python "test^mal^step2"
1256 ### Starting the REPL
1258 * To start the REPL of an implementation in a specific step:
1261 make "repl^IMPL^stepX"
1264 make "repl^ruby^step3"
1265 make "repl^ps^step4"
1268 * If you omit the step, then `stepA` is used:
1278 * To start the REPL of the self-hosted implementation, specify `mal` as the
1279 REPL implementation and use the `MAL_IMPL` make variable to change the
1280 underlying host language (default is JavaScript):
1282 make MAL_IMPL=IMPL "repl^mal^stepX"
1285 make "repl^mal^step2" # js is default
1286 make MAL_IMPL=ruby "repl^mal^step2"
1287 make MAL_IMPL=python "repl^mal"
1290 ### Performance tests
1292 Warning: These performance tests are neither statistically valid nor
1293 comprehensive; runtime performance is a not a primary goal of mal. If
1294 you draw any serious conclusions from these performance tests, then
1295 please contact me about some amazing oceanfront property in Kansas
1296 that I'm willing to sell you for cheap.
1298 * To run performance tests against a single implementation:
1306 * To run performance tests against all implementations:
1311 ### Generating language statistics
1313 * To report line and byte statistics for a single implementation:
1321 ## Dockerized testing
1323 Every implementation directory contains a Dockerfile to create
1324 a docker image containing all the dependencies for that
1325 implementation. In addition, the top-level Makefile contains support
1326 for running the tests target (and perf, stats, repl, etc) within
1327 a docker container for that implementation by passing *"DOCKERIZE=1"*
1328 on the make command line. For example:
1331 make DOCKERIZE=1 "test^js^step3"
1334 Existing implementations already have docker images built and pushed
1335 to the docker registry. However, if
1336 you wish to build or rebuild a docker image locally, the toplevel
1337 Makefile provides a rule for building docker images:
1340 make "docker-build^IMPL"
1345 * Docker images are named *"kanaka/mal-test-IMPL"*
1346 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1347 you will probably need to run this command once manually
1348 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1349 runtime dependencies need to be downloaded to avoid the tests timing
1350 out. These dependencies are downloaded to dot-files in the /mal
1351 directory so they will persist between runs.
1356 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1357 License 2.0). See LICENSE.txt for more details.