5 Mal is a Clojure inspired Lisp interpreter.
7 Mal is implemented in 40 different languages:
19 * ES6 (ECMAScript 6 / ECMAScript 2015)
28 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
34 * [miniMAL](https://github.com/kanaka/miniMAL)
51 Mal is a learning tool. See the [make-a-lisp process
52 guide](process/guide.md). Each implementation of mal is separated into
53 11 incremental, self-contained (and testable) steps that demonstrate
54 core concepts of Lisp. The last step is capable of self-hosting
55 (running the mal implementation of mal).
57 The mal (make a lisp) steps are:
59 * [step0_repl](process/guide.md#step0)
60 * [step1_read_print](process/guide.md#step1)
61 * [step2_eval](process/guide.md#step2)
62 * [step3_env](process/guide.md#step3)
63 * [step4_if_fn_do](process/guide.md#step4)
64 * [step5_tco](process/guide.md#step5)
65 * [step6_file](process/guide.md#step6)
66 * [step7_quote](process/guide.md#step7)
67 * [step8_macros](process/guide.md#step8)
68 * [step9_try](process/guide.md#step9)
69 * [stepA_mal](process/guide.md#stepA)
72 Mal was presented publicly for the first time in a lightning talk at
73 Clojure West 2014 (unfortunately there is no video). See
74 mal/clojurewest2014.mal for the presentation that was given at the
75 conference (yes the presentation is a mal program).
77 If you are interesting in creating a mal implementation (or just
78 interested in using mal for something), please drop by the #mal
79 channel on freenode. In addition to the [make-a-lisp process
80 guide](process/guide.md) there is also a [mal/make-a-lisp
81 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
83 ## Building/running implementations
87 *The GNU awk implemenation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
89 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
93 gawk -O -f stepX_YYY.awk
105 The C implementation of mal requires the following libraries (lib and
106 header packages): glib, libffi6 and either the libedit or GNU readline library.
116 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
118 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
119 a readline compatible library to build. See the `cpp/README.md` for
133 The C# implementation of mal has been tested on Linux using the Mono
134 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
135 required to build and run the C# implementation.
148 lein with-profile +stepX trampoline run
154 sudo npm install -g coffee-script
161 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
163 The Crystal implemenation of mal has been tested with Crystal 0.7.2.
167 crystal run ./stepX_YYY.cr
169 make # needed to run tests
175 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
177 The Elixir implementation of mal has been tested with Elixir 1.0.5.
182 # Or with readline/line editing functionality:
188 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
190 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html) and [rebar](https://github.com/rebar/rebar) to build.
196 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
200 ### ES6 (ECMAScript 6 / ECMAScript 2015)
202 The ES6 implementation uses the [babel](https://babeljs.io) compiler
203 to generate ES5 compatible JavaScript. The generated code has been
204 tested with Node 0.12.4.
209 node build/stepX_YYY.js
215 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
217 The F# implementation of mal has been tested on Linux using the Mono
218 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
219 compiler (mcs) is also necessary to compile the readline dependency. All are
220 required to build and run the F# implementation.
230 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
232 The Factor implementation of mal has been tested with Factor 0.97
233 ([factorcode.org](factorcode.org)).
237 FACTOR_ROOTS=src factor -run=stepX_YYY
242 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
251 The Go implementation of mal requires that go is installed on on the
252 path. The implementation has been tested with Go 1.3.1.
263 The Groovy implementation of mal requires Groovy to run and has been
264 tested with Groovy 1.8.6.
269 groovy ./stepX_YYY.groovy
274 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
278 guile -L ./ stepX_YYY.scm
283 Install the Haskell compiler (ghc/ghci), the Haskell platform and
284 either the editline package (BSD) or the readline package (GPL). On
285 Ubuntu these packages are: ghc, haskell-platform,
286 libghc-readline-dev/libghc-editline-dev
297 The Java implementation of mal requires maven2 to build.
302 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
304 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
317 The Julia implementation of mal has been tested with Julia 0.3.7.
326 Running the Lua implementation of mal requires lua 5.1 or later,
327 luarocks and the lua-rex-pcre library installed.
331 make # to build and link linenoise.so
337 Running the mal implementation of mal involves running stepA of one of
338 the other implementations and passing the mal step to run as a command
343 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
356 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
358 Running the Nim implementation of mal requires Nim 0.11.0 or later.
370 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
380 The MATLAB implementation of mal has been tested with MATLAB version
381 R2014a on Linux. Note that MATLAB is a commercial product. It should
382 be fairly simple to support GNU Octave once it support classdef object
388 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
389 # OR with command line arguments
390 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
395 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
396 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
397 implementation of mal you need to download/install the miniMAL
398 interpreter (which requires Node.js).
401 # Download miniMAL and dependencies
403 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
404 # Now run mal implementation in miniMAL
410 For readline line editing support, install Term::ReadLine::Perl or
411 Term::ReadLine::Gnu from CPAN.
421 The PHP implementation of mal requires the php command line interface
429 ### Postscript Level 2/3
431 The Postscript implementation of mal requires ghostscript to run. It
432 has been tested with ghostscript 9.10.
436 gs -q -dNODISPLAY -I./ stepX_YYY.ps
439 ### Python (2.X or 3.X)
448 You must have [rpython](https://rpython.readthedocs.org/) on your path
449 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
453 make # this takes a long time
459 The R implementation of mal requires R (r-base-core) to run.
463 make libs # to download and build rdyncall
469 The Racket implementation of mal requires the Racket
470 compiler/interpreter to run.
484 ### Rust (1.0.0 nightly)
486 The rust implementation of mal requires the rust compiler and build
487 tool (cargo) to build.
491 cargo run --release --bin stepX_YYY
496 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
500 sbt 'run-main stepX_YYY'
503 scala -classpath target/scala*/classes stepX_YYY
508 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
510 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
511 7.0) to build. Older versions will not work due to changes in the
512 language and standard library.
520 ### Visual Basic.NET ###
522 The VB.NET implementation of mal has been tested on Linux using the Mono
523 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
524 required to build and run the VB.NET implementation.
538 The are nearly 500 generic functional tests (for all implementations)
539 in the `tests/` directory. Each step has a corresponding test file
540 containing tests specific to that step. The `runtest.py` test harness
541 launches a Mal step implementation and then feeds the tests one at
542 a time to the implementation and compares the output/return value to
543 the expected output/return value.
545 To simplify the process of running tests, a top level Makefile is
546 provided with convenient test targets.
548 * To run all the tests across all implementations (be prepared to wait):
554 * To run all tests against a single implementation:
564 * To run tests for a single step against all implementations:
574 * To run tests for a specifc step against a single implementation:
584 ### Self-hosted functional tests
586 * To run the functional tests in self-hosted mode, you specify `mal`
587 as the test implementation and use the `MAL_IMPL` make variable
588 to change the underlying host language (default is JavaScript):
590 make MAL_IMPL=IMPL test^mal^step2
593 make test^mal^step2 # js is default
594 make MAL_IMPL=ruby test^mal^step2
595 make MAL_IMPL=python test^mal^step2
599 ### Performance tests
601 Warning: These performance tests are neither statistically valid nor
602 comprehensive; runtime performance is a not a primary goal of mal. If
603 you draw any serious conclusions from these performance tests, then
604 please contact me about some amazing oceanfront property in Kansas
605 that I'm willing to sell you for cheap.
607 * To run performance tests against a single implementation:
615 * To run performance tests against all implementations:
620 ### Generating language statistics
622 * To report line and byte stastics for a single implementation:
630 * To report line and bytes stastics for general Lisp code (env, core
639 ## Docker test environment
641 There is a Dockerfile included in the `tests/docker` directory that
642 builds a docker image based on Ubuntu Utopic that contains everything
643 needed to run tests against all the implementations (except for MATLAB
644 which is proprietary/licensed).
646 Build the the docker image using a provided script. WARNING: this will
647 likely take over an hour to build from scratch and use more 3 GB of disk:
649 ./tests/docker-build.sh
652 Launch a docker container from that image built above. This will
653 volume mount the mal directory to `/mal` and then give you a bash
654 prompt in the container. You can then run individual mal
655 implementations and tests:
657 ./tests/docker-run.sh
660 You can also specify a command to run within the container. For
661 example, to run step2 tests for every implementation (except MATLAB):
663 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
667 * JVM-based language implementations (Java, Clojure, Scala): you will
668 need to run these implementations once manually first before you can
669 run tests because runtime dependencies need to be downloaded to
670 avoid the tests timing out. These dependencies are download to
671 dot-files in the /mal directory so they will persist between runs.
672 * Compiled languages: if your host system is different enough from
673 Ubuntu Utopic then you may need to re-compile your compiled
674 languages from within the container to avoid linker version
680 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
681 License 2.0). See LICENSE.txt for more details.