Merge branch 'master' of github.com:kanaka/mal
[jackhill/mal.git] / README.md
1 # mal - Make a Lisp
2
3 [![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal)
4
5 ## Description
6
7 Mal is a Clojure inspired Lisp interpreter.
8
9 Mal is implemented in 60 languages:
10
11 * Ada
12 * GNU awk
13 * Bash shell
14 * Basic (C64 and QBasic)
15 * C
16 * C++
17 * C#
18 * ChucK
19 * GNU CLISP
20 * Clojure
21 * CoffeeScript
22 * Crystal
23 * D
24 * Elixir
25 * Emacs Lisp
26 * Erlang
27 * ES6 (ECMAScript 6 / ECMAScript 2015)
28 * F#
29 * Factor
30 * Forth
31 * Go
32 * Groovy
33 * GNU Guile
34 * Haskell
35 * Haxe
36 * Io
37 * Java
38 * JavaScript ([Online Demo](http://kanaka.github.io/mal))
39 * Julia
40 * Kotlin
41 * Logo
42 * Lua
43 * GNU Make
44 * mal itself
45 * MATLAB
46 * [miniMAL](https://github.com/kanaka/miniMAL)
47 * Nim
48 * Object Pascal
49 * Objective C
50 * OCaml
51 * Perl
52 * Perl 6
53 * PHP
54 * Picolisp
55 * PL/pgSQL (Postgres)
56 * PL/SQL (Oracle)
57 * Postscript
58 * PowerShell
59 * Python
60 * RPython
61 * R
62 * Racket
63 * Ruby
64 * Rust
65 * Scala
66 * Swift
67 * Swift 3
68 * Tcl
69 * VHDL
70 * Vimscript
71 * Visual Basic.NET
72
73
74 Mal is a learning tool. See the [make-a-lisp process
75 guide](process/guide.md). Each implementation of mal is separated into
76 11 incremental, self-contained (and testable) steps that demonstrate
77 core concepts of Lisp. The last step is capable of self-hosting
78 (running the mal implementation of mal).
79
80 The mal (make a lisp) steps are:
81
82 * [step0_repl](process/guide.md#step0)
83 * [step1_read_print](process/guide.md#step1)
84 * [step2_eval](process/guide.md#step2)
85 * [step3_env](process/guide.md#step3)
86 * [step4_if_fn_do](process/guide.md#step4)
87 * [step5_tco](process/guide.md#step5)
88 * [step6_file](process/guide.md#step6)
89 * [step7_quote](process/guide.md#step7)
90 * [step8_macros](process/guide.md#step8)
91 * [step9_try](process/guide.md#step9)
92 * [stepA_mal](process/guide.md#stepA)
93
94
95 Mal was presented publicly for the first time in a lightning talk at
96 Clojure West 2014 (unfortunately there is no video). See
97 examples/clojurewest2014.mal for the presentation that was given at the
98 conference (yes the presentation is a mal program). At Midwest.io
99 2015, Joel Martin gave a presentation on Mal titled "Achievement
100 Unlocked: A Better Path to Language Learning".
101 [Video](https://www.youtube.com/watch?v=lgyOAiRtZGw),
102 [Slides](http://kanaka.github.io/midwest.io.mal/).
103
104 If you are interesting in creating a mal implementation (or just
105 interested in using mal for something), please drop by the #mal
106 channel on freenode. In addition to the [make-a-lisp process
107 guide](process/guide.md) there is also a [mal/make-a-lisp
108 FAQ](docs/FAQ.md) where I attempt to answer some common questions.
109
110 ## Building/running implementations
111
112 The simplest way to run any given implementation is to use docker.
113 Every implementation has a docker image pre-built with language
114 dependencies installed. You can launch the REPL using a convenience
115 target in the top level Makefile (where IMPL is the implementation
116 directory name and stepX is the step to run):
117
118 ```
119 make DOCKERIZE=1 "repl^IMPL^stepX"
120 # OR stepA is the default step:
121 make DOCKERIZE=1 "repl^IMPL"
122 ```
123
124
125 ### Ada
126
127 *The Ada implementation was created by [Chris Moore](https://github.com/zmower)*
128
129 The Ada implementation was developed with GNAT 4.9 on debian. It also
130 compiles unchanged on windows if you have windows versions of git,
131 GNAT and (optionally) make. There are no external dependencies
132 (readline not implemented).
133
134 ```
135 cd ada
136 make
137 ./stepX_YYY
138 ```
139
140 ### GNU awk
141
142 *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)*
143
144 The GNU awk implementation of mal has been tested with GNU awk 4.1.1.
145
146 ```
147 cd gawk
148 gawk -O -f stepX_YYY.awk
149 ```
150
151 ### Bash 4
152
153 ```
154 cd bash
155 bash stepX_YYY.sh
156 ```
157
158 ### Basic (C64 and QBasic)
159
160 The Basic implementation uses a preprocessor that can generate Basic
161 code that is compatible with both C64 Basic (CBM v2) and QBasic. The
162 C64 mode has been tested with
163 [cbmbasic](https://github.com/kanaka/cbmbasic) (the patched version is
164 currently required to fix issues with line input) and the QBasic mode
165 has been tested with [qb64](http://www.qb64.net/).
166
167 Generate C64 code and run it using cbmbasic:
168
169 ```
170 cd basic
171 make stepX_YYY.bas
172 STEP=stepX_YYY ./run
173 ```
174
175 Generate QBasic code and load it into qb64:
176
177 ```
178 cd basic
179 make MODE=qbasic stepX_YYY.bas
180 ./qb64 stepX_YYY.bas
181 ```
182
183 Thanks to [Steven Syrek](https://github.com/sjsyrek) for the original
184 inspiration for this implementation.
185
186
187 ### C
188
189 The C implementation of mal requires the following libraries (lib and
190 header packages): glib, libffi6, libgc, and either the libedit or GNU readline
191 library.
192
193 ```
194 cd c
195 make
196 ./stepX_YYY
197 ```
198
199 ### C++
200
201 *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)*
202
203 The C++ implementation of mal requires g++-4.9 or clang++-3.5 and
204 a readline compatible library to build. See the `cpp/README.md` for
205 more details:
206
207 ```
208 cd cpp
209 make
210 # OR
211 make CXX=clang++-3.5
212 ./stepX_YYY
213 ```
214
215
216 ### C# ###
217
218 The C# implementation of mal has been tested on Linux using the Mono
219 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
220 required to build and run the C# implementation.
221
222 ```
223 cd cs
224 make
225 mono ./stepX_YYY.exe
226 ```
227
228 ### ChucK
229
230 *The ChucK implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
231
232 The ChucK implementation has been tested with ChucK 1.3.5.2 on Arch
233 Linux.
234
235 ```
236 cd chuck
237 ./run
238 ```
239
240 ### GNU CLISP
241
242 *The GNU CLISP implementation was created by [Iqbal Ansari](https://github.com/iqbalansari)*
243
244 The implementation has been tested with GNU CLISP v2.49 on Ubuntu 16.04, 14.04 and 12.04
245
246 ```
247 cd clisp
248 make
249 ./run
250 ```
251
252 ### Clojure
253
254 For the most part the Clojure implementation requires Clojure 1.5,
255 however, to pass all tests, Clojure 1.8.0-RC4 is required.
256
257 ```
258 cd clojure
259 lein with-profile +stepX trampoline run
260 ```
261
262 ### CoffeeScript
263
264 ```
265 sudo npm install -g coffee-script
266 cd coffee
267 coffee ./stepX_YYY
268 ```
269
270 ### Crystal
271
272 *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)*
273
274 The Crystal implementation of mal has been tested with Crystal 0.18.4.
275
276 ```
277 cd crystal
278 crystal run ./stepX_YYY.cr
279 # OR
280 make # needed to run tests
281 ./stepX_YYY
282 ```
283
284 ### D
285
286 *The D implementation was created by [Dov Murik](https://github.com/dubek)*
287
288 The D implementation of mal was tested with GDC 4.8. It requires the GNU
289 readline library.
290
291 ```
292 cd d
293 make
294 ./stepX_YYY
295 ```
296
297 ### Emacs Lisp
298
299 *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
300
301 The Emacs Lisp implementation of mal has been tested with Emacs 24.3
302 and 24.5. While there is very basic readline editing (`<backspace>`
303 and `C-d` work, `C-c` cancels the process), it is recommended to use
304 `rlwrap`.
305
306 ```
307 cd elisp
308 emacs -Q --batch --load stepX_YYY.el
309 # with full readline support
310 rlwrap emacs -Q --batch --load stepX_YYY.el
311 ```
312
313 ### Elixir
314
315 *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)*
316
317 The Elixir implementation of mal has been tested with Elixir 1.0.5.
318
319 ```
320 cd elixir
321 mix stepX_YYY
322 # Or with readline/line editing functionality:
323 iex -S mix stepX_YYY
324 ```
325
326 ### Erlang
327
328 *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)*
329
330 The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html)
331 and [rebar](https://github.com/rebar/rebar) to build.
332
333 ```
334 cd erlang
335 make
336 # OR
337 MAL_STEP=stepX_YYY rebar compile escriptize # build individual step
338 ./stepX_YYY
339 ```
340
341 ### ES6 (ECMAScript 6 / ECMAScript 2015)
342
343 The ES6 implementation uses the [babel](https://babeljs.io) compiler
344 to generate ES5 compatible JavaScript. The generated code has been
345 tested with Node 0.12.4.
346
347 ```
348 cd es6
349 make
350 node build/stepX_YYY.js
351 ```
352
353
354 ### F# ###
355
356 *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)*
357
358 The F# implementation of mal has been tested on Linux using the Mono
359 F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C#
360 compiler (mcs) is also necessary to compile the readline dependency. All are
361 required to build and run the F# implementation.
362
363 ```
364 cd fsharp
365 make
366 mono ./stepX_YYY.exe
367 ```
368
369 ### Factor
370
371 *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)*
372
373 The Factor implementation of mal has been tested with Factor 0.97
374 ([factorcode.org](http://factorcode.org)).
375
376 ```
377 cd factor
378 FACTOR_ROOTS=. factor -run=stepX_YYY
379 ```
380
381 ### Forth
382
383 *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
384
385 ```
386 cd forth
387 gforth stepX_YYY.fs
388 ```
389
390 ### Go
391
392 The Go implementation of mal requires that go is installed on on the
393 path. The implementation has been tested with Go 1.3.1.
394
395 ```
396 cd go
397 make
398 ./stepX_YYY
399 ```
400
401
402 ### Groovy
403
404 The Groovy implementation of mal requires Groovy to run and has been
405 tested with Groovy 1.8.6.
406
407 ```
408 cd groovy
409 make
410 groovy ./stepX_YYY.groovy
411 ```
412
413 ### GNU Guile 2.1+
414
415 *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).*
416
417 ```
418 cd guile
419 guile -L ./ stepX_YYY.scm
420 ```
421
422 ### Haskell
423
424 The Haskell implementation requires the ghc compiler version 7.10.1 or
425 later and also the Haskell parsec and readline (or editline) packages.
426
427 ```
428 cd haskell
429 make
430 ./stepX_YYY
431 ```
432
433 ### Haxe
434
435 The Haxe implementation of mal requires Haxe version 3.2 to compile.
436 Four different Haxe targets are supported: Neko, Python, C++, and
437 JavaScript.
438
439 ```
440 cd haxe
441 # Neko
442 make all-neko
443 neko ./stepX_YYY.n
444 # Python
445 make all-python
446 python3 ./stepX_YYY.py
447 # C++
448 make all-cpp
449 ./cpp/stepX_YYY
450 # JavaScript
451 make all-js
452 node ./stepX_YYY.js
453 ```
454
455 ### Io
456
457 *The Io implementation was created by [Dov Murik](https://github.com/dubek)*
458
459 The Io implementation of mal has been tested with Io version 20110905.
460
461 ```
462 cd io
463 io ./stepX_YYY.io
464 ```
465
466 ### Java 1.7
467
468 The Java implementation of mal requires maven2 to build.
469
470 ```
471 cd java
472 mvn compile
473 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
474 # OR
475 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
476 ```
477
478 ### JavaScript/Node
479
480 ```
481 cd js
482 npm update
483 node stepX_YYY.js
484 ```
485
486 ### Julia
487
488 The Julia implementation of mal requires Julia 0.4.
489
490 ```
491 cd julia
492 julia stepX_YYY.jl
493 ```
494
495 ### Kotlin
496
497 *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)*
498
499 The Kotlin implementation of mal has been tested with Kotlin 1.0.
500
501 ```
502 cd kotlin
503 make
504 java -jar stepX_YYY.jar
505 ```
506
507 ### Logo
508
509 *The Logo implementation was created by [Dov Murik](https://github.com/dubek)*
510
511 The Logo implementation of mal has been tested with UCBLogo 6.0.
512
513 ```
514 cd logo
515 logo stepX_YYY.lg
516 ```
517
518 ### Lua
519
520 Running the Lua implementation of mal requires lua 5.1 or later,
521 luarocks and the lua-rex-pcre library installed.
522
523 ```
524 cd lua
525 make # to build and link linenoise.so
526 ./stepX_YYY.lua
527 ```
528
529 ### Mal
530
531 Running the mal implementation of mal involves running stepA of one of
532 the other implementations and passing the mal step to run as a command
533 line argument.
534
535 ```
536 cd IMPL
537 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
538
539 ```
540
541 ### GNU Make 3.81
542
543 ```
544 cd make
545 make -f stepX_YYY.mk
546 ```
547
548 ### Nim 0.15.2
549
550 *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)*
551
552 The Nim implementation of mal has been tested with Nim 0.15.2.
553
554 ```
555 cd nim
556 make
557 # OR
558 nimble build
559 ./stepX_YYY
560 ```
561
562 ### Object Pascal
563
564 The Object Pascal implementation of mal has been built and tested on
565 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
566
567 ```
568 cd objpascal
569 make
570 ./stepX_YYY
571 ```
572
573 ### Objective C
574
575 The Objective C implementation of mal has been built and tested on
576 Linux using clang/LLVM 3.6. It has also been built and tested on OS
577 X using XCode 7.
578
579 ```
580 cd objc
581 make
582 ./stepX_YYY
583 ```
584
585 ### OCaml 4.01.0
586
587 *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)*
588
589 ```
590 cd ocaml
591 make
592 ./stepX_YYY
593 ```
594
595 ### MATLAB
596
597 The MATLAB implementation of mal has been tested with MATLAB version
598 R2014a on Linux. Note that MATLAB is a commercial product. It should
599 be fairly simple to support GNU Octave once it support classdef object
600 syntax.
601
602 ```
603 cd matlab
604 ./stepX_YYY
605 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
606 # OR with command line arguments
607 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
608 ```
609
610 ### miniMAL
611
612 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
613 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
614 implementation of mal you need to download/install the miniMAL
615 interpreter (which requires Node.js).
616 ```
617 cd miniMAL
618 # Download miniMAL and dependencies
619 npm install
620 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
621 # Now run mal implementation in miniMAL
622 miniMAL ./stepX_YYY
623 ```
624
625 ### Perl 5.8
626
627 For readline line editing support, install Term::ReadLine::Perl or
628 Term::ReadLine::Gnu from CPAN.
629
630 ```
631 cd perl
632 perl stepX_YYY.pl
633 ```
634
635 ### Perl 6
636
637 *The Perl 6 implementation was created by [Hinrik Örn Sigurðsson](https://github.com/hinrik)*
638
639 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
640
641 ```
642 cd perl6
643 perl6 stepX_YYY.pl
644 ```
645
646 ### PHP 5.3
647
648 The PHP implementation of mal requires the php command line interface
649 to run.
650
651 ```
652 cd php
653 php stepX_YYY.php
654 ```
655
656 ### Picolisp
657
658 *The Picolisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)*
659
660 The Picolisp implementation requires libreadline and Picolisp 3.1.11
661 or later.
662
663 ```
664 cd pil
665 ./run
666 ```
667
668 ### PL/pgSQL (Postgres SQL Procedural Language)
669
670 The PL/pgSQL implementation of mal requires a running Postgres server
671 (the "kanaka/mal-test-plpgsql" docker image automatically starts
672 a Postgres server). The implementation connects to the Postgres server
673 and create a database named "mal" to store tables and stored
674 procedures. The wrapper script uses the psql command to connect to the
675 server and defaults to the user "postgres" but this can be overridden
676 with the PSQL_USER environment variable. A password can be specified
677 using the PGPASSWORD environment variable. The implementation has been
678 tested with Postgres 9.4.
679
680 ```
681 cd plpgsql
682 ./wrap.sh stepX_YYY.sql
683 # OR
684 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
685 ```
686
687 ### PL/SQL (Oracle SQL Procedural Language)
688
689 The PL/pgSQL implementation of mal requires a running Oracle DB
690 server (the "kanaka/mal-test-plsql" docker image automatically
691 starts an Oracle Express server). The implementation connects to the
692 Oracle server to create types, tables and stored procedures. The
693 default SQL*Plus logon value (username/password@connect_identifier) is
694 "system/oracle" but this can be overridden with the ORACLE_LOGON
695 environment variable. The implementation has been tested with Oracle
696 Express Edition 11g Release 2. Note that any SQL*Plus connection
697 warnings (user password expiration, etc) will interfere with the
698 ability of the wrapper script to communicate with the DB.
699
700 ```
701 cd plsql
702 ./wrap.sh stepX_YYY.sql
703 # OR
704 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
705 ```
706
707 ### Postscript Level 2/3
708
709 The Postscript implementation of mal requires ghostscript to run. It
710 has been tested with ghostscript 9.10.
711
712 ```
713 cd ps
714 gs -q -dNODISPLAY -I./ stepX_YYY.ps
715 ```
716
717 ### PowerShell
718
719 The PowerShell implementation of mal requires the PowerShell script
720 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
721
722 ```
723 cd powershell
724 powershell ./stepX_YYY.ps1
725 ```
726
727 ### Python (2.X or 3.X)
728
729 ```
730 cd python
731 python stepX_YYY.py
732 ```
733
734 ### RPython
735
736 You must have [rpython](https://rpython.readthedocs.org/) on your path
737 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
738
739 ```
740 cd rpython
741 make # this takes a very long time
742 ./stepX_YYY
743 ```
744
745 ### R
746
747 The R implementation of mal requires R (r-base-core) to run.
748
749 ```
750 cd r
751 make libs # to download and build rdyncall
752 Rscript stepX_YYY.r
753 ```
754
755 ### Racket (5.3)
756
757 The Racket implementation of mal requires the Racket
758 compiler/interpreter to run.
759
760 ```
761 cd racket
762 ./stepX_YYY.rkt
763 ```
764
765 ### Ruby (1.9+)
766
767 ```
768 cd ruby
769 ruby stepX_YYY.rb
770 ```
771
772 ### Rust (1.0.0 nightly)
773
774 The rust implementation of mal requires the rust compiler and build
775 tool (cargo) to build.
776
777 ```
778 cd rust
779 cargo run --release --bin stepX_YYY
780 ```
781
782 ### Scala ###
783
784 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
785
786 ```
787 cd scala
788 sbt 'run-main stepX_YYY'
789 # OR
790 sbt compile
791 scala -classpath target/scala*/classes stepX_YYY
792 ```
793
794 ### Swift
795
796 *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)*
797
798 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
799 7.0) to build. Older versions will not work due to changes in the
800 language and standard library.
801
802 ```
803 cd swift
804 make
805 ./stepX_YYY
806 ```
807
808 ### Swift 3
809
810 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
811 has been tested with Swift 3 Preview 3.
812
813 ```
814 cd swift3
815 make
816 ./stepX_YYY
817 ```
818
819 ### Tcl 8.6
820
821 *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)*
822
823 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
824 editing support, install tclreadline.
825
826 ```
827 cd tcl
828 tclsh ./stepX_YYY.tcl
829 ```
830
831 ### VHDL
832
833 *The VHDL implementation was created by [Dov Murik](https://github.com/dubek)*
834
835 The VHDL implementation of mal has been tested with GHDL 0.29.
836
837 ```
838 cd vhdl
839 make
840 ./run_vhdl.sh ./stepX_YYY
841 ```
842
843 ### Vimscript
844
845 *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)*
846
847 The Vimscript implementation of mal requires Vim 8.0 to run.
848
849 ```
850 cd vimscript
851 ./run_vimscript.sh ./stepX_YYY.vim
852 ```
853
854 ### Visual Basic.NET ###
855
856 The VB.NET implementation of mal has been tested on Linux using the Mono
857 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
858 required to build and run the VB.NET implementation.
859
860 ```
861 cd vb
862 make
863 mono ./stepX_YYY.exe
864 ```
865
866
867
868 ## Running tests
869
870 ### Functional tests
871
872 The are over 600 generic functional tests (for all implementations)
873 in the `tests/` directory. Each step has a corresponding test file
874 containing tests specific to that step. The `runtest.py` test harness
875 launches a Mal step implementation and then feeds the tests one at
876 a time to the implementation and compares the output/return value to
877 the expected output/return value.
878
879 To simplify the process of running tests, a top level Makefile is
880 provided with convenient test targets.
881
882 * To run all the tests across all implementations (be prepared to wait):
883
884 ```
885 make test
886 ```
887
888 * To run all tests against a single implementation:
889
890 ```
891 make "test^IMPL"
892
893 # e.g.
894 make "test^clojure"
895 make "test^js"
896 ```
897
898 * To run tests for a single step against all implementations:
899
900 ```
901 make "test^stepX"
902
903 # e.g.
904 make "test^step2"
905 make "test^step7"
906 ```
907
908 * To run tests for a specific step against a single implementation:
909
910 ```
911 make "test^IMPL^stepX"
912
913 # e.g
914 make "test^ruby^step3"
915 make "test^ps^step4"
916 ```
917
918 ### Self-hosted functional tests
919
920 * To run the functional tests in self-hosted mode, you specify `mal`
921 as the test implementation and use the `MAL_IMPL` make variable
922 to change the underlying host language (default is JavaScript):
923 ```
924 make MAL_IMPL=IMPL "test^mal^step2"
925
926 # e.g.
927 make "test^mal^step2" # js is default
928 make MAL_IMPL=ruby "test^mal^step2"
929 make MAL_IMPL=python "test^mal^step2"
930 ```
931
932 ### Starting the REPL
933
934 * To start the REPL of an implementation in a specific step:
935
936 ```
937 make "repl^IMPL^stepX"
938
939 # e.g
940 make "repl^ruby^step3"
941 make "repl^ps^step4"
942 ```
943
944 * If you omit the step, then `stepA` is used:
945
946 ```
947 make "repl^IMPL"
948
949 # e.g
950 make "repl^ruby"
951 make "repl^ps"
952 ```
953
954 * To start the REPL of the self-hosted implementation, specify `mal` as the
955 REPL implementation and use the `MAL_IMPL` make variable to change the
956 underlying host language (default is JavaScript):
957 ```
958 make MAL_IMPL=IMPL "repl^mal^stepX"
959
960 # e.g.
961 make "repl^mal^step2" # js is default
962 make MAL_IMPL=ruby "repl^mal^step2"
963 make MAL_IMPL=python "repl^mal"
964 ```
965
966 ### Performance tests
967
968 Warning: These performance tests are neither statistically valid nor
969 comprehensive; runtime performance is a not a primary goal of mal. If
970 you draw any serious conclusions from these performance tests, then
971 please contact me about some amazing oceanfront property in Kansas
972 that I'm willing to sell you for cheap.
973
974 * To run performance tests against a single implementation:
975 ```
976 make "perf^IMPL"
977
978 # e.g.
979 make "perf^js"
980 ```
981
982 * To run performance tests against all implementations:
983 ```
984 make "perf"
985 ```
986
987 ### Generating language statistics
988
989 * To report line and byte statistics for a single implementation:
990 ```
991 make "stats^IMPL"
992
993 # e.g.
994 make "stats^js"
995 ```
996
997 * To report line and bytes statistics for general Lisp code (env, core
998 and stepA):
999 ```
1000 make "stats-lisp^IMPL"
1001
1002 # e.g.
1003 make "stats-lisp^js"
1004 ```
1005
1006 ## Dockerized testing
1007
1008 Every implementation directory contains a Dockerfile to create
1009 a docker image containing all the dependencies for that
1010 implementation. In addition, the top-level Makefile contains support
1011 for running the tests target (and perf, stats, repl, etc) within
1012 a docker container for that implementation by passing *"DOCKERIZE=1"*
1013 on the make command line. For example:
1014
1015 ```
1016 make DOCKERIZE=1 "test^js^step3"
1017 ```
1018
1019 Existing implementations already have docker images built and pushed
1020 to the docker registry. However, if
1021 you wish to build or rebuild a docker image locally, the toplevel
1022 Makefile provides a rule for building docker images:
1023
1024 ```
1025 make "docker-build^IMPL"
1026 ```
1027
1028
1029 **Notes**:
1030 * Docker images are named *"kanaka/mal-test-IMPL"*
1031 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1032 you will probably need to run these implementations once manually
1033 first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because
1034 runtime dependencies need to be downloaded to avoid the tests timing
1035 out. These dependencies are download to dot-files in the /mal
1036 directory so they will persist between runs.
1037
1038
1039 ## License
1040
1041 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1042 License 2.0). See LICENSE.txt for more details.