public static void Main(string[] args) { bool refreshEnv = false; bool showSexp = false; bool showExpr = false; List <string> files = new List <string>(); foreach (string arg in args) { if (arg.Substring(0, 1) == "-") { switch (arg) { case "-r": case "--refreshEnv": refreshEnv = true; break; case "-v": case "--verbose": showSexp = true; showExpr = true; break; default: Console.Error.WriteLine("Unrecognized commandline option: " + arg); break; } } else { files.Add(arg); } } Environment env = GetStartEnv(refreshEnv); Val result = new NumV(-1); foreach (string file in files) { SExpression sexp = new SExpOpenXML(file); if (showSexp) { Console.WriteLine("Lexical Analyzer Output:"); Console.WriteLine(sexp.ToString()); } ExprC prog = Parser.parse(sexp); if (showExpr) { Console.WriteLine("Parser Output:"); Console.WriteLine(prog.ToString()); } result = prog.interp(env); } Console.WriteLine(result.ToString()); }
public override Val interp(Environment env) { Val checkVal = check.interp(env); if (checkVal is NumV) { return((((NumV)checkVal).num > 0) ? t.interp(env) : f.interp(env)); } else if (checkVal is StrV) { return((((StrV)checkVal).str.Length > 0) ? t.interp(env) : f.interp(env)); } else { throw new InterpException("Conditional jump on non-numeric, non-string"); } }
public override Val interp(Environment env) { List <Val> interpIndices = interpAll(indices, env); List <long> castIndices = new List <long>(); foreach (Val idx in interpIndices) { if (idx is NumV) { castIndices.Add(((NumV)idx).num); } else { throw new InterpException("Indexing with non-numeric"); } } Val interpArr = arr.interp(env); if (interpArr is ArrV) { return(((ArrV)interpArr).GetValue(castIndices)); } else if (interpArr is StrV) { switch (castIndices.Count) { case 1: try { return(new StrV(((StrV)interpArr).str.Substring((int)castIndices[0]))); } catch (ArgumentOutOfRangeException ex) { return(new StrV("")); } case 2: try { return(new StrV(((StrV)interpArr).str.Substring((int)castIndices[0], (int)castIndices[1] - (int)castIndices[0] + 1))); } catch (ArgumentOutOfRangeException ex) { return(new StrV("")); } default: throw new InterpException("Indexing string with incorrect number of indices"); } } else { throw new InterpException("Indexing into non-array"); } }
public override Val interp(Environment env) { NumV inner = num.interp(env) as NumV; if (inner == null) { throw new InterpException("Negating a non-numeric"); } return(new NumV(-inner.num)); }
public static Environment addArgsToEnv(List <String> parms, List <ExprC> args, Environment cloEnv, Environment outerEnv) { if (parms.Count == args.Count) { Environment newEnv = outerEnv.withLocals(cloEnv); // scope to know all calling vars for (int i = 0; i < parms.Count; i++) { String param = parms[i]; ExprC arg = args[i]; Val argVal = arg.interp(outerEnv); newEnv.SetLocal(param, argVal); // overwrite params if var name exists } return(newEnv); } else { throw new InterpException("Calling mismatched argument count"); } }
public override Val interp(Environment env) { if (func is IdC && ((IdC)func).sym == "copyArr") { Console.WriteLine("HERE"); } // Only should be invoked for function calls // BindC handles closure definitions CloV called = func.interp(env) as CloV; if (called != null) // (is a closure) { Environment callingContext = env; Environment cloEnv = addArgsToEnv(called.parms, args, called.env, env); cloEnv.scopeDepth++; Val retVal = called.body.interp(cloEnv); cloEnv.scopeDepth--; // Propogate changes up to caller /*foreach (KeyValuePair<string, Val> pair in cloEnv) * { * // Only for vars originally in scope; don't copy parameters * if (callingContext.ContainsKey(pair.Key) && !called.parms.Contains(pair.Key)) * { * callingContext[pair.Key] = pair.Value; * } * }*/ return(retVal); } else { throw new InterpException("Calling a non-closure"); } }
public override Val interp(Environment env) { Val result; if (lexpr is IdC) // binding a variable { result = rexpr.interp(env); env[((IdC)lexpr).sym] = result; } else if (lexpr is FuncC) // defining a function { FuncC lexprFunc = (FuncC)lexpr; if (lexprFunc.func is IdC) { List <string> parms = new List <string>(); foreach (ExprC parm in lexprFunc.args) { if (parm is IdC) { parms.Add(((IdC)parm).sym); } else { throw new InterpException("Malformed function definition params"); } } result = new CloV((Environment)env.Clone(), rexpr, parms); ((CloV)result).env.SetLocal(((IdC)lexprFunc.func).sym, result); // allow recursion env[((IdC)lexprFunc.func).sym] = result; } else { throw new InterpException("Malformed function definition name"); } } else if (lexpr is IndexC) // defining an array or setting an element { IndexC lexprArray = (IndexC)lexpr; if (lexprArray.arr is IdC) { List <long> indices = new List <long>(); foreach (ExprC idx in lexprArray.indices) { Val idxVal = idx.interp(env); if (idxVal is NumV) { indices.Add(((NumV)idxVal).num); } else { throw new InterpException("Non-numeric array index"); } } if (env.ContainsKey(((IdC)lexprArray.arr).sym)) // setting element { ArrV arr = lexprArray.arr.interp(env) as ArrV; if (arr == null) { throw new InterpException("Indexing non-array"); } result = rexpr.interp(env); arr.SetValue(indices, result); } else // defining new array { result = new ArrV(indices, rexpr.interp(env)); env[((IdC)lexprArray.arr).sym] = result; } } else { throw new InterpException("Malformed array definition name"); } } else { throw new InterpException("Binding with invalid lvalue"); } return(result); }