Control structures
This commit is contained in:
@@ -74,6 +74,19 @@ public interface JetNodeTypes {
|
||||
JetNodeType THROW = new JetNodeType("THROW");
|
||||
JetNodeType CONTINUE = new JetNodeType("CONTINUE");
|
||||
JetNodeType BREAK = new JetNodeType("BREAK");
|
||||
JetNodeType IF = new JetNodeType("IF");
|
||||
JetNodeType CONDITION = new JetNodeType("CONDITION");
|
||||
JetNodeType THEN = new JetNodeType("THEN");
|
||||
JetNodeType ELSE = new JetNodeType("ELSE");
|
||||
JetNodeType TRY = new JetNodeType("TRY");
|
||||
JetNodeType CATCH = new JetNodeType("CATCH");
|
||||
JetNodeType FINALLY = new JetNodeType("FINALLY");
|
||||
JetNodeType FOR = new JetNodeType("FOR");
|
||||
JetNodeType WHILE = new JetNodeType("WHILE");
|
||||
JetNodeType DO_WHILE = new JetNodeType("DO_WHILE");
|
||||
JetNodeType LOOP_PARAMETER = new JetNodeType("LOOP_PARAMETER");
|
||||
JetNodeType LOOP_RANGE = new JetNodeType("LOOP_RANGE");
|
||||
JetNodeType BODY = new JetNodeType("BODY");
|
||||
|
||||
IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME");
|
||||
}
|
||||
|
||||
@@ -42,6 +42,17 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean expectNoAdvance(JetToken expectation, String message) {
|
||||
if (at(expectation)) {
|
||||
advance(); // expectation
|
||||
return true;
|
||||
}
|
||||
|
||||
error(message);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void errorWithRecovery(String message, TokenSet recoverySet) {
|
||||
IElementType tt = tt();
|
||||
if (recoverySet == null || recoverySet.contains(tt)
|
||||
|
||||
@@ -74,19 +74,19 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
parseJump(BREAK);
|
||||
}
|
||||
else if (at(IF_KEYWORD)) {
|
||||
// TODO
|
||||
parseIf();
|
||||
}
|
||||
else if (at(TRY_KEYWORD)) {
|
||||
// TODO
|
||||
parseTry();
|
||||
}
|
||||
else if (at(FOR_KEYWORD)) {
|
||||
// TODO
|
||||
parseFor();
|
||||
}
|
||||
else if (at(WHILE_KEYWORD)) {
|
||||
// TODO
|
||||
parseWhile();
|
||||
}
|
||||
else if (at(DO_KEYWORD)) {
|
||||
// TODO
|
||||
parseDoWhile();
|
||||
}
|
||||
else if (atSet(TokenSet.create(
|
||||
CLASS_KEYWORD,
|
||||
@@ -100,6 +100,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
else if (at(IDENTIFIER)) {
|
||||
advance(); // TODO
|
||||
}
|
||||
else if (at(LBRACE)) {
|
||||
// TODO
|
||||
myJetParsing.parseBlock();
|
||||
}
|
||||
else if (at(INTEGER_LITERAL)) {
|
||||
parseOneTokenExpression(INTEGER_CONSTANT);
|
||||
}
|
||||
@@ -124,6 +128,183 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
else if (at(NULL_KEYWORD)) {
|
||||
parseOneTokenExpression(NULL);
|
||||
}
|
||||
else {
|
||||
errorAndAdvance("Expecting an expression");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* doWhile
|
||||
* : "do" expression "while" "(" expression ")"
|
||||
* ;
|
||||
*/
|
||||
private void parseDoWhile() {
|
||||
assert at(DO_KEYWORD);
|
||||
|
||||
PsiBuilder.Marker loop = mark();
|
||||
|
||||
advance(); // DO_KEYWORD
|
||||
|
||||
parseControlStructureBody();
|
||||
|
||||
expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition");
|
||||
|
||||
parseCondition();
|
||||
|
||||
loop.done(DO_WHILE);
|
||||
}
|
||||
|
||||
/*
|
||||
* while
|
||||
* : "while" "(" expression ")" expression
|
||||
* ;
|
||||
*/
|
||||
private void parseWhile() {
|
||||
assert at(WHILE_KEYWORD);
|
||||
|
||||
PsiBuilder.Marker loop = mark();
|
||||
|
||||
advance(); // WHILE_KEYWORD
|
||||
|
||||
parseCondition();
|
||||
|
||||
parseControlStructureBody();
|
||||
|
||||
loop.done(WHILE);
|
||||
}
|
||||
|
||||
/*
|
||||
* for
|
||||
* : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
|
||||
* ;
|
||||
*/
|
||||
private void parseFor() {
|
||||
assert at(FOR_KEYWORD);
|
||||
|
||||
PsiBuilder.Marker loop = mark();
|
||||
|
||||
advance(); // FOR_KEYWORD
|
||||
|
||||
expect(LPAR, "Expecting '(' to open a loop range", TokenSet.create(RPAR, VAL_KEYWORD, VAR_KEYWORD, IDENTIFIER));
|
||||
|
||||
PsiBuilder.Marker parameter = mark();
|
||||
if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD
|
||||
expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON));
|
||||
if (at(COLON)) {
|
||||
advance(); // COLON
|
||||
myJetParsing.parseTypeRef();
|
||||
}
|
||||
parameter.done(LOOP_PARAMETER);
|
||||
|
||||
expect(IN_KEYWORD, "Expecting 'in'");
|
||||
|
||||
PsiBuilder.Marker range = mark();
|
||||
parseExpression();
|
||||
range.done(LOOP_RANGE);
|
||||
|
||||
expectNoAdvance(RPAR, "Expecting ')'");
|
||||
|
||||
parseControlStructureBody();
|
||||
|
||||
loop.done(FOR);
|
||||
}
|
||||
|
||||
/*
|
||||
* expression
|
||||
*/
|
||||
private void parseControlStructureBody() {
|
||||
PsiBuilder.Marker body = mark();
|
||||
parseExpression();
|
||||
body.done(BODY);
|
||||
|
||||
// TODO: empty body?
|
||||
}
|
||||
|
||||
/*
|
||||
* try
|
||||
* : "try" block catchBlock* finallyBlock?
|
||||
* ;
|
||||
* catchBlock
|
||||
* : "catch" "(" attributes SimpleName ":" userType ")" block
|
||||
* ;
|
||||
*
|
||||
* finallyBlock
|
||||
* : "finally" block
|
||||
* ;
|
||||
*/
|
||||
private void parseTry() {
|
||||
assert at(TRY_KEYWORD);
|
||||
|
||||
PsiBuilder.Marker tryExpression = mark();
|
||||
|
||||
advance(); // TRY_KEYWORD
|
||||
|
||||
myJetParsing.parseBlock();
|
||||
|
||||
while (at(CATCH_KEYWORD)) {
|
||||
PsiBuilder.Marker catchBlock = mark();
|
||||
advance(); // CATCH_KEYWORD
|
||||
|
||||
myJetParsing.parseValueParameterList(false, TokenSet.create(LBRACE, FINALLY_KEYWORD, CATCH_KEYWORD));
|
||||
|
||||
myJetParsing.parseBlock();
|
||||
catchBlock.done(CATCH);
|
||||
}
|
||||
|
||||
if (at(FINALLY_KEYWORD)) {
|
||||
PsiBuilder.Marker finallyBlock = mark();
|
||||
|
||||
advance(); // FINALLY_KEYWORD
|
||||
|
||||
myJetParsing.parseBlock();
|
||||
|
||||
finallyBlock.done(FINALLY);
|
||||
}
|
||||
|
||||
tryExpression.done(TRY);
|
||||
}
|
||||
|
||||
/*
|
||||
* if
|
||||
* : "if" "(" expression ")" expression ("else" expression)?
|
||||
* ;
|
||||
*/
|
||||
private void parseIf() {
|
||||
assert at(IF_KEYWORD);
|
||||
|
||||
PsiBuilder.Marker marker = mark();
|
||||
|
||||
advance(); //IF_KEYWORD
|
||||
|
||||
parseCondition();
|
||||
|
||||
// TODO: empty body?
|
||||
PsiBuilder.Marker thenBranch = mark();
|
||||
parseExpression();
|
||||
thenBranch.done(THEN);
|
||||
|
||||
if (at(ELSE_KEYWORD)) {
|
||||
advance(); // ELSE_KEYWORD
|
||||
|
||||
PsiBuilder.Marker elseBranch = mark();
|
||||
parseExpression();
|
||||
elseBranch.done(ELSE);
|
||||
}
|
||||
|
||||
marker.done(IF);
|
||||
}
|
||||
|
||||
/*
|
||||
* "(" expression ")"
|
||||
*/
|
||||
private void parseCondition() {
|
||||
expect(LPAR, "Expecting a condition in parentheses '(...)'");
|
||||
|
||||
PsiBuilder.Marker condition = mark();
|
||||
parseExpression();
|
||||
condition.done(CONDITION);
|
||||
|
||||
expect(RPAR, "Expecting ')");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -232,7 +413,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
advance(); // LBRACKET
|
||||
|
||||
// If this is an emty map "[:]"
|
||||
// If this is an empty map "[:]"
|
||||
if (at(COLON)) {
|
||||
advance(); // COLON
|
||||
expect(RBRACKET, "Expecting ']' to close an empty map literal '[:]'");
|
||||
@@ -240,6 +421,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is an empty list "[]"
|
||||
if (at(RBRACKET)) {
|
||||
advance(); // RBRACKET
|
||||
literal.done(LIST_LITERAL);
|
||||
return;
|
||||
}
|
||||
|
||||
PsiBuilder.Marker item = mark();
|
||||
parseExpression();
|
||||
|
||||
|
||||
@@ -857,12 +857,10 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* : "{" (expression SEMI)* "}"
|
||||
* ;
|
||||
*/
|
||||
private void parseBlock() {
|
||||
assert at(LBRACE);
|
||||
|
||||
public void parseBlock() {
|
||||
PsiBuilder.Marker block = mark();
|
||||
|
||||
advance(); // LBRACE
|
||||
expect(LBRACE, "Expecting '{' to open a block");
|
||||
|
||||
while (!eof() && !at(RBRACE)) {
|
||||
myExpressionParsing.parseExpression();
|
||||
@@ -1300,7 +1298,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* : parameter ("=" expression)?
|
||||
* ;
|
||||
*/
|
||||
private void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
|
||||
public void parseValueParameterList(boolean isFunctionTypeContents, TokenSet recoverySet) {
|
||||
PsiBuilder.Marker parameters = mark();
|
||||
expect(LPAR, "Expecting '(", recoverySet);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user