コード例 #1
0
        public override object Run(Scope scope)
        {
            var body = (Body as BlockExpression);

            body.Scope.MergeWithScope(Nova.Globals);
            body.Scope.MergeWithScope(scope);

            var visitor = new VariableNameVisitor();

            visitor.Visit(body);

            body.SetChildrenScopes(body.Scope);

            var block = CompilerServices.CreateLambdaForExpression(body);
            var res   = block();

            if (res is Symbol)
            {
                var symval = new BlockExpression(new List <Expression> {
                    new VariableExpression(res)
                }, body.Scope);
                res = CompilerServices.CreateLambdaForExpression(symval)();
            }
            else if (res is NovaInstance)
            {
                var so = (NovaInstance)res;
                if (so is NovaBoxedInstance)
                {
                    res = ((NovaBoxedInstance)so).BoxedObject;
                }
            }
            else if (res is NovaNumber)
            {
                res = NovaNumber.Convert(res);
            }
            else if (res is NovaString)
            {
                res = (string)res;
            }
            else if (res is NovaArray)
            {
                res = ConvertElements((NovaArray)res);
            }
            else if (res is NovaDictionary)
            {
                res = ConvertElements((NovaDictionary)res);
            }

            body.Scope.MergeIntoScope(scope);

            return(res);
        }
コード例 #2
0
        internal object Run(NovaScope scope)
        {
            var body = (BlockExpression)Body;

            body.SetScope(scope);

            body.SetChildrenScopes(body.Scope);

            var block = CompilerServices.CreateLambdaForExpression(Expression.Block(body));

            var res = block();

            if (res is Symbol)
            {
                var symval = new BlockExpression(new List <Expression> {
                    new VariableExpression(res)
                }, body.Scope);
                res = CompilerServices.CreateLambdaForExpression(symval)();
            }

            return(res);
        }
コード例 #3
0
 protected virtual Expression VisitBlock(BlockExpression node)
 {
     node.Body.ForEach(arg => Visit(arg));
     return(node);
 }
コード例 #4
0
        public override Expression Reduce()
        {
            var forLabel = Label("<nova_for>");
            VariableExpression      forReturn   = null;
            LeftHandValueExpression forReturnLh = null;
            var useReturn = true;

            if (Body.Type == typeof(void))
            {
                useReturn = false;
            }
            else
            {
                forReturn         = Variable(Constant("<nova_for_return>"));
                forReturnLh       = LeftHandValue(forReturn);
                forReturn.Scope   = ((NovaExpression)Body).Scope;
                forReturnLh.Scope = ((NovaExpression)Body).Scope;
            }
            var forTest   = Variable(Constant("<nova_for_test>"));
            var forTestLh = LeftHandValue(forTest);

            forTest.Scope   = ((NovaExpression)Body).Scope;
            forTestLh.Scope = ((NovaExpression)Body).Scope;
            var realBody = new List <Expression> {
                Init,
                Label(forLabel),
            };
            var testAssign = Assign(forTestLh, Test);

            realBody.Add(Label(NovaParser.RetryTarget));
            testAssign.Scope = (Body as NovaExpression).Scope;
            realBody.Add(testAssign);
            IfExpression testIf;

            if (useReturn)
            {
                var returnAssign = Assign(forReturnLh, Body);
                returnAssign.Scope = (Body as NovaExpression).Scope;
                testIf             = IfThen(forTest, returnAssign);
            }
            else
            {
                testIf = IfThen(forTest, Body);
            }
            testIf.Scope = ((NovaExpression)Body).Scope;
            realBody.Add(testIf);
            realBody.Add(Label(NovaParser.ContinueTarget));
            realBody.Add(Step);
            realBody.Add(IfThen(forTest, Goto(forLabel)));
            realBody.Add(Label(NovaParser.BreakTarget));
            if (useReturn)
            {
                realBody.Add(forReturn);
            }

            var block = new BlockExpression(realBody)
            {
                Scope = (Body as NovaExpression).Scope
            };

            return(Convert(block, Type));
        }