Пример #1
0
        public void Visit(AST.ReturnStatement statement)
        {
            foreach (AST.Expression expr in statement.Expressions)
            {
                ExpressionCompiler compiler = new ExpressionCompiler(State, 1);
                if (expr == statement.Expressions.Last())
                {
                    compiler = new ExpressionCompiler(State, 0);
                }

                expr.Visit(compiler);
            }

            if (State.newClosedVars.Count > 0)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPCLOSED(State.closureStackPosition - State.initialClosureStackPosition));
            }

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeRET(statement.Expressions.Count));

            hasReturned = true;
        }
Пример #2
0
        public void Visit(AST.FunctionApplicationExpression expression)
        {
            int funcIndex = State.stackPosition;

            if (expression.Obj is AST.SelfLookupExpression)
            {
                AST.SelfLookupExpression lookup = (AST.SelfLookupExpression)expression.Obj;
                int selfPos = State.stackPosition;
                lookup.Obj.Visit(new ExpressionCompiler(State, 1));
                int funcPos = State.stackPosition;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - selfPos)); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(lookup.Name))); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.GETTABLE); State.stackPosition--;

                State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - selfPos)); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakeGETSTACK(State.stackPosition - funcPos)); State.stackPosition++;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - selfPos)); State.stackPosition--;
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - funcPos)); State.stackPosition--;
            }
            else
            {
                expression.Obj.Visit(new ExpressionCompiler(State, 1));
            }

            foreach (AST.Expression expr in expression.Args)
            {
                ExpressionCompiler compiler = new ExpressionCompiler(State, 1);
                if (expr == expression.Args.Last())
                {
                    compiler = new ExpressionCompiler(State, 0);
                }

                expr.Visit(compiler);
            }

            int currentIndex = State.stackPosition;

            int argCount = expression.Args.Count;
            if (expression.Obj is AST.SelfLookupExpression)
            {
                argCount++;
            }

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCALL(argCount));

            if (NumResults > 0)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.MakePOPVARGS(NumResults, true));
                State.stackPosition = funcIndex + NumResults;
            }
            else
            {
                State.stackPosition = funcIndex + 1;
            }
        }