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