internal BacktraceException(Exception inner, BacktraceFrame frame,Interpreter interpreter) : base(inner.Message,inner) { frames.Add(frame); this.interpreter = interpreter; }
internal static BacktraceException push(Exception inner, BacktraceFrame frame,Interpreter interpreter) { if(inner is BacktraceException) { ((BacktraceException)inner).frames.Add(frame); return(BacktraceException)inner; } return new BacktraceException(inner,frame,interpreter); }
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); }