Пример #1
0
        private static void List(Evaluator eval, StackFrame frame)
        {
            var args = frame.args;

            if (args == null)
            {
                eval.SetReturn(null);
                return;
            }

            if (args.IsEmpty)
            {
                eval.SetReturn(new Atom());
                return;
            }

            Atom head, tail;

            head       = tail = new Atom();
            head.value = args.value;
            for (Atom iter = args.next; iter != null; iter = iter.next)
            {
                tail       = tail.next = new Atom();
                tail.value = iter.value;
            }

            eval.Return(head);
        }
Пример #2
0
        // TODO: Осознать, что тут происходит
        private static void TableEach(Evaluator eval, StackFrame frame)
        {
            var args = frame.args;

            var(dict, func) = StructureUtils.Split2(args);
            Context  dictionary = GetDictionary(dict);
            Function proc       = func?.value as Function;

            if (dictionary == null)
            {
                throw new ArgumentException("First argument must be table!");
            }
            if (proc == null)
            {
                throw new ArgumentException("Second argument must be procedure!");
            }

            switch (frame.state.value)
            {
            case "-eval-sexp-body-":
                var list = dictionary
                           .Select(pair => StructureUtils.List(new Atom(AtomType.String, pair.Key), pair.Value))
                           .ToArray();
                frame.temp1 = StructureUtils.List(list);
                frame.state = new Atom("-built-in-table-each-");
                break;

            case "-built-in-table-each-":
                if (eval.HaveReturn())
                {
                    frame.temp2 = StructureUtils.BuildListContainer(frame.temp2, eval.TakeReturn());
                }

                if (frame.temp1 != null)
                {
                    var pair = frame.temp1.atom;
                    frame.temp1 = frame.temp1.next;
                    var newFrame = eval.CreateFrame(
                        "-eval-sexp-args-",
                        new Atom(func, pair),
                        frame.context);
                    newFrame.function = func;
                    newFrame.args     = frame.temp1.atom;
                }
                else
                {
                    eval.SetReturn(null);
                    frame.state = new Atom("-eval-sexp-body-");
                }

                break;
            }
        }
Пример #3
0
        private static void Filter(Evaluator eval, StackFrame frame)
        {
            (var list, var proc, var skip) = StructureUtils.Split3(frame.args);

            bool skipNull = (bool?)skip?.value ?? false;

            switch (frame.state.value)
            {
            case "-eval-sexp-body-":
                frame.temp1 = list;
                frame.state = new Atom("-built-in-map-");
                break;

            case "-built-in-map-":
                if (eval.HaveReturn())
                {
                    var  pred = eval.TakeReturn();
                    bool add  = (bool?)pred?.value ?? false;
                    if (add)
                    {
                        frame.temp2 = StructureUtils.BuildListContainer(frame.temp2, frame.temp3);
                    }
                }
                if (frame.temp1 != null)
                {
                    while (skipNull && frame.temp1.atom == null)
                    {
                        frame.temp1 = frame.temp1.next;
                    }
                    var subExpression = frame.temp1.atom;
                    frame.temp3   = subExpression;
                    frame.temp1   = frame.temp1.next;
                    subExpression = new Atom(subExpression, null);
                    frame.temp1   = frame.temp1.next;
                    var newFrame = eval.CreateFrame(
                        "-eval-sexp-args-",
                        new Atom(proc, subExpression),
                        frame.context);
                    newFrame.function = proc;
                    newFrame.args     = subExpression;
                }
                else
                {
                    eval.SetReturn(frame.temp2.atom);
                    frame.state = new Atom("-eval-sexp-body-");
                }
                break;
            }
        }
Пример #4
0
        private static void TablePred(Evaluator eval, StackFrame frame)
        {
            var atom   = frame.args.atom;
            var result = atom != null && atom.type == AtomType.Native;

            if (!result)
            {
                eval.SetReturn(Atoms.FALSE);
            }
            else
            {
                var table = atom.value as Context;
                eval.Return(table != null ? Atoms.TRUE : Atoms.FALSE);
            }
        }
Пример #5
0
        private static void Each(Evaluator eval, StackFrame frame)
        {
            (var list, var proc, var skip) = StructureUtils.Split3(frame.args);

            bool skipNull = (bool?)skip?.value ?? false;

            switch (frame.state.value)
            {
            case "-eval-sexp-body-":
                frame.temp1 = list;
                frame.state = new Atom("-built-in-each-");
                break;

            case "-built-in-each-":
                if (eval.HaveReturn())
                {
                    frame.temp2 = StructureUtils.BuildListContainer(frame.temp2, eval.TakeReturn());
                }
                if (frame.temp1 != null)
                {
                    while (skipNull && frame.temp1.atom == null)
                    {
                        frame.temp1 = frame.temp1.next;
                    }

                    var subExpression = new Atom(frame.temp1.atom, null);

                    var newFrame = eval.CreateFrame(
                        "-eval-sexp-body-",
                        StructureUtils.List(proc, frame.temp1.atom),
                        frame.context);
                    newFrame.function = proc;
                    newFrame.args     = subExpression;

                    frame.temp1 = frame.temp1.next;
                }
                else
                {
                    eval.SetReturn(null);
                    frame.state = new Atom("-eval-sexp-body-");
                }
                break;
            }
        }