Added for loops to the expression parser, java style.

Also:
- Added a test case for for
- Fixed Identifiable.id() for the runtime Nodes and added missing elements to the list in Identifiable.java.
- Factored keyword and character consumption into a common function.
This commit is contained in:
TomyLobo
2011-11-22 16:08:15 +01:00
parent f217be0bdf
commit effbf9f79c
7 changed files with 114 additions and 32 deletions

View File

@ -32,6 +32,7 @@ import com.sk89q.worldedit.expression.lexer.tokens.OperatorToken;
import com.sk89q.worldedit.expression.lexer.tokens.Token;
import com.sk89q.worldedit.expression.runtime.Conditional;
import com.sk89q.worldedit.expression.runtime.Constant;
import com.sk89q.worldedit.expression.runtime.For;
import com.sk89q.worldedit.expression.runtime.Functions;
import com.sk89q.worldedit.expression.runtime.RValue;
import com.sk89q.worldedit.expression.runtime.Sequence;
@ -119,8 +120,7 @@ public class Parser {
final RValue truePart = parseStatements(true);
final RValue falsePart;
final Token next = peek();
if ((next instanceof KeywordToken) && ((KeywordToken) next).value.equals("else")) {
if (hasKeyword("else")) {
++position;
falsePart = parseStatements(true);
} else {
@ -144,17 +144,29 @@ public class Parser {
++position;
final RValue body = parseStatements(true);
final Token next = peek();
if (!(next instanceof KeywordToken) || !((KeywordToken) next).value.equals("while")) {
throw new ParserException(current.getPosition(), "Expected while");
}
++position;
consumeKeyword("while");
final RValue condition = parseBracket();
statements.add(new While(current.getPosition(), condition, body, true));
break;
}
case 'f': { // for
++position;
consumeCharacter('(');
final RValue init = parseExpression();
consumeCharacter(';');
final RValue condition = parseExpression();
consumeCharacter(';');
final RValue increment = parseExpression();
consumeCharacter(')');
final RValue body = parseStatements(true);
statements.add(new For(current.getPosition(), init, condition, increment, body));
break;
}
default:
throw new ParserException(current.getPosition(), "Unimplemented keyword '" + keyword + "'");
}
@ -272,10 +284,7 @@ public class Parser {
}
private Identifiable parseFunctionCall(IdentifierToken identifierToken) throws ParserException {
if (peek().id() != '(') {
throw new ParserException(peek().getPosition(), "Unexpected character in parseFunctionCall");
}
++position;
consumeCharacter('(');
try {
if (peek().id() == ')') {
@ -309,26 +318,17 @@ public class Parser {
}
private final RValue parseBracket() throws ParserException {
if (peek().id() != '(') {
throw new ParserException(peek().getPosition(), "Unexpected character in parseBracket");
}
++position;
consumeCharacter('(');
final RValue ret = parseExpression();
if (peek().id() != ')') {
throw new ParserException(peek().getPosition(), "Unmatched opening bracket");
}
++position;
consumeCharacter(')');
return ret;
}
private final RValue parseBlock() throws ParserException {
if (peek().id() != '{') {
throw new ParserException(peek().getPosition(), "Unexpected character in parseBlock");
}
++position;
consumeCharacter('{');
if (peek().id() == '}') {
return new Sequence(peek().getPosition());
@ -336,11 +336,39 @@ public class Parser {
final RValue ret = parseStatements(false);
if (peek().id() != '}') {
throw new ParserException(peek().getPosition(), "Unmatched opening brace");
}
++position;
consumeCharacter('}');
return ret;
}
private boolean hasKeyword(String keyword) {
final Token next = peek();
if (!(next instanceof KeywordToken)) {
return false;
}
return ((KeywordToken) next).value.equals(keyword);
}
private void assertCharacter(char character) throws ParserException {
final Token next = peek();
if (next.id() != character) {
throw new ParserException(next.getPosition(), "Expected '" + character + "'");
}
}
private void assertKeyword(String keyword) throws ParserException {
if (!hasKeyword(keyword)) {
throw new ParserException(peek().getPosition(), "Expected '" + keyword + "'");
}
}
private void consumeCharacter(char character) throws ParserException {
assertCharacter(character);
++position;
}
private void consumeKeyword(String keyword) throws ParserException {
assertKeyword(keyword);
++position;
}
}