Example #1
0
        private AST foreachStuff()
        {
            AST statementList = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<FOREACH_STATEMENTS>"));

            // increase __index__
            AST incrementNode = new AST(new Token(Token.TokenType.OPERATOR, "+"));

            incrementNode.addChild(new AST(new Token(Token.TokenType.NAME, "__index__")));
            incrementNode.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "1", new ReturnValue(1.0f))));
            AST_Assignment assignmentNode = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__");

            assignmentNode.addChild(incrementNode);
            statementList.addChild(assignmentNode);

            // if(__index__ >= count(__indexes__)) { break }
            AST_FunctionCall lengthOfArray = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "count"));
            AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));

            argumentList.addChild(new Token(Token.TokenType.NAME, "__indexes__"));
            lengthOfArray.addChild(argumentList);

            AST breakStatement = new AST_IfNode(new Token(Token.TokenType.IF, "IF"));
            AST operatorTree   = new AST(new Token(Token.TokenType.OPERATOR, ">="));

            operatorTree.addChild(new Token(Token.TokenType.NAME, "__index__"));
            operatorTree.addChild(lengthOfArray);

            breakStatement.addChild(operatorTree);
            breakStatement.addChild(new Token(Token.TokenType.BREAK, "break"));
            statementList.addChild(breakStatement);

            // @ variable
            AST_VariableDeclaration declarationTree =
                new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                            ReturnValueType.UNKNOWN_TYPE,
                                            "@");

            statementList.addChild(declarationTree);

            AST arrayIndexLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__indexes__"));

            arrayIndexLookup.addChild(new AST(new Token(Token.TokenType.NAME, "__index__")));

            AST arrayValueLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__array__"));

            arrayValueLookup.addChild(arrayIndexLookup);

            AST_Assignment assignmentTree =
                new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "@");

            assignmentTree.addChild(arrayValueLookup);
            statementList.addChild(assignmentTree);

            return(statementList);
        }
Example #2
0
        private AST fromMinToMaxArrayCreation()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("fromMinToMaxArrayCreation");
#endif

            try {
                Token fromToken = match(Token.TokenType.FROM);

                AST minValue = expression();

                if (minValue == null)
                {
                    throw new Error("Missing expression after 'from'",
                                    Error.ErrorType.SYNTAX,
                                    fromToken.LineNr, fromToken.LinePosition + 5);
                }

                match(Token.TokenType.TO);
                AST maxValue = expression();

                if (maxValue == null)
                {
                    throw new Error("Missing expression after 'to'",
                                    Error.ErrorType.SYNTAX,
                                    fromToken.LineNr, fromToken.LinePosition + 3);
                }

                AST_FunctionCall callRangeFunction = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "range"));
                AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));
                argumentList.addChild(minValue);
                argumentList.addChild(maxValue);
                callRangeFunction.addChild(argumentList);

                return(callRangeFunction);
            }
            catch (Error e) {
                m_errorHandler.errorOccured(e);
                return(null);
            }
        }
