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 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 **3. Mal is a learning tool**
89 Each implementation of mal is separated into
90 11 incremental, self-contained (and testable) steps that demonstrate
91 core concepts of Lisp. The last step is capable of self-hosting
92 (running the mal implementation of mal). See the [make-a-lisp process
93 guide](process/guide.md).
95 The make-a-lisp steps are:
97 * [step0_repl](process/guide.md#step0)
98 * [step1_read_print](process/guide.md#step1)
99 * [step2_eval](process/guide.md#step2)
100 * [step3_env](process/guide.md#step3)
101 * [step4_if_fn_do](process/guide.md#step4)
102 * [step5_tco](process/guide.md#step5)
103 * [step6_file](process/guide.md#step6)
104 * [step7_quote](process/guide.md#step7)
105 * [step8_macros](process/guide.md#step8)
106 * [step9_try](process/guide.md#step9)
107 * [stepA_mal](process/guide.md#stepA)
109 Each make-a-lisp step has an associated architectural diagram. That elements
110 that are new for that step are highlighted in red.
111 Here is the final diagram for [step A](process/guide.md#stepA):
113 ![stepA_mal architecture](process/stepA_mal.png)
115 If you are interesting in creating a mal implementation (or just
116 interested in using mal for something), please drop by the #mal
117 channel on freenode. In addition to the [make-a-lisp process
118 guide](process/guide.md) there is also a [mal/make-a-lisp
119 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
124 Mal was presented publicly for the first time in a lightning talk at
125 Clojure West 2014 (unfortunately there is no video). See
126 examples/clojurewest2014.mal for the presentation that was given at the
127 conference (yes, the presentation is a mal program).
129 At Midwest.io 2015, Joel Martin gave a presentation on Mal titled
130 "Achievement Unlocked: A Better Path to Language Learning".
131 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
132 [Slides](http://kanaka.github.io/midwest.io.mal/).
134 More recently Joel gave a presentation on "Make Your Own Lisp Interpreter
135 in 10 Incremental Steps" at LambdaConf 2016:
136 [Part 1](https://www.youtube.com/watch?v=jVhupfthTEk),
137 [Part 2](https://www.youtube.com/watch?v=X5OQBMGpaTU),
138 [Part 3](https://www.youtube.com/watch?v=6mARZzGgX4U),
139 [Part 4](https://www.youtube.com/watch?v=dCO1SYR5kDU),
140 [Slides](http://kanaka.github.io/lambdaconf/).
142 ## Building/running implementations
144 The simplest way to run any given implementation is to use docker.
145 Every implementation has a docker image pre-built with language
146 dependencies installed. You can launch the REPL using a convenient
147 target in the top level Makefile (where IMPL is the implementation
148 directory name and stepX is the step to run):
151 make DOCKERIZE=1 "repl^IMPL^stepX"
152 # OR stepA is the default step:
153 make DOCKERIZE=1 "repl^IMPL"
159 The Ada implementation was developed with GNAT 4.9 on debian. It also
160 compiles unchanged on windows if you have windows versions of git,
161 GNAT and (optionally) make. There are no external dependencies
162 (readline not implemented).
172 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
176 gawk -O -f stepX_YYY.awk
186 ### BASIC (C64 and QBasic)
188 The BASIC implementation uses a preprocessor that can generate BASIC
189 code that is compatible with both C64 BASIC (CBM v2) and QBasic. The
190 C64 mode has been tested with
191 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
192 currently required to fix issues with line input) and the QBasic mode
193 has been tested with [qb64](http://www.qb64.net/).
195 Generate C64 code and run it using cbmbasic:
203 Generate QBasic code and load it into qb64:
207 make MODE=qbasic stepX_YYY.bas
211 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
212 inspiration for this implementation.
217 The C implementation of mal requires the following libraries (lib and
218 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
229 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
230 a readline compatible library to build. See the `cpp/README.md` for
244 The C# implementation of mal has been tested on Linux using the Mono
245 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
246 required to build and run the C# implementation.
256 The ChucK implementation has been tested with ChucK 1.3.5.2.
265 The implementation has been tested with SBCL, CCL, CMUCL, GNU CLISP, ECL and
266 Allegro CL on Ubuntu 16.04 and Ubuntu 12.04, see
267 the [README](common-lisp/README.org) for more details. Provided you have the
268 dependencies mentioned installed, do the following to run the implementation
278 For the most part the Clojure implementation requires Clojure 1.5,
279 however, to pass all tests, Clojure 1.8.0-RC4 is required.
283 lein with-profile +stepX trampoline run
289 sudo npm install -g coffee-script
296 The Crystal implementation of mal has been tested with Crystal 0.26.1.
300 crystal run ./stepX_YYY.cr
302 make # needed to run tests
308 The D implementation of mal was tested with GDC 4.8. It requires the GNU
319 The Dart implementation has been tested with Dart 1.20.
328 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
329 and 24.5. While there is very basic readline editing (`<backspace>`
330 and `C-d` work, `C-c` cancels the process), it is recommended to use
335 emacs -Q --batch --load stepX_YYY.el
336 # with full readline support
337 rlwrap emacs -Q --batch --load stepX_YYY.el
342 The Elixir implementation of mal has been tested with Elixir 1.0.5.
347 # Or with readline/line editing functionality:
353 The Elm implementation of mal has been tested with Elm 0.18.0
363 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
364 and [rebar](https://github.com/rebar/rebar) to build.
370 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
374 ### ES6 (ECMAScript 6 / ECMAScript 2015)
376 The ES6 implementation uses the [babel](https://babeljs.io) compiler
377 to generate ES5 compatible JavaScript. The generated code has been
378 tested with Node 0.12.4.
383 node build/stepX_YYY.js
389 The F# implementation of mal has been tested on Linux using the Mono
390 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
391 compiler (mcs) is also necessary to compile the readline dependency. All are
392 required to build and run the F# implementation.
402 The Factor implementation of mal has been tested with Factor 0.97
403 ([factorcode.org](http://factorcode.org)).
407 FACTOR_ROOTS=. factor -run=stepX_YYY
412 The Fantom implementation of mal has been tested with Fantom 1.0.70.
416 make lib/fan/stepX_YYY.pod
429 The Go implementation of mal requires that go is installed on on the
430 path. The implementation has been tested with Go 1.3.1.
441 The Groovy implementation of mal requires Groovy to run and has been
442 tested with Groovy 1.8.6.
447 groovy ./stepX_YYY.groovy
454 guile -L ./ stepX_YYY.scm
459 The Smalltalk implementation of mal has been tested with GNU Smalltalk 3.2.91.
468 The Haskell implementation requires the ghc compiler version 7.10.1 or
469 later and also the Haskell parsec and readline (or editline) packages.
477 ### Haxe (Neko, Python, C++ and JavaScript)
479 The Haxe implementation of mal requires Haxe version 3.2 to compile.
480 Four different Haxe targets are supported: Neko, Python, C++, and
490 python3 ./stepX_YYY.py
501 The Hy implementation of mal has been tested with Hy 0.13.0.
510 The Io implementation of mal has been tested with Io version 20110905.
519 The Java implementation of mal requires maven2 to build.
524 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
526 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
539 The Julia implementation of mal requires Julia 0.4.
548 The Kotlin implementation of mal has been tested with Kotlin 1.0.
553 java -jar stepX_YYY.jar
558 The LiveScript implementation of mal has been tested with LiveScript 1.5.
563 node_modules/.bin/lsc stepX_YYY.ls
568 The Logo implementation of mal has been tested with UCBLogo 6.0.
577 The Lua implementation of mal has been tested with Lua 5.2. The
578 implementation requires that luarocks and the lua-rex-pcre library
583 make # to build and link linenoise.so
589 Running the mal implementation of mal involves running stepA of one of
590 the other implementations and passing the mal step to run as a command
595 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
608 The NASM implementation of mal is written for x86-64 Linux, and has been tested
609 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
619 The Nim implementation of mal has been tested with Nim 0.17.0.
631 The Object Pascal implementation of mal has been built and tested on
632 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
642 The Objective C implementation of mal has been built and tested on
643 Linux using clang/LLVM 3.6. It has also been built and tested on OS
660 ### MatLab (GNU Octave and MATLAB)
662 The MatLab implementation has been tested with GNU Octave 4.2.1.
663 It has also been tested with MATLAB version R2014a on Linux. Note that
664 MATLAB is a commercial product.
669 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
670 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
671 # OR with command line arguments
672 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
673 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
678 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
679 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
680 implementation of mal you need to download/install the miniMAL
681 interpreter (which requires Node.js).
684 # Download miniMAL and dependencies
686 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
687 # Now run mal implementation in miniMAL
693 For readline line editing support, install Term::ReadLine::Perl or
694 Term::ReadLine::Gnu from CPAN.
703 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
712 The PHP implementation of mal requires the php command line interface
722 The Picolisp implementation requires libreadline and Picolisp 3.1.11
730 ### PL/pgSQL (Postgres SQL Procedural Language)
732 The PL/pgSQL implementation of mal requires a running Postgres server
733 (the "kanaka/mal-test-plpgsql" docker image automatically starts
734 a Postgres server). The implementation connects to the Postgres server
735 and create a database named "mal" to store tables and stored
736 procedures. The wrapper script uses the psql command to connect to the
737 server and defaults to the user "postgres" but this can be overridden
738 with the PSQL_USER environment variable. A password can be specified
739 using the PGPASSWORD environment variable. The implementation has been
740 tested with Postgres 9.4.
744 ./wrap.sh stepX_YYY.sql
746 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
749 ### PL/SQL (Oracle SQL Procedural Language)
751 The PL/pgSQL implementation of mal requires a running Oracle DB
752 server (the "kanaka/mal-test-plsql" docker image automatically
753 starts an Oracle Express server). The implementation connects to the
754 Oracle server to create types, tables and stored procedures. The
755 default SQL*Plus logon value (username/password@connect_identifier) is
756 "system/oracle" but this can be overridden with the ORACLE_LOGON
757 environment variable. The implementation has been tested with Oracle
758 Express Edition 11g Release 2. Note that any SQL*Plus connection
759 warnings (user password expiration, etc) will interfere with the
760 ability of the wrapper script to communicate with the DB.
764 ./wrap.sh stepX_YYY.sql
766 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
769 ### Postscript Level 2/3
771 The Postscript implementation of mal requires ghostscript to run. It
772 has been tested with ghostscript 9.10.
776 gs -q -dNODISPLAY -I./ stepX_YYY.ps
781 The PowerShell implementation of mal requires the PowerShell script
782 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
786 powershell ./stepX_YYY.ps1
789 ### Python (2.X and 3.X)
798 You must have [rpython](https://rpython.readthedocs.org/) on your path
799 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
803 make # this takes a very long time
809 The R implementation of mal requires R (r-base-core) to run.
813 make libs # to download and build rdyncall
819 The Racket implementation of mal requires the Racket
820 compiler/interpreter to run.
829 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
834 rexx -a ./stepX_YYY.rexxpp
844 ### Rust (1.0.0 nightly)
846 The rust implementation of mal requires the rust compiler and build
847 tool (cargo) to build.
851 cargo run --release --bin stepX_YYY
856 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
860 sbt 'run-main stepX_YYY'
863 scala -classpath target/scala*/classes stepX_YYY
866 ### Scheme (R7RS) ###
868 The Scheme implementation of mal has been tested with Chibi-Scheme
869 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
870 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
871 be able to get it running on other conforming R7RS implementations
872 after figuring out how libraries are loaded and adjusting the
873 `Makefile` and `run` script accordingly.
879 scheme_MODE=chibi ./run
882 scheme_MODE=kawa ./run
884 scheme_MODE=gauche ./run
887 scheme_MODE=chicken ./run
889 scheme_MODE=sagittarius ./run
892 scheme_MODE=cyclone ./run
894 scheme_MODE=foment ./run
899 The Skew implementation of mal has been tested with Skew 0.7.42.
910 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
911 7.0) to build. Older versions will not work due to changes in the
912 language and standard library.
922 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
923 has been tested with Swift 3 Preview 3.
933 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
934 editing support, install tclreadline.
938 tclsh ./stepX_YYY.tcl
943 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
944 It has been tested with Node.js v6.
954 The VHDL implementation of mal has been tested with GHDL 0.29.
959 ./run_vhdl.sh ./stepX_YYY
964 The Vimscript implementation of mal requires Vim 8.0 to run.
968 ./run_vimscript.sh ./stepX_YYY.vim
971 ### Visual Basic.NET ###
973 The VB.NET implementation of mal has been tested on Linux using the Mono
974 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
975 required to build and run the VB.NET implementation.
983 ### WebAssembly (wasm) ###
985 The WebAssembly implementation is written in
986 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
987 runs under the [wac/wace](https://github.com/kanaka/wac) WebAssembly
993 wace ./stepX_YYY.wasm
998 The Yorick implementation of mal was tested on Yorick 2.2.04.
1002 yorick -batch ./stepX_YYY.i
1009 The top level Makefile has a number of useful targets to assist with
1010 implementation development and testing. The `help` target provides
1011 a list of the targets and options:
1017 ### Functional tests
1019 The are over 600 generic functional tests (for all implementations)
1020 in the `tests/` directory. Each step has a corresponding test file
1021 containing tests specific to that step. The `runtest.py` test harness
1022 launches a Mal step implementation and then feeds the tests one at
1023 a time to the implementation and compares the output/return value to
1024 the expected output/return value.
1026 * To run all the tests across all implementations (be prepared to wait):
1032 * To run all tests against a single implementation:
1042 * To run tests for a single step against all implementations:
1052 * To run tests for a specific step against a single implementation:
1055 make "test^IMPL^stepX"
1058 make "test^ruby^step3"
1059 make "test^ps^step4"
1062 ### Self-hosted functional tests
1064 * To run the functional tests in self-hosted mode, you specify `mal`
1065 as the test implementation and use the `MAL_IMPL` make variable
1066 to change the underlying host language (default is JavaScript):
1068 make MAL_IMPL=IMPL "test^mal^step2"
1071 make "test^mal^step2" # js is default
1072 make MAL_IMPL=ruby "test^mal^step2"
1073 make MAL_IMPL=python "test^mal^step2"
1076 ### Starting the REPL
1078 * To start the REPL of an implementation in a specific step:
1081 make "repl^IMPL^stepX"
1084 make "repl^ruby^step3"
1085 make "repl^ps^step4"
1088 * If you omit the step, then `stepA` is used:
1098 * To start the REPL of the self-hosted implementation, specify `mal` as the
1099 REPL implementation and use the `MAL_IMPL` make variable to change the
1100 underlying host language (default is JavaScript):
1102 make MAL_IMPL=IMPL "repl^mal^stepX"
1105 make "repl^mal^step2" # js is default
1106 make MAL_IMPL=ruby "repl^mal^step2"
1107 make MAL_IMPL=python "repl^mal"
1110 ### Performance tests
1112 Warning: These performance tests are neither statistically valid nor
1113 comprehensive; runtime performance is a not a primary goal of mal. If
1114 you draw any serious conclusions from these performance tests, then
1115 please contact me about some amazing oceanfront property in Kansas
1116 that I'm willing to sell you for cheap.
1118 * To run performance tests against a single implementation:
1126 * To run performance tests against all implementations:
1131 ### Generating language statistics
1133 * To report line and byte statistics for a single implementation:
1141 * To report line and bytes statistics for general Lisp code (env, core
1144 make "stats-lisp^IMPL"
1147 make "stats-lisp^js"
1150 ## Dockerized testing
1152 Every implementation directory contains a Dockerfile to create
1153 a docker image containing all the dependencies for that
1154 implementation. In addition, the top-level Makefile contains support
1155 for running the tests target (and perf, stats, repl, etc) within
1156 a docker container for that implementation by passing *"DOCKERIZE=1"*
1157 on the make command line. For example:
1160 make DOCKERIZE=1 "test^js^step3"
1163 Existing implementations already have docker images built and pushed
1164 to the docker registry. However, if
1165 you wish to build or rebuild a docker image locally, the toplevel
1166 Makefile provides a rule for building docker images:
1169 make "docker-build^IMPL"
1174 * Docker images are named *"kanaka/mal-test-IMPL"*
1175 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1176 you will probably need to run this command once manually
1177 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1178 runtime dependencies need to be downloaded to avoid the tests timing
1179 out. These dependencies are downloaded to dot-files in the /mal
1180 directory so they will persist between runs.
1183 ## External Implementations
1185 The following implementations are maintained as separate projects:
1189 * [by Alexander Bagnalla](https://github.com/bagnalla/holyc_mal)
1193 * [by Tim Morgan](https://github.com/seven1m/mal-rust)
1194 * [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).
1197 ## Projects using mal
1199 * [malc](https://github.com/dubek/malc) - Mal (Make A Lisp) compiler. Compiles a Mal program to LLVM assembly language, then binary.
1200 * [frock](https://github.com/chr15m/frock) - Clojure-flavoured PHP. Uses mal/php to run programs.
1204 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1205 License 2.0). See LICENSE.txt for more details.