Ejemplo n.º 1
0
        private static void Cond(Evaluator eval, StackFrame frame)
        {
            switch (frame.state.value)
            {
            case "-eval-sexp-body-":
                frame.temp1 = frame.args;
                frame.state = new Atom("-built-in-cond-head-");
                break;

            case "-built-in-cond-head-":
                if (eval.HaveReturn())
                {
                    var condition = eval.TakeReturn();
                    if (!condition.IsBool)
                    {
                        throw new ArgumentException($"Condition must return boolean atom, but found: {condition}!");
                    }
                    if ((bool)condition.value)
                    {
                        frame.state = new Atom("-built-in-cond-body-");
                        break;
                    }
                }

                if (frame.temp1 != null)
                {
                    frame.temp2 = frame.temp1.atom;
                    frame.temp1 = frame.temp1.next;

                    if (!frame.temp2.IsPair)
                    {
                        throw new ArgumentException($"Condition element must be list, but found: {frame.temp2}!");
                    }

                    eval.CreateFrame("-eval-", frame.temp2.atom, frame.context);
                }
                else
                {
                    //  Ни одно из условий не выполнилось
                    frame.state = new Atom("-eval-sexp-body-");
                    eval.Return(Atoms.FALSE);
                }

                break;

            case "-built-in-cond-body-":
                if (eval.HaveReturn())
                {
                    eval.CloseFrame();
                }
                else
                {
                    eval.CreateFrame("-eval-block-", frame.temp2.next, frame.context);
                }

                break;
            }
        }
Ejemplo n.º 2
0
        private static void Eval(Evaluator eval, StackFrame frame)
        {
            if (!eval.HaveReturn())
            {
                var(expression, ctxAtom) = StructureUtils.Split2(frame.args);
                Context ctx = ctxAtom?.value as Context ?? frame.context.value as Context;
                eval.CreateFrame("-eval-", expression, ctx);
                return;
            }

            eval.CloseFrame();
        }
Ejemplo n.º 3
0
        private static void Apply(Evaluator eval, StackFrame frame)
        {
            if (eval.HaveReturn())
            {
                var  args = frame.args;
                Atom func = args.atom;
                Atom rest = StructureUtils.CloneList(args.next.atom);

                Function proc = func?.value as Function;
                if (proc == null)
                {
                    throw new ArgumentException("First argument must be procedure!");
                }

                eval.CreateFrame("-eval-", new Atom(func, rest), frame.context);
                return;
            }

            eval.CloseFrame();
        }
Ejemplo n.º 4
0
        private static void EvalEach(Evaluator eval, StackFrame frame)
        {
            if (!eval.HaveReturn())
            {
                Atom expression = frame.args;
                Atom first      = frame.args?.atom;
                if (first?.value is Context ctx)
                {
                    expression = frame.args?.next;
                }
                else
                {
                    ctx = frame.context.value as Context;
                }
                eval.CreateFrame("-eval-block-", expression, ctx);
                return;
            }

            eval.CloseFrame();
        }
Ejemplo n.º 5
0
        private static void If(Evaluator eval, StackFrame frame)
        {
            switch (frame.state.value)
            {
            case "-eval-sexp-body-":
            {
                //  (cond BlockA BlockB)
                (frame.temp1, frame.temp2, frame.temp3) = StructureUtils.Split3(frame.args);
                frame.state = new Atom("-built-in-if-cond-");
            }
            break;

            case "-built-in-if-cond-":
            {
                if (eval.HaveReturn())
                {
                    var condition = eval.TakeReturn();
                    if (!condition.IsBool)
                    {
                        throw new ArgumentException($"Condition must return boolean atom, but found: {condition}!");
                    }
                    frame.state = new Atom((bool)condition.value ? "-built-in-if-then-" : "-built-in-if-else-");
                }
                else
                {
                    eval.CreateFrame("-eval-", frame.temp1, frame.context);
                }
            }
            break;

            case "-built-in-if-then-":
            {
                if (frame.temp2 == null)
                {
                    throw new ArgumentException($"If statement must have at least one block of code!");
                }

                if (eval.HaveReturn())
                {
                    eval.CloseFrame();
                    break;
                }

                eval.CreateFrame("-eval-", frame.temp2, frame.context);
            }
            break;

            case "-built-in-if-else-":
                frame.state = new Atom("-eval-sexp-body-");

                if (eval.HaveReturn())
                {
                    eval.CloseFrame();
                    break;
                }

                if (frame.temp3 == null)
                {
                    eval.Return(null);
                }
                else
                {
                    eval.CreateFrame("-eval-", frame.temp3, frame.context);
                }

                break;
            }
        }