Merged master into ada branch + fix Makefile
[jackhill/mal.git] / php / core.php
CommitLineData
ea81a808
JM
1<?php
2
3require_once 'types.php';
8cb5cda4
JM
4require_once 'readline.php';
5require_once 'reader.php';
ea81a808
JM
6require_once 'printer.php';
7
8// Error/Exception functions
9function mal_throw($obj) { throw new Error($obj); }
10
11
12// String functions
13function pr_str() {
14 $ps = array_map(function ($obj) { return _pr_str($obj, True); },
15 func_get_args());
16 return implode(" ", $ps);
17}
18
19function str() {
20 $ps = array_map(function ($obj) { return _pr_str($obj, False); },
21 func_get_args());
22 return implode("", $ps);
23}
24
25function prn() {
26 $ps = array_map(function ($obj) { return _pr_str($obj, True); },
27 func_get_args());
28 print implode(" ", $ps) . "\n";
29 return null;
30}
31
32function println() {
33 $ps = array_map(function ($obj) { return _pr_str($obj, False); },
34 func_get_args());
35 print implode(" ", $ps) . "\n";
36 return null;
37}
38
39
db4c329a
JM
40// Number functions
41function time_ms() {
42 return intval(microtime(1) * 1000);
43}
44
45
ea81a808
JM
46// Hash Map functions
47function assoc($src_hm) {
48 $args = func_get_args();
49 $hm = clone $src_hm;
50 $args[0] = $hm;
51 return call_user_func_array('_assoc_BANG', $args);
52}
53
54function dissoc($src_hm) {
55 $args = func_get_args();
56 $hm = clone $src_hm;
57 $args[0] = $hm;
58 return call_user_func_array('_dissoc_BANG', $args);
59}
60
61function get($hm, $k) {
62 if ($hm && $hm->offsetExists($k)) {
63 return $hm[$k];
64 } else {
65 return NULL;
66 }
67}
68
69function contains_Q($hm, $k) { return array_key_exists($k, $hm); }
70
71function keys($hm) {
72 return call_user_func_array('_list', array_keys($hm->getArrayCopy()));
73}
74function vals($hm) {
75 return call_user_func_array('_list', array_values($hm->getArrayCopy()));
76}
77
78
79// Sequence functions
80function cons($a, $b) {
81 $tmp = $b->getArrayCopy();
82 array_unshift($tmp, $a);
83 $l = new ListClass();
84 $l->exchangeArray($tmp);
85 return $l;
86}
87
88function concat() {
89 $args = func_get_args();
90 $tmp = array();
91 foreach ($args as $arg) {
92 $tmp = array_merge($tmp, $arg->getArrayCopy());
93 }
94 $l = new ListClass();
95 $l->exchangeArray($tmp);
96 return $l;
97}
98
99function nth($seq, $idx) {
b8ee29b2
JM
100 if ($idx < $seq->count()) {
101 return $seq[$idx];
102 } else {
103 throw new Exception("nth: index out of range");
104 }
ea81a808
JM
105}
106
107function first($seq) {
d46927d0 108 if ($seq === NULL || count($seq) === 0) {
ea81a808
JM
109 return NULL;
110 } else {
111 return $seq[0];
112 }
113}
114
115function rest($seq) {
d46927d0
DM
116 if ($seq === NULL) {
117 return new ListClass();
118 } else {
119 $l = new ListClass();
120 $l->exchangeArray(array_slice($seq->getArrayCopy(), 1));
121 return $l;
122 }
ea81a808
JM
123}
124
125function empty_Q($seq) { return $seq->count() === 0; }
126
127function scount($seq) { return ($seq === NULL ? 0 : $seq->count()); }
128
129function conj($src) {
130 $args = array_slice(func_get_args(), 1);
131 $tmp = $src->getArrayCopy();
132 if (_list_Q($src)) {
133 foreach ($args as $arg) { array_unshift($tmp, $arg); }
134 $s = new ListClass();
135 } else {
136 foreach ($args as $arg) { $tmp[] = $arg; }
137 $s = new VectorClass();
138 }
139 $s->exchangeArray($tmp);
140 return $s;
141}
142
143function apply($f) {
144 $args = array_slice(func_get_args(), 1);
145 $last_arg = array_pop($args)->getArrayCopy();
146 return $f->apply(array_merge($args, $last_arg));
147}
148
149function map($f, $seq) {
150 $l = new ListClass();
dbac60df
JM
151 # @ to surpress warning if $f throws an exception
152 @$l->exchangeArray(array_map($f, $seq->getArrayCopy()));
ea81a808
JM
153 return $l;
154}
155
156
157// Metadata functions
158function with_meta($obj, $m) {
159 $new_obj = clone $obj;
160 $new_obj->meta = $m;
161 return $new_obj;
162}
163
164function meta($obj) {
165 return $obj->meta;
166}
167
168
169// Atom functions
170function deref($atm) { return $atm->value; }
171function reset_BANG($atm, $val) { return $atm->value = $val; }
172function swap_BANG($atm, $f) {
173 $args = array_slice(func_get_args(),2);
174 array_unshift($args, $atm->value);
175 $atm->value = call_user_func_array($f, $args);
176 return $atm->value;
177}
178
179
180// core_ns is namespace of type functions
181$core_ns = array(
182 '='=> function ($a, $b) { return _equal_Q($a, $b); },
183 'throw'=> function ($a) { return mal_throw($a); },
184 'nil?'=> function ($a) { return _nil_Q($a); },
185 'true?'=> function ($a) { return _true_Q($a); },
186 'false?'=> function ($a) { return _false_Q($a); },
187 'symbol'=> function () { return call_user_func_array('_symbol', func_get_args()); },
188 'symbol?'=> function ($a) { return _symbol_Q($a); },
b8ee29b2
JM
189 'keyword'=> function () { return call_user_func_array('_keyword', func_get_args()); },
190 'keyword?'=> function ($a) { return _keyword_Q($a); },
8cb5cda4 191
ea81a808
JM
192 'string?'=> function ($a) { return _string_Q($a); },
193 'pr-str'=> function () { return call_user_func_array('pr_str', func_get_args()); },
194 'str'=> function () { return call_user_func_array('str', func_get_args()); },
195 'prn'=> function () { return call_user_func_array('prn', func_get_args()); },
196 'println'=>function () { return call_user_func_array('println', func_get_args()); },
8cb5cda4
JM
197 'readline'=>function ($a) { return mal_readline($a); },
198 'read-string'=>function ($a) { return read_str($a); },
199 'slurp'=> function ($a) { return file_get_contents($a); },
ea81a808
JM
200 '<'=> function ($a, $b) { return $a < $b; },
201 '<='=> function ($a, $b) { return $a <= $b; },
202 '>'=> function ($a, $b) { return $a > $b; },
203 '>='=> function ($a, $b) { return $a >= $b; },
204 '+'=> function ($a, $b) { return intval($a + $b,10); },
205 '-'=> function ($a, $b) { return intval($a - $b,10); },
206 '*'=> function ($a, $b) { return intval($a * $b,10); },
207 '/'=> function ($a, $b) { return intval($a / $b,10); },
db4c329a 208 'time-ms'=>function () { return time_ms(); },
ea81a808
JM
209
210 'list'=> function () { return call_user_func_array('_list', func_get_args()); },
211 'list?'=> function ($a) { return _list_Q($a); },
212 'vector'=> function () { return call_user_func_array('_vector', func_get_args()); },
213 'vector?'=> function ($a) { return _vector_Q($a); },
214 'hash-map' => function () { return call_user_func_array('_hash_map', func_get_args()); },
215 'map?'=> function ($a) { return _hash_map_Q($a); },
216 'assoc' => function () { return call_user_func_array('assoc', func_get_args()); },
217 'dissoc' => function () { return call_user_func_array('dissoc', func_get_args()); },
218 'get' => function ($a, $b) { return get($a, $b); },
219 'contains?' => function ($a, $b) { return contains_Q($a, $b); },
220 'keys' => function ($a) { return keys($a); },
221 'vals' => function ($a) { return vals($a); },
222
223 'sequential?'=> function ($a) { return _sequential_Q($a); },
224 'cons'=> function ($a, $b) { return cons($a, $b); },
225 'concat'=> function () { return call_user_func_array('concat', func_get_args()); },
226 'nth'=> function ($a, $b) { return nth($a, $b); },
227 'first'=> function ($a) { return first($a); },
228 'rest'=> function ($a) { return rest($a); },
229 'empty?'=> function ($a) { return empty_Q($a); },
230 'count'=> function ($a) { return scount($a); },
231 'conj'=> function () { return call_user_func_array('conj', func_get_args()); },
232 'apply'=> function () { return call_user_func_array('apply', func_get_args()); },
233 'map'=> function ($a, $b) { return map($a, $b); },
234
235 'with-meta'=> function ($a, $b) { return with_meta($a, $b); },
236 'meta'=> function ($a) { return meta($a); },
237 'atom'=> function ($a) { return _atom($a); },
238 'atom?'=> function ($a) { return _atom_Q($a); },
239 'deref'=> function ($a) { return deref($a); },
240 'reset!'=> function ($a, $b) { return reset_BANG($a, $b); },
241 'swap!'=> function () { return call_user_func_array('swap_BANG', func_get_args()); },
242);
243
244
245?>