예제 #1
0
파일: Parser.cs 프로젝트: substans/Sprak
        private AST declarationAndAssignment()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("declaration and assignment");
#endif

            AST_VariableDeclaration declarationTree = declaration();
            Token assignmentToken = match(Token.TokenType.ASSIGNMENT);
            AST   expressionTree  = expression();

            if (expressionTree != null)
            {
                AST_Assignment assignmentTree = new AST_Assignment(assignmentToken, declarationTree.Name);

                assignmentTree.addChild(expressionTree);

                AST declarationAndAssignmentTree =
                    new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition));
                declarationAndAssignmentTree.addChild(declarationTree);
                declarationAndAssignmentTree.addChild(assignmentTree);

                return(declarationAndAssignmentTree);
            }
            else
            {
                throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX,
                                lookAhead(1).LineNr, lookAhead(1).LinePosition);
            }
        }
예제 #2
0
파일: Parser.cs 프로젝트: substans/Sprak
        private AST plusplusOrMinusminus()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("plusplusOrMinusminus");
#endif
            Token nameToken     = match(Token.TokenType.NAME);
            Token operatorToken = match(Token.TokenType.OPERATOR);

            AST operationTree = null;

            if (operatorToken.getTokenString() == "++")
            {
                operationTree = new AST(new Token(Token.TokenType.OPERATOR, "+"));
            }
            else if (operatorToken.getTokenString() == "--")
            {
                operationTree = new AST(new Token(Token.TokenType.OPERATOR, "-"));
            }
            else
            {
                throw new Exception("Error!");
            }

            operationTree.addChild(new AST(nameToken));
            operationTree.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "1", new ReturnValue(1.0f))));

            AST assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), nameToken.getTokenString());
            assignmentTree.addChild(operationTree);

            return(assignmentTree);
        }
예제 #3
0
        private AST CreateAssignmentTreeFromInitValue(string pVariableName, object pInitValue)
        {
            Token.TokenType tokenType;
            switch (ReturnValueConversions.SystemTypeToReturnValueType(pInitValue.GetType()))
            {
            case ReturnValueType.BOOL:
                tokenType = Token.TokenType.BOOLEAN_VALUE;
                break;

            case ReturnValueType.STRING:
                tokenType = Token.TokenType.QUOTED_STRING;
                break;

            case ReturnValueType.NUMBER:
                tokenType = Token.TokenType.NUMBER;
                break;

            case ReturnValueType.ARRAY:
                tokenType = Token.TokenType.ARRAY;
                break;

            case ReturnValueType.VOID:
                throw new Error("Can't assign void to variable");

            default:
                throw new Exception("Forgot to implement support for a type?");
            }
            Token initValueToken = new TokenWithValue(tokenType, pInitValue.ToString(), pInitValue);
            AST   assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), pVariableName);

            assignmentTree.addChild(initValueToken);
            return(assignmentTree);
        }
예제 #4
0
파일: Parser.cs 프로젝트: substans/Sprak
        private AST assignmentToArray()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("assignment to array");
#endif

            Token nameToken = null;
            AST   indexNode = null;

                        #if WRITE_DEBUG_INFO
            Console.WriteLine("normal array");
                        #endif
            nameToken = match(Token.TokenType.NAME);
            match(Token.TokenType.BRACKET_LEFT);
            indexNode = expression();
            match(Token.TokenType.BRACKET_RIGHT);

            if (lookAheadType(1) == Token.TokenType.NEW_LINE ||
                lookAheadType(1) == Token.TokenType.EOF)
            {
                // it's a statement without assignment
                return(indexNode);
            }

            Token assignmentToken = match(Token.TokenType.ASSIGNMENT);
            AST   expressionTree  = expression();

            if (expressionTree != null)
            {
                Token          arrayAssignmentToken = new Token(Token.TokenType.ASSIGNMENT_TO_ARRAY, "=", assignmentToken.LineNr, assignmentToken.LinePosition);
                AST_Assignment assignmentTree       = new AST_Assignment(arrayAssignmentToken, nameToken.getTokenString());
                assignmentTree.addChild(indexNode);
                assignmentTree.addChild(expressionTree);

                /*ASTPainter p = new ASTPainter();
                 * Console.WriteLine("---AST---");
                 * p.PaintAST(assignmentTree);
                 * Console.WriteLine("---------");*/
                return(assignmentTree);
            }
            else
            {
                throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX,
                                assignmentToken.LineNr, assignmentToken.LinePosition);
            }
        }
예제 #5
0
파일: Parser.cs 프로젝트: substans/Sprak
        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);
        }
