| author | |
| committer | |
| log | 918e7641fcaa79f75a365751de571807578ae503 |
| tree | 83c58b7b2c8f4141935beb9612d4fd7f0b26fc49 |
| parent | a7555c58d97480e439d1543cc0d4e001b23e4dd1 |
5 files changed, 64 insertions(+), 65 deletions(-)
README.md+6-6| ... | ... | @@ -138,17 +138,17 @@ MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpres |
| 138 | 138 | |
| 139 | 139 | MultiplyOperator : token(Star) | token(Slash) | token(Percent) |
| 140 | 140 | |
| 141 | CastExpression : UnaryExpression token(as) Type | UnaryExpression | |
| 141 | CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression | |
| 142 | 142 | |
| 143 | UnaryExpression : UnaryOp PrimaryExpression | PrimaryExpression | |
| 143 | PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression | |
| 144 | 144 | |
| 145 | UnaryOp : token(Not) | token(Dash) | token(Tilde) | |
| 145 | FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | |
| 146 | 146 | |
| 147 | PrimaryExpression : token(Number) | token(String) | token(Unreachable) | FnCall | GroupedExpression | Block | |
| 147 | PrefixOp : token(Not) | token(Dash) | token(Tilde) | |
| 148 | 148 | |
| 149 | GroupedExpression : token(LParen) Expression token(RParen) | |
| 149 | PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | Block | |
| 150 | 150 | |
| 151 | FnCall : token(Symbol) token(LParen) list(Expression, token(Comma)) token(RParen) | |
| 151 | GroupedExpression : token(LParen) Expression token(RParen) | |
| 152 | 152 | |
| 153 | 153 | Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen) |
| 154 | 154 | ``` |
example/math.zig-1| ... | ... | @@ -3,4 +3,3 @@ export library "math"; |
| 3 | 3 | export fn add(a: i32, b: i32) -> i32 { |
| 4 | 4 | return a + b; |
| 5 | 5 | } |
| 6 |
src/codegen.cpp+14-14| ... | ... | @@ -317,7 +317,7 @@ static void find_declarations(CodeGen *g, AstNode *node) { |
| 317 | 317 | case NodeTypeAddExpr: |
| 318 | 318 | case NodeTypeMultExpr: |
| 319 | 319 | case NodeTypeCastExpr: |
| 320 | case NodeTypeUnaryExpr: | |
| 320 | case NodeTypePrefixOpExpr: | |
| 321 | 321 | case NodeTypePrimaryExpr: |
| 322 | 322 | case NodeTypeGroupedExpr: |
| 323 | 323 | zig_unreachable(); |
| ... | ... | @@ -543,7 +543,7 @@ static void analyze_node(CodeGen *g, AstNode *node) { |
| 543 | 543 | case NodeTypeCastExpr: |
| 544 | 544 | zig_panic("TODO"); |
| 545 | 545 | break; |
| 546 | case NodeTypeUnaryExpr: | |
| 546 | case NodeTypePrefixOpExpr: | |
| 547 | 547 | zig_panic("TODO"); |
| 548 | 548 | break; |
| 549 | 549 | case NodeTypePrimaryExpr: |
| ... | ... | @@ -744,26 +744,26 @@ static LLVMValueRef gen_primary_expr(CodeGen *g, AstNode *node) { |
| 744 | 744 | zig_unreachable(); |
| 745 | 745 | } |
| 746 | 746 | |
| 747 | static LLVMValueRef gen_unary_expr(CodeGen *g, AstNode *node) { | |
| 748 | assert(node->type == NodeTypeUnaryExpr); | |
| 749 | assert(node->data.unary_expr.primary_expr); | |
| 747 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | |
| 748 | assert(node->type == NodeTypePrefixOpExpr); | |
| 749 | assert(node->data.prefix_op_expr.primary_expr); | |
| 750 | 750 | |
| 751 | LLVMValueRef expr = gen_expr(g, node->data.unary_expr.primary_expr); | |
| 751 | LLVMValueRef expr = gen_expr(g, node->data.prefix_op_expr.primary_expr); | |
| 752 | 752 | |
| 753 | switch (node->data.unary_expr.unary_op) { | |
| 754 | case UnaryOpNegation: | |
| 753 | switch (node->data.prefix_op_expr.prefix_op) { | |
| 754 | case PrefixOpNegation: | |
| 755 | 755 | add_debug_source_node(g, node); |
| 756 | 756 | return LLVMBuildNeg(g->builder, expr, ""); |
| 757 | case UnaryOpBoolNot: | |
| 757 | case PrefixOpBoolNot: | |
| 758 | 758 | { |
| 759 | 759 | LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr)); |
| 760 | 760 | add_debug_source_node(g, node); |
| 761 | 761 | return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, ""); |
| 762 | 762 | } |
| 763 | case UnaryOpBinNot: | |
| 763 | case PrefixOpBinNot: | |
| 764 | 764 | add_debug_source_node(g, node); |
| 765 | 765 | return LLVMBuildNot(g->builder, expr, ""); |
| 766 | case UnaryOpInvalid: | |
| 766 | case PrefixOpInvalid: | |
| 767 | 767 | zig_unreachable(); |
| 768 | 768 | } |
| 769 | 769 | |
| ... | ... | @@ -772,7 +772,7 @@ static LLVMValueRef gen_unary_expr(CodeGen *g, AstNode *node) { |
| 772 | 772 | static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { |
| 773 | 773 | assert(node->type == NodeTypeCastExpr); |
| 774 | 774 | |
| 775 | LLVMValueRef expr = gen_expr(g, node->data.cast_expr.unary_expr); | |
| 775 | LLVMValueRef expr = gen_expr(g, node->data.cast_expr.prefix_op_expr); | |
| 776 | 776 | |
| 777 | 777 | if (!node->data.cast_expr.type) |
| 778 | 778 | return expr; |
| ... | ... | @@ -1026,8 +1026,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 1026 | 1026 | return gen_bool_or_expr(g, node); |
| 1027 | 1027 | case NodeTypeReturnExpr: |
| 1028 | 1028 | return gen_return_expr(g, node); |
| 1029 | case NodeTypeUnaryExpr: | |
| 1030 | return gen_unary_expr(g, node); | |
| 1029 | case NodeTypePrefixOpExpr: | |
| 1030 | return gen_prefix_op_expr(g, node); | |
| 1031 | 1031 | case NodeTypeRoot: |
| 1032 | 1032 | case NodeTypeRootExportDecl: |
| 1033 | 1033 | case NodeTypeFnProto: |
src/parser.cpp+34-34| ... | ... | @@ -10,12 +10,12 @@ |
| 10 | 10 | #include <stdarg.h> |
| 11 | 11 | #include <stdio.h> |
| 12 | 12 | |
| 13 | static const char *unary_op_str(UnaryOp unary_op) { | |
| 14 | switch (unary_op) { | |
| 15 | case UnaryOpInvalid: return "(invalid)"; | |
| 16 | case UnaryOpNegation: return "-"; | |
| 17 | case UnaryOpBoolNot: return "!"; | |
| 18 | case UnaryOpBinNot: return "~"; | |
| 13 | static const char *prefix_op_str(PrefixOp prefix_op) { | |
| 14 | switch (prefix_op) { | |
| 15 | case PrefixOpInvalid: return "(invalid)"; | |
| 16 | case PrefixOpNegation: return "-"; | |
| 17 | case PrefixOpBoolNot: return "!"; | |
| 18 | case PrefixOpBinNot: return "~"; | |
| 19 | 19 | } |
| 20 | 20 | zig_unreachable(); |
| 21 | 21 | } |
| ... | ... | @@ -126,8 +126,8 @@ const char *node_type_str(NodeType node_type) { |
| 126 | 126 | return "PrimaryExpr"; |
| 127 | 127 | case NodeTypeGroupedExpr: |
| 128 | 128 | return "GroupedExpr"; |
| 129 | case NodeTypeUnaryExpr: | |
| 130 | return "UnaryExpr"; | |
| 129 | case NodeTypePrefixOpExpr: | |
| 130 | return "PrefixOpExpr"; | |
| 131 | 131 | } |
| 132 | 132 | zig_unreachable(); |
| 133 | 133 | } |
| ... | ... | @@ -296,14 +296,14 @@ void ast_print(AstNode *node, int indent) { |
| 296 | 296 | break; |
| 297 | 297 | case NodeTypeCastExpr: |
| 298 | 298 | fprintf(stderr, "%s\n", node_type_str(node->type)); |
| 299 | ast_print(node->data.cast_expr.unary_expr, indent + 2); | |
| 299 | ast_print(node->data.cast_expr.prefix_op_expr, indent + 2); | |
| 300 | 300 | if (node->data.cast_expr.type) |
| 301 | 301 | ast_print(node->data.cast_expr.type, indent + 2); |
| 302 | 302 | break; |
| 303 | case NodeTypeUnaryExpr: | |
| 303 | case NodeTypePrefixOpExpr: | |
| 304 | 304 | fprintf(stderr, "%s %s\n", node_type_str(node->type), |
| 305 | unary_op_str(node->data.unary_expr.unary_op)); | |
| 306 | ast_print(node->data.unary_expr.primary_expr, indent + 2); | |
| 305 | prefix_op_str(node->data.prefix_op_expr.prefix_op)); | |
| 306 | ast_print(node->data.prefix_op_expr.primary_expr, indent + 2); | |
| 307 | 307 | break; |
| 308 | 308 | case NodeTypePrimaryExpr: |
| 309 | 309 | switch (node->data.primary_expr.type) { |
| ... | ... | @@ -705,26 +705,26 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool |
| 705 | 705 | ast_invalid_token_error(pc, token); |
| 706 | 706 | } |
| 707 | 707 | |
| 708 | static UnaryOp tok_to_unary_op(Token *token) { | |
| 708 | static PrefixOp tok_to_prefix_op(Token *token) { | |
| 709 | 709 | switch (token->id) { |
| 710 | case TokenIdBang: return UnaryOpBoolNot; | |
| 711 | case TokenIdDash: return UnaryOpNegation; | |
| 712 | case TokenIdTilde: return UnaryOpBinNot; | |
| 713 | default: return UnaryOpInvalid; | |
| 710 | case TokenIdBang: return PrefixOpBoolNot; | |
| 711 | case TokenIdDash: return PrefixOpNegation; | |
| 712 | case TokenIdTilde: return PrefixOpBinNot; | |
| 713 | default: return PrefixOpInvalid; | |
| 714 | 714 | } |
| 715 | 715 | } |
| 716 | 716 | |
| 717 | 717 | /* |
| 718 | UnaryOp : token(Not) | token(Dash) | token(Tilde) | |
| 718 | PrefixOp : token(Not) | token(Dash) | token(Tilde) | |
| 719 | 719 | */ |
| 720 | static UnaryOp ast_parse_unary_op(ParseContext *pc, int *token_index, bool mandatory) { | |
| 720 | static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool mandatory) { | |
| 721 | 721 | Token *token = &pc->tokens->at(*token_index); |
| 722 | UnaryOp result = tok_to_unary_op(token); | |
| 723 | if (result == UnaryOpInvalid) { | |
| 722 | PrefixOp result = tok_to_prefix_op(token); | |
| 723 | if (result == PrefixOpInvalid) { | |
| 724 | 724 | if (mandatory) { |
| 725 | 725 | ast_invalid_token_error(pc, token); |
| 726 | 726 | } else { |
| 727 | return UnaryOpInvalid; | |
| 727 | return PrefixOpInvalid; | |
| 728 | 728 | } |
| 729 | 729 | } |
| 730 | 730 | *token_index += 1; |
| ... | ... | @@ -732,38 +732,38 @@ static UnaryOp ast_parse_unary_op(ParseContext *pc, int *token_index, bool manda |
| 732 | 732 | } |
| 733 | 733 | |
| 734 | 734 | /* |
| 735 | UnaryExpression : UnaryOp PrimaryExpression | PrimaryExpression | |
| 735 | PrefixOpExpression : PrefixOp PrimaryExpression | PrimaryExpression | |
| 736 | 736 | */ |
| 737 | static AstNode *ast_parse_unary_expr(ParseContext *pc, int *token_index, bool mandatory) { | |
| 737 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory) { | |
| 738 | 738 | Token *token = &pc->tokens->at(*token_index); |
| 739 | UnaryOp unary_op = ast_parse_unary_op(pc, token_index, false); | |
| 740 | if (unary_op == UnaryOpInvalid) | |
| 739 | PrefixOp prefix_op = ast_parse_prefix_op(pc, token_index, false); | |
| 740 | if (prefix_op == PrefixOpInvalid) | |
| 741 | 741 | return ast_parse_primary_expr(pc, token_index, mandatory); |
| 742 | 742 | |
| 743 | 743 | AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, true); |
| 744 | AstNode *node = ast_create_node(NodeTypeUnaryExpr, token); | |
| 745 | node->data.unary_expr.primary_expr = primary_expr; | |
| 746 | node->data.unary_expr.unary_op = unary_op; | |
| 744 | AstNode *node = ast_create_node(NodeTypePrefixOpExpr, token); | |
| 745 | node->data.prefix_op_expr.primary_expr = primary_expr; | |
| 746 | node->data.prefix_op_expr.prefix_op = prefix_op; | |
| 747 | 747 | |
| 748 | 748 | return node; |
| 749 | 749 | } |
| 750 | 750 | |
| 751 | 751 | |
| 752 | 752 | /* |
| 753 | CastExpression : UnaryExpression token(as) Type | UnaryExpression | |
| 753 | CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression | |
| 754 | 754 | */ |
| 755 | 755 | static AstNode *ast_parse_cast_expression(ParseContext *pc, int *token_index, bool mandatory) { |
| 756 | AstNode *unary_expr = ast_parse_unary_expr(pc, token_index, mandatory); | |
| 757 | if (!unary_expr) | |
| 756 | AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory); | |
| 757 | if (!prefix_op_expr) | |
| 758 | 758 | return nullptr; |
| 759 | 759 | |
| 760 | 760 | Token *as_kw = &pc->tokens->at(*token_index); |
| 761 | 761 | if (as_kw->id != TokenIdKeywordAs) |
| 762 | return unary_expr; | |
| 762 | return prefix_op_expr; | |
| 763 | 763 | *token_index += 1; |
| 764 | 764 | |
| 765 | 765 | AstNode *node = ast_create_node(NodeTypeCastExpr, as_kw); |
| 766 | node->data.cast_expr.unary_expr = unary_expr; | |
| 766 | node->data.cast_expr.prefix_op_expr = prefix_op_expr; | |
| 767 | 767 | |
| 768 | 768 | node->data.cast_expr.type = ast_parse_type(pc, *token_index, token_index); |
| 769 | 769 |
src/parser.hpp+10-10| ... | ... | @@ -40,7 +40,7 @@ enum NodeType { |
| 40 | 40 | NodeTypeCastExpr, |
| 41 | 41 | NodeTypePrimaryExpr, |
| 42 | 42 | NodeTypeGroupedExpr, |
| 43 | NodeTypeUnaryExpr, | |
| 43 | NodeTypePrefixOpExpr, | |
| 44 | 44 | }; |
| 45 | 45 | |
| 46 | 46 | struct AstNodeRoot { |
| ... | ... | @@ -205,7 +205,7 @@ struct AstNodeMultExpr { |
| 205 | 205 | }; |
| 206 | 206 | |
| 207 | 207 | struct AstNodeCastExpr { |
| 208 | AstNode *unary_expr; | |
| 208 | AstNode *prefix_op_expr; | |
| 209 | 209 | // if type is non-null, do cast, otherwise nothing |
| 210 | 210 | AstNode *type; |
| 211 | 211 | }; |
| ... | ... | @@ -234,15 +234,15 @@ struct AstNodeGroupedExpr { |
| 234 | 234 | AstNode *expr; |
| 235 | 235 | }; |
| 236 | 236 | |
| 237 | enum UnaryOp { | |
| 238 | UnaryOpInvalid, | |
| 239 | UnaryOpBoolNot, | |
| 240 | UnaryOpBinNot, | |
| 241 | UnaryOpNegation, | |
| 237 | enum PrefixOp { | |
| 238 | PrefixOpInvalid, | |
| 239 | PrefixOpBoolNot, | |
| 240 | PrefixOpBinNot, | |
| 241 | PrefixOpNegation, | |
| 242 | 242 | }; |
| 243 | 243 | |
| 244 | struct AstNodeUnaryExpr { | |
| 245 | UnaryOp unary_op; | |
| 244 | struct AstNodePrefixOpExpr { | |
| 245 | PrefixOp prefix_op; | |
| 246 | 246 | AstNode *primary_expr; |
| 247 | 247 | }; |
| 248 | 248 | |
| ... | ... | @@ -277,7 +277,7 @@ struct AstNode { |
| 277 | 277 | AstNodeCastExpr cast_expr; |
| 278 | 278 | AstNodePrimaryExpr primary_expr; |
| 279 | 279 | AstNodeGroupedExpr grouped_expr; |
| 280 | AstNodeUnaryExpr unary_expr; | |
| 280 | AstNodePrefixOpExpr prefix_op_expr; | |
| 281 | 281 | } data; |
| 282 | 282 | }; |
| 283 | 283 |