3 [![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal)
7 Mal is a Clojure inspired Lisp interpreter.
9 Mal is implemented in 74 languages:
11 * **Ada** - *created by [Chris Moore](https://github.com/zmower)*
12 * **GNU awk** - *created by [Miutsuru Kariya](https://github.com/kariya-mitsuru)*
14 * **BASIC** (C64 and QBasic)
16 * **C++** - *created by [Stephen Thirlwall](https://github.com/sdt)*
18 * **ChucK** - *created by [Vasilij Schneidermann](https://github.com/wasamasa)*
19 * **Common Lisp** - *created by [Iqbal Ansari](https://github.com/iqbalansari)*
20 * **Clojure** (Clojure and ClojureScript)
22 * **Crystal** - *created by [Linda_pp](https://github.com/rhysd)*
23 * **D** - *created by [Dov Murik](https://github.com/dubek)*
24 * **Dart** - *created by [Harry Terkelsen](https://github.com/hterkelsen)*
25 * **Elixir** - *created by [Martin Ek](https://github.com/ekmartin)*
26 * **Elm** - *created by [Jos van Bakel](https://github.com/c0deaddict)*
27 * **Emacs Lisp** - *created by [Vasilij Schneidermann](https://github.com/wasamasa)*
28 * **Erlang** - *created by [Nathan Fiedler](https://github.com/nlfiedler)*
29 * **ES6** (ECMAScript 6 / ECMAScript 2015)
30 * **F#** - *created by [Peter Stephens](https://github.com/pstephens)*
31 * **Factor** - *created by [Jordan Lewis](https://github.com/jordanlewis)*
32 * **Fantom** - *created by [Dov Murik](https://github.com/dubek)*
33 * **Forth** - *created by [Chris Houser](https://github.com/chouser)*
36 * **GNU Guile** - *created by [Mu Lei](https://github.com/NalaGinrut).*
37 * **GNU Smalltalk** - *created by [Vasilij Schneidermann](https://github.com/wasamasa)*
39 * **Haxe** (Neko, Python, C++ and JavaScript)
41 * **Io** - *created by [Dov Murik](https://github.com/dubek)*
43 * **JavaScript** ([Online Demo](http://kanaka.github.io/mal))
45 * **Kotlin** - *created by [Javier Fernandez-Ivern](https://github.com/ivern)*
46 * **LiveScript** - *created by [Jos van Bakel](https://github.com/c0deaddict)*
47 * **Logo** - *created by [Dov Murik](https://github.com/dubek)*
51 * **Matlab** (GNU Octave and MATLAB)
52 * **[miniMAL](https://github.com/kanaka/miniMAL)**
53 * **NASM** - *created by [Ben Dudson](https://github.com/bendudson)*
54 * **Nim** - *created by [Dennis Felsing](https://github.com/def-)*
57 * **OCaml** - *created by [Chris Houser](https://github.com/chouser)*
59 * **Perl 6** - *created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
61 * **Picolisp** - *created by [Vasilij Schneidermann](https://github.com/wasamasa)*
62 * **PL/pgSQL** (Postgres)
66 * **Python** (2.X and 3.X)
70 * **Rexx** - *created by [Dov Murik](https://github.com/dubek)*
74 * **Scheme (R7RS)** - *created by [Vasilij Schneidermann](https://github.com/wasamasa)*
75 * **Skew** - *created by [Dov Murik](https://github.com/dubek)*
76 * **Swift** - *created by [Keith Rollin](https://github.com/keith-rollin)*
78 * **Tcl** - *created by [Dov Murik](https://github.com/dubek)*
79 * **TypeScript** - *created by [Masahiro Wakame](https://github.com/vvakame)*
80 * **VHDL** - *created by [Dov Murik](https://github.com/dubek)*
81 * **Vimscript** - *created by [Dov Murik](https://github.com/dubek)*
82 * **Visual Basic.NET**
83 * **WebAssembly** (wasm)
84 * **Yorick** - *created by [Dov Murik](https://github.com/dubek)*
87 Mal is a learning tool. See the [make-a-lisp process
88 guide](process/guide.md). Each implementation of mal is separated into
89 11 incremental, self-contained (and testable) steps that demonstrate
90 core concepts of Lisp. The last step is capable of self-hosting
91 (running the mal implementation of mal).
93 The mal (make a lisp) steps are:
95 * [step0_repl](process/guide.md#step0)
96 * [step1_read_print](process/guide.md#step1)
97 * [step2_eval](process/guide.md#step2)
98 * [step3_env](process/guide.md#step3)
99 * [step4_if_fn_do](process/guide.md#step4)
100 * [step5_tco](process/guide.md#step5)
101 * [step6_file](process/guide.md#step6)
102 * [step7_quote](process/guide.md#step7)
103 * [step8_macros](process/guide.md#step8)
104 * [step9_try](process/guide.md#step9)
105 * [stepA_mal](process/guide.md#stepA)
108 Mal was presented publicly for the first time in a lightning talk at
109 Clojure West 2014 (unfortunately there is no video). See
110 examples/clojurewest2014.mal for the presentation that was given at the
111 conference (yes, the presentation is a mal program). At Midwest.io
112 2015, Joel Martin gave a presentation on Mal titled "Achievement
113 Unlocked: A Better Path to Language Learning".
114 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
115 [Slides](http://kanaka.github.io/midwest.io.mal/). More recently
116 Joel gave a presentation on "Make Your Own Lisp Interpreter in
117 10 Incremental Steps" at LambdaConf 2016:
118 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
119 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
120 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
121 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
122 [Slides](http://kanaka.github.io/lambdaconf/).
124 If you are interesting 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.
130 ## Building/running implementations
132 The simplest way to run any given implementation is to use docker.
133 Every implementation has a docker image pre-built with language
134 dependencies installed. You can launch the REPL using a convenient
135 target in the top level Makefile (where IMPL is the implementation
136 directory name and stepX is the step to run):
139 make DOCKERIZE=1 "repl^IMPL^stepX"
140 # OR stepA is the default step:
141 make DOCKERIZE=1 "repl^IMPL"
147 The Ada implementation was developed with GNAT 4.9 on debian. It also
148 compiles unchanged on windows if you have windows versions of git,
149 GNAT and (optionally) make. There are no external dependencies
150 (readline not implemented).
160 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
164 gawk -O -f stepX_YYY.awk
174 ### BASIC (C64 and QBasic)
176 The BASIC implementation uses a preprocessor that can generate BASIC
177 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
178 C64 mode has been tested with
179 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
180 currently required to fix issues with line input) and the QBasic mode
181 has been tested with [qb64](http://www.qb64.net/).
183 Generate C64 code and run it using cbmbasic:
191 Generate QBasic code and load it into qb64:
195 make MODE=qbasic stepX_YYY.bas
199 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
200 inspiration for this implementation.
205 The C implementation of mal requires the following libraries (lib and
206 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
217 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
218 a readline compatible library to build. See the `cpp/README.md` for
232 The C# implementation of mal has been tested on Linux using the Mono
233 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
234 required to build and run the C# implementation.
244 The ChucK implementation has been tested with ChucK 1.3.5.2.
253 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
254 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
255 the [README](common-lisp/README.org) for more details. Provided you have the
256 dependencies mentioned installed, do the following to run the implementation
266 For the most part the Clojure implementation requires Clojure 1.5,
267 however, to pass all tests, Clojure 1.8.0-RC4 is required.
271 lein with-profile +stepX trampoline run
277 sudo npm install -g coffee-script
284 The Crystal implementation of mal has been tested with Crystal 0.26.1.
288 crystal run ./stepX_YYY.cr
290 make # needed to run tests
296 The D implementation of mal was tested with GDC 4.8. It requires the GNU
307 The Dart implementation has been tested with Dart 1.20.
316 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
317 and 24.5. While there is very basic readline editing (`<backspace>`
318 and `C-d` work, `C-c` cancels the process), it is recommended to use
323 emacs -Q --batch --load stepX_YYY.el
324 # with full readline support
325 rlwrap emacs -Q --batch --load stepX_YYY.el
330 The Elixir implementation of mal has been tested with Elixir 1.0.5.
335 # Or with readline/line editing functionality:
341 The Elm implementation of mal has been tested with Elm 0.18.0
351 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
352 and [rebar](https://github.com/rebar/rebar) to build.
358 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
362 ### ES6 (ECMAScript 6 / ECMAScript 2015)
364 The ES6 implementation uses the [babel](https://babeljs.io) compiler
365 to generate ES5 compatible JavaScript. The generated code has been
366 tested with Node 0.12.4.
371 node build/stepX_YYY.js
377 The F# implementation of mal has been tested on Linux using the Mono
378 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
379 compiler (mcs) is also necessary to compile the readline dependency. All are
380 required to build and run the F# implementation.
390 The Factor implementation of mal has been tested with Factor 0.97
391 ([factorcode.org](http://factorcode.org)).
395 FACTOR_ROOTS=. factor -run=stepX_YYY
400 The Fantom implementation of mal has been tested with Fantom 1.0.70.
404 make lib/fan/stepX_YYY.pod
417 The Go implementation of mal requires that go is installed on on the
418 path. The implementation has been tested with Go 1.3.1.
429 The Groovy implementation of mal requires Groovy to run and has been
430 tested with Groovy 1.8.6.
435 groovy ./stepX_YYY.groovy
442 guile -L ./ stepX_YYY.scm
447 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
456 The Haskell implementation requires the ghc compiler version 7.10.1 or
457 later and also the Haskell parsec and readline (or editline) packages.
465 ### Haxe (Neko, Python, C++ and JavaScript)
467 The Haxe implementation of mal requires Haxe version 3.2 to compile.
468 Four different Haxe targets are supported: Neko, Python, C++, and
478 python3 ./stepX_YYY.py
489 The Hy implementation of mal has been tested with Hy 0.13.0.
498 The Io implementation of mal has been tested with Io version 20110905.
507 The Java implementation of mal requires maven2 to build.
512 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
514 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
527 The Julia implementation of mal requires Julia 0.4.
536 The Kotlin implementation of mal has been tested with Kotlin 1.0.
541 java -jar stepX_YYY.jar
546 The LiveScript implementation of mal has been tested with LiveScript 1.5.
551 node_modules/.bin/lsc stepX_YYY.ls
556 The Logo implementation of mal has been tested with UCBLogo 6.0.
565 The Lua implementation of mal has been tested with Lua 5.2. The
566 implementation requires that luarocks and the lua-rex-pcre library
571 make # to build and link linenoise.so
577 Running the mal implementation of mal involves running stepA of one of
578 the other implementations and passing the mal step to run as a command
583 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
596 The NASM implementation of mal is written for x86-64 Linux, and has been tested
597 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
607 The Nim implementation of mal has been tested with Nim 0.17.0.
619 The Object Pascal implementation of mal has been built and tested on
620 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
630 The Objective C implementation of mal has been built and tested on
631 Linux using clang/LLVM 3.6. It has also been built and tested on OS
648 ### MatLab (GNU Octave and MATLAB)
650 The MatLab implementation has been tested with GNU Octave 4.2.1.
651 It has also been tested with MATLAB version R2014a on Linux. Note that
652 MATLAB is a commercial product.
657 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
658 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
659 # OR with command line arguments
660 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
661 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
666 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
667 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
668 implementation of mal you need to download/install the miniMAL
669 interpreter (which requires Node.js).
672 # Download miniMAL and dependencies
674 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
675 # Now run mal implementation in miniMAL
681 For readline line editing support, install Term::ReadLine::Perl or
682 Term::ReadLine::Gnu from CPAN.
691 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
700 The PHP implementation of mal requires the php command line interface
710 The Picolisp implementation requires libreadline and Picolisp 3.1.11
718 ### PL/pgSQL (Postgres SQL Procedural Language)
720 The PL/pgSQL implementation of mal requires a running Postgres server
721 (the "kanaka/mal-test-plpgsql" docker image automatically starts
722 a Postgres server). The implementation connects to the Postgres server
723 and create a database named "mal" to store tables and stored
724 procedures. The wrapper script uses the psql command to connect to the
725 server and defaults to the user "postgres" but this can be overridden
726 with the PSQL_USER environment variable. A password can be specified
727 using the PGPASSWORD environment variable. The implementation has been
728 tested with Postgres 9.4.
732 ./wrap.sh stepX_YYY.sql
734 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
737 ### PL/SQL (Oracle SQL Procedural Language)
739 The PL/pgSQL implementation of mal requires a running Oracle DB
740 server (the "kanaka/mal-test-plsql" docker image automatically
741 starts an Oracle Express server). The implementation connects to the
742 Oracle server to create types, tables and stored procedures. The
743 default SQL*Plus logon value (username/password@connect_identifier) is
744 "system/oracle" but this can be overridden with the ORACLE_LOGON
745 environment variable. The implementation has been tested with Oracle
746 Express Edition 11g Release 2. Note that any SQL*Plus connection
747 warnings (user password expiration, etc) will interfere with the
748 ability of the wrapper script to communicate with the DB.
752 ./wrap.sh stepX_YYY.sql
754 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
757 ### Postscript Level 2/3
759 The Postscript implementation of mal requires ghostscript to run. It
760 has been tested with ghostscript 9.10.
764 gs -q -dNODISPLAY -I./ stepX_YYY.ps
769 The PowerShell implementation of mal requires the PowerShell script
770 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
774 powershell ./stepX_YYY.ps1
777 ### Python (2.X and 3.X)
786 You must have [rpython](https://rpython.readthedocs.org/) on your path
787 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
791 make # this takes a very long time
797 The R implementation of mal requires R (r-base-core) to run.
801 make libs # to download and build rdyncall
807 The Racket implementation of mal requires the Racket
808 compiler/interpreter to run.
817 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
822 rexx -a ./stepX_YYY.rexxpp
832 ### Rust (1.0.0 nightly)
834 The rust implementation of mal requires the rust compiler and build
835 tool (cargo) to build.
839 cargo run --release --bin stepX_YYY
844 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
848 sbt 'run-main stepX_YYY'
851 scala -classpath target/scala*/classes stepX_YYY
854 ### Scheme (R7RS) ###
856 The Scheme implementation of mal has been tested with Chibi-Scheme
857 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
858 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
859 be able to get it running on other conforming R7RS implementations
860 after figuring out how libraries are loaded and adjusting the
861 `Makefile` and `run` script accordingly.
867 scheme_MODE=chibi ./run
870 scheme_MODE=kawa ./run
872 scheme_MODE=gauche ./run
875 scheme_MODE=chicken ./run
877 scheme_MODE=sagittarius ./run
880 scheme_MODE=cyclone ./run
882 scheme_MODE=foment ./run
887 The Skew implementation of mal has been tested with Skew 0.7.42.
898 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
899 7.0) to build. Older versions will not work due to changes in the
900 language and standard library.
910 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
911 has been tested with Swift 3 Preview 3.
921 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
922 editing support, install tclreadline.
926 tclsh ./stepX_YYY.tcl
931 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
932 It has been tested with Node.js v6.
942 The VHDL implementation of mal has been tested with GHDL 0.29.
947 ./run_vhdl.sh ./stepX_YYY
952 The Vimscript implementation of mal requires Vim 8.0 to run.
956 ./run_vimscript.sh ./stepX_YYY.vim
959 ### Visual Basic.NET ###
961 The VB.NET implementation of mal has been tested on Linux using the Mono
962 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
963 required to build and run the VB.NET implementation.
971 ### WebAssembly (wasm) ###
973 The WebAssembly implementation is written in
974 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
975 runs under the [wac/wace](https://github.com/kanaka/wac) WebAssembly
981 wace ./stepX_YYY.wasm
986 The Yorick implementation of mal was tested on Yorick 2.2.04.
990 yorick -batch ./stepX_YYY.i
999 The are over 600 generic functional tests (for all implementations)
1000 in the `tests/` directory. Each step has a corresponding test file
1001 containing tests specific to that step. The `runtest.py` test harness
1002 launches a Mal step implementation and then feeds the tests one at
1003 a time to the implementation and compares the output/return value to
1004 the expected output/return value.
1006 To simplify the process of running tests, a top level Makefile is
1007 provided with convenient test targets.
1009 * To run all the tests across all implementations (be prepared to wait):
1015 * To run all tests against a single implementation:
1025 * To run tests for a single step against all implementations:
1035 * To run tests for a specific step against a single implementation:
1038 make "test^IMPL^stepX"
1041 make "test^ruby^step3"
1042 make "test^ps^step4"
1045 ### Self-hosted functional tests
1047 * To run the functional tests in self-hosted mode, you specify `mal`
1048 as the test implementation and use the `MAL_IMPL` make variable
1049 to change the underlying host language (default is JavaScript):
1051 make MAL_IMPL=IMPL "test^mal^step2"
1054 make "test^mal^step2" # js is default
1055 make MAL_IMPL=ruby "test^mal^step2"
1056 make MAL_IMPL=python "test^mal^step2"
1059 ### Starting the REPL
1061 * To start the REPL of an implementation in a specific step:
1064 make "repl^IMPL^stepX"
1067 make "repl^ruby^step3"
1068 make "repl^ps^step4"
1071 * If you omit the step, then `stepA` is used:
1081 * To start the REPL of the self-hosted implementation, specify `mal` as the
1082 REPL implementation and use the `MAL_IMPL` make variable to change the
1083 underlying host language (default is JavaScript):
1085 make MAL_IMPL=IMPL "repl^mal^stepX"
1088 make "repl^mal^step2" # js is default
1089 make MAL_IMPL=ruby "repl^mal^step2"
1090 make MAL_IMPL=python "repl^mal"
1093 ### Performance tests
1095 Warning: These performance tests are neither statistically valid nor
1096 comprehensive; runtime performance is a not a primary goal of mal. If
1097 you draw any serious conclusions from these performance tests, then
1098 please contact me about some amazing oceanfront property in Kansas
1099 that I'm willing to sell you for cheap.
1101 * To run performance tests against a single implementation:
1109 * To run performance tests against all implementations:
1114 ### Generating language statistics
1116 * To report line and byte statistics for a single implementation:
1124 * To report line and bytes statistics for general Lisp code (env, core
1127 make "stats-lisp^IMPL"
1130 make "stats-lisp^js"
1133 ## Dockerized testing
1135 Every implementation directory contains a Dockerfile to create
1136 a docker image containing all the dependencies for that
1137 implementation. In addition, the top-level Makefile contains support
1138 for running the tests target (and perf, stats, repl, etc) within
1139 a docker container for that implementation by passing *"DOCKERIZE=1"*
1140 on the make command line. For example:
1143 make DOCKERIZE=1 "test^js^step3"
1146 Existing implementations already have docker images built and pushed
1147 to the docker registry. However, if
1148 you wish to build or rebuild a docker image locally, the toplevel
1149 Makefile provides a rule for building docker images:
1152 make "docker-build^IMPL"
1157 * Docker images are named *"kanaka/mal-test-IMPL"*
1158 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1159 you will probably need to run this command once manually
1160 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1161 runtime dependencies need to be downloaded to avoid the tests timing
1162 out. These dependencies are downloaded to dot-files in the /mal
1163 directory so they will persist between runs.
1166 ## External Implementations
1168 The following implementations are maintained as separate projects:
1172 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
1176 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
1177 * [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).
1180 ## Projects using mal
1182 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
1183 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
1187 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1188 License 2.0). See LICENSE.txt for more details.