20 constant mal_type
= MALTYPE_UNDEFINED
;
22 string to_string(bool print_readably
);
27 return objectp(other
) && other.mal_type
== mal_type
;
34 constant mal_type
= MALTYPE_NIL
;
36 string to_string(bool print_readably
)
72 constant mal_type
= MALTYPE_TRUE
;
73 string to_string(bool print_readably
)
84 True MAL_TRUE
= True();
89 constant mal_type
= MALTYPE_FALSE
;
90 string to_string(bool print_readably
)
101 False MAL_FALSE
= False();
105 if(b
) return MAL_TRUE
;
109 class Number(int value
)
111 constant mal_type
= MALTYPE_NUMBER
;
114 string to_string(bool print_readably
)
116 return (string)value
;
119 bool `
==(mixed other
)
121 return ::`
==(other
) && other.value
== value
;
126 return this_object();
130 class Symbol(string value
)
132 constant mal_type
= MALTYPE_SYMBOL
;
135 string to_string(bool print_readably
)
140 bool `
==(mixed other
)
142 return ::`
==(other
) && other.value
== value
;
147 return hash((string)mal_type
) ^
hash(value
);
152 return Symbol(value
);
156 class String(string value
)
158 constant mal_type
= MALTYPE_STRING
;
161 string to_string(bool print_readably
)
164 string s
= replace(value
, "\\", "\\\\");
165 s
= replace(s
, "\"", "\\\"");
166 s
= replace(s
, "\n", "\\n");
167 return "\"" + s
+ "\"";
172 bool `
==(mixed other
)
174 return ::`
==(other
) && other.value
== value
;
179 return hash((string)mal_type
) ^
hash(value
);
184 return String(value
);
189 if(sizeof(value
) == 0) return MAL_NIL
;
190 array(Val
) parts
= ({ });
191 for(int i
= 0; i
< sizeof(value
); i
++)
193 parts
+= ({ String(value
[i..i
]) });
199 class Keyword(string value
)
201 constant mal_type
= MALTYPE_KEYWORD
;
204 string to_string(bool print_readably
)
209 bool `
==(mixed other
)
211 return ::`
==(other
) && other.value
== value
;
216 return hash((string)mal_type
) ^
hash(value
);
221 return Keyword(value
);
225 class Sequence(array(Val
) data
)
228 constant is_sequence
= true
;
230 string to_string(bool print_readably
)
232 return map(data
, lambda(Val e
) { return e.
to_string(print_readably
); }) * " ";
237 return sizeof(data
) == 0;
247 if(index
>= count()) throw("nth: index out of range");
253 if(emptyp()) return MAL_NIL
;
259 return List(data
[1..
]);
262 bool `
==(mixed other
)
264 if(!objectp(other
)) return 0;
265 if(!other.is_sequence
) return 0;
266 if(other.
count() != count()) return 0;
267 for(int i
= 0; i
< count(); i
++)
269 if(other.data
[i
] != data
[i
]) return 0;
276 if(emptyp()) return MAL_NIL
;
284 constant mal_type
= MALTYPE_LIST
;
286 string to_string(bool print_readably
)
288 return "(" + ::to_string(print_readably
) + ")";
296 Val
conj(array(Val
) other
)
298 return List(reverse(other
) + data
);
305 constant mal_type
= MALTYPE_VECTOR
;
307 string to_string(bool print_readably
)
309 return "[" + ::to_string(print_readably
) + "]";
317 Val
conj(array(Val
) other
)
319 return Vector(data
+ other
);
326 constant mal_type
= MALTYPE_MAP
;
327 mapping(Val
:Val
) data
;
329 void create(array(Val
) list
)
331 array(Val
) keys
= Array.
everynth(list
, 2, 0);
332 array(Val
) vals
= Array.
everynth(list
, 2, 1);
333 data
= mkmapping(keys
, vals
);
336 string to_string(bool print_readably
)
338 array(string) strs
= ({ });
339 foreach(data
; Val k
; Val v
)
341 strs
+= ({ k.
to_string(print_readably
), v.
to_string(print_readably
) });
343 return "{" + (strs
* " ") + "}";
351 bool `
==(mixed other
)
353 if(!::`
==(other
)) return 0;
354 if(other.
count() != count()) return 0;
355 foreach(data
; Val k
; Val v
)
357 if(other.data
[k
] != v
) return 0;
362 Val
assoc(array(Val
) list
)
364 array(Val
) keys
= Array.
everynth(list
, 2, 0);
365 array(Val
) vals
= Array.
everynth(list
, 2, 1);
366 Map result
= Map(({ }));
367 result.data
= copy_value(data
);
368 for(int i
= 0; i
< sizeof(keys
); i
++)
370 result.data
[keys
[i
]] = vals
[i
];
375 Val
dissoc(array(Val
) list
)
377 Map result
= Map(({ }));
378 result.data
= copy_value(data
);
379 foreach(list
, Val key
) m_delete(result.data
, key
);
391 class Fn(Val ast
, Val params
, .Env.Env env
, function func
, void|bool macro
)
394 constant mal_type
= MALTYPE_FN
;
395 constant is_fn
= true
;
402 string to_string(bool print_readably
)
404 string tag
= macro ?
"Macro" : "Fn";
405 return "#<" + tag
+ " params=" + params.
to_string(true
) + ">";
408 mixed `
()(mixed ... args
)
415 return Fn(ast
, params
, env
, func
);
420 return Fn(ast
, params
, env
, func
, true
);
424 class BuiltinFn(string name
, function func
)
427 constant mal_type
= MALTYPE_BUILTINFN
;
428 constant is_fn
= true
;
430 string to_string(bool print_readably
)
432 return "#<BuiltinFn " + name
+ ">";
435 mixed `
()(mixed ... args
)
442 return BuiltinFn(name
, func
);
449 constant mal_type
= MALTYPE_ATOM
;
451 string to_string(bool print_readably
)
453 return "(atom " + data.
to_string(print_readably
) + ")";