import std.range;
import std.stdio;
import std.string;
-import std.c.process;
+import core.stdc.stdlib;
import env;
import mal_core;
import readline;
MalType eval_ast(MalType ast, Env env)
{
- if (typeid(ast) == typeid(MalSymbol))
+ if (auto sym = cast(MalSymbol)ast)
{
- auto sym = verify_cast!MalSymbol(ast);
return env.get(sym);
}
- else if (typeid(ast) == typeid(MalList))
+ else if (auto lst = cast(MalList)ast)
{
- auto lst = verify_cast!MalList(ast);
auto el = array(lst.elements.map!(e => EVAL(e, env)));
return new MalList(el);
}
- else if (typeid(ast) == typeid(MalVector))
+ else if (auto lst = cast(MalVector)ast)
{
- auto lst = verify_cast!MalVector(ast);
auto el = array(lst.elements.map!(e => EVAL(e, env)));
return new MalVector(el);
}
- else if (typeid(ast) == typeid(MalHashmap))
+ else if (auto hm = cast(MalHashmap)ast)
{
- auto hm = verify_cast!MalHashmap(ast);
typeof(hm.data) new_data;
foreach (string k, MalType v; hm.data)
{
}
auto aste = ast_list.elements;
+ if (aste.length == 0)
+ {
+ return ast;
+ }
auto a0_sym = cast(MalSymbol) aste[0];
auto sym_name = a0_sym is null ? "" : a0_sym.name;
switch (sym_name)
}
auto first = el.elements[0];
auto rest = el.elements[1..$];
- if (typeid(first) == typeid(MalFunc))
+ if (auto funcobj = cast(MalFunc)first)
{
- auto funcobj = verify_cast!MalFunc(first);
auto callenv = new Env(funcobj.def_env, funcobj.arg_names, rest);
ast = funcobj.func_body;
env = callenv;
continue; // TCO
}
- else if (typeid(first) == typeid(MalBuiltinFunc))
+ else if (auto builtinfuncobj = cast(MalBuiltinFunc)first)
{
- auto builtinfuncobj = verify_cast!MalBuiltinFunc(first);
return builtinfuncobj.fn(rest);
}
else
// core.mal: defined using the language itself
re("(def! not (fn* (a) (if a false true)))", repl_env);
- re("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))", repl_env);
+ re("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))", repl_env);
re("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", repl_env);
- re("(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))", repl_env);
if (args.length > 1)
{
catch (Exception e)
{
writeln("Error: ", e.msg);
- std.c.process.exit(1);
+ exit(1);
}
}