internal DynamicLet(Cons args, Env env, Interpreter interpreter, Loc loc) { this.loc = loc; this.interpreter = interpreter; Cons bindlist = (Cons)args.first; Int32 blen = Cons.Length(bindlist); if ((blen % 2) != 0) //odd { throw new Exception("Odd number of args in dynamic-let binding list"); } binds = new BindPair[blen / 2]; for (int i = 0; i < binds.Length; i++) { // MEH: Better error instead of InvalidCastException //binds[i].dvar = (DynamicVar)interpreter.analyze(bindlist.first, env,loc); if ((binds[i].dvar = (interpreter.analyze(bindlist.first, env, loc) as DynamicVar)) == null) { throw new Exception("Dynamic vars must have prefix *"); } bindlist = bindlist.rest; binds[i].expr = interpreter.analyze(bindlist.first, env, loc); bindlist = bindlist.rest; } this.body = interpreter.analyze(new Cons(interpreter.BLOCK, args.rest), env, loc); }
internal OrExpression(Cons args, Env env, Interpreter interpreter, Loc loc) { this.loc = loc; this.interpreter = interpreter; exprs = new IExpression[Cons.Length(args)]; for (Int32 i = 0; i < exprs.Length; i++, args = args.rest) { exprs[i] = interpreter.analyze(args.first, env, loc); } }
internal SetExpression(Cons args, Env env, Interpreter interpreter, Loc loc) { this.loc = loc; this.interpreter = interpreter; Int32 len = Cons.Length(args); if (len != 2) { throw new Exception("Wrong number of args for set"); } var = (IVar)interpreter.analyze(args.first, env, loc); val = interpreter.analyze(Cons.Second(args), env, loc); }
internal ApplyExpression(Cons args, Env env, Interpreter interpreter, Loc loc) { this.loc = loc; this.interpreter = interpreter; fexpr = interpreter.analyze(args.first, env, loc); if (fexpr is IVar) { fsym = ((IVar)fexpr).getSymbol(); } Int32 len = Cons.Length(args.rest); argexprs = new IExpression[len]; args = args.rest; for (Int32 i = 0; i < argexprs.Length; i++, args = args.rest) { argexprs[i] = interpreter.analyze(args.first, env, loc); } }
internal IfExpression(Cons args, Env env, Interpreter interpreter, Loc loc) { this.loc = loc; this.interpreter = interpreter; Int32 len = Cons.Length(args); if (len < 2 || len > 3) { throw new Exception("Wrong number of args for if"); } test = interpreter.analyze(args.first, env, loc); brtrue = interpreter.analyze(Cons.Second(args), env, loc); if (len == 3) { brfalse = interpreter.analyze(Cons.Third(args), env, loc); } else { brfalse = new QuoteExpr(null); } }
internal DynamicLet(Cons args, Env env, Interpreter interpreter, Loc loc) { this.loc = loc; this.interpreter = interpreter; Cons bindlist = (Cons)args.first; Int32 blen = Cons.Length(bindlist); if ((blen % 2) != 0) //odd { throw new Exception("Odd number of args in dynamic-let binding list"); } binds = new BindPair[blen / 2]; for (int i = 0; i < binds.Length; i++) { binds[i].dvar = (DynamicVar)interpreter.analyze(bindlist.first, env, loc); bindlist = bindlist.rest; binds[i].expr = interpreter.analyze(bindlist.first, env, loc); bindlist = bindlist.rest; } this.body = interpreter.analyze(new Cons(interpreter.BLOCK, args.rest), env, loc); }
internal IExpression analyze(Object expr, Env env, Loc enclosingLoc) { Symbol symbol = expr as Symbol; if (symbol != null) { if (symbol.isDynamic) { return(new DynamicVar(symbol)); } Object var = env.lookup(symbol); if (var is LocalVariable) { return(new LocalVar((LocalVariable)var)); } else { return(new GlobalVar((Symbol)var)); } } if (!(expr is Cons)) //must be literal { return(new QuoteExpr(expr)); } Cons exprs = (Cons)expr; Loc loc = (Loc)reader.locTable[expr]; if (loc != null) { reader.locTable.Remove(expr); } else { loc = enclosingLoc; } Object f = exprs.first; Cons args = exprs.rest; //see if it's a macro Symbol s = f as Symbol; if (s != null && s.isDefined() && s.getGlobalValue() is Macro) { Macro m = (Macro)s.getGlobalValue(); Object[] argarray = Cons.ToVector(args); Object mexprs = null; try { mexprs = m.Invoke(argarray); } catch (Exception ex) { BacktraceFrame frame = new BacktraceFrame(loc, s, args); throw BacktraceException.push(ex, frame, this); } try { return(analyze(mexprs, env, loc)); } catch (Exception ex) { BacktraceFrame frame = new BacktraceFrame(loc, "when expanding ", exprs); throw BacktraceException.push(ex, frame, this); } } Int32 numargs = Cons.Length(args); if (f == DLET) { return(new DynamicLet(args, env, this, loc)); } else if (f == FN) { return(new Closure(args, env, this, loc)); } else if (f == MACRO) { return(new Macro(args, env, this, loc)); } else if (f == WHILE) { return(new WhileExpression(args, env, this, loc)); } else if (f == BLOCK) { if (numargs == 0) { return(new QuoteExpr(null)); } //remove block from block of one else if (numargs == 1) { return(analyze(args.first, env, loc)); } else { return(new BlockExpression(args, env, this, loc)); } } else if (f == OR) { if (numargs == 0) { return(new QuoteExpr(null)); } else { return(new OrExpression(args, env, this, loc)); } } else if (f == IF) { return(new IfExpression(args, env, this, loc)); } else if (f == QUOTE) { return(new QuoteExpr(args.first)); } else if (f == SET) { return(new SetExpression(args, env, this, loc)); } else //presume funcall { return(new ApplyExpression(exprs, env, this, loc)); } }
public static Object listlength(params Object[] args) { Cons x = (Cons)arg(0, args); return(Cons.Length(x)); }