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