コード例 #1
0
ファイル: Scheme.cs プロジェクト: andrakis/SchemingSharply
        public static void AddGlobals(SchemeEnvironment e)
        {
            e.Insert(False.Value, False); e.Insert(True.Value, True); e.Insert(Nil.Value, Nil);
            e.Insert("+", new Cell(Plus)); e.Insert("-", new Cell(Minus));
            e.Insert("*", new Cell(Multiply)); e.Insert("/", new Cell(Divide));
            e.Insert("<", new Cell(LessThan)); e.Insert("<=", new Cell(LessThanEqual));
            e.Insert(">", new Cell(GreaterThan)); e.Insert(">=", new Cell(GreaterThanEqual));
            e.Insert("=", new Cell(Equal)); e.Insert("==", new Cell(Equal));
            e.Insert("print", new Cell(Print));
            e.Insert("head", new Cell(Head)); e.Insert("tail", new Cell(Tail));
            e.Insert("null?", new Cell(Nullp)); e.Insert("list", new Cell(List));
            e.Insert("cons", new Cell(Cons)); e.Insert("append", new Cell(Append));
            e.Insert("length", new Cell(Length));

            // Add CellType.[Name] definitions
            CellType cellType = CellType.SYMBOL;

            foreach (var kv in cellType.GetKeyValues <int>())
            {
                e.Insert("CellType." + kv.Key, new Cell(kv.Value));
            }
        }
コード例 #2
0
ファイル: Scheme.cs プロジェクト: andrakis/SchemingSharply
        protected Cell InternalEval(Cell x, SchemeEnvironment env)
        {
            Cell original = x;

            ++depth;
recurse:
            if (debug)
            {
                if (original != x)
                {
                    Console.WriteLine("{0}) {1} => {2}", new string('-', depth), original, x);
                }
                else
                {
                    Console.WriteLine("{0}) {1}", new string('-', depth), x);
                }
            }
            ++stepCounter;
            if (x.Type == CellType.SYMBOL)
            {
                x = env.Find(x.Value)[x.Value];
                goto done;
            }
            if (x.Type == CellType.NUMBER)
            {
                goto done;
            }
            if (x.ListValue.Count == 0)
            {
                x = StandardRuntime.Nil;
                goto done;
            }
            if (x.ListValue[0].Type == CellType.SYMBOL)
            {
                Cell sym = x.ListValue[0];
                switch ((string)sym)
                {
                case "quote":                         // (quote exp)
                    x = x.ListValue[1];
                    goto done;

                case "if":                            // (if test conseq [alt])
                    Cell test   = x.ListValue[1];
                    Cell conseq = x.ListValue[2];
                    Cell alt    = StandardRuntime.Nil;
                    if (x.ListValue.Count >= 4)
                    {
                        alt = x.ListValue[3];
                    }
                    Cell testval = Eval(test, env);
                    Cell final   = testval == StandardRuntime.False ? alt : conseq;
                    x = final;
                    goto recurse;

                case "set!":                          // (set! var exp) - must exist
                    x = env.Find(x.ListValue[1].Value)[x.ListValue[1].Value] = Eval(x.ListValue[2], env);
                    goto done;

                case "define":                        // (define var exp) - creates new
                    Cell b = Eval(x.ListValue[2], env);
                    env.Insert(x.ListValue[1].Value, b);
                    x = b;
                    goto done;

                case "lambda":                        // (lambda (var*) exp)
                    x.Type        = CellType.LAMBDA;
                    x.Environment = env;
                    goto done;

                case "macro":                         // (macro (var*) exp)
                    x.Type        = CellType.MACRO;
                    x.Environment = env;
                    goto done;

                case "begin":                         // (begin exp*)
                    for (int i = 1; i < x.ListValue.Count - 1; ++i)
                    {
                        Eval(x.ListValue[i], env);
                    }
                    // tail recurse
                    x = x.ListValue.Last();
                    goto recurse;
                }
            }
            // (proc exp*)
            Cell        proc = Eval(x.ListValue[0], env);
            List <Cell> exps = new List <Cell>();

            if (proc.Type == CellType.MACRO)
            {
                exps = x.Tail().ListValue;
            }
            else
            {
                for (int i = 1; i < x.ListValue.Count; ++i)
                {
                    exps.Add(Eval(x.ListValue[i], env));
                }
            }
            if (proc.Type == CellType.LAMBDA)
            {
                env = new SchemeEnvironment(proc.ListValue[1].ListValue, exps, proc.Environment);
                x   = proc.ListValue[2];
                goto recurse;
            }
            else if (proc.Type == CellType.MACRO)
            {
                SchemeEnvironment env2 = new SchemeEnvironment(proc.ListValue[1].ListValue, exps, proc.Environment);
                x = Eval(proc.ListValue[2], env2);
                goto recurse;
            }
            else if (proc.Type == CellType.PROC)
            {
                x = proc.ProcValue(exps.ToArray());
                goto done;
            }
            else if (proc.Type == CellType.PROCENV)
            {
                x = proc.ProcEnvValue(exps.ToArray(), env);
                goto done;
            }

            throw new SchemeException("Invalid item in Eval");

done:
            if (debug)
            {
                Console.WriteLine("{0}) {1} => {2} ", new string('-', depth), original, x);
            }
            --depth;
            return(x);
        }