runtest.py: cleanup all grandchildren too.
[jackhill/mal.git] / README.md
CommitLineData
60154d24
JM
1# mal - Make a Lisp
2
bcddc3e4
JM
3## Description
4
27696157 5Mal is a Clojure inspired Lisp interpreter.
b76aa73b 6
1218ce98 7Mal is implemented in 26 different languages:
bcddc3e4 8
edc3b064 9* Bash shell
bcddc3e4 10* C
edc3b064
JM
11* C#
12* Clojure
891c3f3b 13* CoffeeScript
96032890 14* Forth
1771ab50 15* Go
b76aa73b 16* Haskell
bcddc3e4 17* Java
d32f9b87 18* Javascript ([Online Demo](http://kanaka.github.io/mal))
9d42904e 19* Lua
bcddc3e4
JM
20* GNU Make
21* mal itself
8a9d0a8a 22* MATLAB
1218ce98 23* [miniMAL](https://github.com/kanaka/miniMAL)
bc6448bc 24* OCaml
6301e0b6 25* Perl
edc3b064
JM
26* PHP
27* Postscript
28* Python
9b3362e8 29* R
f5223195 30* Racket
8adb0827 31* Ruby
abdd56eb 32* Rust
821930db 33* Scala
ee7cd585 34* Visual Basic.NET
bcddc3e4
JM
35
36
0f4ca9d1 37Mal is a [learning tool](process/guide.md). Each implementation of mal is separated into 11
b76aa73b
JM
38incremental, self-contained (and testable) steps that demonstrate core
39concepts of Lisp. The last step is capable of self-hosting (running
40the mal implemenation of mal).
bcddc3e4
JM
41
42The mal (make a lisp) steps are:
43
0f4ca9d1
JM
44* [step0_repl](process/guide.md#step0)
45* [step1_read_print](process/guide.md#step1)
46* [step2_eval](process/guide.md#step2)
47* [step3_env](process/guide.md#step3)
48* [step4_if_fn_do](process/guide.md#step4)
49* [step5_tco](process/guide.md#step5)
50* [step6_file](process/guide.md#step6)
51* [step7_quote](process/guide.md#step7)
52* [step8_macros](process/guide.md#step8)
53* [step9_try](process/guide.md#step9)
90f618cb 54* [stepA_mal](process/guide.md#stepA)
bcddc3e4
JM
55
56
57Mal was presented publicly for the first time in a lightning talk at
58Clojure West 2014 (unfortunately there is no video). See
59mal/clojurewest2014.mal for the presentation that was given at the
60conference (yes the presentation is a mal program).
60154d24
JM
61
62## Building/running implementations
63
bcddc3e4 64### Bash 4
60154d24
JM
65
66```
67cd bash
68bash stepX_YYY.sh
69```
70
bcddc3e4 71### C
60154d24 72
01c97316
JM
73The C implementation of mal requires the following libraries (lib and
74header packages): glib, libffi6 and either the libedit or GNU readline library.
54c75382 75
60154d24
JM
76```
77cd c
78make
79./stepX_YYY
80```
81
9b1563a3 82### C# ###
edc3b064
JM
83
84The C# implementation of mal has been tested on Linux using the Mono
85C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
86required to build and run the C# implementation.
87
88```
89cd cs
90make
ee7cd585 91mono ./stepX_YYY.exe
edc3b064
JM
92```
93
94
bcddc3e4 95### Clojure
60154d24
JM
96
97```
98cd clojure
99lein with-profile +stepX trampoline run
100```
101
891c3f3b
JM
102### CoffeeScript
103
104```
105sudo npm install -g coffee-script
106cd coffee
107coffee ./stepX_YYY
108```
109
96032890
C
110### Forth
111
112```
113cd forth
114gforth stepX_YYY.fs
115```
116
1771ab50
JM
117### Go
118
fd888612
JM
119You Go implementation of mal requires that go is installed on on the
120path. The implementation has been tested with Go 1.3.1.
121
1771ab50
JM
122```
123cd go
124make
125./stepX_YYY
126```
127
128
b76aa73b
JM
129### Haskell
130
2988d38e 131Install the Haskell compiler (ghc/ghci), the Haskell platform and
5400d4bf
JM
132either the editline package (BSD) or the readline package (GPL). On
133Ubuntu these packages are: ghc, haskell-platform,
134libghc-readline-dev/libghc-editline-dev
b76aa73b
JM
135
136```
137cd haskell
138make
139./stepX_YYY
140```
141
142
bcddc3e4 143### Java 1.7
60154d24 144
01c97316
JM
145The Java implementation of mal requires maven2 to build.
146
60154d24
JM
147```
148cd java
149mvn compile
150mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
151 # OR
152mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
153```
154
bcddc3e4 155### Javascript/Node
60154d24
JM
156
157```
158cd js
54c75382 159npm update
60154d24
JM
160node stepX_YYY.js
161```
162
9d42904e
JM
163### Lua
164
8a9d0a8a 165Running the Lua implementation of mal requires lua 5.1 or later,
9d42904e
JM
166luarocks and the lua-rex-pcre library installed.
167
168```
169cd lua
170make # to build and link linenoise.so
171./stepX_YYY.lua
172```
173
bcddc3e4 174### Mal
60154d24
JM
175
176Running the mal implementation of mal involves running stepA of one of
177the other implementations and passing the mal step to run as a command
5d446bd8 178line argument.
60154d24
JM
179
180```
181cd IMPL
182IMPL_STEPA_CMD ../mal/stepX_YYY.mal
183
184```
185
bcddc3e4 186### GNU Make 3.81
60154d24
JM
187
188```
189cd make
190make -f stepX_YYY.mk
191```
192
bc6448bc
C
193### OCaml 4.01.0
194
195```
196cd ocaml
197make
198./stepX_YYY
199```
200
8a9d0a8a
JM
201### MATLAB
202
203The MATLAB implementation of mal has been tested with MATLAB version
204R2014a on Linux. Note that MATLAB is a commercial product. It should
205be fairly simple to support GNU Octave once it support classdef object
206syntax.
207
208```
209cd matlab
210./stepX_YYY
211matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
212 # OR with command line arguments
213matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
214```
215
1218ce98
JM
216### miniMAL
217
218[miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
219implemented in less than 1024 bytes of JavaScript. To run the miniMAL
220implementation of mal you need to download/install the miniMAL
221interpreter (which requires Node.js).
222```
1218ce98 223cd miniMAL
478fd9ce
JM
224# Download miniMAL and dependencies
225npm install
226export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
227# Now run mal implementation in miniMAL
1218ce98
JM
228miniMAL ./stepX_YYY
229```
230
9b1563a3 231### Perl 5.8
9e5b2151
JM
232
233For readline line editing support, install Term::ReadLine::Perl or
234Term::ReadLine::Gnu from CPAN.
235
236```
237cd perl
238perl stepX_YYY.pl
239```
240
241
bcddc3e4 242### PHP 5.3
60154d24 243
01c97316
JM
244The PHP implementation of mal requires the php command line interface
245to run.
246
60154d24
JM
247```
248cd php
249php stepX_YYY.php
250```
251
bcddc3e4 252### Postscript Level 2/3
60154d24 253
01c97316
JM
254The Postscript implementation of mal requires ghostscript to run. It
255has been tested with ghostscript 9.10.
256
60154d24
JM
257```
258cd ps
fa64b741 259gs -q -dNODISPLAY -I./ stepX_YYY.ps
60154d24
JM
260```
261
a05f7822 262### Python (2 or 3)
60154d24
JM
263
264```
265cd python
266python stepX_YYY.py
267```
8adb0827 268
9b3362e8
JM
269### R
270
271The R implementation of mal requires R (r-base-core) to run.
272
273```
274cd r
9d42904e 275make libs # to download and build rdyncall
f5223195
JM
276Rscript stepX_YYY.r
277```
278
279### Racket (5.3)
280
281The Racket implementation of mal requires the Racket
282compiler/interpreter to run.
283
284```
285cd racket
286./stepX_YYY.rb
9b3362e8
JM
287```
288
107d9694 289### Ruby (1.9+)
8adb0827
JM
290
291```
292cd ruby
293ruby stepX_YYY.rb
294```
592eb5cf 295
abdd56eb
JM
296### Rust (0.13)
297
298The rust implementation of mal requires the rust compiler and build
299tool (cargo) to build.
300
301```
302cd rust
111dbaf1
JM
303# Need patched pcre lib (should be temporary)
304git clone https://github.com/kanaka/rust-pcre cadencemarseille-pcre
abdd56eb
JM
305cargo build
306./target/stepX_YYY
307```
308
821930db
JM
309### Scala ###
310
311Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
312
313```
314cd scala
315sbt 'run-main stepX_YYY'
316 # OR
317sbt compile
318scala -classpath target/scala*/classes stepX_YYY
319```
320
ee7cd585
JM
321### Visual Basic.NET ###
322
323The VB.NET implementation of mal has been tested on Linux using the Mono
324VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
325required to build and run the VB.NET implementation.
326
327```
328cd vb
329make
330mono ./stepX_YYY.exe
331```
332
333
334
592eb5cf
JM
335## Running tests
336
a816262a 337The are nearly 500 generic Mal tests (for all implementations) in the
592eb5cf
JM
338`tests/` directory. Each step has a corresponding test file containing
339tests specific to that step. The `runtest.py` test harness uses
340pexpect to launch a Mal step implementation and then feeds the tests
341one at a time to the implementation and compares the output/return
342value to the expected output/return value.
343
344To simplify the process of running tests, a top level Makefile is
345provided with convenient test targets.
346
347* To run all the tests across all implementations (be prepared to wait):
348
349```
350make test
351```
352
353* To run all tests against a single implementation:
354
355```
356make test^IMPL
357
358# e.g.
359make test^clojure
360make test^js
361```
362
363* To run tests for a single step against all implementations:
364
365```
366make test^stepX
367
368# e.g.
369make test^step2
370make test^step7
371```
372
373* To run a specifc step against a single implementation:
374
375```
376make test^IMPL^stepX
377
378# e.g
379make test^ruby^step3
380make test^ps^step4
381```
fd888612
JM
382
383## License
384
385Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
386License 2.0). See LICENSE.txt for more details.
387