Commit | Line | Data |
---|---|---|
60154d24 JM |
1 | # mal - Make a Lisp |
2 | ||
f9e6bb80 JM |
3 | [![Build Status](https://travis-ci.org/kanaka/mal.svg?branch=master)](https://travis-ci.org/kanaka/mal) |
4 | ||
bcddc3e4 JM |
5 | ## Description |
6 | ||
27696157 | 7 | Mal is a Clojure inspired Lisp interpreter. |
b76aa73b | 8 | |
61f69fba | 9 | Mal is implemented in 49 languages: |
bcddc3e4 | 10 | |
8c7587af | 11 | * GNU awk |
edc3b064 | 12 | * Bash shell |
bcddc3e4 | 13 | * C |
73fc9366 | 14 | * C++ |
edc3b064 JM |
15 | * C# |
16 | * Clojure | |
891c3f3b | 17 | * CoffeeScript |
6c4dede1 | 18 | * Crystal |
f82cb965 | 19 | * D |
bb526975 | 20 | * Elixir |
e0b7f668 | 21 | * Emacs Lisp |
2cc3804b | 22 | * Erlang |
88e934b6 | 23 | * ES6 (ECMAScript 6 / ECMAScript 2015) |
6f78381f | 24 | * F# |
0fe47e88 | 25 | * Factor |
96032890 | 26 | * Forth |
1771ab50 | 27 | * Go |
7ab0f63e | 28 | * Groovy |
7c6882f2 | 29 | * GNU Guile |
b76aa73b | 30 | * Haskell |
33dec7af | 31 | * Haxe |
61f69fba | 32 | * Io |
bcddc3e4 | 33 | * Java |
39381792 JM |
34 | * JavaScript ([Online Demo](http://kanaka.github.io/mal)) |
35 | * Julia | |
53c2ea70 | 36 | * Kotlin |
9d42904e | 37 | * Lua |
bcddc3e4 JM |
38 | * GNU Make |
39 | * mal itself | |
8a9d0a8a | 40 | * MATLAB |
1218ce98 | 41 | * [miniMAL](https://github.com/kanaka/miniMAL) |
a2cd0a3a | 42 | * Nim |
7cae6e6f | 43 | * Objective C |
bc6448bc | 44 | * OCaml |
6301e0b6 | 45 | * Perl |
edc3b064 JM |
46 | * PHP |
47 | * Postscript | |
48 | * Python | |
23e38cd2 | 49 | * RPython |
9b3362e8 | 50 | * R |
f5223195 | 51 | * Racket |
8adb0827 | 52 | * Ruby |
abdd56eb | 53 | * Rust |
821930db | 54 | * Scala |
8b142f08 | 55 | * Swift |
ea1395aa | 56 | * Swift 3 |
54d9903c | 57 | * Tcl |
50a964ce | 58 | * Vimscript |
ee7cd585 | 59 | * Visual Basic.NET |
bcddc3e4 JM |
60 | |
61 | ||
bd08422d JM |
62 | Mal is a learning tool. See the [make-a-lisp process |
63 | guide](process/guide.md). Each implementation of mal is separated into | |
64 | 11 incremental, self-contained (and testable) steps that demonstrate | |
65 | core concepts of Lisp. The last step is capable of self-hosting | |
66 | (running the mal implementation of mal). | |
bcddc3e4 JM |
67 | |
68 | The mal (make a lisp) steps are: | |
69 | ||
0f4ca9d1 JM |
70 | * [step0_repl](process/guide.md#step0) |
71 | * [step1_read_print](process/guide.md#step1) | |
72 | * [step2_eval](process/guide.md#step2) | |
73 | * [step3_env](process/guide.md#step3) | |
74 | * [step4_if_fn_do](process/guide.md#step4) | |
75 | * [step5_tco](process/guide.md#step5) | |
76 | * [step6_file](process/guide.md#step6) | |
77 | * [step7_quote](process/guide.md#step7) | |
78 | * [step8_macros](process/guide.md#step8) | |
79 | * [step9_try](process/guide.md#step9) | |
90f618cb | 80 | * [stepA_mal](process/guide.md#stepA) |
bcddc3e4 JM |
81 | |
82 | ||
83 | Mal was presented publicly for the first time in a lightning talk at | |
84 | Clojure West 2014 (unfortunately there is no video). See | |
85 | mal/clojurewest2014.mal for the presentation that was given at the | |
86 | conference (yes the presentation is a mal program). | |
60154d24 | 87 | |
144f2b6a | 88 | If you are interesting in creating a mal implementation (or just |
bd62ff74 | 89 | interested in using mal for something), please drop by the #mal |
144f2b6a JM |
90 | channel on freenode. In addition to the [make-a-lisp process |
91 | guide](process/guide.md) there is also a [mal/make-a-lisp | |
92 | FAQ](docs/FAQ.md) where I attempt to answer some common questions. | |
93 | ||
60154d24 JM |
94 | ## Building/running implementations |
95 | ||
5b207de7 JM |
96 | The simplest way to run any given implementation is to use docker. |
97 | Every implementation has a docker image pre-built with language | |
98 | dependencies installed. You can launch the REPL using a convenience | |
99 | target in the top level Makefile (where IMPL is the implementation | |
100 | directory name and stepX is the step to run): | |
101 | ||
102 | ``` | |
103 | make DOCKERIZE=1 "repl^IMPL^stepX" | |
104 | # OR stepA is the default step: | |
105 | make DOCKERIZE=1 "repl^IMPL" | |
106 | ``` | |
107 | ||
108 | ||
8c7587af MK |
109 | ### GNU awk |
110 | ||
4c58cd4e | 111 | *The GNU awk implementation was created by [Miutsuru kariya](https://github.com/kariya-mitsuru)* |
390d5829 | 112 | |
8c7587af MK |
113 | The GNU awk implementation of mal has been tested with GNU awk 4.1.1. |
114 | ||
115 | ``` | |
116 | cd gawk | |
117 | gawk -O -f stepX_YYY.awk | |
118 | ``` | |
119 | ||
bcddc3e4 | 120 | ### Bash 4 |
60154d24 JM |
121 | |
122 | ``` | |
123 | cd bash | |
124 | bash stepX_YYY.sh | |
125 | ``` | |
126 | ||
bcddc3e4 | 127 | ### C |
60154d24 | 128 | |
01c97316 JM |
129 | The C implementation of mal requires the following libraries (lib and |
130 | header packages): glib, libffi6 and either the libedit or GNU readline library. | |
54c75382 | 131 | |
60154d24 JM |
132 | ``` |
133 | cd c | |
134 | make | |
135 | ./stepX_YYY | |
136 | ``` | |
137 | ||
73fc9366 JM |
138 | ### C++ |
139 | ||
a848d783 JM |
140 | *The C++ implementation was created by [Stephen Thirlwall (sdt)](https://github.com/sdt)* |
141 | ||
73fc9366 JM |
142 | The C++ implementation of mal requires g++-4.9 or clang++-3.5 and |
143 | a readline compatible library to build. See the `cpp/README.md` for | |
144 | more details: | |
145 | ||
146 | ``` | |
147 | cd cpp | |
148 | make | |
149 | # OR | |
150 | make CXX=clang++-3.5 | |
151 | ./stepX_YYY | |
152 | ``` | |
153 | ||
154 | ||
9b1563a3 | 155 | ### C# ### |
edc3b064 JM |
156 | |
157 | The C# implementation of mal has been tested on Linux using the Mono | |
158 | C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are | |
159 | required to build and run the C# implementation. | |
160 | ||
161 | ``` | |
162 | cd cs | |
163 | make | |
ee7cd585 | 164 | mono ./stepX_YYY.exe |
edc3b064 JM |
165 | ``` |
166 | ||
167 | ||
bcddc3e4 | 168 | ### Clojure |
60154d24 | 169 | |
aa716df6 JM |
170 | For the most part the Clojure implementation requires Clojure 1.5, |
171 | however, to pass all tests, Clojure 1.8.0-RC4 is required. | |
172 | ||
60154d24 JM |
173 | ``` |
174 | cd clojure | |
175 | lein with-profile +stepX trampoline run | |
176 | ``` | |
177 | ||
891c3f3b JM |
178 | ### CoffeeScript |
179 | ||
180 | ``` | |
181 | sudo npm install -g coffee-script | |
182 | cd coffee | |
183 | coffee ./stepX_YYY | |
184 | ``` | |
185 | ||
58b84dd5 | 186 | ### Crystal |
187 | ||
6427adea | 188 | *The Crystal implementation of mal was created by [Linda_pp](https://github.com/rhysd)* |
6c4dede1 | 189 | |
d3ce5b49 | 190 | The Crystal implementation of mal has been tested with Crystal 0.10.0. |
6c4dede1 | 191 | |
58b84dd5 | 192 | ``` |
193 | cd crystal | |
194 | crystal run ./stepX_YYY.cr | |
6c4dede1 JM |
195 | # OR |
196 | make # needed to run tests | |
197 | ./stepX_YYY | |
58b84dd5 | 198 | ``` |
199 | ||
f82cb965 DM |
200 | ### D |
201 | ||
202 | *The D implementation was created by [Dov Murik](https://github.com/dubek)* | |
203 | ||
204 | The D implementation of mal was tested with GDC 4.8. It requires the GNU | |
205 | readline library. | |
206 | ||
207 | ``` | |
208 | cd d | |
209 | make | |
210 | ./stepX_YYY | |
211 | ``` | |
212 | ||
e0b7f668 VS |
213 | ### Emacs Lisp |
214 | ||
215 | *The Emacs Lisp implementation was created by [Vasilij Schneidermann](https://github.com/wasamasa)* | |
216 | ||
217 | The Emacs Lisp implementation of mal has been tested with Emacs 24.3 | |
218 | and 24.5. While there is very basic readline editing (`<backspace>` | |
219 | and `C-d` work, `C-c` cancels the process), it is recommended to use | |
220 | `rlwrap`. | |
221 | ||
222 | ``` | |
223 | cd elisp | |
224 | emacs -Q --batch --load stepX_YYY.el | |
225 | # with full readline support | |
226 | rlwrap emacs -Q --batch --load stepX_YYY.el | |
227 | ``` | |
228 | ||
bb526975 | 229 | ### Elixir |
230 | ||
231 | *The Elixir implementation was created by [Martin Ek (ekmartin)](https://github.com/ekmartin)* | |
232 | ||
233 | The Elixir implementation of mal has been tested with Elixir 1.0.5. | |
234 | ||
235 | ``` | |
236 | cd elixir | |
df2ca97b | 237 | mix stepX_YYY |
238 | # Or with readline/line editing functionality: | |
bb526975 | 239 | iex -S mix stepX_YYY |
240 | ``` | |
241 | ||
2cc3804b NF |
242 | ### Erlang |
243 | ||
425ef3d7 JM |
244 | *The Erlang implementation was created by [Nathan Fiedler (nlfiedler)](https://github.com/nlfiedler)* |
245 | ||
82484631 JM |
246 | The Erlang implementation of mal requires [Erlang/OTP R17](http://www.erlang.org/download.html) |
247 | and [rebar](https://github.com/rebar/rebar) to build. | |
2cc3804b NF |
248 | |
249 | ``` | |
250 | cd erlang | |
425ef3d7 JM |
251 | make |
252 | # OR | |
253 | MAL_STEP=stepX_YYY rebar compile escriptize # build individual step | |
2cc3804b NF |
254 | ./stepX_YYY |
255 | ``` | |
256 | ||
88e934b6 JM |
257 | ### ES6 (ECMAScript 6 / ECMAScript 2015) |
258 | ||
259 | The ES6 implementation uses the [babel](https://babeljs.io) compiler | |
260 | to generate ES5 compatible JavaScript. The generated code has been | |
261 | tested with Node 0.12.4. | |
262 | ||
263 | ``` | |
264 | cd es6 | |
265 | make | |
266 | node build/stepX_YYY.js | |
267 | ``` | |
268 | ||
269 | ||
6f78381f PS |
270 | ### F# ### |
271 | ||
272 | *The F# implementation was created by [Peter Stephens (pstephens)](https://github.com/pstephens)* | |
273 | ||
274 | The F# implementation of mal has been tested on Linux using the Mono | |
275 | F# compiler (fsharpc) and the Mono runtime (version 3.12.1). The mono C# | |
206a1657 | 276 | compiler (mcs) is also necessary to compile the readline dependency. All are |
6f78381f PS |
277 | required to build and run the F# implementation. |
278 | ||
279 | ``` | |
280 | cd fsharp | |
281 | make | |
282 | mono ./stepX_YYY.exe | |
283 | ``` | |
284 | ||
5a53c643 JL |
285 | ### Factor |
286 | ||
44c8a524 | 287 | *The Factor implementation was created by [Jordan Lewis (jordanlewis)](https://github.com/jordanlewis)* |
5a53c643 | 288 | |
0fe47e88 JM |
289 | The Factor implementation of mal has been tested with Factor 0.97 |
290 | ([factorcode.org](factorcode.org)). | |
291 | ||
5a53c643 JL |
292 | ``` |
293 | cd factor | |
199b1ce7 | 294 | FACTOR_ROOTS=. factor -run=stepX_YYY |
5a53c643 JL |
295 | ``` |
296 | ||
96032890 C |
297 | ### Forth |
298 | ||
a848d783 JM |
299 | *The Forth implementation was created by [Chris Houser (chouser)](https://github.com/chouser)* |
300 | ||
96032890 C |
301 | ``` |
302 | cd forth | |
303 | gforth stepX_YYY.fs | |
304 | ``` | |
305 | ||
1771ab50 JM |
306 | ### Go |
307 | ||
0fe47e88 | 308 | The Go implementation of mal requires that go is installed on on the |
fd888612 JM |
309 | path. The implementation has been tested with Go 1.3.1. |
310 | ||
1771ab50 JM |
311 | ``` |
312 | cd go | |
313 | make | |
314 | ./stepX_YYY | |
315 | ``` | |
316 | ||
317 | ||
7ab0f63e JM |
318 | ### Groovy |
319 | ||
320 | The Groovy implementation of mal requires Groovy to run and has been | |
321 | tested with Groovy 1.8.6. | |
322 | ||
323 | ``` | |
324 | cd groovy | |
325 | make | |
326 | groovy ./stepX_YYY.groovy | |
327 | ``` | |
328 | ||
5a9cda80 JM |
329 | ### GNU Guile 2.1+ |
330 | ||
331 | *The Guile implementation was created by [Mu Lei (NalaGinrut)](https://github.com/NalaGinrut).* | |
332 | ||
333 | ``` | |
334 | cd guile | |
335 | guile -L ./ stepX_YYY.scm | |
336 | ``` | |
7ab0f63e | 337 | |
b76aa73b JM |
338 | ### Haskell |
339 | ||
2988d38e | 340 | Install the Haskell compiler (ghc/ghci), the Haskell platform and |
5400d4bf JM |
341 | either the editline package (BSD) or the readline package (GPL). On |
342 | Ubuntu these packages are: ghc, haskell-platform, | |
343 | libghc-readline-dev/libghc-editline-dev | |
b76aa73b JM |
344 | |
345 | ``` | |
346 | cd haskell | |
347 | make | |
348 | ./stepX_YYY | |
349 | ``` | |
350 | ||
33dec7af JM |
351 | ### Haxe |
352 | ||
353 | The Haxe implementation of mal requires Haxe version 3.2 to compile. | |
354 | Four different Haxe targets are supported: Neko, Python, C++, and | |
355 | JavaScript. | |
356 | ||
357 | ``` | |
358 | cd haxe | |
359 | # Neko | |
360 | make all-neko | |
361 | neko ./stepX_YYY.n | |
362 | # Python | |
363 | make all-python | |
364 | python3 ./stepX_YYY.py | |
365 | # C++ | |
366 | make all-cpp | |
367 | ./cpp/stepX_YYY | |
368 | # JavaScript | |
369 | make all-js | |
370 | node ./stepX_YYY.js | |
371 | ``` | |
372 | ||
61f69fba DM |
373 | ### Io |
374 | ||
375 | *The Io implementation was created by [Dov Murik](https://github.com/dubek)* | |
376 | ||
377 | The Io implementation of mal has been tested with Io version 20110905. | |
378 | ||
379 | ``` | |
380 | cd io | |
381 | io ./stepX_YYY.io | |
382 | ``` | |
b76aa73b | 383 | |
bcddc3e4 | 384 | ### Java 1.7 |
60154d24 | 385 | |
01c97316 JM |
386 | The Java implementation of mal requires maven2 to build. |
387 | ||
60154d24 JM |
388 | ``` |
389 | cd java | |
390 | mvn compile | |
391 | mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY | |
392 | # OR | |
393 | mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS" | |
394 | ``` | |
395 | ||
39381792 | 396 | ### JavaScript/Node |
60154d24 JM |
397 | |
398 | ``` | |
399 | cd js | |
54c75382 | 400 | npm update |
60154d24 JM |
401 | node stepX_YYY.js |
402 | ``` | |
403 | ||
39381792 JM |
404 | ### Julia |
405 | ||
82484631 | 406 | The Julia implementation of mal requires Julia 0.4. |
39381792 JM |
407 | |
408 | ``` | |
409 | cd julia | |
410 | julia stepX_YYY.jl | |
411 | ``` | |
412 | ||
53c2ea70 JFI |
413 | ### Kotlin |
414 | ||
415 | *The Kotlin implementation was created by [Javier Fernandez-Ivern](https://github.com/ivern)* | |
416 | ||
75787d77 | 417 | The Kotlin implementation of mal has been tested with Kotlin 1.0. |
53c2ea70 JFI |
418 | |
419 | ``` | |
420 | cd kotlin | |
421 | make | |
422 | java -jar stepX_YYY.jar | |
423 | ``` | |
424 | ||
9d42904e JM |
425 | ### Lua |
426 | ||
8a9d0a8a | 427 | Running the Lua implementation of mal requires lua 5.1 or later, |
9d42904e JM |
428 | luarocks and the lua-rex-pcre library installed. |
429 | ||
430 | ``` | |
431 | cd lua | |
432 | make # to build and link linenoise.so | |
433 | ./stepX_YYY.lua | |
434 | ``` | |
435 | ||
bcddc3e4 | 436 | ### Mal |
60154d24 JM |
437 | |
438 | Running the mal implementation of mal involves running stepA of one of | |
439 | the other implementations and passing the mal step to run as a command | |
5d446bd8 | 440 | line argument. |
60154d24 JM |
441 | |
442 | ``` | |
443 | cd IMPL | |
444 | IMPL_STEPA_CMD ../mal/stepX_YYY.mal | |
445 | ||
446 | ``` | |
447 | ||
bcddc3e4 | 448 | ### GNU Make 3.81 |
60154d24 JM |
449 | |
450 | ``` | |
451 | cd make | |
452 | make -f stepX_YYY.mk | |
453 | ``` | |
454 | ||
de69b639 | 455 | ### Nim 0.11.0 |
a2cd0a3a | 456 | |
a848d783 JM |
457 | *The Nim implementation was created by [Dennis Felsing (def-)](https://github.com/def-)* |
458 | ||
de69b639 | 459 | Running the Nim implementation of mal requires Nim 0.11.0 or later. |
a2cd0a3a | 460 | |
461 | ``` | |
462 | cd nim | |
463 | make | |
464 | # OR | |
465 | nimble build | |
466 | ./stepX_YYY | |
467 | ``` | |
468 | ||
7cae6e6f JM |
469 | ### Objective C |
470 | ||
471 | The Objective C implementation of mal has been built and tested on | |
2faae94c JM |
472 | Linux using clang/LLVM 3.6. It has also been built and tested on OS |
473 | X using XCode 7. | |
7cae6e6f JM |
474 | |
475 | ``` | |
476 | cd objc | |
477 | make | |
478 | ./stepX_YYY | |
479 | ``` | |
480 | ||
bc6448bc C |
481 | ### OCaml 4.01.0 |
482 | ||
a848d783 JM |
483 | *The OCaml implementation was created by [Chris Houser (chouser)](https://github.com/chouser)* |
484 | ||
bc6448bc C |
485 | ``` |
486 | cd ocaml | |
487 | make | |
488 | ./stepX_YYY | |
489 | ``` | |
490 | ||
8a9d0a8a JM |
491 | ### MATLAB |
492 | ||
493 | The MATLAB implementation of mal has been tested with MATLAB version | |
494 | R2014a on Linux. Note that MATLAB is a commercial product. It should | |
495 | be fairly simple to support GNU Octave once it support classdef object | |
496 | syntax. | |
497 | ||
498 | ``` | |
499 | cd matlab | |
500 | ./stepX_YYY | |
501 | matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY();quit;" | |
502 | # OR with command line arguments | |
503 | matlab -nodisplay -nosplash -nodesktop -nojvm -r "stepX_YYY('arg1','arg2');quit;" | |
504 | ``` | |
505 | ||
1218ce98 JM |
506 | ### miniMAL |
507 | ||
508 | [miniMAL](https://github.com/kanaka/miniMAL) is small Lisp interpreter | |
509 | implemented in less than 1024 bytes of JavaScript. To run the miniMAL | |
510 | implementation of mal you need to download/install the miniMAL | |
511 | interpreter (which requires Node.js). | |
512 | ``` | |
1218ce98 | 513 | cd miniMAL |
478fd9ce JM |
514 | # Download miniMAL and dependencies |
515 | npm install | |
516 | export PATH=`pwd`/node_modules/minimal-lisp/:$PATH | |
517 | # Now run mal implementation in miniMAL | |
1218ce98 JM |
518 | miniMAL ./stepX_YYY |
519 | ``` | |
520 | ||
9b1563a3 | 521 | ### Perl 5.8 |
9e5b2151 JM |
522 | |
523 | For readline line editing support, install Term::ReadLine::Perl or | |
524 | Term::ReadLine::Gnu from CPAN. | |
525 | ||
526 | ``` | |
527 | cd perl | |
528 | perl stepX_YYY.pl | |
529 | ``` | |
530 | ||
531 | ||
bcddc3e4 | 532 | ### PHP 5.3 |
60154d24 | 533 | |
01c97316 JM |
534 | The PHP implementation of mal requires the php command line interface |
535 | to run. | |
536 | ||
60154d24 JM |
537 | ``` |
538 | cd php | |
539 | php stepX_YYY.php | |
540 | ``` | |
541 | ||
bcddc3e4 | 542 | ### Postscript Level 2/3 |
60154d24 | 543 | |
01c97316 JM |
544 | The Postscript implementation of mal requires ghostscript to run. It |
545 | has been tested with ghostscript 9.10. | |
546 | ||
60154d24 JM |
547 | ``` |
548 | cd ps | |
fa64b741 | 549 | gs -q -dNODISPLAY -I./ stepX_YYY.ps |
60154d24 JM |
550 | ``` |
551 | ||
23e38cd2 | 552 | ### Python (2.X or 3.X) |
60154d24 JM |
553 | |
554 | ``` | |
555 | cd python | |
556 | python stepX_YYY.py | |
557 | ``` | |
8adb0827 | 558 | |
23e38cd2 JM |
559 | ### RPython |
560 | ||
561 | You must have [rpython](https://rpython.readthedocs.org/) on your path | |
562 | (included with [pypy](https://bitbucket.org/pypy/pypy/)). | |
563 | ||
564 | ``` | |
565 | cd rpython | |
4e8d7c28 | 566 | make # this takes a very long time |
23e38cd2 JM |
567 | ./stepX_YYY |
568 | ``` | |
569 | ||
9b3362e8 JM |
570 | ### R |
571 | ||
572 | The R implementation of mal requires R (r-base-core) to run. | |
573 | ||
574 | ``` | |
575 | cd r | |
9d42904e | 576 | make libs # to download and build rdyncall |
f5223195 JM |
577 | Rscript stepX_YYY.r |
578 | ``` | |
579 | ||
580 | ### Racket (5.3) | |
581 | ||
582 | The Racket implementation of mal requires the Racket | |
583 | compiler/interpreter to run. | |
584 | ||
585 | ``` | |
586 | cd racket | |
3796240a | 587 | ./stepX_YYY.rkt |
9b3362e8 JM |
588 | ``` |
589 | ||
107d9694 | 590 | ### Ruby (1.9+) |
8adb0827 JM |
591 | |
592 | ``` | |
593 | cd ruby | |
594 | ruby stepX_YYY.rb | |
595 | ``` | |
592eb5cf | 596 | |
9106a221 | 597 | ### Rust (1.0.0 nightly) |
abdd56eb JM |
598 | |
599 | The rust implementation of mal requires the rust compiler and build | |
600 | tool (cargo) to build. | |
601 | ||
602 | ``` | |
603 | cd rust | |
bbeb1b87 | 604 | cargo run --release --bin stepX_YYY |
abdd56eb JM |
605 | ``` |
606 | ||
821930db JM |
607 | ### Scala ### |
608 | ||
609 | Install scala and sbt (http://www.scala-sbt.org/0.13/tutorial/Installing-sbt-on-Linux.html): | |
610 | ||
611 | ``` | |
612 | cd scala | |
613 | sbt 'run-main stepX_YYY' | |
614 | # OR | |
615 | sbt compile | |
616 | scala -classpath target/scala*/classes stepX_YYY | |
617 | ``` | |
618 | ||
2539e6af KR |
619 | ### Swift |
620 | ||
a848d783 JM |
621 | *The Swift implementation was created by [Keith Rollin](https://github.com/keith-rollin)* |
622 | ||
e31349f6 KR |
623 | The Swift implementation of mal requires the Swift 2.0 compiler (XCode |
624 | 7.0) to build. Older versions will not work due to changes in the | |
625 | language and standard library. | |
8b142f08 | 626 | |
2539e6af KR |
627 | ``` |
628 | cd swift | |
629 | make | |
630 | ./stepX_YYY | |
631 | ``` | |
632 | ||
ea1395aa JM |
633 | ### Swift 3 |
634 | ||
635 | The Swift 3 implementation of mal requires the Swift 3.0 compiler. It | |
636 | has been tested with the development version of the Swift 3 from | |
637 | 2016-02-08. | |
638 | ||
639 | ``` | |
640 | cd swift3 | |
641 | make | |
642 | ./stepX_YYY | |
643 | ``` | |
644 | ||
54d9903c DM |
645 | ### Tcl 8.6 |
646 | ||
647 | *The Tcl implementation was created by [Dov Murik](https://github.com/dubek)* | |
648 | ||
649 | The Tcl implementation of mal requires Tcl 8.6 to run. For readline line | |
650 | editing support, install tclreadline. | |
651 | ||
652 | ``` | |
653 | cd tcl | |
654 | tclsh ./stepX_YYY.tcl | |
655 | ``` | |
656 | ||
50a964ce DM |
657 | ### Vimscript |
658 | ||
659 | *The Vimscript implementation was created by [Dov Murik](https://github.com/dubek)* | |
660 | ||
661 | The Vimscript implementation of mal requires Vim to run. It has been tested | |
662 | with Vim 7.4. | |
663 | ||
664 | ``` | |
665 | cd vimscript | |
666 | ./run_vimscript.sh ./stepX_YYY.vim | |
667 | ``` | |
668 | ||
ee7cd585 JM |
669 | ### Visual Basic.NET ### |
670 | ||
671 | The VB.NET implementation of mal has been tested on Linux using the Mono | |
672 | VB compiler (vbnc) and the Mono runtime (version 2.10.8.1). Both are | |
673 | required to build and run the VB.NET implementation. | |
674 | ||
675 | ``` | |
676 | cd vb | |
677 | make | |
678 | mono ./stepX_YYY.exe | |
679 | ``` | |
680 | ||
681 | ||
682 | ||
592eb5cf JM |
683 | ## Running tests |
684 | ||
294aba2c JM |
685 | ### Functional tests |
686 | ||
687 | The are nearly 500 generic functional tests (for all implementations) | |
688 | in the `tests/` directory. Each step has a corresponding test file | |
689 | containing tests specific to that step. The `runtest.py` test harness | |
bd62ff74 JM |
690 | launches a Mal step implementation and then feeds the tests one at |
691 | a time to the implementation and compares the output/return value to | |
692 | the expected output/return value. | |
592eb5cf JM |
693 | |
694 | To simplify the process of running tests, a top level Makefile is | |
695 | provided with convenient test targets. | |
696 | ||
697 | * To run all the tests across all implementations (be prepared to wait): | |
698 | ||
699 | ``` | |
700 | make test | |
701 | ``` | |
702 | ||
703 | * To run all tests against a single implementation: | |
704 | ||
705 | ``` | |
e5737b08 | 706 | make "test^IMPL" |
592eb5cf JM |
707 | |
708 | # e.g. | |
e5737b08 SL |
709 | make "test^clojure" |
710 | make "test^js" | |
592eb5cf JM |
711 | ``` |
712 | ||
713 | * To run tests for a single step against all implementations: | |
714 | ||
715 | ``` | |
e5737b08 | 716 | make "test^stepX" |
592eb5cf JM |
717 | |
718 | # e.g. | |
e5737b08 SL |
719 | make "test^step2" |
720 | make "test^step7" | |
592eb5cf JM |
721 | ``` |
722 | ||
4c58cd4e | 723 | * To run tests for a specific step against a single implementation: |
592eb5cf JM |
724 | |
725 | ``` | |
e5737b08 | 726 | make "test^IMPL^stepX" |
592eb5cf JM |
727 | |
728 | # e.g | |
e5737b08 SL |
729 | make "test^ruby^step3" |
730 | make "test^ps^step4" | |
592eb5cf | 731 | ``` |
fd888612 | 732 | |
294aba2c JM |
733 | ### Self-hosted functional tests |
734 | ||
735 | * To run the functional tests in self-hosted mode, you specify `mal` | |
736 | as the test implementation and use the `MAL_IMPL` make variable | |
737 | to change the underlying host language (default is JavaScript): | |
738 | ``` | |
e5737b08 | 739 | make MAL_IMPL=IMPL "test^mal^step2" |
294aba2c JM |
740 | |
741 | # e.g. | |
e5737b08 SL |
742 | make "test^mal^step2" # js is default |
743 | make MAL_IMPL=ruby "test^mal^step2" | |
744 | make MAL_IMPL=python "test^mal^step2" | |
294aba2c JM |
745 | ``` |
746 | ||
854cf2a6 DM |
747 | ### Starting the REPL |
748 | ||
749 | * To start the REPL of an implementation in a specific step: | |
750 | ||
751 | ``` | |
752 | make "repl^IMPL^stepX" | |
753 | ||
754 | # e.g | |
755 | make "repl^ruby^step3" | |
756 | make "repl^ps^step4" | |
757 | ``` | |
758 | ||
759 | * If you omit the step, then `stepA` is used: | |
760 | ||
761 | ``` | |
762 | make "repl^IMPL" | |
763 | ||
764 | # e.g | |
765 | make "repl^ruby" | |
766 | make "repl^ps" | |
767 | ``` | |
768 | ||
769 | * To start the REPL of the self-hosted implementation, specify `mal` as the | |
770 | REPL implementation and use the `MAL_IMPL` make variable to change the | |
771 | underlying host language (default is JavaScript): | |
772 | ``` | |
773 | make MAL_IMPL=IMPL "repl^mal^stepX" | |
774 | ||
775 | # e.g. | |
776 | make "repl^mal^step2" # js is default | |
777 | make MAL_IMPL=ruby "repl^mal^step2" | |
778 | make MAL_IMPL=python "repl^mal" | |
779 | ``` | |
294aba2c JM |
780 | |
781 | ### Performance tests | |
782 | ||
8569b2af JM |
783 | Warning: These performance tests are neither statistically valid nor |
784 | comprehensive; runtime performance is a not a primary goal of mal. If | |
785 | you draw any serious conclusions from these performance tests, then | |
786 | please contact me about some amazing oceanfront property in Kansas | |
787 | that I'm willing to sell you for cheap. | |
788 | ||
294aba2c JM |
789 | * To run performance tests against a single implementation: |
790 | ``` | |
e5737b08 | 791 | make "perf^IMPL" |
294aba2c JM |
792 | |
793 | # e.g. | |
e5737b08 | 794 | make "perf^js" |
294aba2c JM |
795 | ``` |
796 | ||
797 | * To run performance tests against all implementations: | |
798 | ``` | |
e5737b08 | 799 | make "perf" |
294aba2c JM |
800 | ``` |
801 | ||
802 | ### Generating language statistics | |
803 | ||
4c58cd4e | 804 | * To report line and byte statistics for a single implementation: |
294aba2c | 805 | ``` |
e5737b08 | 806 | make "stats^IMPL" |
294aba2c JM |
807 | |
808 | # e.g. | |
e5737b08 | 809 | make "stats^js" |
294aba2c JM |
810 | ``` |
811 | ||
4c58cd4e | 812 | * To report line and bytes statistics for general Lisp code (env, core |
294aba2c JM |
813 | and stepA): |
814 | ``` | |
e5737b08 | 815 | make "stats-lisp^IMPL" |
294aba2c JM |
816 | |
817 | # e.g. | |
e5737b08 | 818 | make "stats-lisp^js" |
294aba2c JM |
819 | ``` |
820 | ||
5b207de7 | 821 | ## Dockerized testing |
75363567 | 822 | |
5b207de7 JM |
823 | Every implementation directory contains a Dockerfile to create |
824 | a docker image containing all the dependencies for that | |
825 | implementation. In addition, the top-level Makefile contains support | |
826 | for running the tests target (and perf, stats, repl, etc) within | |
827 | a docker container for that implementation by passing *"DOCKERIZE=1"* | |
828 | on the make command line. For example: | |
75363567 | 829 | |
75363567 | 830 | ``` |
5b207de7 | 831 | make DOCKERIZE=1 "test^js^step3" |
75363567 JM |
832 | ``` |
833 | ||
5b207de7 JM |
834 | Existing implementations already have docker images built and pushed |
835 | to the docker registry. However, if | |
836 | you wish to build or rebuild a docker image locally, the toplevel | |
837 | Makefile provides a rule for building docker images: | |
838 | ||
75363567 | 839 | ``` |
5b207de7 JM |
840 | make "docker-build^IMPL" |
841 | ``` | |
842 | ||
75363567 JM |
843 | |
844 | **Notes**: | |
5b207de7 JM |
845 | * Docker images are named *"kanaka/mal-test-IMPL"* |
846 | * JVM-based language implementations (Groovy, Java, Clojure, Scala): | |
847 | you will probably need to run these implementations once manually | |
848 | first (make DOCKERIZE=1 "repl^IMPL")before you can run tests because | |
849 | runtime dependencies need to be downloaded to avoid the tests timing | |
850 | out. These dependencies are download to dot-files in the /mal | |
851 | directory so they will persist between runs. | |
75363567 | 852 | |
294aba2c | 853 | |
fd888612 JM |
854 | ## License |
855 | ||
856 | Mal (make-a-lisp) is licensed under the MPL 2.0 (Mozilla Public | |
857 | License 2.0). See LICENSE.txt for more details. |