public static bool Declare(Symbol name) { if (!gsl.ContainsKey(name)) { gsl[name] = new SpecialVariable(name); return(true); } return(false); }
public IVariable FindLeft(Symbol s) { if (ContainsParam(s)) { return(Env.Find(s)); } IVariable ret = SpecialVariable.Find(s); if (ret is null) { return(Env.Find(s)); } return(ret); }
public object FindRight(Symbol s) { if (ContainsParam(s)) { return(Env.Find(s)); } IVariable ret = SpecialVariable.Find(s); if (ret is null) { return(Env.FindOrExtern(s)); } return(ret); }
public static void CompileSpecial(IType body, Environment e, Function p) { if (e != Global.env) { throw new SyntaxError("SPECIAL: can only be declared in the outmost environment"); } var name = Util.RequireExactly(body, 1, "SPECIAL")[0]; if (!(name is Symbol s)) { throw new SyntaxError("SPECIAL: illegal name"); } if (SpecialVariable.Declare(s)) { SpecialVariable.Find(s).Push(p, Global.nil); } }
public static void CompileLet(IType body, Environment e, Function p) { if (!(body is Cons b)) { throw new SyntaxError("LET: insufficient argument"); } var bindings = b.car; Environment cure = new Environment(e); List <IL.IEntity> lvalues = new List <IL.IEntity>(); List <SpecialVariable> specials = new List <SpecialVariable>(); List <IL.IEntity> svalues = new List <IL.IEntity>(); Function fn = new Function(cure); while (bindings is Cons l) { var cur = l.car; bindings = l.cdr; if (cur is Cons c) { var temp = Util.RequireExactly(cur, 2, "LET"); IType name = temp[0], value = temp[1]; if (!(name is Symbol s)) { throw new SyntaxError("LET: illegal name"); } var sv = SpecialVariable.Find(s); var v = e.AddUnnamedVariable(); Core.CompileSingleExpr(value, e, p); p.Load(v); if (sv is null) { fn.AddParam(s); lvalues.Add(v); } else { specials.Add(sv); svalues.Add(v); } } else if (cur is Symbol s) { var sv = SpecialVariable.Find(s); if (sv is null) { fn.AddParam(s); lvalues.Add(Global.nil); } else { specials.Add(sv); svalues.Add(Global.nil); } } else { throw new SyntaxError("LET: illegal binding"); } } LocalVariable f = e.AddUnnamedVariable(), retp = e.AddUnnamedVariable(); CompileProgn(b.cdr, cure, fn); fn.Return(); p.Store(fn); p.Load(f); for (int i = 0; i < specials.Count; ++i) { specials[i].Push(p, svalues[i]); } p.Call(f, lvalues.ToArray()); p.Load(retp); foreach (var i in specials) { i.Pop(p); } p.Store(retp); }