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 47 languages:
23 * ES6 (ECMAScript 6 / ECMAScript 2015)
33 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
40 * [miniMAL](https://github.com/kanaka/miniMAL)
60 Mal is a learning tool. See the [make-a-lisp process
61 guide](process/guide.md). Each implementation of mal is separated into
62 11 incremental, self-contained (and testable) steps that demonstrate
63 core concepts of Lisp. The last step is capable of self-hosting
64 (running the mal implementation of mal).
66 The mal (make a lisp) steps are:
68 * [step0_repl](process/guide.md#step0)
69 * [step1_read_print](process/guide.md#step1)
70 * [step2_eval](process/guide.md#step2)
71 * [step3_env](process/guide.md#step3)
72 * [step4_if_fn_do](process/guide.md#step4)
73 * [step5_tco](process/guide.md#step5)
74 * [step6_file](process/guide.md#step6)
75 * [step7_quote](process/guide.md#step7)
76 * [step8_macros](process/guide.md#step8)
77 * [step9_try](process/guide.md#step9)
78 * [stepA_mal](process/guide.md#stepA)
81 Mal was presented publicly for the first time in a lightning talk at
82 Clojure West 2014 (unfortunately there is no video). See
83 mal/clojurewest2014.mal for the presentation that was given at the
84 conference (yes the presentation is a mal program).
86 If you are interesting in creating a mal implementation (or just
87 interested in using mal for something), please drop by the #mal
88 channel on freenode. In addition to the [make-a-lisp process
89 guide](process/guide.md) there is also a [mal/make-a-lisp
90 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
92 ## Building/running implementations
96 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
98 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
102 gawk -O -f stepX_YYY.awk
114 The C implementation of mal requires the following libraries (lib and
115 header packages): glib, libffi6 and either the libedit or GNU readline library.
125 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
127 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
128 a readline compatible library to build. See the `cpp/README.md` for
142 The C# implementation of mal has been tested on Linux using the Mono
143 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
144 required to build and run the C# implementation.
155 For the most part the Clojure implementation requires Clojure 1.5,
156 however, to pass all tests, Clojure 1.8.0-RC4 is required.
160 lein with-profile +stepX trampoline run
166 sudo npm install -g coffee-script
173 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
175 The Crystal implementation of mal has been tested with Crystal 0.10.0.
179 crystal run ./stepX_YYY.cr
181 make # needed to run tests
187 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
189 The D implementation of mal was tested with GDC 4.8. It requires the GNU
200 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
202 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
203 and 24.5. While there is very basic readline editing (`<backspace>`
204 and `C-d` work, `C-c` cancels the process), it is recommended to use
209 emacs -Q --batch --load stepX_YYY.el
210 # with full readline support
211 rlwrap emacs -Q --batch --load stepX_YYY.el
216 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
218 The Elixir implementation of mal has been tested with Elixir 1.0.5.
223 # Or with readline/line editing functionality:
229 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
231 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
232 and [rebar](https://github.com/rebar/rebar) to build.
238 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
242 ### ES6 (ECMAScript 6 / ECMAScript 2015)
244 The ES6 implementation uses the [babel](https://babeljs.io) compiler
245 to generate ES5 compatible JavaScript. The generated code has been
246 tested with Node 0.12.4.
251 node build/stepX_YYY.js
257 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
259 The F# implementation of mal has been tested on Linux using the Mono
260 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
261 compiler (mcs) is also necessary to compile the readline dependency. All are
262 required to build and run the F# implementation.
272 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
274 The Factor implementation of mal has been tested with Factor 0.97
275 ([factorcode.org](factorcode.org)).
279 FACTOR_ROOTS=. factor -run=stepX_YYY
284 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
293 The Go implementation of mal requires that go is installed on on the
294 path. The implementation has been tested with Go 1.3.1.
305 The Groovy implementation of mal requires Groovy to run and has been
306 tested with Groovy 1.8.6.
311 groovy ./stepX_YYY.groovy
316 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
320 guile -L ./ stepX_YYY.scm
325 Install the Haskell compiler (ghc/ghci), the Haskell platform and
326 either the editline package (BSD) or the readline package (GPL). On
327 Ubuntu these packages are: ghc, haskell-platform,
328 libghc-readline-dev/libghc-editline-dev
338 The Haxe implementation of mal requires Haxe version 3.2 to compile.
339 Four different Haxe targets are supported: Neko, Python, C++, and
349 python3 ./stepX_YYY.py
361 The Java implementation of mal requires maven2 to build.
366 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
368 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
381 The Julia implementation of mal requires Julia 0.4.
390 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
392 The Kotlin implementation of mal has been tested with Kotlin 1.0.
397 java -jar stepX_YYY.jar
402 Running the Lua implementation of mal requires lua 5.1 or later,
403 luarocks and the lua-rex-pcre library installed.
407 make # to build and link linenoise.so
413 Running the mal implementation of mal involves running stepA of one of
414 the other implementations and passing the mal step to run as a command
419 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
432 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
434 Running the Nim implementation of mal requires Nim 0.11.0 or later.
446 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
456 The MATLAB implementation of mal has been tested with MATLAB version
457 R2014a on Linux. Note that MATLAB is a commercial product. It should
458 be fairly simple to support GNU Octave once it support classdef object
464 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
465 # OR with command line arguments
466 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
471 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
472 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
473 implementation of mal you need to download/install the miniMAL
474 interpreter (which requires Node.js).
477 # Download miniMAL and dependencies
479 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
480 # Now run mal implementation in miniMAL
486 For readline line editing support, install Term::ReadLine::Perl or
487 Term::ReadLine::Gnu from CPAN.
497 The PHP implementation of mal requires the php command line interface
505 ### Postscript Level 2/3
507 The Postscript implementation of mal requires ghostscript to run. It
508 has been tested with ghostscript 9.10.
512 gs -q -dNODISPLAY -I./ stepX_YYY.ps
515 ### Python (2.X or 3.X)
524 You must have [rpython](https://rpython.readthedocs.org/) on your path
525 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
529 make # this takes a very long time
535 The R implementation of mal requires R (r-base-core) to run.
539 make libs # to download and build rdyncall
545 The Racket implementation of mal requires the Racket
546 compiler/interpreter to run.
560 ### Rust (1.0.0 nightly)
562 The rust implementation of mal requires the rust compiler and build
563 tool (cargo) to build.
567 cargo run --release --bin stepX_YYY
572 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
576 sbt 'run-main stepX_YYY'
579 scala -classpath target/scala*/classes stepX_YYY
584 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
586 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
587 7.0) to build. Older versions will not work due to changes in the
588 language and standard library.
598 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
599 has been tested with the development version of the Swift 3 from
610 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
612 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
613 editing support, install tclreadline.
617 tclsh ./stepX_YYY.tcl
622 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
624 The Vimscript implementation of mal requires Vim to run. It has been tested
629 ./run_vimscript.sh ./stepX_YYY.vim
632 ### Visual Basic.NET ###
634 The VB.NET implementation of mal has been tested on Linux using the Mono
635 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
636 required to build and run the VB.NET implementation.
650 The are nearly 500 generic functional tests (for all implementations)
651 in the `tests/` directory. Each step has a corresponding test file
652 containing tests specific to that step. The `runtest.py` test harness
653 launches a Mal step implementation and then feeds the tests one at
654 a time to the implementation and compares the output/return value to
655 the expected output/return value.
657 To simplify the process of running tests, a top level Makefile is
658 provided with convenient test targets.
660 * To run all the tests across all implementations (be prepared to wait):
666 * To run all tests against a single implementation:
676 * To run tests for a single step against all implementations:
686 * To run tests for a specific step against a single implementation:
689 make "test^IMPL^stepX"
692 make "test^ruby^step3"
696 ### Self-hosted functional tests
698 * To run the functional tests in self-hosted mode, you specify `mal`
699 as the test implementation and use the `MAL_IMPL` make variable
700 to change the underlying host language (default is JavaScript):
702 make MAL_IMPL=IMPL "test^mal^step2"
705 make "test^mal^step2" # js is default
706 make MAL_IMPL=ruby "test^mal^step2"
707 make MAL_IMPL=python "test^mal^step2"
710 ### Starting the REPL
712 * To start the REPL of an implementation in a specific step:
715 make "repl^IMPL^stepX"
718 make "repl^ruby^step3"
722 * If you omit the step, then `stepA` is used:
732 * To start the REPL of the self-hosted implementation, specify `mal` as the
733 REPL implementation and use the `MAL_IMPL` make variable to change the
734 underlying host language (default is JavaScript):
736 make MAL_IMPL=IMPL "repl^mal^stepX"
739 make "repl^mal^step2" # js is default
740 make MAL_IMPL=ruby "repl^mal^step2"
741 make MAL_IMPL=python "repl^mal"
744 ### Performance tests
746 Warning: These performance tests are neither statistically valid nor
747 comprehensive; runtime performance is a not a primary goal of mal. If
748 you draw any serious conclusions from these performance tests, then
749 please contact me about some amazing oceanfront property in Kansas
750 that I'm willing to sell you for cheap.
752 * To run performance tests against a single implementation:
760 * To run performance tests against all implementations:
765 ### Generating language statistics
767 * To report line and byte statistics for a single implementation:
775 * To report line and bytes statistics for general Lisp code (env, core
778 make "stats-lisp^IMPL"
784 ## Docker test environment
786 There is a Dockerfile included in the `tests/docker` directory that
787 builds a docker image based on Ubuntu Utopic that contains everything
788 needed to run tests against all the implementations (except for MATLAB
789 which is proprietary/licensed).
791 Build the docker image using a provided script. WARNING: this will
792 likely take over an hour to build from scratch and use more 3 GB of disk:
794 ./tests/docker-build.sh
797 Launch a docker container from that image built above. This will
798 volume mount the mal directory to `/mal` and then give you a bash
799 prompt in the container. You can then run individual mal
800 implementations and tests:
802 ./tests/docker-run.sh
805 You can also specify a command to run within the container. For
806 example, to run step2 tests for every implementation (except MATLAB):
808 ./tests/docker-run.sh make SKIP_IMPLS="matlab" "test^step2"
812 * JVM-based language implementations (Java, Clojure, Scala): you will
813 need to run these implementations once manually first before you can
814 run tests because runtime dependencies need to be downloaded to
815 avoid the tests timing out. These dependencies are download to
816 dot-files in the /mal directory so they will persist between runs.
817 * Compiled languages: if your host system is different enough from
818 Ubuntu Utopic then you may need to re-compile your compiled
819 languages from within the container to avoid linker version
825 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
826 License 2.0). See LICENSE.txt for more details.