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 77 languages (78 different implementations and 99 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-58) | [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 | [PL/pgSQL](#plpgsql-postgres-sql-procedural-language) (Postgres) | [Joel Martin](https://github.com/kanaka) |
67 | [PL/SQL](#plsql-oracle-sql-procedural-language) (Oracle) | [Joel Martin](https://github.com/kanaka) |
68 | [PostScript](#postscript-level-23) | [Joel Martin](https://github.com/kanaka) |
69 | [PowerShell](#powershell) | [Joel Martin](https://github.com/kanaka) |
70 | [Python](#python-2x-and-3x) (2.X & 3.X) | [Joel Martin](https://github.com/kanaka) |
71 | [RPython](#rpython) | [Joel Martin](https://github.com/kanaka) |
72 | [R](#r) | [Joel Martin](https://github.com/kanaka) |
73 | [Racket](#racket-53) | [Joel Martin](https://github.com/kanaka) |
74 | [Rexx](#rexx) | [Dov Murik](https://github.com/dubek) |
75 | [Ruby](#ruby-19) | [Joel Martin](https://github.com/kanaka) |
76 | [Rust](#rust-100-nightly) | [Joel Martin](https://github.com/kanaka) |
77 | [Scala](#scala) | [Joel Martin](https://github.com/kanaka) |
78 | [Scheme (R7RS)](#scheme-r7rs) | [Vasilij Schneidermann](https://github.com/wasamasa) |
79 | [Skew](#skew) | [Dov Murik](https://github.com/dubek) |
80 | [Swift 2](#swift) | [Keith Rollin](https://github.com/keith-rollin) |
81 | [Swift 3](#swift-3) | [Joel Martin](https://github.com/kanaka) |
82 | [Swift 4](#swift-4) | [陆遥](https://github.com/LispLY) |
83 | [Tcl](#tcl-86) | [Dov Murik](https://github.com/dubek) |
84 | [TypeScript](#typescript) | [Masahiro Wakame](https://github.com/vvakame) |
85 | [Vala](#vala) | [Simon Tatham](https://github.com/sgtatham) |
86 | [VHDL](#vhdl) | [Dov Murik](https://github.com/dubek) |
87 | [Vimscript](#vimscript) | [Dov Murik](https://github.com/dubek) |
88 | [Visual Basic.NET](#visual-basicnet) | [Joel Martin](https://github.com/kanaka) |
89 | [WebAssembly](#webassembly-wasm) (wasm) | [Joel Martin](https://github.com/kanaka) |
90 | [Yorick](#yorick) | [Dov Murik](https://github.com/dubek) |
93 **3. Mal is a learning tool**
95 Each implementation of mal is separated into
96 11 incremental, self-contained (and testable) steps that demonstrate
97 core concepts of Lisp. The last step is capable of self-hosting
98 (running the mal implementation of mal). See the [make-a-lisp process
99 guide](process/guide.md).
101 The make-a-lisp steps are:
103 * [step0_repl](process/guide.md#step0)
104 * [step1_read_print](process/guide.md#step1)
105 * [step2_eval](process/guide.md#step2)
106 * [step3_env](process/guide.md#step3)
107 * [step4_if_fn_do](process/guide.md#step4)
108 * [step5_tco](process/guide.md#step5)
109 * [step6_file](process/guide.md#step6)
110 * [step7_quote](process/guide.md#step7)
111 * [step8_macros](process/guide.md#step8)
112 * [step9_try](process/guide.md#step9)
113 * [stepA_mal](process/guide.md#stepA)
115 Each make-a-lisp step has an associated architectural diagram. That elements
116 that are new for that step are highlighted in red.
117 Here is the final diagram for [step A](process/guide.md#stepA):
119 ![stepA_mal architecture](process/stepA_mal.png)
121 If you are interesting in creating a mal implementation (or just
122 interested in using mal for something), please drop by the #mal
123 channel on freenode. In addition to the [make-a-lisp process
124 guide](process/guide.md) there is also a [mal/make-a-lisp
125 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
130 Mal was presented publicly for the first time in a lightning talk at
131 Clojure West 2014 (unfortunately there is no video). See
132 examples/clojurewest2014.mal for the presentation that was given at the
133 conference (yes, the presentation is a mal program).
135 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
136 "Achievement Unlocked: A Better Path to Language Learning".
137 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
138 [Slides](http://kanaka.github.io/midwest.io.mal/).
140 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
141 in 10 Incremental Steps" at LambdaConf 2016:
142 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
143 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
144 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
145 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
146 [Slides](http://kanaka.github.io/lambdaconf/).
148 ## Building/running implementations
150 The simplest way to run any given implementation is to use docker.
151 Every implementation has a docker image pre-built with language
152 dependencies installed. You can launch the REPL using a convenient
153 target in the top level Makefile (where IMPL is the implementation
154 directory name and stepX is the step to run):
157 make DOCKERIZE=1 "repl^IMPL^stepX"
158 # OR stepA is the default step:
159 make DOCKERIZE=1 "repl^IMPL"
162 ## External Implementations
164 The following implementations are maintained as separate projects:
168 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
172 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
173 * [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).
176 ## Other mal Projects
178 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
179 * [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.
180 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
183 ## Implementation Details
187 The Ada implementation was developed with GNAT 4.9 on debian. It also
188 compiles unchanged on windows if you have windows versions of git,
189 GNAT and (optionally) make. There are no external dependencies
190 (readline not implemented).
200 The second Ada implementation was developed with GNAT 8 and links with
201 the GNU readline library.
211 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
215 gawk -O -f stepX_YYY.awk
225 ### BASIC (C64 and QBasic)
227 The BASIC implementation uses a preprocessor that can generate BASIC
228 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
229 C64 mode has been tested with
230 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
231 currently required to fix issues with line input) and the QBasic mode
232 has been tested with [qb64](http://www.qb64.net/).
234 Generate C64 code and run it using cbmbasic:
242 Generate QBasic code and load it into qb64:
246 make MODE=qbasic stepX_YYY.bas
250 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
251 inspiration for this implementation.
255 The BBC BASIC V implementation can run in the Brandy interpreter:
259 brandy -quit stepX_YYY.bbc
262 Or in ARM BBC BASIC V under RISC OS 3 or later:
265 *Dir bbc-basic.riscos
272 The C implementation of mal requires the following libraries (lib and
273 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
284 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
285 a readline compatible library to build. See the `cpp/README.md` for
299 The C# implementation of mal has been tested on Linux using the Mono
300 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
301 required to build and run the C# implementation.
311 The ChucK implementation has been tested with ChucK 1.3.5.2.
320 For the most part the Clojure implementation requires Clojure 1.5,
321 however, to pass all tests, Clojure 1.8.0-RC4 is required.
325 lein with-profile +stepX trampoline run
331 sudo npm install -g coffee-script
338 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
339 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
340 the [README](common-lisp/README.org) for more details. Provided you have the
341 dependencies mentioned installed, do the following to run the implementation
351 The Crystal implementation of mal has been tested with Crystal 0.26.1.
355 crystal run ./stepX_YYY.cr
357 make # needed to run tests
363 The D implementation of mal was tested with GDC 4.8. It requires the GNU
374 The Dart implementation has been tested with Dart 1.20.
383 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
384 and 24.5. While there is very basic readline editing (`<backspace>`
385 and `C-d` work, `C-c` cancels the process), it is recommended to use
390 emacs -Q --batch --load stepX_YYY.el
391 # with full readline support
392 rlwrap emacs -Q --batch --load stepX_YYY.el
397 The Elixir implementation of mal has been tested with Elixir 1.0.5.
402 # Or with readline/line editing functionality:
408 The Elm implementation of mal has been tested with Elm 0.18.0
418 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
419 and [rebar](https://github.com/rebar/rebar) to build.
425 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
429 ### ES6 (ECMAScript 2015)
431 The ES6 / ECMAScript 2015 implementation uses the
432 [babel](https://babeljs.io) compiler to generate ES5 compatible
433 JavaScript. The generated code has been tested with Node 0.12.4.
438 node build/stepX_YYY.js
444 The F# implementation of mal has been tested on Linux using the Mono
445 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
446 compiler (mcs) is also necessary to compile the readline dependency. All are
447 required to build and run the F# implementation.
457 The Factor implementation of mal has been tested with Factor 0.97
458 ([factorcode.org](http://factorcode.org)).
462 FACTOR_ROOTS=. factor -run=stepX_YYY
467 The Fantom implementation of mal has been tested with Fantom 1.0.70.
471 make lib/fan/stepX_YYY.pod
486 guile -L ./ stepX_YYY.scm
491 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
500 The Go implementation of mal requires that go is installed on on the
501 path. The implementation has been tested with Go 1.3.1.
512 The Groovy implementation of mal requires Groovy to run and has been
513 tested with Groovy 1.8.6.
518 groovy ./stepX_YYY.groovy
523 The Haskell implementation requires the ghc compiler version 7.10.1 or
524 later and also the Haskell parsec and readline (or editline) packages.
532 ### Haxe (Neko, Python, C++ and JavaScript)
534 The Haxe implementation of mal requires Haxe version 3.2 to compile.
535 Four different Haxe targets are supported: Neko, Python, C++, and
545 python3 ./stepX_YYY.py
556 The Hy implementation of mal has been tested with Hy 0.13.0.
565 The Io implementation of mal has been tested with Io version 20110905.
574 The Java implementation of mal requires maven2 to build.
579 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
581 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
594 The Julia implementation of mal requires Julia 0.4.
603 The Kotlin implementation of mal has been tested with Kotlin 1.0.
608 java -jar stepX_YYY.jar
613 The LiveScript implementation of mal has been tested with LiveScript 1.5.
618 node_modules/.bin/lsc stepX_YYY.ls
623 The Logo implementation of mal has been tested with UCBLogo 6.0.
632 The Lua implementation of mal has been tested with Lua 5.2. The
633 implementation requires that luarocks and the lua-rex-pcre library
638 make # to build and link linenoise.so
644 Running the mal implementation of mal involves running stepA of one of
645 the other implementations and passing the mal step to run as a command
650 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
663 The NASM implementation of mal is written for x86-64 Linux, and has been tested
664 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
674 The Nim implementation of mal has been tested with Nim 0.17.0.
686 The Object Pascal implementation of mal has been built and tested on
687 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
697 The Objective C implementation of mal has been built and tested on
698 Linux using clang/LLVM 3.6. It has also been built and tested on OS
715 ### MATLAB (GNU Octave and MATLAB)
717 The MatLab implementation has been tested with GNU Octave 4.2.1.
718 It has also been tested with MATLAB version R2014a on Linux. Note that
719 MATLAB is a commercial product.
724 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
725 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
726 # OR with command line arguments
727 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
728 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
733 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
734 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
735 implementation of mal you need to download/install the miniMAL
736 interpreter (which requires Node.js).
739 # Download miniMAL and dependencies
741 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
742 # Now run mal implementation in miniMAL
748 For readline line editing support, install Term::ReadLine::Perl or
749 Term::ReadLine::Gnu from CPAN.
758 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
767 The PHP implementation of mal requires the php command line interface
777 The Picolisp implementation requires libreadline and Picolisp 3.1.11
785 ### PL/pgSQL (Postgres SQL Procedural Language)
787 The PL/pgSQL implementation of mal requires a running Postgres server
788 (the "kanaka/mal-test-plpgsql" docker image automatically starts
789 a Postgres server). The implementation connects to the Postgres server
790 and create a database named "mal" to store tables and stored
791 procedures. The wrapper script uses the psql command to connect to the
792 server and defaults to the user "postgres" but this can be overridden
793 with the PSQL_USER environment variable. A password can be specified
794 using the PGPASSWORD environment variable. The implementation has been
795 tested with Postgres 9.4.
799 ./wrap.sh stepX_YYY.sql
801 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
804 ### PL/SQL (Oracle SQL Procedural Language)
806 The PL/pgSQL implementation of mal requires a running Oracle DB
807 server (the "kanaka/mal-test-plsql" docker image automatically
808 starts an Oracle Express server). The implementation connects to the
809 Oracle server to create types, tables and stored procedures. The
810 default SQL\*Plus logon value (username/password@connect_identifier) is
811 "system/oracle" but this can be overridden with the ORACLE_LOGON
812 environment variable. The implementation has been tested with Oracle
813 Express Edition 11g Release 2. Note that any SQL\*Plus connection
814 warnings (user password expiration, etc) will interfere with the
815 ability of the wrapper script to communicate with the DB.
819 ./wrap.sh stepX_YYY.sql
821 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
824 ### Postscript Level 2/3
826 The Postscript implementation of mal requires ghostscript to run. It
827 has been tested with ghostscript 9.10.
831 gs -q -dNODISPLAY -I./ stepX_YYY.ps
836 The PowerShell implementation of mal requires the PowerShell script
837 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
841 powershell ./stepX_YYY.ps1
844 ### Python (2.X and 3.X)
853 You must have [rpython](https://rpython.readthedocs.org/) on your path
854 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
858 make # this takes a very long time
864 The R implementation of mal requires R (r-base-core) to run.
868 make libs # to download and build rdyncall
874 The Racket implementation of mal requires the Racket
875 compiler/interpreter to run.
884 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
889 rexx -a ./stepX_YYY.rexxpp
899 ### Rust (1.0.0 nightly)
901 The rust implementation of mal requires the rust compiler and build
902 tool (cargo) to build.
906 cargo run --release --bin stepX_YYY
911 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
915 sbt 'run-main stepX_YYY'
918 scala -classpath target/scala*/classes stepX_YYY
921 ### Scheme (R7RS) ###
923 The Scheme implementation of mal has been tested with Chibi-Scheme
924 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
925 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
926 be able to get it running on other conforming R7RS implementations
927 after figuring out how libraries are loaded and adjusting the
928 `Makefile` and `run` script accordingly.
934 scheme_MODE=chibi ./run
937 scheme_MODE=kawa ./run
939 scheme_MODE=gauche ./run
942 scheme_MODE=chicken ./run
944 scheme_MODE=sagittarius ./run
947 scheme_MODE=cyclone ./run
949 scheme_MODE=foment ./run
954 The Skew implementation of mal has been tested with Skew 0.7.42.
965 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
966 7.0) to build. Older versions will not work due to changes in the
967 language and standard library.
977 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
978 has been tested with Swift 3 Preview 3.
988 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
989 has been tested with Swift 4.2.3 release.
999 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
1000 editing support, install tclreadline.
1004 tclsh ./stepX_YYY.tcl
1009 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
1010 It has been tested with Node.js v6.
1020 The Vala implementation of mal has been tested with the Vala 0.40.8
1021 compiler. You will need to install `valac` and `libreadline-dev` or
1032 The VHDL implementation of mal has been tested with GHDL 0.29.
1037 ./run_vhdl.sh ./stepX_YYY
1042 The Vimscript implementation of mal requires Vim 8.0 to run.
1046 ./run_vimscript.sh ./stepX_YYY.vim
1049 ### Visual Basic.NET ###
1051 The VB.NET implementation of mal has been tested on Linux using the Mono
1052 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1053 required to build and run the VB.NET implementation.
1058 mono ./stepX_YYY.exe
1061 ### WebAssembly (wasm) ###
1063 The WebAssembly implementation is written in
1064 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1065 runs under several different non-web embeddings (runtimes):
1067 [wasmtime](https://github.com/CraneStation/wasmtime),
1068 [wax](https://github.com/kanaka/wac),
1069 [wace](https://github.com/kanaka/wac),
1070 [warpy](https://github.com/kanaka/warpy).
1076 ./run.js ./stepX_YYY.wasm
1078 make wasm_MODE=wasmtime
1079 wasmtime --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1082 wace ./stepX_YYY.wasm
1084 make wasm_MODE=wace_libc
1085 wace ./stepX_YYY.wasm
1087 make wasm_MODE=warpy
1088 warpy --argv --memory-pages 256 ./stepX_YYY.wasm
1093 The Yorick implementation of mal was tested on Yorick 2.2.04.
1097 yorick -batch ./stepX_YYY.i
1104 The top level Makefile has a number of useful targets to assist with
1105 implementation development and testing. The `help` target provides
1106 a list of the targets and options:
1112 ### Functional tests
1114 The are over 600 generic functional tests (for all implementations)
1115 in the `tests/` directory. Each step has a corresponding test file
1116 containing tests specific to that step. The `runtest.py` test harness
1117 launches a Mal step implementation and then feeds the tests one at
1118 a time to the implementation and compares the output/return value to
1119 the expected output/return value.
1121 * To run all the tests across all implementations (be prepared to wait):
1127 * To run all tests against a single implementation:
1137 * To run tests for a single step against all implementations:
1147 * To run tests for a specific step against a single implementation:
1150 make "test^IMPL^stepX"
1153 make "test^ruby^step3"
1154 make "test^ps^step4"
1157 ### Self-hosted functional tests
1159 * To run the functional tests in self-hosted mode, you specify `mal`
1160 as the test implementation and use the `MAL_IMPL` make variable
1161 to change the underlying host language (default is JavaScript):
1163 make MAL_IMPL=IMPL "test^mal^step2"
1166 make "test^mal^step2" # js is default
1167 make MAL_IMPL=ruby "test^mal^step2"
1168 make MAL_IMPL=python "test^mal^step2"
1171 ### Starting the REPL
1173 * To start the REPL of an implementation in a specific step:
1176 make "repl^IMPL^stepX"
1179 make "repl^ruby^step3"
1180 make "repl^ps^step4"
1183 * If you omit the step, then `stepA` is used:
1193 * To start the REPL of the self-hosted implementation, specify `mal` as the
1194 REPL implementation and use the `MAL_IMPL` make variable to change the
1195 underlying host language (default is JavaScript):
1197 make MAL_IMPL=IMPL "repl^mal^stepX"
1200 make "repl^mal^step2" # js is default
1201 make MAL_IMPL=ruby "repl^mal^step2"
1202 make MAL_IMPL=python "repl^mal"
1205 ### Performance tests
1207 Warning: These performance tests are neither statistically valid nor
1208 comprehensive; runtime performance is a not a primary goal of mal. If
1209 you draw any serious conclusions from these performance tests, then
1210 please contact me about some amazing oceanfront property in Kansas
1211 that I'm willing to sell you for cheap.
1213 * To run performance tests against a single implementation:
1221 * To run performance tests against all implementations:
1226 ### Generating language statistics
1228 * To report line and byte statistics for a single implementation:
1236 ## Dockerized testing
1238 Every implementation directory contains a Dockerfile to create
1239 a docker image containing all the dependencies for that
1240 implementation. In addition, the top-level Makefile contains support
1241 for running the tests target (and perf, stats, repl, etc) within
1242 a docker container for that implementation by passing *"DOCKERIZE=1"*
1243 on the make command line. For example:
1246 make DOCKERIZE=1 "test^js^step3"
1249 Existing implementations already have docker images built and pushed
1250 to the docker registry. However, if
1251 you wish to build or rebuild a docker image locally, the toplevel
1252 Makefile provides a rule for building docker images:
1255 make "docker-build^IMPL"
1260 * Docker images are named *"kanaka/mal-test-IMPL"*
1261 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1262 you will probably need to run this command once manually
1263 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1264 runtime dependencies need to be downloaded to avoid the tests timing
1265 out. These dependencies are downloaded to dot-files in the /mal
1266 directory so they will persist between runs.
1271 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1272 License 2.0). See LICENSE.txt for more details.