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