diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-01-22 22:59:52 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-01-22 22:59:52 -0500 |
| commit | 201a3c121a5c28273138b1160c5aac4e24d619bd (patch) | |
| tree | 68480040ae3c4cedce7d8bf953cd69359b6749f1 /src/parser.cpp | |
| parent | 47cf8520adb245dbd34ad60fc9206b7eaab5e0be (diff) | |
| download | zig-201a3c121a5c28273138b1160c5aac4e24d619bd.tar.gz zig-201a3c121a5c28273138b1160c5aac4e24d619bd.zip | |
introduce comptime expression
closes #221
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 73 |
1 files changed, 34 insertions, 39 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 569a23d130..dbb6836e60 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -585,29 +585,14 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m } /* -GotoExpression = option("inline") "goto" Symbol +GotoExpression = "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); - zig_unreachable(); - } else { - return nullptr; - } - } else if (first_token->id == TokenIdKeywordGoto) { - goto_token = first_token; - is_inline = false; + Token *goto_token = &pc->tokens->at(*token_index); + if (goto_token->id == TokenIdKeywordGoto) { *token_index += 1; } else if (mandatory) { - ast_expect_token(pc, first_token, TokenIdKeywordGoto); + ast_expect_token(pc, goto_token, TokenIdKeywordGoto); zig_unreachable(); } else { return nullptr; @@ -617,11 +602,30 @@ static AstNode *ast_parse_goto_expr(ParseContext *pc, size_t *token_index, bool 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 | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl +CompTimeExpression = "comptime" Expression +*/ +static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, bool mandatory) { + Token *comptime_token = &pc->tokens->at(*token_index); + if (comptime_token->id == TokenIdKeywordCompTime) { + *token_index += 1; + } else if (mandatory) { + ast_expect_token(pc, comptime_token, TokenIdKeywordCompTime); + zig_unreachable(); + } else { + return nullptr; + } + + AstNode *node = ast_create_node(pc, NodeTypeCompTime, comptime_token); + node->data.comptime_expr.expr = ast_parse_expression(pc, token_index, true); + return node; +} + +/* +PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | CompTimeExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" */ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) { @@ -706,6 +710,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo if (goto_node) return goto_node; + AstNode *comptime_node = ast_parse_comptime_expr(pc, token_index, false); + if (comptime_node) + return comptime_node; + AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false); if (grouped_expr_node) { return grouped_expr_node; @@ -835,7 +843,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde } /* -SuffixOpExpression = option("inline") PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) +SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen) ArrayAccessExpression : token(LBracket) Expression token(RBracket) SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression) token(RBracket) option(token(Const)) @@ -843,24 +851,9 @@ FieldAccessExpression : token(Dot) token(Symbol) StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression */ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { - Token *inline_token = &pc->tokens->at(*token_index); - bool is_comptime; - if (inline_token->id == TokenIdKeywordInline) { - // TODO make it an error if something other than function call has the comptime keyword - is_comptime = true; - *token_index += 1; - } else { - is_comptime = false; - } - - AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); - if (!primary_expr) { - if (is_comptime) { - *token_index -= 1; - } + if (!primary_expr) return nullptr; - } while (true) { Token *first_token = &pc->tokens->at(*token_index); @@ -869,7 +862,6 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token); node->data.fn_call_expr.fn_ref_expr = primary_expr; - node->data.fn_call_expr.is_comptime = is_comptime; ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params); primary_expr = node; @@ -2624,6 +2616,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont case NodeTypeGoto: // none break; + case NodeTypeCompTime: + visit_field(&node->data.comptime_expr.expr, visit, context); + break; case NodeTypeBreak: // none break; |
