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 44 different languages:
22 * ES6 (ECMAScript 6 / ECMAScript 2015)
31 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
38 * [miniMAL](https://github.com/kanaka/miniMAL)
57 Mal is a learning tool. See the [make-a-lisp process
58 guide](process/guide.md). Each implementation of mal is separated into
59 11 incremental, self-contained (and testable) steps that demonstrate
60 core concepts of Lisp. The last step is capable of self-hosting
61 (running the mal implementation of mal).
63 The mal (make a lisp) steps are:
65 * [step0_repl](process/guide.md#step0)
66 * [step1_read_print](process/guide.md#step1)
67 * [step2_eval](process/guide.md#step2)
68 * [step3_env](process/guide.md#step3)
69 * [step4_if_fn_do](process/guide.md#step4)
70 * [step5_tco](process/guide.md#step5)
71 * [step6_file](process/guide.md#step6)
72 * [step7_quote](process/guide.md#step7)
73 * [step8_macros](process/guide.md#step8)
74 * [step9_try](process/guide.md#step9)
75 * [stepA_mal](process/guide.md#stepA)
78 Mal was presented publicly for the first time in a lightning talk at
79 Clojure West 2014 (unfortunately there is no video). See
80 mal/clojurewest2014.mal for the presentation that was given at the
81 conference (yes the presentation is a mal program).
83 If you are interesting in creating a mal implementation (or just
84 interested in using mal for something), please drop by the #mal
85 channel on freenode. In addition to the [make-a-lisp process
86 guide](process/guide.md) there is also a [mal/make-a-lisp
87 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
89 ## Building/running implementations
93 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
95 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
99 gawk -O -f stepX_YYY.awk
111 The C implementation of mal requires the following libraries (lib and
112 header packages): glib, libffi6 and either the libedit or GNU readline library.
122 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
124 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
125 a readline compatible library to build. See the `cpp/README.md` for
139 The C# implementation of mal has been tested on Linux using the Mono
140 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
141 required to build and run the C# implementation.
152 For the most part the Clojure implementation requires Clojure 1.5,
153 however, to pass all tests, Clojure 1.8.0-RC4 is required.
157 lein with-profile +stepX trampoline run
163 sudo npm install -g coffee-script
170 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
172 The Crystal implementation of mal has been tested with Crystal 0.10.0.
176 crystal run ./stepX_YYY.cr
178 make # needed to run tests
184 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
186 The D implementation of mal was tested with GDC 4.8. It requires the GNU
197 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
199 The Elixir implementation of mal has been tested with Elixir 1.0.5.
204 # Or with readline/line editing functionality:
210 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
212 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
213 and [rebar](https://github.com/rebar/rebar) to build.
219 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
223 ### ES6 (ECMAScript 6 / ECMAScript 2015)
225 The ES6 implementation uses the [babel](https://babeljs.io) compiler
226 to generate ES5 compatible JavaScript. The generated code has been
227 tested with Node 0.12.4.
232 node build/stepX_YYY.js
238 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
240 The F# implementation of mal has been tested on Linux using the Mono
241 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
242 compiler (mcs) is also necessary to compile the readline dependency. All are
243 required to build and run the F# implementation.
253 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
255 The Factor implementation of mal has been tested with Factor 0.97
256 ([factorcode.org](factorcode.org)).
260 FACTOR_ROOTS=. factor -run=stepX_YYY
265 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
274 The Go implementation of mal requires that go is installed on on the
275 path. The implementation has been tested with Go 1.3.1.
286 The Groovy implementation of mal requires Groovy to run and has been
287 tested with Groovy 1.8.6.
292 groovy ./stepX_YYY.groovy
297 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
301 guile -L ./ stepX_YYY.scm
306 Install the Haskell compiler (ghc/ghci), the Haskell platform and
307 either the editline package (BSD) or the readline package (GPL). On
308 Ubuntu these packages are: ghc, haskell-platform,
309 libghc-readline-dev/libghc-editline-dev
320 The Java implementation of mal requires maven2 to build.
325 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
327 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
340 The Julia implementation of mal requires Julia 0.4.
349 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
351 The Kotlin implementation of mal has been tested with Kotlin 1.0.0-beta.
356 java -jar stepX_YYY.jar
361 Running the Lua implementation of mal requires lua 5.1 or later,
362 luarocks and the lua-rex-pcre library installed.
366 make # to build and link linenoise.so
372 Running the mal implementation of mal involves running stepA of one of
373 the other implementations and passing the mal step to run as a command
378 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
391 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
393 Running the Nim implementation of mal requires Nim 0.11.0 or later.
405 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
415 The MATLAB implementation of mal has been tested with MATLAB version
416 R2014a on Linux. Note that MATLAB is a commercial product. It should
417 be fairly simple to support GNU Octave once it support classdef object
423 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
424 # OR with command line arguments
425 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
430 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
431 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
432 implementation of mal you need to download/install the miniMAL
433 interpreter (which requires Node.js).
436 # Download miniMAL and dependencies
438 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
439 # Now run mal implementation in miniMAL
445 For readline line editing support, install Term::ReadLine::Perl or
446 Term::ReadLine::Gnu from CPAN.
456 The PHP implementation of mal requires the php command line interface
464 ### Postscript Level 2/3
466 The Postscript implementation of mal requires ghostscript to run. It
467 has been tested with ghostscript 9.10.
471 gs -q -dNODISPLAY -I./ stepX_YYY.ps
474 ### Python (2.X or 3.X)
483 You must have [rpython](https://rpython.readthedocs.org/) on your path
484 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
488 make # this takes a very long time
494 The R implementation of mal requires R (r-base-core) to run.
498 make libs # to download and build rdyncall
504 The Racket implementation of mal requires the Racket
505 compiler/interpreter to run.
519 ### Rust (1.0.0 nightly)
521 The rust implementation of mal requires the rust compiler and build
522 tool (cargo) to build.
526 cargo run --release --bin stepX_YYY
531 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
535 sbt 'run-main stepX_YYY'
538 scala -classpath target/scala*/classes stepX_YYY
543 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
545 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
546 7.0) to build. Older versions will not work due to changes in the
547 language and standard library.
557 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
559 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
560 editing support, install tclreadline.
564 tclsh ./stepX_YYY.tcl
569 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
571 The Vimscript implementation of mal requires Vim to run. It has been tested
576 ./run_vimscript.sh ./stepX_YYY.vim
579 ### Visual Basic.NET ###
581 The VB.NET implementation of mal has been tested on Linux using the Mono
582 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
583 required to build and run the VB.NET implementation.
597 The are nearly 500 generic functional tests (for all implementations)
598 in the `tests/` directory. Each step has a corresponding test file
599 containing tests specific to that step. The `runtest.py` test harness
600 launches a Mal step implementation and then feeds the tests one at
601 a time to the implementation and compares the output/return value to
602 the expected output/return value.
604 To simplify the process of running tests, a top level Makefile is
605 provided with convenient test targets.
607 * To run all the tests across all implementations (be prepared to wait):
613 * To run all tests against a single implementation:
623 * To run tests for a single step against all implementations:
633 * To run tests for a specific step against a single implementation:
636 make "test^IMPL^stepX"
639 make "test^ruby^step3"
643 ### Self-hosted functional tests
645 * To run the functional tests in self-hosted mode, you specify `mal`
646 as the test implementation and use the `MAL_IMPL` make variable
647 to change the underlying host language (default is JavaScript):
649 make MAL_IMPL=IMPL "test^mal^step2"
652 make "test^mal^step2" # js is default
653 make MAL_IMPL=ruby "test^mal^step2"
654 make MAL_IMPL=python "test^mal^step2"
657 ### Starting the REPL
659 * To start the REPL of an implementation in a specific step:
662 make "repl^IMPL^stepX"
665 make "repl^ruby^step3"
669 * If you omit the step, then `stepA` is used:
679 * To start the REPL of the self-hosted implementation, specify `mal` as the
680 REPL implementation and use the `MAL_IMPL` make variable to change the
681 underlying host language (default is JavaScript):
683 make MAL_IMPL=IMPL "repl^mal^stepX"
686 make "repl^mal^step2" # js is default
687 make MAL_IMPL=ruby "repl^mal^step2"
688 make MAL_IMPL=python "repl^mal"
691 ### Performance tests
693 Warning: These performance tests are neither statistically valid nor
694 comprehensive; runtime performance is a not a primary goal of mal. If
695 you draw any serious conclusions from these performance tests, then
696 please contact me about some amazing oceanfront property in Kansas
697 that I'm willing to sell you for cheap.
699 * To run performance tests against a single implementation:
707 * To run performance tests against all implementations:
712 ### Generating language statistics
714 * To report line and byte statistics for a single implementation:
722 * To report line and bytes statistics for general Lisp code (env, core
725 make "stats-lisp^IMPL"
731 ## Docker test environment
733 There is a Dockerfile included in the `tests/docker` directory that
734 builds a docker image based on Ubuntu Utopic that contains everything
735 needed to run tests against all the implementations (except for MATLAB
736 which is proprietary/licensed).
738 Build the docker image using a provided script. WARNING: this will
739 likely take over an hour to build from scratch and use more 3 GB of disk:
741 ./tests/docker-build.sh
744 Launch a docker container from that image built above. This will
745 volume mount the mal directory to `/mal` and then give you a bash
746 prompt in the container. You can then run individual mal
747 implementations and tests:
749 ./tests/docker-run.sh
752 You can also specify a command to run within the container. For
753 example, to run step2 tests for every implementation (except MATLAB):
755 ./tests/docker-run.sh make SKIP_IMPLS="matlab" "test^step2"
759 * JVM-based language implementations (Java, Clojure, Scala): you will
760 need to run these implementations once manually first before you can
761 run tests because runtime dependencies need to be downloaded to
762 avoid the tests timing out. These dependencies are download to
763 dot-files in the /mal directory so they will persist between runs.
764 * Compiled languages: if your host system is different enough from
765 Ubuntu Utopic then you may need to re-compile your compiled
766 languages from within the container to avoid linker version
772 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
773 License 2.0). See LICENSE.txt for more details.