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