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 40 different languages:
21 * ES6 (ECMAScript 6 / ECMAScript 2015)
30 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
36 * [miniMAL](https://github.com/kanaka/miniMAL)
53 Mal is a learning tool. See the [make-a-lisp process
54 guide](process/guide.md). Each implementation of mal is separated into
55 11 incremental, self-contained (and testable) steps that demonstrate
56 core concepts of Lisp. The last step is capable of self-hosting
57 (running the mal implementation of mal).
59 The mal (make a lisp) steps are:
61 * [step0_repl](process/guide.md#step0)
62 * [step1_read_print](process/guide.md#step1)
63 * [step2_eval](process/guide.md#step2)
64 * [step3_env](process/guide.md#step3)
65 * [step4_if_fn_do](process/guide.md#step4)
66 * [step5_tco](process/guide.md#step5)
67 * [step6_file](process/guide.md#step6)
68 * [step7_quote](process/guide.md#step7)
69 * [step8_macros](process/guide.md#step8)
70 * [step9_try](process/guide.md#step9)
71 * [stepA_mal](process/guide.md#stepA)
74 Mal was presented publicly for the first time in a lightning talk at
75 Clojure West 2014 (unfortunately there is no video). See
76 mal/clojurewest2014.mal for the presentation that was given at the
77 conference (yes the presentation is a mal program).
79 If you are interesting in creating a mal implementation (or just
80 interested in using mal for something), please drop by the #mal
81 channel on freenode. In addition to the [make-a-lisp process
82 guide](process/guide.md) there is also a [mal/make-a-lisp
83 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
85 ## Building/running implementations
89 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
91 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
95 gawk -O -f stepX_YYY.awk
107 The C implementation of mal requires the following libraries (lib and
108 header packages): glib, libffi6 and either the libedit or GNU readline library.
118 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
120 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
121 a readline compatible library to build. See the `cpp/README.md` for
135 The C# implementation of mal has been tested on Linux using the Mono
136 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
137 required to build and run the C# implementation.
150 lein with-profile +stepX trampoline run
156 sudo npm install -g coffee-script
163 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
165 The Crystal implementation of mal has been tested with Crystal 0.8.0.
169 crystal run ./stepX_YYY.cr
171 make # needed to run tests
177 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
179 The Elixir implementation of mal has been tested with Elixir 1.0.5.
184 # Or with readline/line editing functionality:
190 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
192 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html) and [rebar](https://github.com/rebar/rebar) to build.
198 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
202 ### ES6 (ECMAScript 6 / ECMAScript 2015)
204 The ES6 implementation uses the [babel](https://babeljs.io) compiler
205 to generate ES5 compatible JavaScript. The generated code has been
206 tested with Node 0.12.4.
211 node build/stepX_YYY.js
217 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
219 The F# implementation of mal has been tested on Linux using the Mono
220 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
221 compiler (mcs) is also necessary to compile the readline dependency. All are
222 required to build and run the F# implementation.
232 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
234 The Factor implementation of mal has been tested with Factor 0.97
235 ([factorcode.org](factorcode.org)).
239 FACTOR_ROOTS=src factor -run=stepX_YYY
244 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
253 The Go implementation of mal requires that go is installed on on the
254 path. The implementation has been tested with Go 1.3.1.
265 The Groovy implementation of mal requires Groovy to run and has been
266 tested with Groovy 1.8.6.
271 groovy ./stepX_YYY.groovy
276 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
280 guile -L ./ stepX_YYY.scm
285 Install the Haskell compiler (ghc/ghci), the Haskell platform and
286 either the editline package (BSD) or the readline package (GPL). On
287 Ubuntu these packages are: ghc, haskell-platform,
288 libghc-readline-dev/libghc-editline-dev
299 The Java implementation of mal requires maven2 to build.
304 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
306 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
319 The Julia implementation of mal has been tested with Julia 0.3.7.
328 Running the Lua implementation of mal requires lua 5.1 or later,
329 luarocks and the lua-rex-pcre library installed.
333 make # to build and link linenoise.so
339 Running the mal implementation of mal involves running stepA of one of
340 the other implementations and passing the mal step to run as a command
345 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
358 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
360 Running the Nim implementation of mal requires Nim 0.11.0 or later.
372 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
382 The MATLAB implementation of mal has been tested with MATLAB version
383 R2014a on Linux. Note that MATLAB is a commercial product. It should
384 be fairly simple to support GNU Octave once it support classdef object
390 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
391 # OR with command line arguments
392 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
397 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
398 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
399 implementation of mal you need to download/install the miniMAL
400 interpreter (which requires Node.js).
403 # Download miniMAL and dependencies
405 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
406 # Now run mal implementation in miniMAL
412 For readline line editing support, install Term::ReadLine::Perl or
413 Term::ReadLine::Gnu from CPAN.
423 The PHP implementation of mal requires the php command line interface
431 ### Postscript Level 2/3
433 The Postscript implementation of mal requires ghostscript to run. It
434 has been tested with ghostscript 9.10.
438 gs -q -dNODISPLAY -I./ stepX_YYY.ps
441 ### Python (2.X or 3.X)
450 You must have [rpython](https://rpython.readthedocs.org/) on your path
451 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
455 make # this takes a long time
461 The R implementation of mal requires R (r-base-core) to run.
465 make libs # to download and build rdyncall
471 The Racket implementation of mal requires the Racket
472 compiler/interpreter to run.
486 ### Rust (1.0.0 nightly)
488 The rust implementation of mal requires the rust compiler and build
489 tool (cargo) to build.
493 cargo run --release --bin stepX_YYY
498 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
502 sbt 'run-main stepX_YYY'
505 scala -classpath target/scala*/classes stepX_YYY
510 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
512 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
513 7.0) to build. Older versions will not work due to changes in the
514 language and standard library.
522 ### Visual Basic.NET ###
524 The VB.NET implementation of mal has been tested on Linux using the Mono
525 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
526 required to build and run the VB.NET implementation.
540 The are nearly 500 generic functional tests (for all implementations)
541 in the `tests/` directory. Each step has a corresponding test file
542 containing tests specific to that step. The `runtest.py` test harness
543 launches a Mal step implementation and then feeds the tests one at
544 a time to the implementation and compares the output/return value to
545 the expected output/return value.
547 To simplify the process of running tests, a top level Makefile is
548 provided with convenient test targets.
550 * To run all the tests across all implementations (be prepared to wait):
556 * To run all tests against a single implementation:
566 * To run tests for a single step against all implementations:
576 * To run tests for a specific step against a single implementation:
586 ### Self-hosted functional tests
588 * To run the functional tests in self-hosted mode, you specify `mal`
589 as the test implementation and use the `MAL_IMPL` make variable
590 to change the underlying host language (default is JavaScript):
592 make MAL_IMPL=IMPL test^mal^step2
595 make test^mal^step2 # js is default
596 make MAL_IMPL=ruby test^mal^step2
597 make MAL_IMPL=python test^mal^step2
601 ### Performance tests
603 Warning: These performance tests are neither statistically valid nor
604 comprehensive; runtime performance is a not a primary goal of mal. If
605 you draw any serious conclusions from these performance tests, then
606 please contact me about some amazing oceanfront property in Kansas
607 that I'm willing to sell you for cheap.
609 * To run performance tests against a single implementation:
617 * To run performance tests against all implementations:
622 ### Generating language statistics
624 * To report line and byte statistics for a single implementation:
632 * To report line and bytes statistics for general Lisp code (env, core
641 ## Docker test environment
643 There is a Dockerfile included in the `tests/docker` directory that
644 builds a docker image based on Ubuntu Utopic that contains everything
645 needed to run tests against all the implementations (except for MATLAB
646 which is proprietary/licensed).
648 Build the docker image using a provided script. WARNING: this will
649 likely take over an hour to build from scratch and use more 3 GB of disk:
651 ./tests/docker-build.sh
654 Launch a docker container from that image built above. This will
655 volume mount the mal directory to `/mal` and then give you a bash
656 prompt in the container. You can then run individual mal
657 implementations and tests:
659 ./tests/docker-run.sh
662 You can also specify a command to run within the container. For
663 example, to run step2 tests for every implementation (except MATLAB):
665 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
669 * JVM-based language implementations (Java, Clojure, Scala): you will
670 need to run these implementations once manually first before you can
671 run tests because runtime dependencies need to be downloaded to
672 avoid the tests timing out. These dependencies are download to
673 dot-files in the /mal directory so they will persist between runs.
674 * Compiled languages: if your host system is different enough from
675 Ubuntu Utopic then you may need to re-compile your compiled
676 languages from within the container to avoid linker version
682 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
683 License 2.0). See LICENSE.txt for more details.