| ... | ... | @@ -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 | 4007 | static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) { |
| 4004 | 4008 | CTok *tok = &ctok->tokens.at(*tok_i); |
| 4005 | 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 | 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 | 4035 | CTok *tok = &ctok->tokens.at(*tok_i); |
| 4032 | 4036 | switch (tok->id) { |
| 4033 | 4037 | case CTokIdCharLit: |
| ... | ... | @@ -4044,55 +4048,110 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { |
| 4044 | 4048 | return parse_ctok_num_lit(c, ctok, tok_i, false); |
| 4045 | 4049 | case CTokIdSymbol: |
| 4046 | 4050 | { |
| 4047 | | bool need_symbol = false; |
| 4048 | | CTokId curr_id = CTokIdSymbol; |
| 4051 | *tok_i += 1; |
| 4049 | 4052 | Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); |
| 4050 | | AstNode *curr_node = 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; |
| 4053 | return trans_create_node_symbol(c, symbol_name); |
| 4074 | 4054 | } |
| 4075 | 4055 | case CTokIdLParen: |
| 4076 | 4056 | { |
| 4077 | 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 | 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 | 4076 | return nullptr; |
| 4083 | 4077 | } |
| 4084 | 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 | 4089 | case CTokIdDot: |
| 4088 | 4090 | case CTokIdEOF: |
| 4089 | 4091 | case CTokIdRParen: |
| 4092 | case CTokIdAsterisk: |
| 4093 | case CTokIdBang: |
| 4094 | case CTokIdTilde: |
| 4090 | 4095 | // not able to make sense of this |
| 4091 | 4096 | return nullptr; |
| 4092 | 4097 | } |
| 4093 | 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 | 4155 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { |
| 4097 | 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 | 4164 | assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name)); |
| 4106 | 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 | 4168 | if (result_node == nullptr) { |
| 4110 | 4169 | return; |
| 4111 | 4170 | } |