static eValue ParseAST(eValue ast, Env env) { if (ast is eSymbol) { return(env.get((eSymbol)ast)); } else if (ast is eList) { eList oldList = (eList)ast; eList newList = ast.list_Q() ? new eList() : (eList) new eVector(); foreach (eValue mv in oldList.getValue()) { newList.conj_BANG(Eval(mv, env)); } return(newList); } else if (ast is eHashMap) { var hashMap = new Dictionary <string, eValue>(); foreach (var entry in ((eHashMap)ast).getValue()) { hashMap.Add(entry.Key, Eval((eValue)entry.Value, env)); } return(new eHashMap(hashMap)); } else { return(ast); } }
public void Loop(string[] args) { eList _argv = new eList(); for (int i = 1; i < args.Length; i++) { _argv.conj_BANG(new eString(args[i])); } this.enviroment.set(new eSymbol("*ARGV*"), _argv); while (true) { string line; try { line = ReadLine.Read("user> "); if (line == null) { break; } if (line == "") { continue; } } catch (IOException e) { Console.WriteLine("IOException: " + e.Message); break; } try { Console.WriteLine(this.Print(this.EvalString(line))); } catch (Evil.Types.eContinue) { continue; } catch (Evil.Types.eException e) { Console.WriteLine($"Error: {printer._pr_str (e.getValue (), false)}"); continue; } catch (Exception e) { Console.WriteLine($"Error: {e.Message}"); Console.WriteLine(e.StackTrace); continue; } } }
public Env(Env outer, eList binds, eList exprs) { this.outer = outer; for (int i = 0; i < binds.size(); i++) { string sym = ((eSymbol)binds.nth(i)).getName(); if (sym == "&") { data[((eSymbol)binds.nth(i + 1)).getName()] = exprs.slice(i); break; } else { data[sym] = exprs.nth(i); } } }
private static eValue ReadList(Reader reader, eList list, char start, char end) { string token = reader.next(); if (token[0] != start) { throw new ParseError("expected '" + start + "'"); } while ((token = reader.peek()) != null && token[0] != end) { list.conj_BANG(ReadForm(reader)); } if (token == null) { throw new ParseError("expected '" + end + "', got EOF"); } reader.next(); return(list); }
private static eValue ReadHashMap(Reader reader) { eList list = (eList)ReadList(reader, new eList(), '{', '}'); return(new eHashMap(list)); }
public static string _pr_str_args(eList args, String sep, bool print_readably) { return(join(args.getValue(), sep, print_readably)); }
static eValue Eval(eValue orig_ast, Env env) { eValue a0, a1, a2, res; eList el; while (true) { if (!orig_ast.list_Q()) { return(ParseAST(orig_ast, env)); } eValue expanded = macroexpand(orig_ast, env); if (!expanded.list_Q()) { return(ParseAST(expanded, env)); } eList ast = (eList)expanded; if (ast.size() == 0) { return(ast); } a0 = ast[0]; String a0sym = a0 is eSymbol ? ((eSymbol)a0).getName() : "__<*fn*>__"; switch (a0sym) { case "def": // define vareable res = Eval(ast[2] /* vareable value */, env); env.set((eSymbol)ast[1] /* vareable name */, res); return(res); case "let": a1 = ast[1]; a2 = ast[2]; eSymbol key; eValue val; Env let_env = new Env(env); for (int i = 0; i < ((eList)a1).size(); i += 2) { key = (eSymbol)((eList)a1) [i]; val = ((eList)a1) [i + 1]; let_env.set(key, Eval(val, let_env)); } orig_ast = a2; env = let_env; break; case "quote": return(ast[1]); case "quasiquote": orig_ast = quasiquote(ast[1]); break; case "defmacro": // define macros res = Eval(ast[2] /* macros value */, env); ((eFunction)res).setMacro(); env.set(((eSymbol)ast[1] /* macros name */), res); return(res); case "macroexpand": // return macros body return(macroexpand(ast[1] /* macros name */, env)); case "try*": try { return(Eval(ast[1], env)); } catch (Exception e) { if (ast.size() > 2) { eValue exc; a2 = ast[2]; eValue a20 = ((eList)a2) [0]; if (((eSymbol)a20).getName() == "catch*") { if (e is Evil.Types.eException) { exc = ((Evil.Types.eException)e).getValue(); } else { exc = new eString(e.StackTrace); } return(Eval(((eList)a2) [2], new Env(env, ((eList)a2).slice(1, 2), new eList(exc)))); } } throw e; } case "do": // simple block construction ParseAST(ast.slice(1, ast.size() - 1), env); orig_ast = ast[ast.size() - 1]; break; case "if": a1 = ast[1]; eValue cond = Eval(a1, env); if (cond == Evil.Types.Nil || cond == Evil.Types.False) { // eval false slot form if (ast.size() > 3) { orig_ast = ast[3]; } else { return(Evil.Types.Nil); } } else { // eval true slot form orig_ast = ast[2]; } break; case "fn": eList a1f = (eList)ast[1]; eValue a2f = ast[2]; Env cur_env = env; return(new eFunction(a2f, env, a1f, args => Eval(a2f, new Env(cur_env, a1f, args)))); default: el = (eList)ParseAST(ast, env); var f = (eFunction)el[0]; eValue fnast = f.getAst(); if (fnast != null) { orig_ast = fnast; env = f.genEnv(el.rest()); } else { return(f.apply(el.rest())); } break; } } }