示例#1
0
 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);
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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);
        }