Step 0 of Make-a-Lisp for Erlang
[jackhill/mal.git] / README.md
index 9427657..7b71d40 100644 (file)
--- a/README.md
+++ b/README.md
@@ -2,48 +2,63 @@
 
 ## Description
 
-Mal is an interpreter for a subset of the Clojure programming
-language. Mal is implemented from scratch in 19 different languages:
+Mal is a Clojure inspired Lisp interpreter.
+
+Mal is implemented in 32 different languages:
 
 * Bash shell
 * C
+* C++
 * C#
 * Clojure
 * CoffeeScript
+* Erlang
+* Factor
+* Forth
 * Go
+* Haskell
 * Java
-* Javascript ([Online Demo](http://kanaka.github.io/mal))
+* JavaScript ([Online Demo](http://kanaka.github.io/mal))
+* Julia
+* Lua
 * GNU Make
 * mal itself
+* MATLAB
+* [miniMAL](https://github.com/kanaka/miniMAL)
+* Nim
+* OCaml
 * Perl
 * PHP
 * Postscript
 * Python
 * R
+* Racket
 * Ruby
 * Rust
 * Scala
+* Swift
 * Visual Basic.NET
 
 
-Mal is also a learning tool. Each implementation of mal is separated
-into 11 incremental, self-contained (and testable) steps that
-demonstrate core concepts of Lisp. The last step is capable of
-self-hosting (running the mal implemenation of mal).
+Mal is a learning tool. See the [make-a-lisp process
+guide](process/guide.md). Each implementation of mal is separated into
+11 incremental, self-contained (and testable) steps that demonstrate
+core concepts of Lisp. The last step is capable of self-hosting
+(running the mal implementation of mal).
 
 The mal (make a lisp) steps are:
 
-* step0_repl
-* step1_read_print
-* step2_eval
-* step3_env
-* step4_if_fn_do
-* step5_tco
-* step6_file
-* step7_quote
-* step8_macros
-* step9_try
-* stepA_interop
+* [step0_repl](process/guide.md#step0)
+* [step1_read_print](process/guide.md#step1)
+* [step2_eval](process/guide.md#step2)
+* [step3_env](process/guide.md#step3)
+* [step4_if_fn_do](process/guide.md#step4)
+* [step5_tco](process/guide.md#step5)
+* [step6_file](process/guide.md#step6)
+* [step7_quote](process/guide.md#step7)
+* [step8_macros](process/guide.md#step8)
+* [step9_try](process/guide.md#step9)
+* [stepA_mal](process/guide.md#stepA)
 
 
 Mal was presented publicly for the first time in a lightning talk at
@@ -51,6 +66,12 @@ Clojure West 2014 (unfortunately there is no video). See
 mal/clojurewest2014.mal for the presentation that was given at the
 conference (yes the presentation is a mal program).
 
+If you are interesting in creating a mal implementation (or just
+interested in using mal for something), please drop by the #mal
+channel on freenode. In addition to the [make-a-lisp process
+guide](process/guide.md) there is also a [mal/make-a-lisp
+FAQ](docs/FAQ.md) where I attempt to answer some common questions.
+
 ## Building/running implementations
 
 ### Bash 4
@@ -71,6 +92,23 @@ make
 ./stepX_YYY
 ```
 
+### C++
+
+*The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
+
+The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
+a readline compatible library to build. See the `cpp/README.md` for
+more details:
+
+```
+cd cpp
+make
+    # OR
+make CXX=clang++-3.5
+./stepX_YYY
+```
+
+
 ### C# ###
 
 The C# implementation of mal has been tested on Linux using the Mono
@@ -99,8 +137,42 @@ cd coffee
 coffee ./stepX_YYY
 ```
 
+### Erlang
+
+Requires [rebar](https://github.com/rebar/rebar) to build.
+
+```
+cd erlang
+MAL_STEP=stepX_YYY rebar compile escriptize
+./stepX_YYY
+```
+
+### Factor
+
+*The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
+
+The Factor implementation of mal has been tested with Factor 0.97
+([factorcode.org](factorcode.org)).
+
+```
+cd factor
+FACTOR_ROOTS=src factor -run=stepX_YYY
+```
+
+### Forth
+
+*The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
+
+```
+cd forth
+gforth stepX_YYY.fs
+```
+
 ### Go
 
+The Go implementation of mal requires that go is installed on on the
+path. The implementation has been tested with Go 1.3.1.
+
 ```
 cd go
 make
@@ -108,6 +180,20 @@ make
 ```
 
 
+### Haskell
+
+Install the Haskell compiler (ghc/ghci), the Haskell platform and
+either the editline package (BSD) or the readline package (GPL). On
+Ubuntu these packages are: ghc, haskell-platform,
+libghc-readline-dev/libghc-editline-dev
+
+```
+cd haskell
+make
+./stepX_YYY
+```
+
+
 ### Java 1.7
 
 The Java implementation of mal requires maven2 to build.
@@ -120,7 +206,7 @@ mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
 ```
 
-### Javascript/Node
+### JavaScript/Node
 
 ```
 cd js
@@ -128,6 +214,26 @@ npm update
 node stepX_YYY.js
 ```
 
+### Julia
+
+The Julia implementation of mal has been tested with Julia 0.3.7.
+
+```
+cd julia
+julia stepX_YYY.jl
+```
+
+### Lua
+
+Running the Lua implementation of mal requires lua 5.1 or later,
+luarocks and the lua-rex-pcre library installed.
+
+```
+cd lua
+make  # to build and link linenoise.so
+./stepX_YYY.lua
+```
+
 ### Mal
 
 Running the mal implementation of mal involves running stepA of one of
@@ -147,6 +253,61 @@ cd make
 make -f stepX_YYY.mk
 ```
 
+### Nim 0.10.3
+
+*The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
+
+Running the Nim implementation of mal requires Nim's current devel branch
+(0.10.3) or later, and the nre library installed.
+
+```
+cd nim
+make
+  # OR
+nimble build
+./stepX_YYY
+```
+
+### OCaml 4.01.0
+
+*The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
+
+```
+cd ocaml
+make
+./stepX_YYY
+```
+
+### MATLAB
+
+The MATLAB implementation of mal has been tested with MATLAB version
+R2014a on Linux. Note that MATLAB is a commercial product. It should
+be fairly simple to support GNU Octave once it support classdef object
+syntax.
+
+```
+cd matlab
+./stepX_YYY
+matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
+    # OR with command line arguments
+matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
+```
+
+### miniMAL
+
+[miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
+implemented in less than 1024 bytes of JavaScript. To run the miniMAL
+implementation of mal you need to download/install the miniMAL
+interpreter (which requires Node.js).
+```
+cd miniMAL
+# Download miniMAL and dependencies
+npm install
+export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
+# Now run mal implementation in miniMAL
+miniMAL ./stepX_YYY
+```
+
 ### Perl 5.8
 
 For readline line editing support, install Term::ReadLine::Perl or
@@ -191,28 +352,35 @@ The R implementation of mal requires R (r-base-core) to run.
 
 ```
 cd r
-make libs
-Rscript stepX_YYY.rb
+make libs  # to download and build rdyncall
+Rscript stepX_YYY.r
+```
+
+### Racket (5.3)
+
+The Racket implementation of mal requires the Racket
+compiler/interpreter to run.
+
+```
+cd racket
+./stepX_YYY.rkt
 ```
 
-### Ruby (1.8)
+### Ruby (1.9+)
 
 ```
 cd ruby
 ruby stepX_YYY.rb
 ```
 
-### Rust (0.13)
+### Rust (1.0.0 nightly)
 
 The rust implementation of mal requires the rust compiler and build
 tool (cargo) to build.
 
 ```
 cd rust
-# Need patched pcre lib (should be temporary)
-git clone https://github.com/kanaka/rust-pcre cadencemarseille-pcre
-cargo build
-./target/stepX_YYY
+cargo run --release --bin stepX_YYY
 ```
 
 ### Scala ###
@@ -227,6 +395,19 @@ sbt compile
 scala -classpath target/scala*/classes stepX_YYY
 ```
 
+### Swift
+
+*The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
+
+The Swift implemenation of mal requires the Swift compiler (XCode) to
+build.
+
+```
+cd swift
+make
+./stepX_YYY
+```
+
 ### Visual Basic.NET ###
 
 The VB.NET implementation of mal has been tested on Linux using the Mono
@@ -243,12 +424,14 @@ mono ./stepX_YYY.exe
 
 ## Running tests
 
-The are nearly 500 generic Mal tests (for all implementations) in the
-`tests/` directory. Each step has a corresponding test file containing
-tests specific to that step. The `runtest.py` test harness uses
-pexpect to launch a Mal step implementation and then feeds the tests
-one at a time to the implementation and compares the output/return
-value to the expected output/return value.
+### Functional tests
+
+The are nearly 500 generic functional tests (for all implementations)
+in the `tests/` directory. Each step has a corresponding test file
+containing tests specific to that step. The `runtest.py` test harness
+launches a Mal step implementation and then feeds the tests one at
+a time to the implementation and compares the output/return value to
+the expected output/return value.
 
 To simplify the process of running tests, a top level Makefile is
 provided with convenient test targets.
@@ -279,7 +462,7 @@ make test^step2
 make test^step7
 ```
 
-* To run a specifc step against a single implementation:
+* To run tests for a specifc step against a single implementation:
 
 ```
 make test^IMPL^stepX
@@ -288,3 +471,103 @@ make test^IMPL^stepX
 make test^ruby^step3
 make test^ps^step4
 ```
+
+### Self-hosted functional tests
+
+* To run the functional tests in self-hosted mode, you specify `mal`
+  as the test implementation and use the `MAL_IMPL` make variable
+  to change the underlying host language (default is JavaScript):
+```
+make MAL_IMPL=IMPL test^mal^step2
+
+# e.g.
+make test^mal^step2   # js is default
+make MAL_IMPL=ruby test^mal^step2
+make MAL_IMPL=python test^mal^step2
+```
+
+
+### Performance tests
+
+Warning: These performance tests are neither statistically valid nor
+comprehensive; runtime performance is a not a primary goal of mal. If
+you draw any serious conclusions from these performance tests, then
+please contact me about some amazing oceanfront property in Kansas
+that I'm willing to sell you for cheap.
+
+* To run performance tests against a single implementation:
+```
+make perf^IMPL
+
+# e.g.
+make perf^js
+```
+
+* To run performance tests against all implementations:
+```
+make perf
+```
+
+### Generating language statistics
+
+* To report line and byte stastics for a single implementation:
+```
+make stats^IMPL
+
+# e.g.
+make stats^js
+```
+
+* To report line and bytes stastics for general Lisp code (env, core
+  and stepA):
+```
+make stats-lisp^IMPL
+
+# e.g.
+make stats-lisp^js
+```
+
+## Docker test environment
+
+There is a Dockerfile included in the `tests/docker` directory that
+builds a docker image based on Ubuntu Utopic that contains everything
+needed to run tests against all the implementations (except for MATLAB
+which is proprietary/licensed).
+
+Build the the docker image using a provided script. WARNING: this will
+likely take over an hour to build from scratch and use more 3 GB of disk:
+```bash
+./tests/docker-build.sh
+```
+
+Launch a docker container from that image built above. This will
+volume mount the mal directory to `/mal` and then give you a bash
+prompt in the container. You can then run individual mal
+implementations and tests:
+```bash
+./tests/docker-run.sh
+```
+
+You can also specify a command to run within the container. For
+example, to run step2 tests for every implementation (except MATLAB):
+```bash
+./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
+```
+
+**Notes**:
+* JVM-based language implementations (Java, Clojure, Scala): you will
+  need to run these implementations once manually first before you can
+  run tests because runtime dependencies need to be downloaded to
+  avoid the tests timing out. These dependencies are download to
+  dot-files in the /mal directory so they will persist between runs.
+* Compiled languages: if your host system is different enough from
+  Ubuntu Utopic then you may need to re-compile your compiled
+  languages from within the container to avoid linker version
+  mismatches.
+
+
+## License
+
+Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
+License 2.0). See LICENSE.txt for more details.
+