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