Example #3
0
        private AST loop()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("loop");
            #endif
            AST loopBlockStatements = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<LOOP_BLOCK_STATEMENTS>"));

            AST_LoopNode loopTree = new AST_LoopNode(match(Token.TokenType.LOOP));

            string loopVariableName = "@"; // default name if no name is specified directly after 'loop' keyword

            bool isForeachLoop = false;
            if(lookAheadType(1) != Token.TokenType.NEW_LINE)
            {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("foreach loop!");
            #endif
                isForeachLoop = true;

                // __index__
                AST_VariableDeclaration loopIndexDeclaration
                = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                        ReturnValueType.NUMBER,
                                                        "__index__");
                loopBlockStatements.addChild(loopIndexDeclaration);

                AST_Assignment loopIndexAssignment
                    = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__");
                loopIndexAssignment.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "-1", -1.0f)));

                loopBlockStatements.addChild(loopIndexAssignment);

                Token savePoint = lookAhead(1); // will backtrack from here if matching loopVariable + loopRangeExpression fails
                //Console.WriteLine("Created save point at token " + savePoint);

                Token loopVariable = null;
                AST loopRangeExpression = null; // what the loop will loop through

                if ((lookAheadType (1) == Token.TokenType.NAME && lookAheadType(2) == Token.TokenType.IN) ||
                    (lookAheadType (1) == Token.TokenType.NAME && lookAheadType(2) == Token.TokenType.FROM))
                {
                    loopVariable = match (Token.TokenType.NAME);

                    if(lookAheadType(1) == Token.TokenType.IN) {
                        match (Token.TokenType.IN);
                    }
                    else if(lookAheadType(1) == Token.TokenType.FROM) {
                        // proceed
                    }

                    try {
                        //Console.WriteLine ("Found a potential loop variable " + loopVariable.getTokenString() + ", trying to match loop range expression with a loop variable");
                        loopRangeExpression = expression();
                        if(loopRangeExpression == null) {
                            //Console.WriteLine ("null! Failed to match statement after loop variable, will backtrack and assume this loop does not use a loop variable");
                            backtrackToToken (savePoint);
                        } else {
                            loopVariableName = loopVariable.getTokenString();
                            //Console.WriteLine("Success, loop variable is called: " + loopVariableName);
                        }
                    }
                    catch(Error e) {
                        //Console.WriteLine ("Failed to match statement after loop variable, will backtrack and assume this loop does not use a loop variable");
                        backtrackToToken (savePoint);
                    }
                }

                if (loopRangeExpression == null) {
                    //Console.WriteLine ("There is no loop variable, trying to match a bare loop range expression");
                    loopRangeExpression = expression();
                }

                if (loopRangeExpression == null) {
                    throw new Error ("Failed to match the expression after 'loop'", Error.ErrorType.SYNTAX, loopTree.getToken ().LineNr, loopTree.getToken ().LinePosition);
                }

                //Console.WriteLine ("Loop range/array expression: ");
                //(new ASTPainter ()).PaintAST (loopRangeExpression);

                // __array__ (is a copy of the array to loop over)
                AST_VariableDeclaration loopArrayDeclaration = new AST_VariableDeclaration(
                    new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                    ReturnValueType.UNKNOWN_TYPE,
                    "__array__");

                loopBlockStatements.addChild(loopArrayDeclaration);

                AST_Assignment loopArrayAssignment =
                    new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__array__");

                if(loopRangeExpression != null) {
                    loopArrayAssignment.addChild(loopRangeExpression);
                }
                else {
                    throw new Error("Can't understand array expression in loop", Error.ErrorType.SYNTAX,
                                    loopArrayAssignment.getToken().LineNr,
                                    loopArrayAssignment.getToken().LinePosition);
                }

                loopBlockStatements.addChild(loopArrayAssignment);

                // __indexes__ (holds all the indexes in the array, since it works like a SortedDictionary)
                // __indexes = getIndexes(__array__)
                AST_VariableDeclaration indexesDeclaration = new AST_VariableDeclaration(
                    new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                    ReturnValueType.UNKNOWN_TYPE,
                    "__indexes__");

                loopBlockStatements.addChild(indexesDeclaration);

                AST_FunctionCall getArrayIndexes = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "GetIndexes"));
                AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));
                argumentList.addChild(new Token(Token.TokenType.NAME, "__array__"));
                getArrayIndexes.addChild(argumentList);

                AST_Assignment indexesAssignment = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__indexes__");
                indexesAssignment.addChild(getArrayIndexes);
                loopBlockStatements.addChild(indexesAssignment);
            }
            else
            {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("infinite loop!");
            #endif
            }

            /*
             * 		loopParentTree
             * 			__index__-declaration
             * 			__array__-declaration & assigment
             * 			loop tree
             * 				loop body
             * 					foreach stuff
             * 					rest of statements
             * 					goto beginning of loop
             *
             * */

            allowLineBreak();
            AST loopBody = statementList(false);
            loopBody.addChild(new AST(new Token(Token.TokenType.GOTO_BEGINNING_OF_LOOP, "<GOTO_BEGINNING_OF_LOOP>")));
            allowLineBreak();
            match(Token.TokenType.BLOCK_END);

            if(isForeachLoop) {
                loopBody.addChildFirst(foreachStuff(loopVariableName));
            }

            loopTree.addChild(loopBody);

            loopBlockStatements.addChild(loopTree);

            AST_LoopBlockNode loopBlock = new AST_LoopBlockNode(new Token(Token.TokenType.LOOP_BLOCK, "<LOOP_BLOCK>"));
            loopBlock.addChild(loopBlockStatements);

            return loopBlock;
        }