예제 #6
0
파일: Parser.cs 프로젝트: substans/Sprak
        private AST assignmentAndOperator()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("assignment and operator");
#endif

            Token nameToken      = match(Token.TokenType.NAME);
            Token operatorToken  = match(Token.TokenType.OPERATOR);
            AST   expressionTree = expression();

            if (expressionTree != null)
            {
                AST_Assignment assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), nameToken.getTokenString());
                AST            selfOperation  = null;

                if (operatorToken.getTokenString() == "+=")
                {
                    selfOperation = new AST(new Token(Token.TokenType.OPERATOR, "+"));
                }
                else
                {
                    throw new Error("Can't handle the operator '" + operatorToken.getTokenString() + "'",
                                    Error.ErrorType.SYNTAX, assignmentTree.getToken().LineNr,
                                    assignmentTree.getToken().LinePosition);
                }
                selfOperation.addChild(nameToken);
                selfOperation.addChild(expressionTree);
                assignmentTree.addChild(selfOperation);

                return(assignmentTree);
            }
            else
            {
                throw new Error("The expression after " + operatorToken.getTokenString()
                                + " makes no sense", Error.ErrorType.SYNTAX,
                                operatorToken.LineNr, operatorToken.LinePosition);
            }
        }
예제 #7
0
파일: Parser.cs 프로젝트: substans/Sprak
        private AST assignment()
        {
#if WRITE_DEBUG_INFO
            Console.WriteLine("assignment");
#endif

            Token nameToken       = match(Token.TokenType.NAME);
            Token assignmentToken = match(Token.TokenType.ASSIGNMENT);
            AST   expressionTree  = expression();

            if (expressionTree != null)
            {
                AST_Assignment assignmentTree = new AST_Assignment(assignmentToken, nameToken.getTokenString());
                assignmentTree.addChild(expressionTree);

                return(assignmentTree);
            }
            else
            {
                throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX,
                                assignmentToken.LineNr, assignmentToken.LinePosition);
            }
        }
예제 #8
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;
        }
예제 #9
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;
        }
예제 #10
0
        private AST declarationAndAssignment()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("declaration and assignment");
            #endif

            AST_VariableDeclaration declarationTree = declaration();
            Token assignmentToken = match(Token.TokenType.ASSIGNMENT);
            AST expressionTree = expression();

            if(expressionTree != null) {
                AST_Assignment assignmentTree = new AST_Assignment(assignmentToken, declarationTree.Name);

                assignmentTree.addChild(expressionTree);

                AST declarationAndAssignmentTree =
                        new AST(new Token(Token.TokenType.STATEMENT_LIST, "<DECLARATION_AND_ASSIGNMENT>", declarationTree.getToken().LineNr, declarationTree.getToken().LinePosition));
                declarationAndAssignmentTree.addChild(declarationTree);
                declarationAndAssignmentTree.addChild(assignmentTree);

                return declarationAndAssignmentTree;
            } else {
                throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX,
                    lookAhead(1).LineNr, lookAhead(1).LinePosition);
            }
        }
예제 #11
0
        private AST assignmentToArray()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("assignment to array");
            #endif

            Token nameToken = null;
            AST indexNode = null;

            #if WRITE_DEBUG_INFO
                Console.WriteLine("normal array");
            #endif
            nameToken = match(Token.TokenType.NAME);
            match(Token.TokenType.BRACKET_LEFT);
            indexNode = expression();
            match(Token.TokenType.BRACKET_RIGHT);

            if(lookAheadType(1) == Token.TokenType.NEW_LINE ||
               lookAheadType(1) == Token.TokenType.EOF)
            {
                // it's a statement without assignment
                return indexNode;
            }

            Token assignmentToken = match(Token.TokenType.ASSIGNMENT);
            AST expressionTree = expression();

            if(expressionTree != null) {
                Token arrayAssignmentToken = new Token(Token.TokenType.ASSIGNMENT_TO_ARRAY, "=", assignmentToken.LineNr, assignmentToken.LinePosition);
                AST_Assignment assignmentTree = new AST_Assignment(arrayAssignmentToken, nameToken.getTokenString());
                assignmentTree.addChild(indexNode);
                assignmentTree.addChild(expressionTree);

                /*ASTPainter p = new ASTPainter();
                Console.WriteLine("---AST---");
                p.PaintAST(assignmentTree);
                Console.WriteLine("---------");*/
                return assignmentTree;
            }
            else {
                throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX,
                    assignmentToken.LineNr, assignmentToken.LinePosition);
            }
        }
