예제 #1
0
        private static void Define(Evaluator eval, StackFrame frame)
        {
            var(sym, value, context) = StructureUtils.Split3(frame.args);

            if (sym.type != AtomType.Symbol)
            {
                throw new ArgumentException("Definition name must be symbol!");
            }

            if (eval.HaveReturn())
            {
                string  name   = (string)sym.value;
                Atom    result = eval.TakeReturn();
                Context ctx    = context?.value as Context ?? frame.context.value as Context;
                if (result?.value is Closure function)
                {
                    function.Name = name;
                }
                //Console.WriteLine($"DEFINE: '{name}' = '{result}' at -internal-state-{ctx}");
                ContextUtils.Define(ctx, result, name);
                eval.Return(result);
                return;
            }

            eval.CreateFrame("-eval-", value, frame.context);
            frame.state = Atoms.INTERNAL_STATE;
        }
예제 #2
0
        private static void Undefine(Evaluator eval, StackFrame frame)
        {
            var  args = frame.args;
            Atom sym  = (Atom)args?.value;

            if (sym.type != AtomType.Symbol)
            {
                throw new ArgumentException("Undefining name must be symbol!");
            }

            var ctx    = frame.context.value as Context;
            var result = ContextUtils.Undefine(ctx, (string)sym.value);

            eval.Return(result);
        }
예제 #3
0
        private static void TableImportAll(Evaluator eval, StackFrame frame)
        {
            var(src, dst) = StructureUtils.Split2(frame.args);

            if (dst == null || dst.IsPair)
            {
                dst = frame.context.atom;
            }

            var srcCtx = GetDictionary(src);
            var dstCtx = GetDictionary(dst);

            ContextUtils.ImportAllSymbols(srcCtx, dstCtx);

            eval.Return(null);
        }
예제 #4
0
        private static void TableImport(Evaluator eval, StackFrame frame)
        {
            var(src, dst, names) = StructureUtils.Split3(frame.args);

            if (names == null && dst.IsPair)
            {
                names = dst;
                dst   = frame.context.atom;
            }

            var srcCtx = GetDictionary(src);
            var dstCtx = GetDictionary(dst);

            string[] nameList = StructureUtils.ListToStringArray(names, "TABLE");

            ContextUtils.ImportSymbols(srcCtx, dstCtx, nameList);

            eval.Return(null);
        }
예제 #5
0
        private static void SetFirst(Evaluator eval, StackFrame frame)
        {
            var  args = frame.args;
            Atom sym  = (Atom)args?.value;

            if (sym.type != AtomType.Symbol)
            {
                throw new ArgumentException("Variable name must be symbol!");
            }

            if (eval.HaveReturn())
            {
                var result = eval.TakeReturn();
                var ctx    = frame.context.value as Context;
                ContextUtils.Set(ctx, result, (string)sym.value);
                eval.Return(result);
                return;
            }

            eval.CreateFrame("-eval-", args.next?.atom, frame.context);
            frame.state = Atoms.INTERNAL_STATE;
        }
예제 #6
0
        public Atom Evaluate(Atom atom, Context current_context, string startState = null)
        {
            _retValue   = null;
            _haveReturn = false;
            Stack.CreateFrame(startState ?? "-eval-", atom, current_context);

            Console.WriteLine("Start evaluation");
            while (Stack.stack.Count > 0)
            {
                if (ErrorMessage != null)
                {
                    Console.WriteLine($"[ERROR] {ErrorMessage}");
                    ErrorMessage = null;
                    return(null);
                }

                // Console.WriteLine($"RetValue: {_retValue}");
                // Stack.Dump(1);
                //Thread.Sleep(50);

                Function   func;
                StackFrame frame = Stack.TopFrame;
                switch (frame.state.value)
                {
                case "-eval-":
                    if (frame.expression.IsPair)
                    {
                        frame.state = new Atom("-eval-sexp-head-");
                        continue;
                    }
                    if (frame.expression.IsSymbol)
                    {
                        var name = (string)frame.expression.value;
                        try
                        {
                            SetReturn(ContextUtils.Get((Context)frame.context.value, name));
                        }
                        catch (BombardoException e)
                        {
                            Console.WriteLine($"[ERROR] {e}");
                            return(null);
                        }
                        CloseFrame();
                        continue;
                    }
                    SetReturn(frame.expression);
                    CloseFrame();
                    continue;

                case "-eval-each-":
                    if (HaveReturn())
                    {
                        frame.temp1 = StructureUtils.BuildListContainer(frame.temp1, TakeReturn());
                    }
                    if (frame.expression != null)
                    {
                        var subExpression = frame.expression.atom;
                        frame.expression = frame.expression.next;
                        Stack.CreateFrame("-eval-", subExpression, frame.context);
                        continue;
                    }
                    SetReturn(frame.temp1.atom);
                    // frame.temp1 = null;
                    CloseFrame();
                    continue;

                case "-eval-block-":
                    if (HaveReturn())
                    {
                        frame.temp1 = TakeReturn();
                    }
                    if (frame.expression != null)
                    {
                        var subExpression = frame.expression.atom;
                        frame.expression = frame.expression.next;
                        Stack.CreateFrame("-eval-", subExpression, frame.context);
                        continue;
                    }
                    SetReturn(frame.temp1);
                    // frame.temp1 = null;
                    CloseFrame();
                    continue;

                case "-eval-sexp-head-":
                    if (!HaveReturn())
                    {
                        var head = frame.expression.atom;
                        Stack.CreateFrame("-eval-", head, frame.context);
                        continue;
                    }

                    frame.function = TakeReturn();
                    if (!frame.function.IsFunction)
                    {
                        Console.WriteLine($"[ERROR] Head is not function: {frame.function}");
                        return(null);
                    }

                    frame.state = new Atom("-eval-sexp-args-");
                    continue;

                case "-eval-sexp-args-":
                    if (!HaveReturn())
                    {
                        func = (Function)frame.function.value;
                        if (func.EvalArgs && frame.expression.next != null)
                        {
                            Stack.CreateFrame("-eval-each-", frame.expression.next, frame.context);
                            continue;
                        }
                        frame.args  = frame.expression.next;
                        frame.state = new Atom("-eval-sexp-body-");
                        continue;
                    }

                    frame.args  = TakeReturn();
                    frame.state = new Atom("-eval-sexp-body-");
                    continue;

                case "-eval-sexp-body-":
                    func = (Function)frame.function.value;
                    if (!HaveReturn())
                    {
                        func.Apply(this, frame);
                        continue;
                    }
                    if (func.EvalResult)
                    {
                        frame.state = new Atom("-eval-sexp-result-");
                        frame.temp1 = TakeReturn();
                        continue;
                    }
                    CloseFrame();
                    continue;

                case "-eval-sexp-result-":
                    if (!HaveReturn())
                    {
                        Stack.CreateFrame("-eval-", frame.temp1, frame.context);
                        continue;
                    }
                    SetReturn(frame.temp1);
                    frame.temp1 = null;
                    CloseFrame();
                    continue;
                }

                //	  Ни один из указанных стейтов, значит:
                //  Либо это стейты функции и тогда её надо вызывать
                if (frame.function != null)
                {
                    func = (Function)frame.function.value;
                    func.Apply(this, frame);
                    continue;
                }

                //	Либо если нет функции - то это ошибка интерпретации
                SetError($"Wrong evaluation state: {frame.state.value}");
            }

            if (HaveReturn())
            {
                return(TakeReturn());
            }

            return(null);
        }