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