diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-01-15 17:40:12 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-01-15 17:40:12 -0700 |
| commit | 0311b35a21e9896772cb982750be680b0ef71f1f (patch) | |
| tree | 11ad9a19e13d0a4c4f6fd7853a3a0b25f2eb282b /src/parser.cpp | |
| parent | 74b1665586bafe0fcd063480b9480a77cbf93ab2 (diff) | |
| download | zig-0311b35a21e9896772cb982750be680b0ef71f1f.tar.gz zig-0311b35a21e9896772cb982750be680b0ef71f1f.zip | |
reduce precedence of {} suffix operator
this makes []u8 {1, 2, 3, 4} work for array literal
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 164 |
1 files changed, 91 insertions, 73 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 2886c5e8f7..adcbeae830 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -903,6 +903,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool mandatory); static AstNode *ast_parse_block_expr(ParseContext *pc, int *token_index, bool mandatory); static AstNode *ast_parse_unwrap_maybe_expr(ParseContext *pc, int *token_index, bool mandatory); +static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory); static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { if (token->id == token_id) { @@ -998,7 +999,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) { *token_index += 1; ast_expect_token(pc, colon, TokenIdColon); - node->data.param_decl.type = ast_parse_unwrap_maybe_expr(pc, token_index, true); + node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true); return node; } @@ -1114,7 +1115,7 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, int *token_index, bo node->data.array_type.is_const = true; } - node->data.array_type.child_type = ast_parse_unwrap_maybe_expr(pc, token_index, true); + node->data.array_type.child_type = ast_parse_prefix_op_expr(pc, token_index, true); return node; } @@ -1159,7 +1160,7 @@ static void ast_parse_asm_output_item(ParseContext *pc, int *token_index, AstNod if (token->id == TokenIdSymbol) { ast_buf_from_token(pc, token, &asm_output->variable_name); } else if (token->id == TokenIdArrow) { - asm_output->return_type = ast_parse_unwrap_maybe_expr(pc, token_index, true); + asm_output->return_type = ast_parse_prefix_op_expr(pc, token_index, true); } else { ast_invalid_token_error(pc, token); } @@ -1402,81 +1403,23 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool } /* -SuffixOpExpression : PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression | ContainerInitExpression) -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)) -FieldAccessExpression : token(Dot) token(Symbol) +CurlySuffixExpression : PrefixOpExpression option(ContainerInitExpression) ContainerInitExpression : token(LBrace) ContainerInitBody token(RBrace) ContainerInitBody : list(StructLiteralField, token(Comma)) | list(Expression, token(Comma)) -StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression */ -static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, bool mandatory) { - AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); - if (!primary_expr) { +static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index, bool mandatory) { + AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory); + if (!prefix_op_expr) { return nullptr; } while (true) { Token *first_token = &pc->tokens->at(*token_index); - if (first_token->id == TokenIdLParen) { - *token_index += 1; - - AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token); - node->data.fn_call_expr.fn_ref_expr = primary_expr; - ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params); - - primary_expr = node; - } else if (first_token->id == TokenIdLBracket) { - *token_index += 1; - - AstNode *expr_node = ast_parse_expression(pc, token_index, true); - - Token *ellipsis_or_r_bracket = &pc->tokens->at(*token_index); - - if (ellipsis_or_r_bracket->id == TokenIdEllipsis) { - *token_index += 1; - - AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token); - node->data.slice_expr.array_ref_expr = primary_expr; - node->data.slice_expr.start = expr_node; - node->data.slice_expr.end = ast_parse_expression(pc, token_index, false); - - ast_eat_token(pc, token_index, TokenIdRBracket); - - Token *const_tok = &pc->tokens->at(*token_index); - if (const_tok->id == TokenIdKeywordConst) { - *token_index += 1; - node->data.slice_expr.is_const = true; - } - - primary_expr = node; - } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) { - *token_index += 1; - - AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token); - node->data.array_access_expr.array_ref_expr = primary_expr; - node->data.array_access_expr.subscript = expr_node; - - primary_expr = node; - } else { - ast_invalid_token_error(pc, first_token); - } - } else if (first_token->id == TokenIdDot) { - *token_index += 1; - - Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol); - - AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token); - node->data.field_access_expr.struct_expr = primary_expr; - ast_buf_from_token(pc, name_token, &node->data.field_access_expr.field_name); - - primary_expr = node; - } else if (first_token->id == TokenIdLBrace) { + if (first_token->id == TokenIdLBrace) { *token_index += 1; AstNode *node = ast_create_node(pc, NodeTypeContainerInitExpr, first_token); - node->data.container_init_expr.type = primary_expr; + node->data.container_init_expr.type = prefix_op_expr; Token *token = &pc->tokens->at(*token_index); if (token->id == TokenIdDot) { @@ -1536,6 +1479,81 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo } } + prefix_op_expr = node; + } else { + return prefix_op_expr; + } + } +} + +/* +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)) +FieldAccessExpression : token(Dot) token(Symbol) +StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression +*/ +static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, bool mandatory) { + AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); + if (!primary_expr) { + return nullptr; + } + + while (true) { + Token *first_token = &pc->tokens->at(*token_index); + if (first_token->id == TokenIdLParen) { + *token_index += 1; + + AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token); + node->data.fn_call_expr.fn_ref_expr = primary_expr; + ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params); + + primary_expr = node; + } else if (first_token->id == TokenIdLBracket) { + *token_index += 1; + + AstNode *expr_node = ast_parse_expression(pc, token_index, true); + + Token *ellipsis_or_r_bracket = &pc->tokens->at(*token_index); + + if (ellipsis_or_r_bracket->id == TokenIdEllipsis) { + *token_index += 1; + + AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token); + node->data.slice_expr.array_ref_expr = primary_expr; + node->data.slice_expr.start = expr_node; + node->data.slice_expr.end = ast_parse_expression(pc, token_index, false); + + ast_eat_token(pc, token_index, TokenIdRBracket); + + Token *const_tok = &pc->tokens->at(*token_index); + if (const_tok->id == TokenIdKeywordConst) { + *token_index += 1; + node->data.slice_expr.is_const = true; + } + + primary_expr = node; + } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) { + *token_index += 1; + + AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token); + node->data.array_access_expr.array_ref_expr = primary_expr; + node->data.array_access_expr.subscript = expr_node; + + primary_expr = node; + } else { + ast_invalid_token_error(pc, first_token); + } + } else if (first_token->id == TokenIdDot) { + *token_index += 1; + + Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol); + + AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token); + node->data.field_access_expr.struct_expr = primary_expr; + ast_buf_from_token(pc, name_token, &node->data.field_access_expr.field_name); + primary_expr = node; } else { return primary_expr; @@ -1623,10 +1641,10 @@ static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mand } /* -MultiplyExpression : PrefixOpExpression MultiplyOperator MultiplyExpression | PrefixOpExpression +MultiplyExpression : CurlySuffixExpression MultiplyOperator MultiplyExpression | CurlySuffixExpression */ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool mandatory) { - AstNode *operand_1 = ast_parse_prefix_op_expr(pc, token_index, mandatory); + AstNode *operand_1 = ast_parse_curly_suffix_expr(pc, token_index, mandatory); if (!operand_1) return nullptr; @@ -1636,7 +1654,7 @@ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool man if (mult_op == BinOpTypeInvalid) return operand_1; - AstNode *operand_2 = ast_parse_prefix_op_expr(pc, token_index, true); + AstNode *operand_2 = ast_parse_curly_suffix_expr(pc, token_index, true); AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token); node->data.bin_op_expr.op1 = operand_1; @@ -1948,7 +1966,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda node->data.if_var_expr.var_decl.expr = ast_parse_expression(pc, token_index, true); } else if (eq_or_colon->id == TokenIdColon) { *token_index += 1; - node->data.if_var_expr.var_decl.type = ast_parse_unwrap_maybe_expr(pc, token_index, true); + node->data.if_var_expr.var_decl.type = ast_parse_prefix_op_expr(pc, token_index, true); ast_eat_token(pc, token_index, TokenIdMaybeAssign); node->data.if_var_expr.var_decl.expr = ast_parse_expression(pc, token_index, true); @@ -2028,7 +2046,7 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true); return node; } else if (eq_or_colon->id == TokenIdColon) { - node->data.variable_declaration.type = ast_parse_unwrap_maybe_expr(pc, token_index, true); + node->data.variable_declaration.type = ast_parse_prefix_op_expr(pc, token_index, true); Token *eq_token = &pc->tokens->at(*token_index); if (eq_token->id == TokenIdEq) { *token_index += 1; @@ -2394,7 +2412,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args); Token *next_token = &pc->tokens->at(*token_index); - node->data.fn_proto.return_type = ast_parse_unwrap_maybe_expr(pc, token_index, false); + node->data.fn_proto.return_type = ast_parse_prefix_op_expr(pc, token_index, false); if (!node->data.fn_proto.return_type) { node->data.fn_proto.return_type = ast_create_void_type_node(pc, next_token); } |
