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