runtest: Don't worry about how implementation echoes input
[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.3.5 The
651 implementation requires luarocks to be installed.
652
653 ```
654 cd impls/lua
655 make # to build and link linenoise.so and rex_pcre.so
656 ./stepX_YYY.lua
657 ```
658
659 ### Mal
660
661 Running the mal implementation of mal involves running stepA of one of
662 the other implementations and passing the mal step to run as a command
663 line argument.
664
665 ```
666 cd impls/IMPL
667 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
668
669 ```
670
671 ### GNU Make 3.81
672
673 ```
674 cd impls/make
675 make -f stepX_YYY.mk
676 ```
677
678 ### NASM
679
680 The NASM implementation of mal is written for x86-64 Linux, and has been tested
681 with Linux 3.16.0-4-amd64 and NASM version 2.11.05.
682
683 ```
684 cd impls/nasm
685 make
686 ./stepX_YYY
687 ```
688
689 ### Nim 1.0.4
690
691 The Nim implementation of mal has been tested with Nim 1.0.4.
692
693 ```
694 cd impls/nim
695 make
696 # OR
697 nimble build
698 ./stepX_YYY
699 ```
700
701 ### Object Pascal
702
703 The Object Pascal implementation of mal has been built and tested on
704 Linux using the Free Pascal compiler version 2.6.2 and 2.6.4.
705
706 ```
707 cd impls/objpascal
708 make
709 ./stepX_YYY
710 ```
711
712 ### Objective C
713
714 The Objective C implementation of mal has been built and tested on
715 Linux using clang/LLVM 3.6. It has also been built and tested on OS
716 X using XCode 7.
717
718 ```
719 cd impls/objc
720 make
721 ./stepX_YYY
722 ```
723
724 ### OCaml 4.01.0
725
726 ```
727 cd impls/ocaml
728 make
729 ./stepX_YYY
730 ```
731
732 ### MATLAB (GNU Octave and MATLAB)
733
734 The MatLab implementation has been tested with GNU Octave 4.2.1.
735 It has also been tested with MATLAB version R2014a on Linux. Note that
736 MATLAB is a commercial product.
737
738 ```
739 cd impls/matlab
740 ./stepX_YYY
741 octave -q --no-gui --no-history --eval "stepX_YYY();quit;"
742 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;"
743 # OR with command line arguments
744 octave -q --no-gui --no-history --eval "stepX_YYY('arg1','arg2');quit;"
745 matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;"
746 ```
747
748 ### miniMAL
749
750 [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter
751 implemented in less than 1024 bytes of JavaScript. To run the miniMAL
752 implementation of mal you need to download/install the miniMAL
753 interpreter (which requires Node.js).
754 ```
755 cd impls/miniMAL
756 # Download miniMAL and dependencies
757 npm install
758 export PATH=`pwd`/node_modules/minimal-lisp/:$PATH
759 # Now run mal implementation in miniMAL
760 miniMAL ./stepX_YYY
761 ```
762
763 ### Perl 5
764
765 The Perl 5 implementation should work with perl 5.19.3 and later.
766
767 For readline line editing support, install Term::ReadLine::Perl or
768 Term::ReadLine::Gnu from CPAN.
769
770 ```
771 cd impls/perl
772 perl stepX_YYY.pl
773 ```
774
775 ### Perl 6
776
777 The Perl 6 implementation was tested on Rakudo Perl 6 2016.04.
778
779 ```
780 cd impls/perl6
781 perl6 stepX_YYY.pl
782 ```
783
784 ### PHP 5.3
785
786 The PHP implementation of mal requires the php command line interface
787 to run.
788
789 ```
790 cd impls/php
791 php stepX_YYY.php
792 ```
793
794 ### Picolisp
795
796 The Picolisp implementation requires libreadline and Picolisp 3.1.11
797 or later.
798
799 ```
800 cd impls/picolisp
801 ./run
802 ```
803
804 ### Pike
805
806 The Pike implementation was tested on Pike 8.0.
807
808 ```
809 cd impls/pike
810 pike stepX_YYY.pike
811 ```
812
813 ### PL/pgSQL (PostgreSQL SQL Procedural Language)
814
815 The PL/pgSQL implementation of mal requires a running PostgreSQL server
816 (the "kanaka/mal-test-plpgsql" docker image automatically starts
817 a PostgreSQL server). The implementation connects to the PostgreSQL server
818 and create a database named "mal" to store tables and stored
819 procedures. The wrapper script uses the psql command to connect to the
820 server and defaults to the user "postgres" but this can be overridden
821 with the PSQL_USER environment variable. A password can be specified
822 using the PGPASSWORD environment variable. The implementation has been
823 tested with PostgreSQL 9.4.
824
825 ```
826 cd impls/plpgsql
827 ./wrap.sh stepX_YYY.sql
828 # OR
829 PSQL_USER=myuser PGPASSWORD=mypass ./wrap.sh stepX_YYY.sql
830 ```
831
832 ### PL/SQL (Oracle SQL Procedural Language)
833
834 The PL/SQL implementation of mal requires a running Oracle DB
835 server (the "kanaka/mal-test-plsql" docker image automatically
836 starts an Oracle Express server). The implementation connects to the
837 Oracle server to create types, tables and stored procedures. The
838 default SQL\*Plus logon value (username/password@connect_identifier) is
839 "system/oracle" but this can be overridden with the ORACLE_LOGON
840 environment variable. The implementation has been tested with Oracle
841 Express Edition 11g Release 2. Note that any SQL\*Plus connection
842 warnings (user password expiration, etc) will interfere with the
843 ability of the wrapper script to communicate with the DB.
844
845 ```
846 cd impls/plsql
847 ./wrap.sh stepX_YYY.sql
848 # OR
849 ORACLE_LOGON=myuser/mypass@ORCL ./wrap.sh stepX_YYY.sql
850 ```
851
852 ### PostScript Level 2/3
853
854 The PostScript implementation of mal requires Ghostscript to run. It
855 has been tested with Ghostscript 9.10.
856
857 ```
858 cd impls/ps
859 gs -q -dNODISPLAY -I./ stepX_YYY.ps
860 ```
861
862 ### PowerShell
863
864 The PowerShell implementation of mal requires the PowerShell script
865 language. It has been tested with PowerShell 6.0.0 Alpha 9 on Linux.
866
867 ```
868 cd impls/powershell
869 powershell ./stepX_YYY.ps1
870 ```
871
872 ### Python (2.X and 3.X)
873
874 ```
875 cd impls/python
876 python stepX_YYY.py
877 ```
878
879 ### Python.2 (3.X)
880
881 The second Python implementation makes heavy use of type annotations and uses the Arpeggio parser library.
882
883 ```
884 # Recommended: do these steps in a Python virtual environment.
885 pip3 install Arpeggio==1.9.0
886 python3 stepX_YYY.py
887 ```
888
889 ### RPython
890
891 You must have [rpython](https://rpython.readthedocs.org/) on your path
892 (included with [pypy](https://bitbucket.org/pypy/pypy/)).
893
894 ```
895 cd impls/rpython
896 make # this takes a very long time
897 ./stepX_YYY
898 ```
899
900 ### R
901
902 The R implementation of mal requires R (r-base-core) to run.
903
904 ```
905 cd impls/r
906 make libs # to download and build rdyncall
907 Rscript stepX_YYY.r
908 ```
909
910 ### Racket (5.3)
911
912 The Racket implementation of mal requires the Racket
913 compiler/interpreter to run.
914
915 ```
916 cd impls/racket
917 ./stepX_YYY.rkt
918 ```
919
920 ### Rexx
921
922 The Rexx implementation of mal has been tested with Regina Rexx 3.6.
923
924 ```
925 cd impls/rexx
926 make
927 rexx -a ./stepX_YYY.rexxpp
928 ```
929
930 ### Ruby (1.9+)
931
932 ```
933 cd impls/ruby
934 ruby stepX_YYY.rb
935 ```
936
937 ### Rust (1.38+)
938
939 The rust implementation of mal requires the rust compiler and build
940 tool (cargo) to build.
941
942 ```
943 cd impls/rust
944 cargo run --release --bin stepX_YYY
945 ```
946
947 ### Scala ###
948
949 Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html):
950
951 ```
952 cd impls/scala
953 sbt 'run-main stepX_YYY'
954 # OR
955 sbt compile
956 scala -classpath target/scala*/classes stepX_YYY
957 ```
958
959 ### Scheme (R7RS) ###
960
961 The Scheme implementation of mal has been tested with Chibi-Scheme
962 0.7.3, Kawa 2.4, Gauche 0.9.5, CHICKEN 4.11.0, Sagittarius 0.8.3,
963 Cyclone 0.6.3 (Git version) and Foment 0.4 (Git version). You should
964 be able to get it running on other conforming R7RS implementations
965 after figuring out how libraries are loaded and adjusting the
966 `Makefile` and `run` script accordingly.
967
968 ```
969 cd impls/scheme
970 make symlinks
971 # chibi
972 scheme_MODE=chibi ./run
973 # kawa
974 make kawa
975 scheme_MODE=kawa ./run
976 # gauche
977 scheme_MODE=gauche ./run
978 # chicken
979 make chicken
980 scheme_MODE=chicken ./run
981 # sagittarius
982 scheme_MODE=sagittarius ./run
983 # cyclone
984 make cyclone
985 scheme_MODE=cyclone ./run
986 # foment
987 scheme_MODE=foment ./run
988 ```
989
990 ### Skew ###
991
992 The Skew implementation of mal has been tested with Skew 0.7.42.
993
994 ```
995 cd impls/skew
996 make
997 node stepX_YYY.js
998 ```
999
1000
1001 ### Swift
1002
1003 The Swift implementation of mal requires the Swift 2.0 compiler (XCode
1004 7.0) to build. Older versions will not work due to changes in the
1005 language and standard library.
1006
1007 ```
1008 cd impls/swift
1009 make
1010 ./stepX_YYY
1011 ```
1012
1013 ### Swift 3
1014
1015 The Swift 3 implementation of mal requires the Swift 3.0 compiler. It
1016 has been tested with Swift 3 Preview 3.
1017
1018 ```
1019 cd impls/swift3
1020 make
1021 ./stepX_YYY
1022 ```
1023
1024 ### Swift 4
1025
1026 The Swift 4 implementation of mal requires the Swift 4.0 compiler. It
1027 has been tested with Swift 4.2.3 release.
1028
1029 ```
1030 cd impls/swift4
1031 make
1032 ./stepX_YYY
1033 ```
1034
1035 ### Swift 5
1036
1037 The Swift 5 implementation of mal requires the Swift 5.0 compiler. It
1038 has been tested with Swift 5.1.1 release.
1039
1040 ```
1041 cd impls/swift5
1042 swift run stepX_YYY
1043 ```
1044
1045 ### Tcl 8.6
1046
1047 The Tcl implementation of mal requires Tcl 8.6 to run. For readline line
1048 editing support, install tclreadline.
1049
1050 ```
1051 cd impls/tcl
1052 tclsh ./stepX_YYY.tcl
1053 ```
1054
1055 ### TypeScript
1056
1057 The TypeScript implementation of mal requires the TypeScript 2.2 compiler.
1058 It has been tested with Node.js v6.
1059
1060 ```
1061 cd impls/ts
1062 make
1063 node ./stepX_YYY.js
1064 ```
1065
1066 ### Vala
1067
1068 The Vala implementation of mal has been tested with the Vala 0.40.8
1069 compiler. You will need to install `valac` and `libreadline-dev` or
1070 equivalent.
1071
1072 ```
1073 cd impls/vala
1074 make
1075 ./stepX_YYY
1076 ```
1077
1078 ### VHDL
1079
1080 The VHDL implementation of mal has been tested with GHDL 0.29.
1081
1082 ```
1083 cd impls/vhdl
1084 make
1085 ./run_vhdl.sh ./stepX_YYY
1086 ```
1087
1088 ### Vimscript
1089
1090 The Vimscript implementation of mal requires Vim 8.0 to run.
1091
1092 ```
1093 cd impls/vimscript
1094 ./run_vimscript.sh ./stepX_YYY.vim
1095 ```
1096
1097 ### Visual Basic.NET ###
1098
1099 The VB.NET implementation of mal has been tested on Linux using the Mono
1100 VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are
1101 required to build and run the VB.NET implementation.
1102
1103 ```
1104 cd impls/vb
1105 make
1106 mono ./stepX_YYY.exe
1107 ```
1108
1109 ### WebAssembly (wasm) ###
1110
1111 The WebAssembly implementation is written in
1112 [Wam](https://github.com/kanaka/wam) (WebAssembly Macro language) and
1113 runs under several different non-web embeddings (runtimes):
1114 [node](https://nodejs.org),
1115 [wasmtime](https://github.com/CraneStation/wasmtime),
1116 [wasmer](https://wasmer.io),
1117 [lucet](https://github.com/fastly/lucet),
1118 [wax](https://github.com/kanaka/wac),
1119 [wace](https://github.com/kanaka/wac),
1120 [warpy](https://github.com/kanaka/warpy).
1121
1122 ```
1123 cd impls/wasm
1124 # node
1125 make wasm_MODE=node
1126 ./run.js ./stepX_YYY.wasm
1127 # wasmtime
1128 make wasm_MODE=wasmtime
1129 wasmtime --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1130 # wasmer
1131 make wasm_MODE=wasmer
1132 wasmer run --dir=./ --dir=../ --dir=/ ./stepX_YYY.wasm
1133 # lucet
1134 make wasm_MODE=lucet
1135 lucet-wasi --dir=./:./ --dir=../:../ --dir=/:/ ./stepX_YYY.so
1136 # wax
1137 make wasm_MODE=wax
1138 wax ./stepX_YYY.wasm
1139 # wace
1140 make wasm_MODE=wace_libc
1141 wace ./stepX_YYY.wasm
1142 # warpy
1143 make wasm_MODE=warpy
1144 warpy --argv --memory-pages 256 ./stepX_YYY.wasm
1145 ```
1146
1147 ### Wren
1148
1149 The Wren implementation of mal was tested on Wren 0.2.0.
1150
1151 ```
1152 cd impls/wren
1153 wren ./stepX_YYY.wren
1154 ```
1155
1156 ### Yorick
1157
1158 The Yorick implementation of mal was tested on Yorick 2.2.04.
1159
1160 ```
1161 cd impls/yorick
1162 yorick -batch ./stepX_YYY.i
1163 ```
1164
1165 ### Zig
1166
1167 The Zig implementation of mal was tested on Zig 0.5.
1168
1169 ```
1170 cd impls/zig
1171 zig build stepX_YYY
1172 ```
1173
1174
1175
1176 ## Running tests
1177
1178 The top level Makefile has a number of useful targets to assist with
1179 implementation development and testing. The `help` target provides
1180 a list of the targets and options:
1181
1182 ```
1183 make help
1184 ```
1185
1186 ### Functional tests
1187
1188 The are almost 800 generic functional tests (for all implementations)
1189 in the `tests/` directory. Each step has a corresponding test file
1190 containing tests specific to that step. The `runtest.py` test harness
1191 launches a Mal step implementation and then feeds the tests one at
1192 a time to the implementation and compares the output/return value to
1193 the expected output/return value.
1194
1195 * To run all the tests across all implementations (be prepared to wait):
1196
1197 ```
1198 make test
1199 ```
1200
1201 * To run all tests against a single implementation:
1202
1203 ```
1204 make "test^IMPL"
1205
1206 # e.g.
1207 make "test^clojure"
1208 make "test^js"
1209 ```
1210
1211 * To run tests for a single step against all implementations:
1212
1213 ```
1214 make "test^stepX"
1215
1216 # e.g.
1217 make "test^step2"
1218 make "test^step7"
1219 ```
1220
1221 * To run tests for a specific step against a single implementation:
1222
1223 ```
1224 make "test^IMPL^stepX"
1225
1226 # e.g
1227 make "test^ruby^step3"
1228 make "test^ps^step4"
1229 ```
1230
1231 ### Self-hosted functional tests
1232
1233 * To run the functional tests in self-hosted mode, you specify `mal`
1234 as the test implementation and use the `MAL_IMPL` make variable
1235 to change the underlying host language (default is JavaScript):
1236 ```
1237 make MAL_IMPL=IMPL "test^mal^step2"
1238
1239 # e.g.
1240 make "test^mal^step2" # js is default
1241 make MAL_IMPL=ruby "test^mal^step2"
1242 make MAL_IMPL=python "test^mal^step2"
1243 ```
1244
1245 ### Starting the REPL
1246
1247 * To start the REPL of an implementation in a specific step:
1248
1249 ```
1250 make "repl^IMPL^stepX"
1251
1252 # e.g
1253 make "repl^ruby^step3"
1254 make "repl^ps^step4"
1255 ```
1256
1257 * If you omit the step, then `stepA` is used:
1258
1259 ```
1260 make "repl^IMPL"
1261
1262 # e.g
1263 make "repl^ruby"
1264 make "repl^ps"
1265 ```
1266
1267 * To start the REPL of the self-hosted implementation, specify `mal` as the
1268 REPL implementation and use the `MAL_IMPL` make variable to change the
1269 underlying host language (default is JavaScript):
1270 ```
1271 make MAL_IMPL=IMPL "repl^mal^stepX"
1272
1273 # e.g.
1274 make "repl^mal^step2" # js is default
1275 make MAL_IMPL=ruby "repl^mal^step2"
1276 make MAL_IMPL=python "repl^mal"
1277 ```
1278
1279 ### Performance tests
1280
1281 Warning: These performance tests are neither statistically valid nor
1282 comprehensive; runtime performance is a not a primary goal of mal. If
1283 you draw any serious conclusions from these performance tests, then
1284 please contact me about some amazing oceanfront property in Kansas
1285 that I'm willing to sell you for cheap.
1286
1287 * To run performance tests against a single implementation:
1288 ```
1289 make "perf^IMPL"
1290
1291 # e.g.
1292 make "perf^js"
1293 ```
1294
1295 * To run performance tests against all implementations:
1296 ```
1297 make "perf"
1298 ```
1299
1300 ### Generating language statistics
1301
1302 * To report line and byte statistics for a single implementation:
1303 ```
1304 make "stats^IMPL"
1305
1306 # e.g.
1307 make "stats^js"
1308 ```
1309
1310 ## Dockerized testing
1311
1312 Every implementation directory contains a Dockerfile to create
1313 a docker image containing all the dependencies for that
1314 implementation. In addition, the top-level Makefile contains support
1315 for running the tests target (and perf, stats, repl, etc) within
1316 a docker container for that implementation by passing *"DOCKERIZE=1"*
1317 on the make command line. For example:
1318
1319 ```
1320 make DOCKERIZE=1 "test^js^step3"
1321 ```
1322
1323 Existing implementations already have docker images built and pushed
1324 to the docker registry. However, if
1325 you wish to build or rebuild a docker image locally, the toplevel
1326 Makefile provides a rule for building docker images:
1327
1328 ```
1329 make "docker-build^IMPL"
1330 ```
1331
1332
1333 **Notes**:
1334 * Docker images are named *"kanaka/mal-test-IMPL"*
1335 * JVM-based language implementations (Groovy, Java, Clojure, Scala):
1336 you will probably need to run this command once manually
1337 first `make DOCKERIZE=1 "repl^IMPL"` before you can run tests because
1338 runtime dependencies need to be downloaded to avoid the tests timing
1339 out. These dependencies are downloaded to dot-files in the /mal
1340 directory so they will persist between runs.
1341
1342
1343 ## License
1344
1345 Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public
1346 License 2.0). See LICENSE.txt for more details.