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;
}