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