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