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