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