public 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); }
public IExpression Analyze(Object expr, IEnvironment env, Location 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; Location loc = (Location)InnerReader.LocationTable[expr]; if (loc != null) InnerReader.LocationTable.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.GlobalValue is Macro) { Macro m = (Macro)s.GlobalValue; 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.GetLength(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 BacktraceException(Exception inner, BacktraceFrame frame, Interpreter interpreter) : base(inner.Message, inner) { InnerFrames.Add(frame); InnerInterpreter = interpreter; }