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