Merge pull request #127 from dubek/fix-nim-tokenizer-oom
[jackhill/mal.git] / README.md
CommitLineData
60154d24
JM
1# mal - Make a Lisp
2
f9e6bb80
JM
3[![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal)
4
bcddc3e4
JM
5## Description
6
27696157 7Mal is a Clojure inspired Lisp interpreter.
b76aa73b 8
f82cb965 9Mal is implemented in 44 different languages:
bcddc3e4 10
8c7587af 11* GNU awk
edc3b064 12* Bash shell
bcddc3e4 13* C
73fc9366 14* C++
edc3b064
JM
15* C#
16* Clojure
891c3f3b 17* CoffeeScript
6c4dede1 18* Crystal
f82cb965 19* D
bb526975 20* Elixir
2cc3804b 21* Erlang
88e934b6 22* ES6 (ECMAScript 6 / ECMAScript 2015)
6f78381f 23* F#
0fe47e88 24* Factor
96032890 25* Forth
1771ab50 26* Go
7ab0f63e 27* Groovy
7c6882f2 28* GNU Guile
b76aa73b 29* Haskell
bcddc3e4 30* Java
39381792
JM
31* JavaScript ([Online Demo](http://kanaka.github.io/mal))
32* Julia
53c2ea70 33* Kotlin
9d42904e 34* Lua
bcddc3e4
JM
35* GNU Make
36* mal itself
8a9d0a8a 37* MATLAB
1218ce98 38* [miniMAL](https://github.com/kanaka/miniMAL)
a2cd0a3a 39* Nim
bc6448bc 40* OCaml
6301e0b6 41* Perl
edc3b064
JM
42* PHP
43* Postscript
44* Python
23e38cd2 45* RPython
9b3362e8 46* R
f5223195 47* Racket
8adb0827 48* Ruby
abdd56eb 49* Rust
821930db 50* Scala
8b142f08 51* Swift
54d9903c 52* Tcl
50a964ce 53* Vimscript
ee7cd585 54* Visual Basic.NET
bcddc3e4
JM
55
56
bd08422d
JM
57Mal is a learning tool. See the [make-a-lisp process
58guide](process/guide.md). Each implementation of mal is separated into
5911 incremental, self-contained (and testable) steps that demonstrate
60core concepts of Lisp. The last step is capable of self-hosting
61(running the mal implementation of mal).
bcddc3e4
JM
62
63The mal (make a lisp) steps are:
64
0f4ca9d1
JM
65* [step0_repl](process/guide.md#step0)
66* [step1_read_print](process/guide.md#step1)
67* [step2_eval](process/guide.md#step2)
68* [step3_env](process/guide.md#step3)
69* [step4_if_fn_do](process/guide.md#step4)
70* [step5_tco](process/guide.md#step5)
71* [step6_file](process/guide.md#step6)
72* [step7_quote](process/guide.md#step7)
73* [step8_macros](process/guide.md#step8)
74* [step9_try](process/guide.md#step9)
90f618cb 75* [stepA_mal](process/guide.md#stepA)
bcddc3e4
JM
76
77
78Mal was presented publicly for the first time in a lightning talk at
79Clojure West 2014 (unfortunately there is no video). See
80mal/clojurewest2014.mal for the presentation that was given at the
81conference (yes the presentation is a mal program).
60154d24 82
144f2b6a 83If you are interesting in creating a mal implementation (or just
bd62ff74 84interested in using mal for something), please drop by the #mal
144f2b6a
JM
85channel on freenode. In addition to the [make-a-lisp process
86guide](process/guide.md) there is also a [mal/make-a-lisp
87FAQ](docs/FAQ.md) where I attempt to answer some common questions.
88
60154d24
JM
89## Building/running implementations
90
8c7587af
MK
91### GNU awk
92
4c58cd4e 93*The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
390d5829 94
8c7587af
MK
95The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
96
97```
98cd gawk
99gawk -O -f stepX_YYY.awk
100```
101
bcddc3e4 102### Bash 4
60154d24
JM
103
104```
105cd bash
106bash stepX_YYY.sh
107```
108
bcddc3e4 109### C
60154d24 110
01c97316
JM
111The C implementation of mal requires the following libraries (lib and
112header packages): glib, libffi6 and either the libedit or GNU readline library.
54c75382 113
60154d24
JM
114```
115cd c
116make
117./stepX_YYY
118```
119
73fc9366
JM
120### C++
121
a848d783
JM
122*The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
123
73fc9366
JM
124The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
125a readline compatible library to build. See the `cpp/README.md` for
126more details:
127
128```
129cd cpp
130make
131 # OR
132make CXX=clang++-3.5
133./stepX_YYY
134```
135
136
9b1563a3 137### C# ###
edc3b064
JM
138
139The C# implementation of mal has been tested on Linux using the Mono
140C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
141required to build and run the C# implementation.
142
143```
144cd cs
145make
ee7cd585 146mono ./stepX_YYY.exe
edc3b064
JM
147```
148
149
bcddc3e4 150### Clojure
60154d24
JM
151
152```
153cd clojure
154lein with-profile +stepX trampoline run
155```
156
891c3f3b
JM
157### CoffeeScript
158
159```
160sudo npm install -g coffee-script
161cd coffee
162coffee ./stepX_YYY
163```
164
58b84dd5 165### Crystal
166
6427adea 167*The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
6c4dede1 168
624b7bc6 169The Crystal implementation of mal has been tested with Crystal 0.8.0.
6c4dede1 170
58b84dd5 171```
172cd crystal
173crystal run ./stepX_YYY.cr
6c4dede1
JM
174 # OR
175make # needed to run tests
176./stepX_YYY
58b84dd5 177```
178
f82cb965
DM
179### D
180
181*The D implementation was created by [Dov Murik](https://github.com/dubek)*
182
183The D implementation of mal was tested with GDC 4.8. It requires the GNU
184readline library.
185
186```
187cd d
188make
189./stepX_YYY
190```
191
bb526975 192### Elixir
193
194*The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
195
196The Elixir implementation of mal has been tested with Elixir 1.0.5.
197
198```
199cd elixir
df2ca97b 200mix stepX_YYY
201# Or with readline/line editing functionality:
bb526975 202iex -S mix stepX_YYY
203```
204
2cc3804b
NF
205### Erlang
206
425ef3d7
JM
207*The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
208
82484631
JM
209The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
210and [rebar](https://github.com/rebar/rebar) to build.
2cc3804b
NF
211
212```
213cd erlang
425ef3d7
JM
214make
215 # OR
216MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
2cc3804b
NF
217./stepX_YYY
218```
219
88e934b6
JM
220### ES6 (ECMAScript 6 / ECMAScript 2015)
221
222The ES6 implementation uses the [babel](https://babeljs.io) compiler
223to generate ES5 compatible JavaScript. The generated code has been
224tested with Node 0.12.4.
225
226```
227cd es6
228make
229node build/stepX_YYY.js
230```
231
232
6f78381f
PS
233### F# ###
234
235*The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
236
237The F# implementation of mal has been tested on Linux using the Mono
238F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
206a1657 239compiler (mcs) is also necessary to compile the readline dependency. All are
6f78381f
PS
240required to build and run the F# implementation.
241
242```
243cd fsharp
244make
245mono ./stepX_YYY.exe
246```
247
5a53c643
JL
248### Factor
249
44c8a524 250*The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
5a53c643 251
0fe47e88
JM
252The Factor implementation of mal has been tested with Factor 0.97
253([factorcode.org](factorcode.org)).
254
5a53c643
JL
255```
256cd factor
199b1ce7 257FACTOR_ROOTS=. factor -run=stepX_YYY
5a53c643
JL
258```
259
96032890
C
260### Forth
261
a848d783
JM
262*The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
263
96032890
C
264```
265cd forth
266gforth stepX_YYY.fs
267```
268
1771ab50
JM
269### Go
270
0fe47e88 271The Go implementation of mal requires that go is installed on on the
fd888612
JM
272path. The implementation has been tested with Go 1.3.1.
273
1771ab50
JM
274```
275cd go
276make
277./stepX_YYY
278```
279
280
7ab0f63e
JM
281### Groovy
282
283The Groovy implementation of mal requires Groovy to run and has been
284tested with Groovy 1.8.6.
285
286```
287cd groovy
288make
289groovy ./stepX_YYY.groovy
290```
291
5a9cda80
JM
292### GNU Guile 2.1+
293
294*The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
295
296```
297cd guile
298guile -L ./ stepX_YYY.scm
299```
7ab0f63e 300
b76aa73b
JM
301### Haskell
302
2988d38e 303Install the Haskell compiler (ghc/ghci), the Haskell platform and
5400d4bf
JM
304either the editline package (BSD) or the readline package (GPL). On
305Ubuntu these packages are: ghc, haskell-platform,
306libghc-readline-dev/libghc-editline-dev
b76aa73b
JM
307
308```
309cd haskell
310make
311./stepX_YYY
312```
313
314
bcddc3e4 315### Java 1.7
60154d24 316
01c97316
JM
317The Java implementation of mal requires maven2 to build.
318
60154d24
JM
319```
320cd java
321mvn compile
322mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
323 # OR
324mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
325```
326
39381792 327### JavaScript/Node
60154d24
JM
328
329```
330cd js
54c75382 331npm update
60154d24
JM
332node stepX_YYY.js
333```
334
39381792
JM
335### Julia
336
82484631 337The Julia implementation of mal requires Julia 0.4.
39381792
JM
338
339```
340cd julia
341julia stepX_YYY.jl
342```
343
53c2ea70
JFI
344### Kotlin
345
346*The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
347
4121b4ee 348The Kotlin implementation of mal has been tested with Kotlin 1.0.0-beta.
53c2ea70
JFI
349
350```
351cd kotlin
352make
353java -jar stepX_YYY.jar
354```
355
9d42904e
JM
356### Lua
357
8a9d0a8a 358Running the Lua implementation of mal requires lua 5.1 or later,
9d42904e
JM
359luarocks and the lua-rex-pcre library installed.
360
361```
362cd lua
363make # to build and link linenoise.so
364./stepX_YYY.lua
365```
366
bcddc3e4 367### Mal
60154d24
JM
368
369Running the mal implementation of mal involves running stepA of one of
370the other implementations and passing the mal step to run as a command
5d446bd8 371line argument.
60154d24
JM
372
373```
374cd IMPL
375IMPL_STEPA_CMD ../mal/stepX_YYY.mal
376
377```
378
bcddc3e4 379### GNU Make 3.81
60154d24
JM
380
381```
382cd make
383make -f stepX_YYY.mk
384```
385
de69b639 386### Nim 0.11.0
a2cd0a3a 387
a848d783
JM
388*The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
389
de69b639 390Running the Nim implementation of mal requires Nim 0.11.0 or later.
a2cd0a3a 391
392```
393cd nim
394make
395 # OR
396nimble build
397./stepX_YYY
398```
399
bc6448bc
C
400### OCaml 4.01.0
401
a848d783
JM
402*The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
403
bc6448bc
C
404```
405cd ocaml
406make
407./stepX_YYY
408```
409
8a9d0a8a
JM
410### MATLAB
411
412The MATLAB implementation of mal has been tested with MATLAB version
413R2014a on Linux. Note that MATLAB is a commercial product. It should
414be fairly simple to support GNU Octave once it support classdef object
415syntax.
416
417```
418cd matlab
419./stepX_YYY
420matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
421 # OR with command line arguments
422matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
423```
424
1218ce98
JM
425### miniMAL
426
427[miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
428implemented in less than 1024 bytes of JavaScript. To run the miniMAL
429implementation of mal you need to download/install the miniMAL
430interpreter (which requires Node.js).
431```
1218ce98 432cd miniMAL
478fd9ce
JM
433# Download miniMAL and dependencies
434npm install
435export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
436# Now run mal implementation in miniMAL
1218ce98
JM
437miniMAL ./stepX_YYY
438```
439
9b1563a3 440### Perl 5.8
9e5b2151
JM
441
442For readline line editing support, install Term::ReadLine::Perl or
443Term::ReadLine::Gnu from CPAN.
444
445```
446cd perl
447perl stepX_YYY.pl
448```
449
450
bcddc3e4 451### PHP 5.3
60154d24 452
01c97316
JM
453The PHP implementation of mal requires the php command line interface
454to run.
455
60154d24
JM
456```
457cd php
458php stepX_YYY.php
459```
460
bcddc3e4 461### Postscript Level 2/3
60154d24 462
01c97316
JM
463The Postscript implementation of mal requires ghostscript to run. It
464has been tested with ghostscript 9.10.
465
60154d24
JM
466```
467cd ps
fa64b741 468gs -q -dNODISPLAY -I./ stepX_YYY.ps
60154d24
JM
469```
470
23e38cd2 471### Python (2.X or 3.X)
60154d24
JM
472
473```
474cd python
475python stepX_YYY.py
476```
8adb0827 477
23e38cd2
JM
478### RPython
479
480You must have [rpython](https://rpython.readthedocs.org/) on your path
481(included with [pypy](https://bitbucket.org/pypy/pypy/)).
482
483```
484cd rpython
4e8d7c28 485make # this takes a very long time
23e38cd2
JM
486./stepX_YYY
487```
488
9b3362e8
JM
489### R
490
491The R implementation of mal requires R (r-base-core) to run.
492
493```
494cd r
9d42904e 495make libs # to download and build rdyncall
f5223195
JM
496Rscript stepX_YYY.r
497```
498
499### Racket (5.3)
500
501The Racket implementation of mal requires the Racket
502compiler/interpreter to run.
503
504```
505cd racket
3796240a 506./stepX_YYY.rkt
9b3362e8
JM
507```
508
107d9694 509### Ruby (1.9+)
8adb0827
JM
510
511```
512cd ruby
513ruby stepX_YYY.rb
514```
592eb5cf 515
9106a221 516### Rust (1.0.0 nightly)
abdd56eb
JM
517
518The rust implementation of mal requires the rust compiler and build
519tool (cargo) to build.
520
521```
522cd rust
bbeb1b87 523cargo run --release --bin stepX_YYY
abdd56eb
JM
524```
525
821930db
JM
526### Scala ###
527
528Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
529
530```
531cd scala
532sbt 'run-main stepX_YYY'
533 # OR
534sbt compile
535scala -classpath target/scala*/classes stepX_YYY
536```
537
2539e6af
KR
538### Swift
539
a848d783
JM
540*The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
541
e31349f6
KR
542The Swift implementation of mal requires the Swift 2.0 compiler (XCode
5437.0) to build. Older versions will not work due to changes in the
544language and standard library.
8b142f08 545
2539e6af
KR
546```
547cd swift
548make
549./stepX_YYY
550```
551
54d9903c
DM
552### Tcl 8.6
553
554*The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
555
556The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
557editing support, install tclreadline.
558
559```
560cd tcl
561tclsh ./stepX_YYY.tcl
562```
563
50a964ce
DM
564### Vimscript
565
566*The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
567
568The Vimscript implementation of mal requires Vim to run. It has been tested
569with Vim 7.4.
570
571```
572cd vimscript
573./run_vimscript.sh ./stepX_YYY.vim
574```
575
ee7cd585
JM
576### Visual Basic.NET ###
577
578The VB.NET implementation of mal has been tested on Linux using the Mono
579VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
580required to build and run the VB.NET implementation.
581
582```
583cd vb
584make
585mono ./stepX_YYY.exe
586```
587
588
589
592eb5cf
JM
590## Running tests
591
294aba2c
JM
592### Functional tests
593
594The are nearly 500 generic functional tests (for all implementations)
595in the `tests/` directory. Each step has a corresponding test file
596containing tests specific to that step. The `runtest.py` test harness
bd62ff74
JM
597launches a Mal step implementation and then feeds the tests one at
598a time to the implementation and compares the output/return value to
599the expected output/return value.
592eb5cf
JM
600
601To simplify the process of running tests, a top level Makefile is
602provided with convenient test targets.
603
604* To run all the tests across all implementations (be prepared to wait):
605
606```
607make test
608```
609
610* To run all tests against a single implementation:
611
612```
613make test^IMPL
614
615# e.g.
616make test^clojure
617make test^js
618```
619
620* To run tests for a single step against all implementations:
621
622```
623make test^stepX
624
625# e.g.
626make test^step2
627make test^step7
628```
629
4c58cd4e 630* To run tests for a specific step against a single implementation:
592eb5cf
JM
631
632```
633make test^IMPL^stepX
634
635# e.g
636make test^ruby^step3
637make test^ps^step4
638```
fd888612 639
294aba2c
JM
640### Self-hosted functional tests
641
642* To run the functional tests in self-hosted mode, you specify `mal`
643 as the test implementation and use the `MAL_IMPL` make variable
644 to change the underlying host language (default is JavaScript):
645```
646make MAL_IMPL=IMPL test^mal^step2
647
648# e.g.
649make test^mal^step2 # js is default
650make MAL_IMPL=ruby test^mal^step2
651make MAL_IMPL=python test^mal^step2
652```
653
654
655### Performance tests
656
8569b2af
JM
657Warning: These performance tests are neither statistically valid nor
658comprehensive; runtime performance is a not a primary goal of mal. If
659you draw any serious conclusions from these performance tests, then
660please contact me about some amazing oceanfront property in Kansas
661that I'm willing to sell you for cheap.
662
294aba2c
JM
663* To run performance tests against a single implementation:
664```
665make perf^IMPL
666
667# e.g.
668make perf^js
669```
670
671* To run performance tests against all implementations:
672```
673make perf
674```
675
676### Generating language statistics
677
4c58cd4e 678* To report line and byte statistics for a single implementation:
294aba2c
JM
679```
680make stats^IMPL
681
682# e.g.
683make stats^js
684```
685
4c58cd4e 686* To report line and bytes statistics for general Lisp code (env, core
294aba2c
JM
687 and stepA):
688```
689make stats-lisp^IMPL
690
691# e.g.
692make stats-lisp^js
693```
694
75363567
JM
695## Docker test environment
696
697There is a Dockerfile included in the `tests/docker` directory that
698builds a docker image based on Ubuntu Utopic that contains everything
699needed to run tests against all the implementations (except for MATLAB
700which is proprietary/licensed).
701
4c58cd4e 702Build the docker image using a provided script. WARNING: this will
75363567
JM
703likely take over an hour to build from scratch and use more 3 GB of disk:
704```bash
705./tests/docker-build.sh
706```
707
708Launch a docker container from that image built above. This will
709volume mount the mal directory to `/mal` and then give you a bash
710prompt in the container. You can then run individual mal
711implementations and tests:
712```bash
713./tests/docker-run.sh
714```
715
716You can also specify a command to run within the container. For
717example, to run step2 tests for every implementation (except MATLAB):
718```bash
719./tests/docker-run.sh make SKIP_IMPLS="matlab" test^step2
720```
721
722**Notes**:
723* JVM-based language implementations (Java, Clojure, Scala): you will
724 need to run these implementations once manually first before you can
725 run tests because runtime dependencies need to be downloaded to
726 avoid the tests timing out. These dependencies are download to
727 dot-files in the /mal directory so they will persist between runs.
bd62ff74 728* Compiled languages: if your host system is different enough from
75363567
JM
729 Ubuntu Utopic then you may need to re-compile your compiled
730 languages from within the container to avoid linker version
731 mismatches.
732
294aba2c 733
fd888612
JM
734## License
735
736Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
737License 2.0). See LICENSE.txt for more details.