diff options
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 152 |
1 files changed, 103 insertions, 49 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 693cc6d2c0..34d7f4ae96 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -35,6 +35,16 @@ static const char *bin_op_str(BinOpType bin_op) { zig_unreachable(); } +static const char *prefix_op_str(PrefixOp prefix_op) { + switch (prefix_op) { + case PrefixOpInvalid: return "(invalid)"; + case PrefixOpNegation: return "-"; + case PrefixOpBoolNot: return "!"; + case PrefixOpBinNot: return "~"; + } + zig_unreachable(); +} + __attribute__ ((format (printf, 2, 3))) __attribute__ ((noreturn)) static void ast_error(Token *token, const char *format, ...) { @@ -70,8 +80,8 @@ const char *node_type_str(NodeType node_type) { return "Block"; case NodeTypeBinOpExpr: return "BinOpExpr"; - case NodeTypeFnCall: - return "FnCall"; + case NodeTypeFnCallExpr: + return "FnCallExpr"; case NodeTypeExternBlock: return "ExternBlock"; case NodeTypeDirective: @@ -84,6 +94,8 @@ const char *node_type_str(NodeType node_type) { return "PrimaryExpr"; case NodeTypeGroupedExpr: return "GroupedExpr"; + case NodeTypePrefixOpExpr: + return "PrefixOpExpr"; } zig_unreachable(); } @@ -188,10 +200,11 @@ void ast_print(AstNode *node, int indent) { ast_print(node->data.bin_op_expr.op1, indent + 2); ast_print(node->data.bin_op_expr.op2, indent + 2); break; - case NodeTypeFnCall: - fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.fn_call.name)); - for (int i = 0; i < node->data.fn_call.params.length; i += 1) { - AstNode *child = node->data.fn_call.params.at(i); + case NodeTypeFnCallExpr: + fprintf(stderr, "%s\n", node_type_str(node->type)); + ast_print(node->data.fn_call_expr.fn_ref_expr, indent + 2); + for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { + AstNode *child = node->data.fn_call_expr.params.at(i); ast_print(child, indent + 2); } break; @@ -200,10 +213,15 @@ void ast_print(AstNode *node, int indent) { break; case NodeTypeCastExpr: fprintf(stderr, "%s\n", node_type_str(node->type)); - ast_print(node->data.cast_expr.primary_expr, indent + 2); + ast_print(node->data.cast_expr.prefix_op_expr, indent + 2); if (node->data.cast_expr.type) ast_print(node->data.cast_expr.type, indent + 2); break; + case NodeTypePrefixOpExpr: + fprintf(stderr, "%s %s\n", node_type_str(node->type), + prefix_op_str(node->data.prefix_op_expr.prefix_op)); + ast_print(node->data.prefix_op_expr.primary_expr, indent + 2); + break; case NodeTypePrimaryExpr: switch (node->data.primary_expr.type) { case PrimaryExprTypeNumber: @@ -217,10 +235,6 @@ void ast_print(AstNode *node, int indent) { case PrimaryExprTypeUnreachable: fprintf(stderr, "PrimaryExpr Unreachable\n"); break; - case PrimaryExprTypeFnCall: - fprintf(stderr, "PrimaryExpr FnCall\n"); - ast_print(node->data.primary_expr.data.fn_call, indent + 2); - break; case PrimaryExprTypeGroupedExpr: fprintf(stderr, "PrimaryExpr GroupedExpr\n"); ast_print(node->data.primary_expr.data.grouped_expr, indent + 2); @@ -229,6 +243,10 @@ void ast_print(AstNode *node, int indent) { fprintf(stderr, "PrimaryExpr Block\n"); ast_print(node->data.primary_expr.data.block, indent + 2); break; + case PrimaryExprTypeSymbol: + fprintf(stderr, "PrimaryExpr Symbol %s\n", + buf_ptr(&node->data.primary_expr.data.symbol)); + break; } break; case NodeTypeGroupedExpr: @@ -525,32 +543,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, int *token_index, bool } /* -FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) ; -*/ -static AstNode *ast_parse_fn_call(ParseContext *pc, int *token_index, bool mandatory) { - Token *fn_name = &pc->tokens->at(*token_index); - if (fn_name->id != TokenIdSymbol) { - if (mandatory) { - ast_invalid_token_error(pc, fn_name); - } else { - return nullptr; - } - } - - *token_index += 1; - - AstNode *node = ast_create_node(NodeTypeFnCall, fn_name); - - - ast_buf_from_token(pc, fn_name, &node->data.fn_call.name); - - ast_parse_fn_call_param_list(pc, *token_index, token_index, &node->data.fn_call.params); - - return node; -} - -/* -PrimaryExpression : token(Number) | token(String) | token(Unreachable) | FnCall | GroupedExpression | Block +PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | token(Symbol) */ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); @@ -572,6 +565,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool node->data.primary_expr.type = PrimaryExprTypeUnreachable; *token_index += 1; return node; + } else if (token->id == TokenIdSymbol) { + AstNode *node = ast_create_node(NodeTypePrimaryExpr, token); + node->data.primary_expr.type = PrimaryExprTypeSymbol; + ast_buf_from_token(pc, token, &node->data.primary_expr.data.symbol); + *token_index += 1; + return node; } AstNode *block_node = ast_parse_block(pc, token_index, false); @@ -590,14 +589,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool return node; } - AstNode *fn_call_node = ast_parse_fn_call(pc, token_index, false); - if (fn_call_node) { - AstNode *node = ast_create_node(NodeTypePrimaryExpr, token); - node->data.primary_expr.type = PrimaryExprTypeFnCall; - node->data.primary_expr.data.fn_call = fn_call_node; - return node; - } - if (!mandatory) return nullptr; @@ -605,20 +596,83 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool } /* -CastExpression : PrimaryExpression token(As) Type | PrimaryExpression +FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression */ -static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) { +static AstNode *ast_parse_fn_call_expr(ParseContext *pc, int *token_index, bool mandatory) { AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); if (!primary_expr) return nullptr; + Token *l_paren = &pc->tokens->at(*token_index); + if (l_paren->id != TokenIdLParen) + return primary_expr; + + AstNode *node = ast_create_node_with_node(NodeTypeFnCallExpr, primary_expr); + node->data.fn_call_expr.fn_ref_expr = primary_expr; + ast_parse_fn_call_param_list(pc, *token_index, token_index, &node->data.fn_call_expr.params); + + return node; +} + +static PrefixOp tok_to_prefix_op(Token *token) { + switch (token->id) { + case TokenIdBang: return PrefixOpBoolNot; + case TokenIdDash: return PrefixOpNegation; + case TokenIdTilde: return PrefixOpBinNot; + default: return PrefixOpInvalid; + } +} + +/* +PrefixOp : token(Not) | token(Dash) | token(Tilde) +*/ +static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool mandatory) { + Token *token = &pc->tokens->at(*token_index); + PrefixOp result = tok_to_prefix_op(token); + if (result == PrefixOpInvalid) { + if (mandatory) { + ast_invalid_token_error(pc, token); + } else { + return PrefixOpInvalid; + } + } + *token_index += 1; + return result; +} + +/* +PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression +*/ +static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) { + Token *token = &pc->tokens->at(*token_index); + PrefixOp prefix_op = ast_parse_prefix_op(pc, token_index, false); + if (prefix_op == PrefixOpInvalid) + return ast_parse_fn_call_expr(pc, token_index, mandatory); + + AstNode *primary_expr = ast_parse_fn_call_expr(pc, token_index, true); + AstNode *node = ast_create_node(NodeTypePrefixOpExpr, token); + node->data.prefix_op_expr.primary_expr = primary_expr; + node->data.prefix_op_expr.prefix_op = prefix_op; + + return node; +} + + +/* +CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression +*/ +static AstNode *ast_parse_cast_expression(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; + Token *as_kw = &pc->tokens->at(*token_index); if (as_kw->id != TokenIdKeywordAs) - return primary_expr; + return prefix_op_expr; *token_index += 1; AstNode *node = ast_create_node(NodeTypeCastExpr, as_kw); - node->data.cast_expr.primary_expr = primary_expr; + node->data.cast_expr.prefix_op_expr = prefix_op_expr; node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index); |
