aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-05-03 18:12:07 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-05-03 18:12:07 -0400
commit698829b772fe39c4311a75b20324256b8d7392b1 (patch)
treec1434e819ef38698a79a711c164ca62d9418a9c7 /src/parser.cpp
parent644ea2dde9fbb1f948cf12115df2a15e908f3c29 (diff)
downloadzig-698829b772fe39c4311a75b20324256b8d7392b1.tar.gz
zig-698829b772fe39c4311a75b20324256b8d7392b1.zip
change while syntax
Old: ``` while (condition; expression) {} ``` New: ``` while (condition) : (expression) {} ``` This is in preparation to allow nullable and error union types as the condition. See #357
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp46
1 files changed, 37 insertions, 9 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 3898ddbb81..a8c26f3c0e 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1580,7 +1580,7 @@ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, size_t *token_index, bo
}
/*
-WhileExpression(body) = option("inline") "while" "(" Expression option(";" Expression) ")" body
+WhileExpression(body) = option("inline") "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body))
*/
static AstNode *ast_parse_while_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *first_token = &pc->tokens->at(*token_index);
@@ -1613,21 +1613,49 @@ static AstNode *ast_parse_while_expr(ParseContext *pc, size_t *token_index, bool
ast_eat_token(pc, token_index, TokenIdLParen);
node->data.while_expr.condition = ast_parse_expression(pc, token_index, true);
+ ast_eat_token(pc, token_index, TokenIdRParen);
- Token *semi_or_rparen = &pc->tokens->at(*token_index);
-
- if (semi_or_rparen->id == TokenIdRParen) {
+ Token *open_bar_tok = &pc->tokens->at(*token_index);
+ if (open_bar_tok->id == TokenIdBinOr) {
*token_index += 1;
- node->data.while_expr.body = ast_parse_block_or_expression(pc, token_index, true);
- } else if (semi_or_rparen->id == TokenIdSemicolon) {
+
+ Token *star_tok = &pc->tokens->at(*token_index);
+ if (star_tok->id == TokenIdStar) {
+ *token_index += 1;
+ node->data.while_expr.var_is_ptr = true;
+ }
+
+ Token *var_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
+ node->data.while_expr.var_symbol = token_buf(var_name_tok);
+ ast_eat_token(pc, token_index, TokenIdBinOr);
+ }
+
+ Token *colon_tok = &pc->tokens->at(*token_index);
+ if (colon_tok->id == TokenIdColon) {
*token_index += 1;
+ ast_eat_token(pc, token_index, TokenIdLParen);
node->data.while_expr.continue_expr = ast_parse_expression(pc, token_index, true);
ast_eat_token(pc, token_index, TokenIdRParen);
- node->data.while_expr.body = ast_parse_block_or_expression(pc, token_index, true);
- } else {
- ast_invalid_token_error(pc, semi_or_rparen);
}
+ node->data.while_expr.body = ast_parse_block_or_expression(pc, token_index, true);
+
+ Token *else_tok = &pc->tokens->at(*token_index);
+ if (else_tok->id == TokenIdKeywordElse) {
+ *token_index += 1;
+
+ Token *else_bar_tok = &pc->tokens->at(*token_index);
+ if (else_bar_tok->id == TokenIdBinOr) {
+ *token_index += 1;
+
+ Token *err_name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
+ node->data.while_expr.err_symbol = token_buf(err_name_tok);
+
+ ast_eat_token(pc, token_index, TokenIdBinOr);
+ }
+
+ node->data.while_expr.body = ast_parse_block_or_expression(pc, token_index, true);
+ }
return node;
}