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 43 different languages:
21 * ES6 (ECMAScript 6 / ECMAScript 2015)
30 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
37 * [miniMAL](https://github.com/kanaka/miniMAL)
56 Mal is a learning tool. See the [make-a-lisp process
57 guide](process/guide.md). Each implementation of mal is separated into
58 11 incremental, self-contained (and testable) steps that demonstrate
59 core concepts of Lisp. The last step is capable of self-hosting
60 (running the mal implementation of mal).
62 The mal (make a lisp) steps are:
64 * [step0_repl](process/guide.md#step0)
65 * [step1_read_print](process/guide.md#step1)
66 * [step2_eval](process/guide.md#step2)
67 * [step3_env](process/guide.md#step3)
68 * [step4_if_fn_do](process/guide.md#step4)
69 * [step5_tco](process/guide.md#step5)
70 * [step6_file](process/guide.md#step6)
71 * [step7_quote](process/guide.md#step7)
72 * [step8_macros](process/guide.md#step8)
73 * [step9_try](process/guide.md#step9)
74 * [stepA_mal](process/guide.md#stepA)
77 Mal was presented publicly for the first time in a lightning talk at
78 Clojure West 2014 (unfortunately there is no video). See
79 mal/clojurewest2014.mal for the presentation that was given at the
80 conference (yes the presentation is a mal program).
82 If you are interesting in creating a mal implementation (or just
83 interested in using mal for something), please drop by the #mal
84 channel on freenode. In addition to the [make-a-lisp process
85 guide](process/guide.md) there is also a [mal/make-a-lisp
86 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
88 ## Building/running implementations
92 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
94 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
98 gawk -O -f stepX_YYY.awk
110 The C implementation of mal requires the following libraries (lib and
111 header packages): glib, libffi6 and either the libedit or GNU readline library.
121 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
123 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
124 a readline compatible library to build. See the `cpp/README.md` for
138 The C# implementation of mal has been tested on Linux using the Mono
139 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
140 required to build and run the C# implementation.
153 lein with-profile +stepX trampoline run
159 sudo npm install -g coffee-script
166 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
168 The Crystal implementation of mal has been tested with Crystal 0.8.0.
172 crystal run ./stepX_YYY.cr
174 make # needed to run tests
180 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
182 The Elixir implementation of mal has been tested with Elixir 1.0.5.
187 # Or with readline/line editing functionality:
193 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
195 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
196 and [rebar](https://github.com/rebar/rebar) to build.
202 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
206 ### ES6 (ECMAScript 6 / ECMAScript 2015)
208 The ES6 implementation uses the [babel](https://babeljs.io) compiler
209 to generate ES5 compatible JavaScript. The generated code has been
210 tested with Node 0.12.4.
215 node build/stepX_YYY.js
221 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
223 The F# implementation of mal has been tested on Linux using the Mono
224 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
225 compiler (mcs) is also necessary to compile the readline dependency. All are
226 required to build and run the F# implementation.
236 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
238 The Factor implementation of mal has been tested with Factor 0.97
239 ([factorcode.org](factorcode.org)).
243 FACTOR_ROOTS=. factor -run=stepX_YYY
248 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
257 The Go implementation of mal requires that go is installed on on the
258 path. The implementation has been tested with Go 1.3.1.
269 The Groovy implementation of mal requires Groovy to run and has been
270 tested with Groovy 1.8.6.
275 groovy ./stepX_YYY.groovy
280 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
284 guile -L ./ stepX_YYY.scm
289 Install the Haskell compiler (ghc/ghci), the Haskell platform and
290 either the editline package (BSD) or the readline package (GPL). On
291 Ubuntu these packages are: ghc, haskell-platform,
292 libghc-readline-dev/libghc-editline-dev
303 The Java implementation of mal requires maven2 to build.
308 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
310 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
323 The Julia implementation of mal requires Julia 0.4.
332 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
334 The Kotlin implementation of mal has been tested with Kotlin 1.0.0-beta.
339 java -jar stepX_YYY.jar
344 Running the Lua implementation of mal requires lua 5.1 or later,
345 luarocks and the lua-rex-pcre library installed.
349 make # to build and link linenoise.so
355 Running the mal implementation of mal involves running stepA of one of
356 the other implementations and passing the mal step to run as a command
361 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
374 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
376 Running the Nim implementation of mal requires Nim 0.11.0 or later.
388 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
398 The MATLAB implementation of mal has been tested with MATLAB version
399 R2014a on Linux. Note that MATLAB is a commercial product. It should
400 be fairly simple to support GNU Octave once it support classdef object
406 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
407 # OR with command line arguments
408 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
413 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
414 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
415 implementation of mal you need to download/install the miniMAL
416 interpreter (which requires Node.js).
419 # Download miniMAL and dependencies
421 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
422 # Now run mal implementation in miniMAL
428 For readline line editing support, install Term::ReadLine::Perl or
429 Term::ReadLine::Gnu from CPAN.
439 The PHP implementation of mal requires the php command line interface
447 ### Postscript Level 2/3
449 The Postscript implementation of mal requires ghostscript to run. It
450 has been tested with ghostscript 9.10.
454 gs -q -dNODISPLAY -I./ stepX_YYY.ps
457 ### Python (2.X or 3.X)
466 You must have [rpython](https://rpython.readthedocs.org/) on your path
467 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
471 make # this takes a very long time
477 The R implementation of mal requires R (r-base-core) to run.
481 make libs # to download and build rdyncall
487 The Racket implementation of mal requires the Racket
488 compiler/interpreter to run.
502 ### Rust (1.0.0 nightly)
504 The rust implementation of mal requires the rust compiler and build
505 tool (cargo) to build.
509 cargo run --release --bin stepX_YYY
514 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
518 sbt 'run-main stepX_YYY'
521 scala -classpath target/scala*/classes stepX_YYY
526 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
528 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
529 7.0) to build. Older versions will not work due to changes in the
530 language and standard library.
540 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
542 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
543 editing support, install tclreadline.
547 tclsh ./stepX_YYY.tcl
552 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
554 The Vimscript implementation of mal requires Vim to run. It has been tested
559 ./run_vimscript.sh ./stepX_YYY.vim
562 ### Visual Basic.NET ###
564 The VB.NET implementation of mal has been tested on Linux using the Mono
565 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
566 required to build and run the VB.NET implementation.
580 The are nearly 500 generic functional tests (for all implementations)
581 in the `tests/` directory. Each step has a corresponding test file
582 containing tests specific to that step. The `runtest.py` test harness
583 launches a Mal step implementation and then feeds the tests one at
584 a time to the implementation and compares the output/return value to
585 the expected output/return value.
587 To simplify the process of running tests, a top level Makefile is
588 provided with convenient test targets.
590 * To run all the tests across all implementations (be prepared to wait):
596 * To run all tests against a single implementation:
606 * To run tests for a single step against all implementations:
616 * To run tests for a specific step against a single implementation:
626 ### Self-hosted functional tests
628 * To run the functional tests in self-hosted mode, you specify `mal`
629 as the test implementation and use the `MAL_IMPL` make variable
630 to change the underlying host language (default is JavaScript):
632 make MAL_IMPL=IMPL test^mal^step2
635 make test^mal^step2 # js is default
636 make MAL_IMPL=ruby test^mal^step2
637 make MAL_IMPL=python test^mal^step2
641 ### Performance tests
643 Warning: These performance tests are neither statistically valid nor
644 comprehensive; runtime performance is a not a primary goal of mal. If
645 you draw any serious conclusions from these performance tests, then
646 please contact me about some amazing oceanfront property in Kansas
647 that I'm willing to sell you for cheap.
649 * To run performance tests against a single implementation:
657 * To run performance tests against all implementations:
662 ### Generating language statistics
664 * To report line and byte statistics for a single implementation:
672 * To report line and bytes statistics for general Lisp code (env, core
681 ## Docker test environment
683 There is a Dockerfile included in the `tests/docker` directory that
684 builds a docker image based on Ubuntu Utopic that contains everything
685 needed to run tests against all the implementations (except for MATLAB
686 which is proprietary/licensed).
688 Build the docker image using a provided script. WARNING: this will
689 likely take over an hour to build from scratch and use more 3 GB of disk:
691 ./tests/docker-build.sh
694 Launch a docker container from that image built above. This will
695 volume mount the mal directory to `/mal` and then give you a bash
696 prompt in the container. You can then run individual mal
697 implementations and tests:
699 ./tests/docker-run.sh
702 You can also specify a command to run within the container. For
703 example, to run step2 tests for every implementation (except MATLAB):
705 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
709 * JVM-based language implementations (Java, Clojure, Scala): you will
710 need to run these implementations once manually first before you can
711 run tests because runtime dependencies need to be downloaded to
712 avoid the tests timing out. These dependencies are download to
713 dot-files in the /mal directory so they will persist between runs.
714 * Compiled languages: if your host system is different enough from
715 Ubuntu Utopic then you may need to re-compile your compiled
716 languages from within the container to avoid linker version
722 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
723 License 2.0). See LICENSE.txt for more details.