| ... | @@ -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,55 +4048,110 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { | ... | @@ -4044,55 +4048,110 @@ 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) { |
| | 4065 | *tok_i += 1; |
| | 4066 | return inner_node; |
| | 4067 | } |
| | 4068 | |
| | 4069 | AstNode *node_to_cast = parse_ctok_expr(c, ctok, tok_i); |
| | 4070 | if (node_to_cast == nullptr) { |
| | 4071 | return nullptr; |
| | 4072 | } |
| | 4073 | |
| | 4074 | CTok *next_tok2 = &ctok->tokens.at(*tok_i); |
| | 4075 | if (next_tok2->id != CTokIdRParen) { |
| 4082 | return nullptr; | 4076 | return nullptr; |
| 4083 | } | 4077 | } |
| 4084 | *tok_i += 1; | 4078 | *tok_i += 1; |
| 4085 | return inner_node; | 4079 | |
| | 4080 | if (inner_node->type == NodeTypeAddrOfExpr) { |
| | 4081 | AstNode *call_node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| | 4082 | call_node->data.fn_call_expr.params.append(inner_node); |
| | 4083 | call_node->data.fn_call_expr.params.append(node_to_cast); |
| | 4084 | return call_node; |
| | 4085 | } else { |
| | 4086 | return trans_create_node_cast(c, inner_node, node_to_cast); |
| | 4087 | } |
| 4086 | } | 4088 | } |
| 4087 | case CTokIdDot: | 4089 | case CTokIdDot: |
| 4088 | case CTokIdEOF: | 4090 | case CTokIdEOF: |
| 4089 | case CTokIdRParen: | 4091 | case CTokIdRParen: |
| | 4092 | case CTokIdAsterisk: |
| | 4093 | case CTokIdBang: |
| | 4094 | case CTokIdTilde: |
| 4090 | // not able to make sense of this | 4095 | // not able to make sense of this |
| 4091 | return nullptr; | 4096 | return nullptr; |
| 4092 | } | 4097 | } |
| 4093 | zig_unreachable(); | 4098 | zig_unreachable(); |
| 4094 | } | 4099 | } |
| 4095 | | 4100 | |
| | 4101 | static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 4102 | return parse_ctok_prefix_op_expr(c, ctok, tok_i); |
| | 4103 | } |
| | 4104 | |
| | 4105 | static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 4106 | AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i); |
| | 4107 | if (node == nullptr) |
| | 4108 | return nullptr; |
| | 4109 | |
| | 4110 | while (true) { |
| | 4111 | CTok *first_tok = &ctok->tokens.at(*tok_i); |
| | 4112 | if (first_tok->id == CTokIdDot) { |
| | 4113 | *tok_i += 1; |
| | 4114 | |
| | 4115 | CTok *name_tok = &ctok->tokens.at(*tok_i); |
| | 4116 | if (name_tok->id != CTokIdSymbol) { |
| | 4117 | return nullptr; |
| | 4118 | } |
| | 4119 | *tok_i += 1; |
| | 4120 | |
| | 4121 | node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol)); |
| | 4122 | } else if (first_tok->id == CTokIdAsterisk) { |
| | 4123 | *tok_i += 1; |
| | 4124 | |
| | 4125 | node = trans_create_node_addr_of(c, false, false, node); |
| | 4126 | } else { |
| | 4127 | return node; |
| | 4128 | } |
| | 4129 | } |
| | 4130 | } |
| | 4131 | |
| | 4132 | static PrefixOp ctok_to_prefix_op(CTok *token) { |
| | 4133 | switch (token->id) { |
| | 4134 | case CTokIdBang: return PrefixOpBoolNot; |
| | 4135 | case CTokIdMinus: return PrefixOpNegation; |
| | 4136 | case CTokIdTilde: return PrefixOpBinNot; |
| | 4137 | case CTokIdAsterisk: return PrefixOpDereference; |
| | 4138 | default: return PrefixOpInvalid; |
| | 4139 | } |
| | 4140 | } |
| | 4141 | static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 4142 | CTok *op_tok = &ctok->tokens.at(*tok_i); |
| | 4143 | PrefixOp prefix_op = ctok_to_prefix_op(op_tok); |
| | 4144 | if (prefix_op == PrefixOpInvalid) { |
| | 4145 | return parse_ctok_suffix_op_expr(c, ctok, tok_i); |
| | 4146 | } |
| | 4147 | *tok_i += 1; |
| | 4148 | |
| | 4149 | AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i); |
| | 4150 | if (prefix_op_expr == nullptr) |
| | 4151 | return nullptr; |
| | 4152 | return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr); |
| | 4153 | } |
| | 4154 | |
| 4096 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { | 4155 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { |
| 4097 | tokenize_c_macro(ctok, (const uint8_t *)char_ptr); | 4156 | tokenize_c_macro(ctok, (const uint8_t *)char_ptr); |
| 4098 | | 4157 | |
| ... | @@ -4105,7 +4164,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -4105,7 +4164,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)); | 4164 | assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name)); |
| 4106 | tok_i += 1; | 4165 | tok_i += 1; |
| 4107 | | 4166 | |
| 4108 | AstNode *result_node = parse_ctok(c, ctok, &tok_i); | 4167 | AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i); |
| 4109 | if (result_node == nullptr) { | 4168 | if (result_node == nullptr) { |
| 4110 | return; | 4169 | return; |
| 4111 | } | 4170 | } |