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