5 Mal is a Clojure inspired Lisp interpreter.
7 Mal is implemented in 27 different languages:
18 * Javascript ([Online Demo](http://kanaka.github.io/mal))
23 * [miniMAL](https://github.com/kanaka/miniMAL)
38 Mal is a learning tool. See the [make-a-lisp process
39 guide](process/guide.md). Each implementation of mal is separated into
40 11 incremental, self-contained (and testable) steps that demonstrate
41 core concepts of Lisp. The last step is capable of self-hosting
42 (running the mal implementation of mal).
44 The mal (make a lisp) steps are:
46 * [step0_repl](process/guide.md#step0)
47 * [step1_read_print](process/guide.md#step1)
48 * [step2_eval](process/guide.md#step2)
49 * [step3_env](process/guide.md#step3)
50 * [step4_if_fn_do](process/guide.md#step4)
51 * [step5_tco](process/guide.md#step5)
52 * [step6_file](process/guide.md#step6)
53 * [step7_quote](process/guide.md#step7)
54 * [step8_macros](process/guide.md#step8)
55 * [step9_try](process/guide.md#step9)
56 * [stepA_mal](process/guide.md#stepA)
59 Mal was presented publicly for the first time in a lightning talk at
60 Clojure West 2014 (unfortunately there is no video). See
61 mal/clojurewest2014.mal for the presentation that was given at the
62 conference (yes the presentation is a mal program).
64 If you are interesting in creating a mal implementation (or just
65 interested in using mal for something), please stop by the #mal
66 channel on freenode. In addition to the [make-a-lisp process
67 guide](process/guide.md) there is also a [mal/make-a-lisp
68 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
70 ## Building/running implementations
81 The C implementation of mal requires the following libraries (lib and
82 header packages): glib, libffi6 and either the libedit or GNU readline library.
92 The C# implementation of mal has been tested on Linux using the Mono
93 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
94 required to build and run the C# implementation.
107 lein with-profile +stepX trampoline run
113 sudo npm install -g coffee-script
127 You Go implementation of mal requires that go is installed on on the
128 path. The implementation has been tested with Go 1.3.1.
139 Install the Haskell compiler (ghc/ghci), the Haskell platform and
140 either the editline package (BSD) or the readline package (GPL). On
141 Ubuntu these packages are: ghc, haskell-platform,
142 libghc-readline-dev/libghc-editline-dev
153 The Java implementation of mal requires maven2 to build.
158 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
160 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
173 Running the Lua implementation of mal requires lua 5.1 or later,
174 luarocks and the lua-rex-pcre library installed.
178 make # to build and link linenoise.so
184 Running the mal implementation of mal involves running stepA of one of
185 the other implementations and passing the mal step to run as a command
190 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
203 Running the Nim implementation of mal requires Nim's current devel branch
204 (0.10.3) or later, and the nre library installed.
224 The MATLAB implementation of mal has been tested with MATLAB version
225 R2014a on Linux. Note that MATLAB is a commercial product. It should
226 be fairly simple to support GNU Octave once it support classdef object
232 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
233 # OR with command line arguments
234 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
239 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
240 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
241 implementation of mal you need to download/install the miniMAL
242 interpreter (which requires Node.js).
245 # Download miniMAL and dependencies
247 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
248 # Now run mal implementation in miniMAL
254 For readline line editing support, install Term::ReadLine::Perl or
255 Term::ReadLine::Gnu from CPAN.
265 The PHP implementation of mal requires the php command line interface
273 ### Postscript Level 2/3
275 The Postscript implementation of mal requires ghostscript to run. It
276 has been tested with ghostscript 9.10.
280 gs -q -dNODISPLAY -I./ stepX_YYY.ps
292 The R implementation of mal requires R (r-base-core) to run.
296 make libs # to download and build rdyncall
302 The Racket implementation of mal requires the Racket
303 compiler/interpreter to run.
317 ### Rust (1.0.0 nightly)
319 The rust implementation of mal requires the rust compiler and build
320 tool (cargo) to build.
324 cargo run --release --bin stepX_YYY
329 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
333 sbt 'run-main stepX_YYY'
336 scala -classpath target/scala*/classes stepX_YYY
339 ### Visual Basic.NET ###
341 The VB.NET implementation of mal has been tested on Linux using the Mono
342 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
343 required to build and run the VB.NET implementation.
357 The are nearly 500 generic functional tests (for all implementations)
358 in the `tests/` directory. Each step has a corresponding test file
359 containing tests specific to that step. The `runtest.py` test harness
360 uses pexpect to launch a Mal step implementation and then feeds the
361 tests one at a time to the implementation and compares the
362 output/return value to the expected output/return value.
364 To simplify the process of running tests, a top level Makefile is
365 provided with convenient test targets.
367 * To run all the tests across all implementations (be prepared to wait):
373 * To run all tests against a single implementation:
383 * To run tests for a single step against all implementations:
393 * To run tests for a specifc step against a single implementation:
403 ### Self-hosted functional tests
405 * To run the functional tests in self-hosted mode, you specify `mal`
406 as the test implementation and use the `MAL_IMPL` make variable
407 to change the underlying host language (default is JavaScript):
409 make MAL_IMPL=IMPL test^mal^step2
412 make test^mal^step2 # js is default
413 make MAL_IMPL=ruby test^mal^step2
414 make MAL_IMPL=python test^mal^step2
418 ### Performance tests
420 Warning: These performance tests are neither statistically valid nor
421 comprehensive; runtime performance is a not a primary goal of mal. If
422 you draw any serious conclusions from these performance tests, then
423 please contact me about some amazing oceanfront property in Kansas
424 that I'm willing to sell you for cheap.
426 * To run performance tests against a single implementation:
434 * To run performance tests against all implementations:
439 ### Generating language statistics
441 * To report line and byte stastics for a single implementation:
449 * To report line and bytes stastics for general Lisp code (env, core
458 ## Docker test environment
460 There is a Dockerfile included in the `tests/docker` directory that
461 builds a docker image based on Ubuntu Utopic that contains everything
462 needed to run tests against all the implementations (except for MATLAB
463 which is proprietary/licensed).
465 Build the the docker image using a provided script. WARNING: this will
466 likely take over an hour to build from scratch and use more 3 GB of disk:
468 ./tests/docker-build.sh
471 Launch a docker container from that image built above. This will
472 volume mount the mal directory to `/mal` and then give you a bash
473 prompt in the container. You can then run individual mal
474 implementations and tests:
476 ./tests/docker-run.sh
479 You can also specify a command to run within the container. For
480 example, to run step2 tests for every implementation (except MATLAB):
482 ./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
486 * JVM-based language implementations (Java, Clojure, Scala): you will
487 need to run these implementations once manually first before you can
488 run tests because runtime dependencies need to be downloaded to
489 avoid the tests timing out. These dependencies are download to
490 dot-files in the /mal directory so they will persist between runs.
491 * Compiled languages: if you host system is different enough from
492 Ubuntu Utopic then you may need to re-compile your compiled
493 languages from within the container to avoid linker version
499 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
500 License 2.0). See LICENSE.txt for more details.