예제 #12
0
        private AST assignmentAndOperator()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("assignment and operator");
            #endif

            Token nameToken = match(Token.TokenType.NAME);
            Token operatorToken = match(Token.TokenType.OPERATOR);
            AST expressionTree = expression();

            if(expressionTree != null) {
                AST_Assignment assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), nameToken.getTokenString());
                AST selfOperation = null;

                if(operatorToken.getTokenString() == "+=") {
                    selfOperation = new AST(new Token(Token.TokenType.OPERATOR, "+"));
                }
                else if(operatorToken.getTokenString() == "*=") {
                    selfOperation = new AST(new Token(Token.TokenType.OPERATOR, "*"));
                }
                else if(operatorToken.getTokenString() == "-=") {
                    selfOperation = new AST(new Token(Token.TokenType.OPERATOR, "-"));
                }
                else if(operatorToken.getTokenString() == "/=") {
                    selfOperation = new AST(new Token(Token.TokenType.OPERATOR, "/"));
                }
                else {
                    throw new Error("Can't handle the operator '" + operatorToken.getTokenString() + "'",
                                    Error.ErrorType.SYNTAX, assignmentTree.getToken().LineNr,
                                    assignmentTree.getToken().LinePosition);
                }
                selfOperation.addChild(nameToken);
                selfOperation.addChild(expressionTree);
                assignmentTree.addChild(selfOperation);

                return assignmentTree;
            }
            else {
                throw new Error("The expression after " + operatorToken.getTokenString()
                                + " makes no sense", Error.ErrorType.SYNTAX,
                    operatorToken.LineNr, operatorToken.LinePosition);
            }
        }
예제 #13
0
        private AST assignment()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("assignment");
            #endif

            Token nameToken = match(Token.TokenType.NAME);
            Token assignmentToken = match(Token.TokenType.ASSIGNMENT);
            AST expressionTree = expression();

            if(expressionTree != null) {
                AST_Assignment assignmentTree = new AST_Assignment(assignmentToken, nameToken.getTokenString());
                assignmentTree.addChild(expressionTree);

                return assignmentTree;
            }
            else {
                throw new Error("The expression after = makes no sense", Error.ErrorType.SYNTAX,
                    assignmentToken.LineNr, assignmentToken.LinePosition);
            }
        }
예제 #14
0
파일: Parser.cs 프로젝트: substans/Sprak
        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);
        }
예제 #15
0
        private AST plusplusOrMinusminus()
        {
            #if WRITE_DEBUG_INFO
            Console.WriteLine("plusplusOrMinusminus");
            #endif
            Token nameToken = match(Token.TokenType.NAME);
            Token operatorToken = match(Token.TokenType.OPERATOR);

            AST operationTree = null;

            if(operatorToken.getTokenString() == "++") {
                operationTree = new AST(new Token(Token.TokenType.OPERATOR, "+"));
            }
            else if(operatorToken.getTokenString() == "--") {
                operationTree = new AST(new Token(Token.TokenType.OPERATOR, "-"));
            }
            else {
                throw new Error("Invalid operator token");
            }

            operationTree.addChild(new AST(nameToken));
            operationTree.addChild(new AST(new TokenWithValue(Token.TokenType.NUMBER, "1", 1.0f)));

            AST assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), nameToken.getTokenString());
            assignmentTree.addChild(operationTree);

            return assignmentTree;
        }
예제 #16
0
 private AST CreateAssignmentTreeFromInitValue(string pVariableName, ReturnValue pInitValue)
 {
     Token.TokenType tokenType;
     switch(pInitValue.getReturnValueType()) {
         case ReturnValueType.BOOL:
             tokenType = Token.TokenType.BOOLEAN_VALUE;
         break;
         case ReturnValueType.STRING:
             tokenType = Token.TokenType.QUOTED_STRING;
         break;
         case ReturnValueType.NUMBER:
             tokenType = Token.TokenType.NUMBER;
         break;
         case ReturnValueType.ARRAY:
             tokenType = Token.TokenType.ARRAY;
         break;
         case ReturnValueType.VOID:
             throw new Error("Can't assign void to variable");
         default:
             throw new Exception("Forgot to implement support for a type?");
     }
     Token initValueToken = new TokenWithValue(tokenType, pInitValue.ToString(), pInitValue);
     AST assignmentTree = new AST_Assignment(new Token(Token.TokenType.ASSIGNMENT, "="), pVariableName);
     assignmentTree.addChild(initValueToken);
     return assignmentTree;
 }
예제 #17
0
파일: Parser.cs 프로젝트: substans/Sprak
        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;
        }