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