| ... | @@ -4000,6 +4000,10 @@ static void render_macros(Context *c) { | ... | @@ -4000,6 +4000,10 @@ static void render_macros(Context *c) { |
| 4000 | } | 4000 | } |
| 4001 | } | 4001 | } |
| 4002 | | 4002 | |
| | 4003 | static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i); |
| | 4004 | static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i); |
| | 4005 | static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i); |
| | 4006 | |
| 4003 | static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) { | 4007 | static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) { |
| 4004 | CTok *tok = &ctok->tokens.at(*tok_i); | 4008 | CTok *tok = &ctok->tokens.at(*tok_i); |
| 4005 | if (tok->id == CTokIdNumLitInt) { | 4009 | if (tok->id == CTokIdNumLitInt) { |
| ... | @@ -4027,7 +4031,7 @@ static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, b | ... | @@ -4027,7 +4031,7 @@ static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, b |
| 4027 | return nullptr; | 4031 | return nullptr; |
| 4028 | } | 4032 | } |
| 4029 | | 4033 | |
| 4030 | static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { | 4034 | static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| 4031 | CTok *tok = &ctok->tokens.at(*tok_i); | 4035 | CTok *tok = &ctok->tokens.at(*tok_i); |
| 4032 | switch (tok->id) { | 4036 | switch (tok->id) { |
| 4033 | case CTokIdCharLit: | 4037 | case CTokIdCharLit: |
| ... | @@ -4044,38 +4048,17 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { | ... | @@ -4044,38 +4048,17 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { |
| 4044 | return parse_ctok_num_lit(c, ctok, tok_i, false); | 4048 | return parse_ctok_num_lit(c, ctok, tok_i, false); |
| 4045 | case CTokIdSymbol: | 4049 | case CTokIdSymbol: |
| 4046 | { | 4050 | { |
| 4047 | bool need_symbol = false; | 4051 | *tok_i += 1; |
| 4048 | CTokId curr_id = CTokIdSymbol; | | |
| 4049 | Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); | 4052 | Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); |
| 4050 | AstNode *curr_node = trans_create_node_symbol(c, symbol_name); | 4053 | return trans_create_node_symbol(c, symbol_name); |
| 4051 | AstNode *parent_node = curr_node; | | |
| 4052 | do { | | |
| 4053 | *tok_i += 1; | | |
| 4054 | CTok* curr_tok = &ctok->tokens.at(*tok_i); | | |
| 4055 | if (need_symbol) { | | |
| 4056 | if (curr_tok->id == CTokIdSymbol) { | | |
| 4057 | symbol_name = buf_create_from_buf(&curr_tok->data.symbol); | | |
| 4058 | curr_node = trans_create_node_field_access(c, parent_node, buf_create_from_buf(symbol_name)); | | |
| 4059 | parent_node = curr_node; | | |
| 4060 | need_symbol = false; | | |
| 4061 | } else { | | |
| 4062 | return nullptr; | | |
| 4063 | } | | |
| 4064 | } else { | | |
| 4065 | if (curr_tok->id == CTokIdDot) { | | |
| 4066 | need_symbol = true; | | |
| 4067 | continue; | | |
| 4068 | } else { | | |
| 4069 | break; | | |
| 4070 | } | | |
| 4071 | } | | |
| 4072 | } while (curr_id != CTokIdEOF); | | |
| 4073 | return curr_node; | | |
| 4074 | } | 4054 | } |
| 4075 | case CTokIdLParen: | 4055 | case CTokIdLParen: |
| 4076 | { | 4056 | { |
| 4077 | *tok_i += 1; | 4057 | *tok_i += 1; |
| 4078 | AstNode *inner_node = parse_ctok(c, ctok, tok_i); | 4058 | AstNode *inner_node = parse_ctok_expr(c, ctok, tok_i); |
| | 4059 | if (inner_node == nullptr) { |
| | 4060 | return nullptr; |
| | 4061 | } |
| 4079 | | 4062 | |
| 4080 | CTok *next_tok = &ctok->tokens.at(*tok_i); | 4063 | CTok *next_tok = &ctok->tokens.at(*tok_i); |
| 4081 | if (next_tok->id != CTokIdRParen) { | 4064 | if (next_tok->id != CTokIdRParen) { |
| ... | @@ -4087,12 +4070,69 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { | ... | @@ -4087,12 +4070,69 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { |
| 4087 | case CTokIdDot: | 4070 | case CTokIdDot: |
| 4088 | case CTokIdEOF: | 4071 | case CTokIdEOF: |
| 4089 | case CTokIdRParen: | 4072 | case CTokIdRParen: |
| | 4073 | case CTokIdAsterisk: |
| | 4074 | case CTokIdBang: |
| | 4075 | case CTokIdTilde: |
| 4090 | // not able to make sense of this | 4076 | // not able to make sense of this |
| 4091 | return nullptr; | 4077 | return nullptr; |
| 4092 | } | 4078 | } |
| 4093 | zig_unreachable(); | 4079 | zig_unreachable(); |
| 4094 | } | 4080 | } |
| 4095 | | 4081 | |
| | 4082 | static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 4083 | return parse_ctok_prefix_op_expr(c, ctok, tok_i); |
| | 4084 | } |
| | 4085 | |
| | 4086 | static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 4087 | AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i); |
| | 4088 | if (node == nullptr) |
| | 4089 | return nullptr; |
| | 4090 | |
| | 4091 | while (true) { |
| | 4092 | CTok *first_tok = &ctok->tokens.at(*tok_i); |
| | 4093 | if (first_tok->id == CTokIdDot) { |
| | 4094 | *tok_i += 1; |
| | 4095 | |
| | 4096 | CTok *name_tok = &ctok->tokens.at(*tok_i); |
| | 4097 | if (name_tok->id != CTokIdSymbol) { |
| | 4098 | return nullptr; |
| | 4099 | } |
| | 4100 | *tok_i += 1; |
| | 4101 | |
| | 4102 | node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol)); |
| | 4103 | } else if (first_tok->id == CTokIdAsterisk) { |
| | 4104 | *tok_i += 1; |
| | 4105 | |
| | 4106 | node = trans_create_node_addr_of(c, false, false, node); |
| | 4107 | } else { |
| | 4108 | return node; |
| | 4109 | } |
| | 4110 | } |
| | 4111 | } |
| | 4112 | |
| | 4113 | static PrefixOp ctok_to_prefix_op(CTok *token) { |
| | 4114 | switch (token->id) { |
| | 4115 | case CTokIdBang: return PrefixOpBoolNot; |
| | 4116 | case CTokIdMinus: return PrefixOpNegation; |
| | 4117 | case CTokIdTilde: return PrefixOpBinNot; |
| | 4118 | case CTokIdAsterisk: return PrefixOpDereference; |
| | 4119 | default: return PrefixOpInvalid; |
| | 4120 | } |
| | 4121 | } |
| | 4122 | static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 4123 | CTok *op_tok = &ctok->tokens.at(*tok_i); |
| | 4124 | PrefixOp prefix_op = ctok_to_prefix_op(op_tok); |
| | 4125 | if (prefix_op == PrefixOpInvalid) { |
| | 4126 | return parse_ctok_suffix_op_expr(c, ctok, tok_i); |
| | 4127 | } |
| | 4128 | *tok_i += 1; |
| | 4129 | |
| | 4130 | AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i); |
| | 4131 | if (prefix_op_expr == nullptr) |
| | 4132 | return nullptr; |
| | 4133 | return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr); |
| | 4134 | } |
| | 4135 | |
| 4096 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { | 4136 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { |
| 4097 | tokenize_c_macro(ctok, (const uint8_t *)char_ptr); | 4137 | tokenize_c_macro(ctok, (const uint8_t *)char_ptr); |
| 4098 | | 4138 | |
| ... | @@ -4105,7 +4145,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -4105,7 +4145,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch |
| 4105 | assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name)); | 4145 | assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name)); |
| 4106 | tok_i += 1; | 4146 | tok_i += 1; |
| 4107 | | 4147 | |
| 4108 | AstNode *result_node = parse_ctok(c, ctok, &tok_i); | 4148 | AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i); |
| 4109 | if (result_node == nullptr) { | 4149 | if (result_node == nullptr) { |
| 4110 | return; | 4150 | return; |
| 4111 | } | 4151 | } |