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