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