Example #4
0
        private AST functionCall()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("function call");
            #endif

            Token nameToken = match(Token.TokenType.NAME);

            AST functionCallTree =
                new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, nameToken.getTokenString(), nameToken.LineNr, nameToken.LinePosition));

            var argumentList = FunctionArgumentList ();

            functionCallTree.getToken ().LineNr = nameToken.LineNr;
            functionCallTree.getToken ().LinePosition = nameToken.LinePosition;
            functionCallTree.addChild(argumentList);

            return functionCallTree;
        }
Example #5
0
        private AST fromMinToMaxArrayCreation()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("fromMinToMaxArrayCreation");
            #endif

            try {
                Token fromToken = match(Token.TokenType.FROM);

                AST minValue = expression();

                if(minValue == null) { throw new Error("Missing expression after 'from'",
                                             	Error.ErrorType.SYNTAX,
                                                    fromToken.LineNr, fromToken.LinePosition + 5 ); }

                match(Token.TokenType.TO);
                AST maxValue = expression();

                if(maxValue == null) { throw new Error("Missing expression after 'to'",
                                             	Error.ErrorType.SYNTAX,
                                                    fromToken.LineNr, fromToken.LinePosition + 3 ); }

                AST_FunctionCall callRangeFunction = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "Range"));
                AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));
                argumentList.addChild(minValue);
                argumentList.addChild(maxValue);
                callRangeFunction.addChild(argumentList);

                return callRangeFunction;
            }
            catch(Error e) {
                m_errorHandler.errorOccured(e);
                return null;
            }
        }
Example #6
0
        private AST foreachStuff(string pLoopVariableName)
        {
            AST statementList = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<FOREACH_STATEMENTS>"));

            // increase __index__
            AST incrementNode = new AST(new Token(Token.TokenType.OPERATOR, "+"));
            incrementNode.addChild(new AST(new Token(Token.TokenType.NAME, "__index__")));
            incrementNode.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "1", 1.0f)));
            AST_Assignment assignmentNode = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__");
            assignmentNode.addChild(incrementNode);
            statementList.addChild(assignmentNode);

            // if(__index__ >= count(__indexes__)) { break }
            AST_FunctionCall lengthOfArray = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "Count"));
            AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));
            argumentList.addChild(new Token(Token.TokenType.NAME, "__indexes__"));
            lengthOfArray.addChild(argumentList);

            AST breakStatement = new AST_IfNode(new Token(Token.TokenType.IF, "IF"));
            AST operatorTree = new AST(new Token(Token.TokenType.OPERATOR, ">="));
            operatorTree.addChild(new Token(Token.TokenType.NAME, "__index__"));
            operatorTree.addChild(lengthOfArray);

            breakStatement.addChild(operatorTree);
            breakStatement.addChild(new Token(Token.TokenType.BREAK, "break"));
            statementList.addChild(breakStatement);

            // Loop variable
            AST_VariableDeclaration declarationTree =
                new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"), ReturnValueType.UNKNOWN_TYPE, pLoopVariableName);
            statementList.addChild(declarationTree);

            AST arrayIndexLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__indexes__"));
            arrayIndexLookup.addChild(new AST(new Token(Token.TokenType.NAME, "__index__")));

            AST arrayValueLookup = new AST(new Token(Token.TokenType.ARRAY_LOOKUP, "__array__"));
            arrayValueLookup.addChild(arrayIndexLookup);

            AST_Assignment assignmentTree =
                new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), pLoopVariableName);
            assignmentTree.addChild(arrayValueLookup);
            statementList.addChild(assignmentTree);

            return statementList;
        }
