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