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