Example #7
0
        private AST dotNotationExpression()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("dot notation expression");
            #endif

            AST lhs = parenthesisExpression();

            if ( lookAhead(1).getTokenType() == Token.TokenType.DOT)
            {
                match (Token.TokenType.DOT);

                #if WRITE_DEBUG_INFO
                Console.WriteLine("It's a dot notation expression!!! for example: object.f(a, b)");
                #endif

                Token nameToken = match(Token.TokenType.NAME);

                AST functionCallTree =
                    new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, "RemoteFunctionCall", nameToken.LineNr, nameToken.LinePosition));

                // These are the argument sent through the remote function call
                AST innerArgumentList = FunctionArgumentList ();

                // The call to RemoteFunctionCall always takes three args: <id>, <functionName> & <args>
                AST argumentList = new AST (new Token (Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));

                // <ID>
                argumentList.addChild (lhs); // use whatever is on the left side of the dot in the function (method rather) call (.)
                //Console.WriteLine ("Method call ID: ");
                //(new ASTPainter()).PaintAST(lhs);

                // <FunctionName>
                Token functionNameToken = new TokenWithValue (
                    Token.TokenType.QUOTED_STRING,
                    nameToken.getTokenString (),
                    nameToken.LineNr,
                    nameToken.LinePosition,
                    nameToken.getTokenString());

                argumentList.addChild (new AST(functionNameToken));

                // <args>
                AST_ArrayEndSignal argsArray = new AST_ArrayEndSignal(new Token(Token.TokenType.ARRAY_END_SIGNAL, "<ARRAY>"));
                //Console.WriteLine ("Inner args:");
                foreach (var child in innerArgumentList.getChildren()) {
                    //Console.WriteLine (child.getTokenString ());
                    argsArray.addChild (child);
                }
                argsArray.ArraySize = innerArgumentList.getChildren().Count; // DAMNIT DON'T FORGET THIS ONE
                argumentList.addChild (argsArray); // send the arguments as an array to RemoteFunctionCall

                functionCallTree.addChild(argumentList);
                return functionCallTree;
            } else {
                return lhs;
            }
        }
Example #8
0
        private AST functionCall()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("function call");
#endif

            Token nameToken = match(Token.TokenType.NAME);

            AST functionCallTree =
                new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, nameToken.getTokenString(), nameToken.LineNr, nameToken.LinePosition));

            match(Token.TokenType.PARANTHESIS_LEFT);

            functionCallTree.getToken().LineNr       = nameToken.LineNr;
            functionCallTree.getToken().LinePosition = nameToken.LinePosition;

            AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));

            if (lookAheadType(1) != Token.TokenType.PARANTHESIS_RIGHT)
            {
                while (true)
                {
                    AST expressionTree = expression();

                    if (expressionTree != null)
                    {
                        argumentList.addChild(expressionTree);                         // add arguments as subtrees
                    }
                    else
                    {
                        throw new Error("Something is wrong with the argument list", Error.ErrorType.SYNTAX,
                                        lookAhead(1).LineNr, lookAhead(1).LinePosition);
                    }

                    if (lookAheadType(1) == Token.TokenType.COMMA)
                    {
                        match(Token.TokenType.COMMA);
                        continue;
                    }
                    else
                    {
                        // Is something wrong?
                        if (lookAheadType(1) == Token.TokenType.NEW_LINE ||
                            lookAheadType(1) == Token.TokenType.EOF)
                        {
                            throw new Error("Ending parenthesis is missing in function call"
                                            , Error.ErrorType.SYNTAX,
                                            lookAhead(1).LineNr, lookAhead(1).LinePosition);
                        }
                        else if (lookAheadType(1) == Token.TokenType.NAME ||
                                 lookAheadType(1) == Token.TokenType.QUOTED_STRING ||
                                 lookAheadType(1) == Token.TokenType.NUMBER)
                        {
                            throw new Error("A comma is missing in argument list"
                                            , Error.ErrorType.SYNTAX,
                                            lookAhead(1).LineNr, lookAhead(1).LinePosition);
                        }

                        break;
                    }
                }
            }

            match(Token.TokenType.PARANTHESIS_RIGHT);

            functionCallTree.addChild(argumentList);

            return(functionCallTree);
        }
Example #9
0
        private AST loop()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("loop");
