go: add metadata and atoms. HashMap dedicated type.
[jackhill/mal.git] / README.md
1 # mal - Make a Lisp
2
3 ## Description
4
5 Mal is an interpreter for a subset of the Clojure programming
6 language. Mal is implemented from scratch in 13 different languages:
7
8 * Bash shell
9 * C
10 * C#
11 * Clojure
12 * Java
13 * Javascript ([Online Demo](http://kanaka.github.io/mal))
14 * GNU Make
15 * mal itself
16 * Perl
17 * PHP
18 * Postscript
19 * Python
20 * Ruby
21
22
23 Mal is also a learning tool. Each implentation of mal is separated
24 into 11 incremental, self-contained (and testable) steps that
25 demonstrate core concepts of Lisp. The last step is capable of
26 self-hosting (running the mal implemenation of mal).
27
28 The mal (make a lisp) steps are:
29
30 * step0_repl
31 * step1_read_print
32 * step2_eval
33 * step3_env
34 * step4_if_fn_do
35 * step5_tco
36 * step6_file
37 * step7_quote
38 * step8_macros
39 * step9_interop
40 * stepA_more
41
42
43 Mal was presented publicly for the first time in a lightning talk at
44 Clojure West 2014 (unfortunately there is no video). See
45 mal/clojurewest2014.mal for the presentation that was given at the
46 conference (yes the presentation is a mal program).
47
48 ## Building/running implementations
49
50 ### Bash 4
51
52 ```
53 cd bash
54 bash stepX_YYY.sh
55 ```
56
57 ### C
58
59 The C implementation of mal requires the following libraries: glib,
60 libffi6 and either the libedit or GNU readline library.
61
62 ```
63 cd c
64 make
65 ./stepX_YYY
66 ```
67
68 ### C# ###
69
70 The C# implementation of mal has been tested on Linux using the Mono
71 C# compiler (mcs) and the Mono runtime (version 2.10.8.1). Both are
72 required to build and run the C# implementation.
73
74 ```
75 cd cs
76 make
77 mono ./stepX_YYY
78 ```
79
80
81 ### Clojure
82
83 ```
84 cd clojure
85 lein with-profile +stepX trampoline run
86 ```
87
88 ### Java 1.7
89
90 ```
91 cd java
92 mvn compile
93 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY
94 # OR
95 mvn -quiet exec:java -Dexec.mainClass=mal.stepX_YYY -Dexec.args="CMDLINE_ARGS"
96 ```
97
98 ### Javascript/Node
99
100 ```
101 cd js
102 npm update
103 node stepX_YYY.js
104 ```
105
106 ### Mal
107
108 Running the mal implementation of mal involves running stepA of one of
109 the other implementations and passing the mal step to run as a command
110 line argument.
111
112 ```
113 cd IMPL
114 IMPL_STEPA_CMD ../mal/stepX_YYY.mal
115
116 ```
117
118 ### GNU Make 3.81
119
120 ```
121 cd make
122 make -f stepX_YYY.mk
123 ```
124
125 ### Perl 5.8
126
127 For readline line editing support, install Term::ReadLine::Perl or
128 Term::ReadLine::Gnu from CPAN.
129
130 ```
131 cd perl
132 perl stepX_YYY.pl
133 ```
134
135
136 ### PHP 5.3
137
138 ```
139 cd php
140 php stepX_YYY.php
141 ```
142
143 ### Postscript Level 2/3
144
145 ```
146 cd ps
147 gs -q -dNODISPLAY -I./ stepX_YYY.ps
148 ```
149
150 ### Python (2 or 3)
151
152 ```
153 cd python
154 python stepX_YYY.py
155 ```
156
157 ### Ruby (1.8)
158
159 ```
160 cd ruby
161 ruby stepX_YYY.rb
162 ```
163
164 ## Running tests
165
166 The are nearly 400 generic Mal tests (for all implementations) in the
167 `tests/` directory. Each step has a corresponding test file containing
168 tests specific to that step. The `runtest.py` test harness uses
169 pexpect to launch a Mal step implementation and then feeds the tests
170 one at a time to the implementation and compares the output/return
171 value to the expected output/return value.
172
173 To simplify the process of running tests, a top level Makefile is
174 provided with convenient test targets.
175
176 * To run all the tests across all implementations (be prepared to wait):
177
178 ```
179 make test
180 ```
181
182 * To run all tests against a single implementation:
183
184 ```
185 make test^IMPL
186
187 # e.g.
188 make test^clojure
189 make test^js
190 ```
191
192 * To run tests for a single step against all implementations:
193
194 ```
195 make test^stepX
196
197 # e.g.
198 make test^step2
199 make test^step7
200 ```
201
202 * To run a specifc step against a single implementation:
203
204 ```
205 make test^IMPL^stepX
206
207 # e.g
208 make test^ruby^step3
209 make test^ps^step4
210 ```