aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-11-26 23:33:07 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-11-26 23:33:07 -0500
commit1fba7f36960551fe0a12aa754c2d789c8784a8cc (patch)
tree7392244fa87b45413b9b57a651088ad4d97c3b00 /src/parser.cpp
parentb3ff28189ce8f28abf077dcf343d0d95bf5645c3 (diff)
downloadzig-1fba7f36960551fe0a12aa754c2d789c8784a8cc.tar.gz
zig-1fba7f36960551fe0a12aa754c2d789c8784a8cc.zip
IR: add inline goto
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 00f8b430f2..00f05b25ec 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -584,6 +584,40 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m
}
/*
+GotoExpression = option("inline") "goto" Symbol
+*/
+static AstNode *ast_parse_goto_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
+ Token *first_token = &pc->tokens->at(*token_index);
+ Token *goto_token;
+ bool is_inline;
+ if (first_token->id == TokenIdKeywordInline) {
+ is_inline = true;
+ goto_token = &pc->tokens->at(*token_index + 1);
+ if (goto_token->id == TokenIdKeywordGoto) {
+ *token_index += 2;
+ } else if (mandatory) {
+ ast_expect_token(pc, first_token, TokenIdKeywordGoto);
+ } else {
+ return nullptr;
+ }
+ } else if (first_token->id == TokenIdKeywordGoto) {
+ goto_token = first_token;
+ is_inline = false;
+ *token_index += 1;
+ } else if (mandatory) {
+ ast_expect_token(pc, first_token, TokenIdKeywordGoto);
+ } else {
+ return nullptr;
+ }
+
+ AstNode *node = ast_create_node(pc, NodeTypeGoto, goto_token);
+
+ Token *dest_symbol = ast_eat_token(pc, token_index, TokenIdSymbol);
+ node->data.goto_expr.name = token_buf(dest_symbol);
+ node->data.goto_expr.is_inline = is_inline;
+ return node;
+}
+/*
PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
*/
@@ -672,18 +706,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
node->data.symbol_expr.symbol = token_buf(token);
return node;
- } else if (token->id == TokenIdKeywordGoto) {
- AstNode *node = ast_create_node(pc, NodeTypeGoto, token);
- *token_index += 1;
-
- Token *dest_symbol = &pc->tokens->at(*token_index);
- *token_index += 1;
- ast_expect_token(pc, dest_symbol, TokenIdSymbol);
-
- node->data.goto_expr.name = token_buf(dest_symbol);
- return node;
}
+ AstNode *goto_node = ast_parse_goto_expr(pc, token_index, false);
+ if (goto_node)
+ return goto_node;
+
AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);
if (grouped_expr_node) {
return grouped_expr_node;