#endif
            AST loopBlockStatements = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<LOOP_BLOCK_STATEMENTS>"));

            AST_LoopNode loopTree = new AST_LoopNode(match(Token.TokenType.LOOP));

            bool isForeachLoop = false;
            if (lookAheadType(1) != Token.TokenType.NEW_LINE)
            {
#if WRITE_DEBUG_INFO
                Console.WriteLine("foreach loop!");
#endif
                isForeachLoop = true;

                // __index__
                AST_VariableDeclaration loopIndexDeclaration
                    = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                  ReturnValueType.NUMBER,
                                                  "__index__");
                loopBlockStatements.addChild(loopIndexDeclaration);

                AST_Assignment loopIndexAssignment
                    = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__");
                loopIndexAssignment.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "-1", new ReturnValue(-1.0f))));

                loopBlockStatements.addChild(loopIndexAssignment);

                // match
                //match(Token.TokenType.PARANTHESIS_LEFT);
                AST arrayExpression = expression();
                //match(Token.TokenType.PARANTHESIS_RIGHT);

                // __array__ (is a copy of the array to loop over)
                AST_VariableDeclaration loopArrayDeclaration
                    = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                  ReturnValueType.ARRAY,
                                                  "__array__");
                loopBlockStatements.addChild(loopArrayDeclaration);

                AST_Assignment loopArrayAssignment =
                    new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__array__");

                if (arrayExpression != null)
                {
                    loopArrayAssignment.addChild(arrayExpression);
                }
                else
                {
                    throw new Error("Can't understand array expression in loop", Error.ErrorType.SYNTAX,
                                    loopArrayAssignment.getToken().LineNr,
                                    loopArrayAssignment.getToken().LinePosition);
                }

                loopBlockStatements.addChild(loopArrayAssignment);

                // __indexes__ (holds all the indexes in the array, since it works like a SortedDictionary)
                // __indexes = getIndexes(__array__)
                AST_VariableDeclaration indexesDeclaration
                    = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                  ReturnValueType.ARRAY,
                                                  "__indexes__");
                loopBlockStatements.addChild(indexesDeclaration);

                AST_FunctionCall getArrayIndexes = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL,
                                                                                  "getIndexes"));
                AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));
                argumentList.addChild(new Token(Token.TokenType.NAME, "__array__"));
                getArrayIndexes.addChild(argumentList);

                AST_Assignment indexesAssignment =
                    new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__indexes__");
                indexesAssignment.addChild(getArrayIndexes);
                loopBlockStatements.addChild(indexesAssignment);
            }
            else
            {
#if WRITE_DEBUG_INFO
                Console.WriteLine("infinite loop!");
#endif
            }

            /*
             *      loopParentTree
             *          __index__-declaration
             *          __array__-declaration & assigment
             *          loop tree
             *              loop body
             *                  foreach stuff
             *                  rest of statements
             *                  goto beginning of loop
             *
             * */

            allowLineBreak();
            AST loopBody = statementList(false);
            loopBody.addChild(new AST(new Token(Token.TokenType.GOTO_BEGINNING_OF_LOOP, "<GOTO_BEGINNING_OF_LOOP>")));
            allowLineBreak();
            match(Token.TokenType.BLOCK_END);

            if (isForeachLoop)
            {
                loopBody.addChildFirst(foreachStuff());
            }

            loopTree.addChild(loopBody);

            loopBlockStatements.addChild(loopTree);

            AST_LoopBlockNode loopBlock = new AST_LoopBlockNode(new Token(Token.TokenType.LOOP_BLOCK, "<LOOP_BLOCK>"));
            loopBlock.addChild(loopBlockStatements);

            return(loopBlock);
        }
