diff options
| author | Josh Wolfe <thejoshwolfe@gmail.com> | 2015-11-29 14:46:05 -0700 |
|---|---|---|
| committer | Josh Wolfe <thejoshwolfe@gmail.com> | 2015-11-29 14:46:05 -0700 |
| commit | 9a014b52ccc22d7ec24804f90993cfe08e3d20c4 (patch) | |
| tree | e7e90f22ed9ad940cb3c22b6d02d70bcb2b7dd96 /src/parser.cpp | |
| parent | 4466a4533c0f1ba33143bfead7ba99910d331531 (diff) | |
| download | zig-9a014b52ccc22d7ec24804f90993cfe08e3d20c4.tar.gz zig-9a014b52ccc22d7ec24804f90993cfe08e3d20c4.zip | |
flatten expression ast to hide operator precedence
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 297 |
1 files changed, 109 insertions, 188 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 07ade572f0..693cc6d2c0 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -10,43 +10,27 @@ #include <stdarg.h> #include <stdio.h> -static const char *mult_op_str(MultOp mult_op) { - switch (mult_op) { - case MultOpInvalid: return "(invalid)"; - case MultOpMult: return "*"; - case MultOpDiv: return "/"; - case MultOpMod: return "%"; - } - zig_unreachable(); -} - -static const char *add_op_str(AddOp add_op) { - switch (add_op) { - case AddOpInvalid: return "(invalid)"; - case AddOpAdd: return "+"; - case AddOpSub: return "-"; - } - zig_unreachable(); -} - -static const char *bit_shift_op_str(BitShiftOp bit_shift_op) { - switch (bit_shift_op) { - case BitShiftOpInvalid: return "(invalid)"; - case BitShiftOpLeft: return "<<"; - case BitShiftOpRight: return ">>"; - } - zig_unreachable(); -} - -static const char *cmp_op_str(CmpOp cmp_op) { - switch (cmp_op) { - case CmpOpInvalid: return "(invalid)"; - case CmpOpEq: return "="; - case CmpOpNotEq: return "!="; - case CmpOpLessThan: return "<"; - case CmpOpGreaterThan: return ">"; - case CmpOpLessOrEq: return "<="; - case CmpOpGreaterOrEq: return ">="; +static const char *bin_op_str(BinOpType bin_op) { + switch (bin_op) { + case BinOpTypeInvalid: return "(invalid)"; + case BinOpTypeBoolOr: return "||"; + case BinOpTypeBoolAnd: return "&&"; + case BinOpTypeCmpEq: return "=="; + case BinOpTypeCmpNotEq: return "!="; + case BinOpTypeCmpLessThan: return "<"; + case BinOpTypeCmpGreaterThan: return ">"; + case BinOpTypeCmpLessOrEq: return "<="; + case BinOpTypeCmpGreaterOrEq: return ">="; + case BinOpTypeBinOr: return "|"; + case BinOpTypeBinXor: return "^"; + case BinOpTypeBinAnd: return "&"; + case BinOpTypeBitShiftLeft: return "<<"; + case BinOpTypeBitShiftRight: return ">>"; + case BinOpTypeAdd: return "+"; + case BinOpTypeSub: return "-"; + case BinOpTypeMult: return "*"; + case BinOpTypeDiv: return "/"; + case BinOpTypeMod: return "%"; } zig_unreachable(); } @@ -84,8 +68,8 @@ const char *node_type_str(NodeType node_type) { return "Type"; case NodeTypeBlock: return "Block"; - case NodeTypeBoolOrExpr: - return "BoolOrExpr"; + case NodeTypeBinOpExpr: + return "BinOpExpr"; case NodeTypeFnCall: return "FnCall"; case NodeTypeExternBlock: @@ -94,22 +78,6 @@ const char *node_type_str(NodeType node_type) { return "Directive"; case NodeTypeReturnExpr: return "ReturnExpr"; - case NodeTypeBoolAndExpr: - return "BoolAndExpr"; - case NodeTypeComparisonExpr: - return "ComparisonExpr"; - case NodeTypeBinOrExpr: - return "BinOrExpr"; - case NodeTypeBinXorExpr: - return "BinXorExpr"; - case NodeTypeBinAndExpr: - return "BinAndExpr"; - case NodeTypeBitShiftExpr: - return "BitShiftExpr"; - case NodeTypeAddExpr: - return "AddExpr"; - case NodeTypeMultExpr: - return "MultExpr"; case NodeTypeCastExpr: return "CastExpr"; case NodeTypePrimaryExpr: @@ -214,11 +182,11 @@ void ast_print(AstNode *node, int indent) { fprintf(stderr, "%s\n", node_type_str(node->type)); ast_print(node->data.fn_decl.fn_proto, indent + 2); break; - case NodeTypeBoolOrExpr: - fprintf(stderr, "%s\n", node_type_str(node->type)); - ast_print(node->data.bool_or_expr.op1, indent + 2); - if (node->data.bool_or_expr.op2) - ast_print(node->data.bool_or_expr.op2, indent + 2); + case NodeTypeBinOpExpr: + fprintf(stderr, "%s %s\n", node_type_str(node->type), + bin_op_str(node->data.bin_op_expr.bin_op)); + 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)); @@ -230,58 +198,6 @@ void ast_print(AstNode *node, int indent) { case NodeTypeDirective: fprintf(stderr, "%s\n", node_type_str(node->type)); break; - case NodeTypeBoolAndExpr: - fprintf(stderr, "%s\n", node_type_str(node->type)); - ast_print(node->data.bool_and_expr.op1, indent + 2); - if (node->data.bool_and_expr.op2) - ast_print(node->data.bool_and_expr.op2, indent + 2); - break; - case NodeTypeComparisonExpr: - fprintf(stderr, "%s %s\n", node_type_str(node->type), - cmp_op_str(node->data.comparison_expr.cmp_op)); - ast_print(node->data.comparison_expr.op1, indent + 2); - if (node->data.comparison_expr.op2) - ast_print(node->data.comparison_expr.op2, indent + 2); - break; - case NodeTypeBinOrExpr: - fprintf(stderr, "%s\n", node_type_str(node->type)); - ast_print(node->data.bin_or_expr.op1, indent + 2); - if (node->data.bin_or_expr.op2) - ast_print(node->data.bin_or_expr.op2, indent + 2); - break; - case NodeTypeBinXorExpr: - fprintf(stderr, "%s\n", node_type_str(node->type)); - ast_print(node->data.bin_xor_expr.op1, indent + 2); - if (node->data.bin_xor_expr.op2) - ast_print(node->data.bin_xor_expr.op2, indent + 2); - break; - case NodeTypeBinAndExpr: - fprintf(stderr, "%s\n", node_type_str(node->type)); - ast_print(node->data.bin_and_expr.op1, indent + 2); - if (node->data.bin_and_expr.op2) - ast_print(node->data.bin_and_expr.op2, indent + 2); - break; - case NodeTypeBitShiftExpr: - fprintf(stderr, "%s %s\n", node_type_str(node->type), - bit_shift_op_str(node->data.bit_shift_expr.bit_shift_op)); - ast_print(node->data.bit_shift_expr.op1, indent + 2); - if (node->data.bit_shift_expr.op2) - ast_print(node->data.bit_shift_expr.op2, indent + 2); - break; - case NodeTypeAddExpr: - fprintf(stderr, "%s %s\n", node_type_str(node->type), - add_op_str(node->data.add_expr.add_op)); - ast_print(node->data.add_expr.op1, indent + 2); - if (node->data.add_expr.op2) - ast_print(node->data.add_expr.op2, indent + 2); - break; - case NodeTypeMultExpr: - fprintf(stderr, "%s %s\n", node_type_str(node->type), - mult_op_str(node->data.mult_expr.mult_op)); - ast_print(node->data.mult_expr.op1, indent + 2); - if (node->data.mult_expr.op2) - ast_print(node->data.mult_expr.op2, indent + 2); - break; case NodeTypeCastExpr: fprintf(stderr, "%s\n", node_type_str(node->type)); ast_print(node->data.cast_expr.primary_expr, indent + 2); @@ -709,26 +625,26 @@ static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bo return node; } -static MultOp tok_to_mult_op(Token *token) { +static BinOpType tok_to_mult_op(Token *token) { switch (token->id) { - case TokenIdStar: return MultOpMult; - case TokenIdSlash: return MultOpDiv; - case TokenIdPercent: return MultOpMod; - default: return MultOpInvalid; + case TokenIdStar: return BinOpTypeMult; + case TokenIdSlash: return BinOpTypeDiv; + case TokenIdPercent: return BinOpTypeMod; + default: return BinOpTypeInvalid; } } /* MultiplyOperator : token(Star) | token(Slash) | token(Percent) */ -static MultOp ast_parse_mult_op(ParseContext *pc, int *token_index, bool mandatory) { +static BinOpType ast_parse_mult_op(ParseContext *pc, int *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); - MultOp result = tok_to_mult_op(token); - if (result == MultOpInvalid) { + BinOpType result = tok_to_mult_op(token); + if (result == BinOpTypeInvalid) { if (mandatory) { ast_invalid_token_error(pc, token); } else { - return MultOpInvalid; + return BinOpTypeInvalid; } } *token_index += 1; @@ -744,39 +660,39 @@ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool man return nullptr; Token *token = &pc->tokens->at(*token_index); - MultOp mult_op = ast_parse_mult_op(pc, token_index, false); - if (mult_op == MultOpInvalid) + BinOpType mult_op = ast_parse_mult_op(pc, token_index, false); + if (mult_op == BinOpTypeInvalid) return operand_1; AstNode *operand_2 = ast_parse_cast_expression(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeMultExpr, token); - node->data.mult_expr.op1 = operand_1; - node->data.mult_expr.mult_op = mult_op; - node->data.mult_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = mult_op; + node->data.bin_op_expr.op2 = operand_2; return node; } -static AddOp tok_to_add_op(Token *token) { +static BinOpType tok_to_add_op(Token *token) { switch (token->id) { - case TokenIdPlus: return AddOpAdd; - case TokenIdDash: return AddOpSub; - default: return AddOpInvalid; + case TokenIdPlus: return BinOpTypeAdd; + case TokenIdDash: return BinOpTypeSub; + default: return BinOpTypeInvalid; } } /* AdditionOperator : token(Plus) | token(Minus) */ -static AddOp ast_parse_add_op(ParseContext *pc, int *token_index, bool mandatory) { +static BinOpType ast_parse_add_op(ParseContext *pc, int *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); - AddOp result = tok_to_add_op(token); - if (result == AddOpInvalid) { + BinOpType result = tok_to_add_op(token); + if (result == BinOpTypeInvalid) { if (mandatory) { ast_invalid_token_error(pc, token); } else { - return AddOpInvalid; + return BinOpTypeInvalid; } } *token_index += 1; @@ -792,39 +708,39 @@ static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mand return nullptr; Token *token = &pc->tokens->at(*token_index); - AddOp add_op = ast_parse_add_op(pc, token_index, false); - if (add_op == AddOpInvalid) + BinOpType add_op = ast_parse_add_op(pc, token_index, false); + if (add_op == BinOpTypeInvalid) return operand_1; AstNode *operand_2 = ast_parse_mult_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeAddExpr, token); - node->data.add_expr.op1 = operand_1; - node->data.add_expr.add_op = add_op; - node->data.add_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = add_op; + node->data.bin_op_expr.op2 = operand_2; return node; } -static BitShiftOp tok_to_bit_shift_op(Token *token) { +static BinOpType tok_to_bit_shift_op(Token *token) { switch (token->id) { - case TokenIdBitShiftLeft: return BitShiftOpLeft; - case TokenIdBitShiftRight: return BitShiftOpRight; - default: return BitShiftOpInvalid; + case TokenIdBitShiftLeft: return BinOpTypeBitShiftLeft; + case TokenIdBitShiftRight: return BinOpTypeBitShiftRight; + default: return BinOpTypeInvalid; } } /* BitShiftOperator : token(BitShiftLeft | token(BitShiftRight) */ -static BitShiftOp ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) { +static BinOpType ast_parse_bit_shift_op(ParseContext *pc, int *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); - BitShiftOp result = tok_to_bit_shift_op(token); - if (result == BitShiftOpInvalid) { + BinOpType result = tok_to_bit_shift_op(token); + if (result == BinOpTypeInvalid) { if (mandatory) { ast_invalid_token_error(pc, token); } else { - return BitShiftOpInvalid; + return BinOpTypeInvalid; } } *token_index += 1; @@ -840,16 +756,16 @@ static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, boo return nullptr; Token *token = &pc->tokens->at(*token_index); - BitShiftOp bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false); - if (bit_shift_op == BitShiftOpInvalid) + BinOpType bit_shift_op = ast_parse_bit_shift_op(pc, token_index, false); + if (bit_shift_op == BinOpTypeInvalid) return operand_1; AstNode *operand_2 = ast_parse_add_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeBitShiftExpr, token); - node->data.bit_shift_expr.op1 = operand_1; - node->data.bit_shift_expr.bit_shift_op = bit_shift_op; - node->data.bit_shift_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = bit_shift_op; + node->data.bin_op_expr.op2 = operand_2; return node; } @@ -870,9 +786,10 @@ static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool AstNode *operand_2 = ast_parse_bit_shift_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeBinAndExpr, token); - node->data.bin_and_expr.op1 = operand_1; - node->data.bin_and_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = BinOpTypeBinAnd; + node->data.bin_op_expr.op2 = operand_2; return node; } @@ -892,9 +809,10 @@ static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool AstNode *operand_2 = ast_parse_bin_and_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeBinXorExpr, token); - node->data.bin_xor_expr.op1 = operand_1; - node->data.bin_xor_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = BinOpTypeBinXor; + node->data.bin_op_expr.op2 = operand_2; return node; } @@ -914,33 +832,34 @@ static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool m AstNode *operand_2 = ast_parse_bin_xor_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeBinOrExpr, token); - node->data.bin_or_expr.op1 = operand_1; - node->data.bin_or_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = BinOpTypeBinOr; + node->data.bin_op_expr.op2 = operand_2; return node; } -static CmpOp tok_to_cmp_op(Token *token) { +static BinOpType tok_to_cmp_op(Token *token) { switch (token->id) { - case TokenIdCmpEq: return CmpOpEq; - case TokenIdCmpNotEq: return CmpOpNotEq; - case TokenIdCmpLessThan: return CmpOpLessThan; - case TokenIdCmpGreaterThan: return CmpOpGreaterThan; - case TokenIdCmpLessOrEq: return CmpOpLessOrEq; - case TokenIdCmpGreaterOrEq: return CmpOpGreaterOrEq; - default: return CmpOpInvalid; + case TokenIdCmpEq: return BinOpTypeCmpEq; + case TokenIdCmpNotEq: return BinOpTypeCmpNotEq; + case TokenIdCmpLessThan: return BinOpTypeCmpLessThan; + case TokenIdCmpGreaterThan: return BinOpTypeCmpGreaterThan; + case TokenIdCmpLessOrEq: return BinOpTypeCmpLessOrEq; + case TokenIdCmpGreaterOrEq: return BinOpTypeCmpGreaterOrEq; + default: return BinOpTypeInvalid; } } -static CmpOp ast_parse_comparison_operator(ParseContext *pc, int *token_index, bool mandatory) { +static BinOpType ast_parse_comparison_operator(ParseContext *pc, int *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); - CmpOp result = tok_to_cmp_op(token); - if (result == CmpOpInvalid) { + BinOpType result = tok_to_cmp_op(token); + if (result == BinOpTypeInvalid) { if (mandatory) { ast_invalid_token_error(pc, token); } else { - return CmpOpInvalid; + return BinOpTypeInvalid; } } *token_index += 1; @@ -956,16 +875,16 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo return nullptr; Token *token = &pc->tokens->at(*token_index); - CmpOp cmp_op = ast_parse_comparison_operator(pc, token_index, false); - if (cmp_op == CmpOpInvalid) + BinOpType cmp_op = ast_parse_comparison_operator(pc, token_index, false); + if (cmp_op == BinOpTypeInvalid) return operand_1; AstNode *operand_2 = ast_parse_bin_or_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeComparisonExpr, token); - node->data.comparison_expr.op1 = operand_1; - node->data.comparison_expr.cmp_op = cmp_op; - node->data.comparison_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = cmp_op; + node->data.bin_op_expr.op2 = operand_2; return node; } @@ -985,9 +904,10 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool AstNode *operand_2 = ast_parse_comparison_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeBoolAndExpr, token); - node->data.bool_and_expr.op1 = operand_1; - node->data.bool_and_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd; + node->data.bin_op_expr.op2 = operand_2; return node; } @@ -1024,9 +944,10 @@ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool AstNode *operand_2 = ast_parse_bool_and_expr(pc, token_index, true); - AstNode *node = ast_create_node(NodeTypeBoolOrExpr, token); - node->data.bool_or_expr.op1 = operand_1; - node->data.bool_or_expr.op2 = operand_2; + AstNode *node = ast_create_node(NodeTypeBinOpExpr, token); + node->data.bin_op_expr.op1 = operand_1; + node->data.bin_op_expr.bin_op = BinOpTypeBoolOr; + node->data.bin_op_expr.op2 = operand_2; return node; } |
