Ejemplo n.º 1
0
        /* primaryexp -> prefixexp { `.' NAME | index | `:' NAME funcargs | funcargs } */
        private AST.Expression ParsePrimaryExpr()
        {
            AST.Expression prefixExp;

            /* prefixexp -> NAME | '(' expr ')' */
            if (Stream.IsName())
            {
                prefixExp = new AST.NameExpression(Stream.GetName().Value);
                Stream.MoveNext();
            }
            else if (Stream.IsKeyword("("))
            {
                Stream.MoveNext();

                prefixExp = new AST.ParenExpression(ParseExpression());

                Stream.GetKeywordAndMove(")");
            }
            else
            {
                throw new ParserException();
            }

            AST.Expression primaryExp = prefixExp;

            while (true)
            {
                if (Stream.IsKeyword("."))
                {
                    Stream.MoveNext();
                    String lookupName = Stream.GetName().Value;
                    Stream.MoveNext();
                    primaryExp = new AST.LookupExpression(primaryExp, lookupName);
                }
                else if (Stream.IsKeyword("[")) /* index -> '[' expr ']' */
                {
                    Stream.MoveNext();

                    primaryExp = new AST.IndexExpression(primaryExp, ParseExpression());

                    Stream.GetKeywordAndMove("]");
                }
                else if (Stream.IsKeyword(":"))
                {
                    Stream.MoveNext();

                    String functionName = Stream.GetName().Value;
                    Stream.MoveNext();

                    primaryExp = new AST.SelfLookupExpression(primaryExp, functionName);

                    List<AST.Expression> args = ParseFuncArgs();

                    primaryExp = new AST.FunctionApplicationExpression(primaryExp, args);
                }
                else if (Stream.IsKeyword("(") || Stream.IsKeyword("{") || Stream.IsString())
                {
                    List<AST.Expression> args = ParseFuncArgs();
                    primaryExp = new AST.FunctionApplicationExpression(primaryExp, args);
                }
                else
                {
                    break;
                }
            }

            return primaryExp;
        }
Ejemplo n.º 2
0
        public void Visit(AST.FunctionStatement statement)
        {
            bool isSelfFunction = statement.SelfName != null;
            bool isGlobal = !isSelfFunction && statement.FieldNames.Count == 0;

            if (!isGlobal)
            {
                // Get the table
                AST.Expression expr = new AST.NameExpression(statement.MainName);

                if (statement.FieldNames.Count > 0)
                {
                    foreach (String field in statement.FieldNames.GetRange(0, statement.FieldNames.Count - 1))
                    {
                        expr = new AST.LookupExpression(expr, field);
                    }

                    if (isSelfFunction)
                    {
                        expr = new AST.LookupExpression(expr, statement.FieldNames.Last());
                    }
                }

                expr.Visit(new ExpressionCompiler(State, 1));

                // Get the key
                if (isSelfFunction)
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(statement.SelfName))); State.stackPosition++;
                }
                else
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakeLOADK(State.AddConstant(statement.FieldNames.Last()))); State.stackPosition++;
                }
            }

            FunctionCompiler funcCompiler = new FunctionCompiler(State, statement.Body, isSelfFunction);

            VirtualMachine.Function function = new VirtualMachine.Function(funcCompiler.State.bytecodes.ToArray(), funcCompiler.State.constants.ToArray(), Guid.NewGuid().ToString(),
                                                                           funcCompiler.State.childFunctions, funcCompiler.State.positions, statement.MainName);
            State.childFunctions.Add(function);

            State.bytecodes.Add(VirtualMachine.OpCodes.MakeCLOSURE(State.AddConstant(function.Id))); State.stackPosition++;

            if (!isGlobal)
            {
                State.bytecodes.Add(VirtualMachine.OpCodes.PUTTABLE); State.stackPosition -= 3;
            }
            else
            {
                if (State.stackVars.ContainsKey(statement.MainName))
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTSTACK(State.stackPosition - State.stackVars[statement.MainName])); State.stackPosition--;
                }
                else
                {
                    State.bytecodes.Add(VirtualMachine.OpCodes.MakePUTGLOBAL(State.AddConstant(statement.MainName))); State.stackPosition--;
                }
            }
        }