Example #10
0
        private AST loop()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("loop");
            #endif
            AST loopBlockStatements = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<LOOP_BLOCK_STATEMENTS>"));

            AST_LoopNode loopTree = new AST_LoopNode(match(Token.TokenType.LOOP));

            bool isForeachLoop = false;
            if(lookAheadType(1) != Token.TokenType.NEW_LINE)
            {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("foreach loop!");
            #endif
                isForeachLoop = true;

                // __index__
                AST_VariableDeclaration loopIndexDeclaration
                = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                        ReturnValueType.NUMBER,
                                                        "__index__");
                loopBlockStatements.addChild(loopIndexDeclaration);

                AST_Assignment loopIndexAssignment
                    = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__index__");
                loopIndexAssignment.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "-1", new ReturnValue(-1.0f))));

                loopBlockStatements.addChild(loopIndexAssignment);

                // match
                //match(Token.TokenType.PARANTHESIS_LEFT);
                AST arrayExpression = expression();
                //match(Token.TokenType.PARANTHESIS_RIGHT);

                // __array__ (is a copy of the array to loop over)
                AST_VariableDeclaration loopArrayDeclaration
                = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                        ReturnValueType.ARRAY,
                                                        "__array__");
                loopBlockStatements.addChild(loopArrayDeclaration);

                AST_Assignment loopArrayAssignment =
                    new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__array__");

                if(arrayExpression != null) {
                    loopArrayAssignment.addChild(arrayExpression);
                }
                else {
                    throw new Error("Can't understand array expression in loop", Error.ErrorType.SYNTAX,
                                    loopArrayAssignment.getToken().LineNr,
                                    loopArrayAssignment.getToken().LinePosition);
                }

                loopBlockStatements.addChild(loopArrayAssignment);

                // __indexes__ (holds all the indexes in the array, since it works like a SortedDictionary)
                // __indexes = getIndexes(__array__)
                AST_VariableDeclaration indexesDeclaration
                = new AST_VariableDeclaration(new Token(Token.TokenType.VAR_DECLARATION, "<VAR_DECL>"),
                                                        ReturnValueType.ARRAY,
                                                        "__indexes__");
                loopBlockStatements.addChild(indexesDeclaration);

                AST_FunctionCall getArrayIndexes = new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL,
                                                                                  "getIndexes"));
                AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));
                argumentList.addChild(new Token(Token.TokenType.NAME, "__array__"));
                getArrayIndexes.addChild(argumentList);

                AST_Assignment indexesAssignment =
                new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), "__indexes__");
                indexesAssignment.addChild(getArrayIndexes);
                loopBlockStatements.addChild(indexesAssignment);
            }
            else
            {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("infinite loop!");
            #endif
            }

            /*
             * 		loopParentTree
             * 			__index__-declaration
             * 			__array__-declaration & assigment
             * 			loop tree
             * 				loop body
             * 					foreach stuff
             * 					rest of statements
             * 					goto beginning of loop
             *
             * */

            allowLineBreak();
            AST loopBody = statementList(false);
            loopBody.addChild(new AST(new Token(Token.TokenType.GOTO_BEGINNING_OF_LOOP, "<GOTO_BEGINNING_OF_LOOP>")));
            allowLineBreak();
            match(Token.TokenType.BLOCK_END);

            if(isForeachLoop) {
                loopBody.addChildFirst(foreachStuff());
            }

            loopTree.addChild(loopBody);

            loopBlockStatements.addChild(loopTree);

            AST_LoopBlockNode loopBlock = new AST_LoopBlockNode(new Token(Token.TokenType.LOOP_BLOCK, "<LOOP_BLOCK>"));
            loopBlock.addChild(loopBlockStatements);

            return loopBlock;
        }
Example #11
0
        private AST functionCall()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("function call");
            #endif

            Token nameToken = match(Token.TokenType.NAME);

            AST functionCallTree =
                new AST_FunctionCall(new Token(Token.TokenType.FUNCTION_CALL, nameToken.getTokenString(), nameToken.LineNr, nameToken.LinePosition));

            match(Token.TokenType.PARANTHESIS_LEFT);

            functionCallTree.getToken().LineNr = nameToken.LineNr;
            functionCallTree.getToken().LinePosition = nameToken.LinePosition;

            AST argumentList = new AST(new Token(Token.TokenType.NODE_GROUP, "<ARGUMENT_LIST>"));

            if (lookAheadType(1) != Token.TokenType.PARANTHESIS_RIGHT) {

                while(true) {

                    AST expressionTree = expression();

                    if(expressionTree != null)
                    {
                        argumentList.addChild(expressionTree); // add arguments as subtrees
                    }
                    else
                    {
                        throw new Error("Something is wrong with the argument list", Error.ErrorType.SYNTAX,
                            lookAhead(1).LineNr, lookAhead(1).LinePosition);
                    }

                    if (lookAheadType(1) == Token.TokenType.COMMA) {
                        match(Token.TokenType.COMMA);
                        continue;
                    } else {

                        // Is something wrong?
                        if( lookAheadType(1) == Token.TokenType.NEW_LINE ||
                            lookAheadType(1) == Token.TokenType.EOF )
                        {
                            throw new Error("Ending parenthesis is missing in function call"
                                , Error.ErrorType.SYNTAX,
                                lookAhead(1).LineNr, lookAhead(1).LinePosition);
                        }
                        else if( lookAheadType(1) == Token.TokenType.NAME ||
                                 lookAheadType(1) == Token.TokenType.QUOTED_STRING ||
                                 lookAheadType(1) == Token.TokenType.NUMBER )
                        {
                            throw new Error("A comma is missing in argument list"
                                , Error.ErrorType.SYNTAX,
                                lookAhead(1).LineNr, lookAhead(1).LinePosition);
                        }

                        break;
                    }
                }
            }

            match(Token.TokenType.PARANTHESIS_RIGHT);

            functionCallTree.addChild(argumentList);

            return functionCallTree;
        }