5 Mal is a Clojure inspired Lisp interpreter.
7 Mal is implemented in 30 different languages:
19 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
25 * [miniMAL](https://github.com/kanaka/miniMAL)
41 Mal is a learning tool. See the [make-a-lisp process
42 guide](process/guide.md). Each implementation of mal is separated into
43 11 incremental, self-contained (and testable) steps that demonstrate
44 core concepts of Lisp. The last step is capable of self-hosting
45 (running the mal implementation of mal).
47 The mal (make a lisp) steps are:
49 * [step0_repl](process/guide.md#step0)
50 * [step1_read_print](process/guide.md#step1)
51 * [step2_eval](process/guide.md#step2)
52 * [step3_env](process/guide.md#step3)
53 * [step4_if_fn_do](process/guide.md#step4)
54 * [step5_tco](process/guide.md#step5)
55 * [step6_file](process/guide.md#step6)
56 * [step7_quote](process/guide.md#step7)
57 * [step8_macros](process/guide.md#step8)
58 * [step9_try](process/guide.md#step9)
59 * [stepA_mal](process/guide.md#stepA)
62 Mal was presented publicly for the first time in a lightning talk at
63 Clojure West 2014 (unfortunately there is no video). See
64 mal/clojurewest2014.mal for the presentation that was given at the
65 conference (yes the presentation is a mal program).
67 If you are interesting in creating a mal implementation (or just
68 interested in using mal for something), please drop by the #mal
69 channel on freenode. In addition to the [make-a-lisp process
70 guide](process/guide.md) there is also a [mal/make-a-lisp
71 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
73 ## Building/running implementations
84 The C implementation of mal requires the following libraries (lib and
85 header packages): glib, libffi6 and either the libedit or GNU readline library.
95 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
97 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
98 a readline compatible library to build. See the `cpp/README.md` for
112 The C# implementation of mal has been tested on Linux using the Mono
113 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
114 required to build and run the C# implementation.
127 lein with-profile +stepX trampoline run
133 sudo npm install -g coffee-script
140 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
149 You Go implementation of mal requires that go is installed on on the
150 path. The implementation has been tested with Go 1.3.1.
161 Install the Haskell compiler (ghc/ghci), the Haskell platform and
162 either the editline package (BSD) or the readline package (GPL). On
163 Ubuntu these packages are: ghc, haskell-platform,
164 libghc-readline-dev/libghc-editline-dev
175 The Java implementation of mal requires maven2 to build.
180 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
182 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
195 The Julia implementation of mal has been tested with Julia 0.3.7.
204 Running the Lua implementation of mal requires lua 5.1 or later,
205 luarocks and the lua-rex-pcre library installed.
209 make # to build and link linenoise.so
215 Running the mal implementation of mal involves running stepA of one of
216 the other implementations and passing the mal step to run as a command
221 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
234 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
236 Running the Nim implementation of mal requires Nim's current devel branch
237 (0.10.3) or later, and the nre library installed.
249 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
259 The MATLAB implementation of mal has been tested with MATLAB version
260 R2014a on Linux. Note that MATLAB is a commercial product. It should
261 be fairly simple to support GNU Octave once it support classdef object
267 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
268 # OR with command line arguments
269 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
274 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
275 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
276 implementation of mal you need to download/install the miniMAL
277 interpreter (which requires Node.js).
280 # Download miniMAL and dependencies
282 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
283 # Now run mal implementation in miniMAL
289 For readline line editing support, install Term::ReadLine::Perl or
290 Term::ReadLine::Gnu from CPAN.
300 The PHP implementation of mal requires the php command line interface
308 ### Postscript Level 2/3
310 The Postscript implementation of mal requires ghostscript to run. It
311 has been tested with ghostscript 9.10.
315 gs -q -dNODISPLAY -I./ stepX_YYY.ps
327 The R implementation of mal requires R (r-base-core) to run.
331 make libs # to download and build rdyncall
337 The Racket implementation of mal requires the Racket
338 compiler/interpreter to run.
352 ### Rust (1.0.0 nightly)
354 The rust implementation of mal requires the rust compiler and build
355 tool (cargo) to build.
359 cargo run --release --bin stepX_YYY
364 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
368 sbt 'run-main stepX_YYY'
371 scala -classpath target/scala*/classes stepX_YYY
376 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
378 The Swift implemenation of mal requires the Swift compiler (XCode) to
387 ### Visual Basic.NET ###
389 The VB.NET implementation of mal has been tested on Linux using the Mono
390 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
391 required to build and run the VB.NET implementation.
405 The are nearly 500 generic functional tests (for all implementations)
406 in the `tests/` directory. Each step has a corresponding test file
407 containing tests specific to that step. The `runtest.py` test harness
408 launches a Mal step implementation and then feeds the tests one at
409 a time to the implementation and compares the output/return value to
410 the expected output/return value.
412 To simplify the process of running tests, a top level Makefile is
413 provided with convenient test targets.
415 * To run all the tests across all implementations (be prepared to wait):
421 * To run all tests against a single implementation:
431 * To run tests for a single step against all implementations:
441 * To run tests for a specifc step against a single implementation:
451 ### Self-hosted functional tests
453 * To run the functional tests in self-hosted mode, you specify `mal`
454 as the test implementation and use the `MAL_IMPL` make variable
455 to change the underlying host language (default is JavaScript):
457 make MAL_IMPL=IMPL test^mal^step2
460 make test^mal^step2 # js is default
461 make MAL_IMPL=ruby test^mal^step2
462 make MAL_IMPL=python test^mal^step2
466 ### Performance tests
468 Warning: These performance tests are neither statistically valid nor
469 comprehensive; runtime performance is a not a primary goal of mal. If
470 you draw any serious conclusions from these performance tests, then
471 please contact me about some amazing oceanfront property in Kansas
472 that I'm willing to sell you for cheap.
474 * To run performance tests against a single implementation:
482 * To run performance tests against all implementations:
487 ### Generating language statistics
489 * To report line and byte stastics for a single implementation:
497 * To report line and bytes stastics for general Lisp code (env, core
506 ## Docker test environment
508 There is a Dockerfile included in the `tests/docker` directory that
509 builds a docker image based on Ubuntu Utopic that contains everything
510 needed to run tests against all the implementations (except for MATLAB
511 which is proprietary/licensed).
513 Build the the docker image using a provided script. WARNING: this will
514 likely take over an hour to build from scratch and use more 3 GB of disk:
516 ./tests/docker-build.sh
519 Launch a docker container from that image built above. This will
520 volume mount the mal directory to `/mal` and then give you a bash
521 prompt in the container. You can then run individual mal
522 implementations and tests:
524 ./tests/docker-run.sh
527 You can also specify a command to run within the container. For
528 example, to run step2 tests for every implementation (except MATLAB):
530 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
534 * JVM-based language implementations (Java, Clojure, Scala): you will
535 need to run these implementations once manually first before you can
536 run tests because runtime dependencies need to be downloaded to
537 avoid the tests timing out. These dependencies are download to
538 dot-files in the /mal directory so they will persist between runs.
539 * Compiled languages: if your host system is different enough from
540 Ubuntu Utopic then you may need to re-compile your compiled
541 languages from within the container to avoid linker version
547 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
548 License 2.0). See LICENSE.txt for more details.