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); }
private AST ifThenElse() { #if WRITE_DEBUG_INFO Console.WriteLine("if block"); #endif AST ifThenElseTree; AST trueChild; AST falseChild = null; AST expr; try { match(Token.TokenType.IF); expr = expression(); // child 0 match(Token.TokenType.NEW_LINE); trueChild = statementList(false); // child 1 if (lookAheadType(1) == Token.TokenType.ELSE) { #if WRITE_DEBUG_INFO Console.WriteLine("else block"); #endif match(Token.TokenType.ELSE); match(Token.TokenType.NEW_LINE); falseChild = statementList(false); // child 2 match(Token.TokenType.BLOCK_END); } else { #if WRITE_DEBUG_INFO Console.WriteLine("no else block"); #endif match(Token.TokenType.BLOCK_END); } } catch (Error e) { // The error caught here will probably be from the match() function. // Since that means we're missing some part of the if-statement we can give a better // error message by throwing a new one. throw new Error("Something is wrong with the IF-statement", Error.ErrorType.SYNTAX, e.getLineNr(), e.getLinePosition()); } ifThenElseTree = new AST_IfNode(new Token(Token.TokenType.IF, "if", lookAhead(1).LineNr, lookAhead(1).LinePosition)); ifThenElseTree.addChild(expr); ifThenElseTree.addChild(trueChild); if (falseChild != null) { ifThenElseTree.addChild(falseChild); } return(ifThenElseTree); }
private AST ifThenElse() { #if WRITE_DEBUG_INFO Console.WriteLine("if block"); #endif AST ifThenElseTree; AST trueChild; AST falseChild = null; AST expr; try { Token ifToken = match(Token.TokenType.IF); expr = expression(); // child 0 if (expr == null) { throw new Error("The if statement is missing an expression after the 'if'", Error.ErrorType.SYNTAX, ifToken.LineNr, ifToken.LinePosition); } if(lookAheadType(1) == Token.TokenType.NEW_LINE) { match(Token.TokenType.NEW_LINE); } else { throw new Error("Found assignment (=) in if statement. Use == instead?", Error.ErrorType.SYNTAX, ifToken.LineNr, ifToken.LinePosition); } trueChild = statementList(false); // child 1 if ((lookAheadType(1) == Token.TokenType.ELSE) && (lookAheadType(2) == Token.TokenType.IF)) { #if WRITE_DEBUG_INFO Console.WriteLine("if else block"); #endif match(Token.TokenType.ELSE); var ifElseBranch = statement(); // ifThenElse(); // have to put it into a statement list to make scopes work falseChild = new AST(new Token(Token.TokenType.STATEMENT_LIST, "<STATEMENT_LIST>")); if(ifElseBranch != null) { falseChild.addChild(ifElseBranch); } #if WRITE_DEBUG_INFO Console.WriteLine("Popping out from ifElse branch"); #endif } else if (lookAheadType(1) == Token.TokenType.ELSE) { #if WRITE_DEBUG_INFO Console.WriteLine("else block"); #endif match(Token.TokenType.ELSE); if(lookAhead(1).getTokenType() == Token.TokenType.NEW_LINE) { match(Token.TokenType.NEW_LINE); } else { throw new Error("The else statement is missing a line break after it", Error.ErrorType.SYNTAX, ifToken.LineNr, ifToken.LinePosition); } falseChild = statementList(false); // child 2 if(lookAhead(1).getTokenType() == Token.TokenType.BLOCK_END) { match(Token.TokenType.BLOCK_END); } else { throw new Error("The if statement is missing a following 'end'", Error.ErrorType.SYNTAX, ifToken.LineNr, ifToken.LinePosition); } } else { #if WRITE_DEBUG_INFO Console.WriteLine("no else block"); #endif if(lookAhead(1).getTokenType() == Token.TokenType.BLOCK_END) { match(Token.TokenType.BLOCK_END); } else { throw new Error("The if statement is missing a following 'end'", Error.ErrorType.SYNTAX, ifToken.LineNr, ifToken.LinePosition); } } } catch(Error e) { // The error caught here will probably be from the match() function. // Since that means we're missing some part of the if-statement we can give a better // error message by throwing a new one. throw e; // new Error("Something is wrong with the IF-statement", Error.ErrorType.SYNTAX, e.getLineNr(), e.getLinePosition()); } ifThenElseTree = new AST_IfNode(new Token(Token.TokenType.IF, "if", lookAhead(1).LineNr, lookAhead(1).LinePosition)); ifThenElseTree.addChild (expr); ifThenElseTree.addChild(trueChild); if (falseChild != null) { ifThenElseTree.addChild(falseChild); } return ifThenElseTree; }
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; }
private AST ifThenElse() { #if WRITE_DEBUG_INFO Console.WriteLine("if block"); #endif AST ifThenElseTree; AST trueChild; AST falseChild = null; AST expr; try { match(Token.TokenType.IF); expr = expression(); // child 0 match(Token.TokenType.NEW_LINE); trueChild = statementList(false); // child 1 if (lookAheadType(1) == Token.TokenType.ELSE) { #if WRITE_DEBUG_INFO Console.WriteLine("else block"); #endif match(Token.TokenType.ELSE); match(Token.TokenType.NEW_LINE); falseChild = statementList(false); // child 2 match(Token.TokenType.BLOCK_END); } else { #if WRITE_DEBUG_INFO Console.WriteLine("no else block"); #endif match(Token.TokenType.BLOCK_END); } } catch(Error e) { // The error caught here will probably be from the match() function. // Since that means we're missing some part of the if-statement we can give a better // error message by throwing a new one. throw new Error("Something is wrong with the IF-statement", Error.ErrorType.SYNTAX, e.getLineNr(), e.getLinePosition()); } ifThenElseTree = new AST_IfNode(new Token(Token.TokenType.IF, "if", lookAhead(1).LineNr, lookAhead(1).LinePosition)); ifThenElseTree.addChild(expr); ifThenElseTree.addChild(trueChild); if (falseChild != null) { ifThenElseTree.addChild(falseChild); } return ifThenElseTree; }