stage1 修复bug

This commit is contained in:
zzy
2026-07-13 21:50:28 +08:00
parent b67edc5cee
commit f7f71c5f52
5 changed files with 75 additions and 44 deletions

View File

@@ -128,7 +128,7 @@ static int spl_resolve_type_member(spl_comp_t *ctx, spl_type_info_t *type, const
vec_for(type->variants, i) {
if (strcmp(vec_at(type->variants, i).name, field) == 0) {
spl_emit(ctx, SPL_PUSH, SPL_I32, vec_at(type->variants, i).value);
*result = (spl_expr_result_t){spl_type_basic(SPL_I32), 0};
*result = (spl_expr_result_t){type, 0};
return 1;
}
}
@@ -633,7 +633,7 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *typ
if (sz <= sizeof(spl_val_t)) {
spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset);
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
spl_emit(ctx, SPL_LOAD, spl_type_emit_type(type), 0);
return (spl_expr_result_t){type, 0};
} else {
spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset);
@@ -698,7 +698,7 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
if (v) {
spl_val_t cv = 0;
if (map_get(ctx->const_values, name, &cv)) {
spl_emit(ctx, SPL_PUSH, SPL_I32, cv);
spl_emit(ctx, SPL_PUSH, spl_type_emit_type(v->type), cv);
spl_expr_result_t r = {v->type, 0};
return r;
}
@@ -736,10 +736,9 @@ static spl_expr_result_t parse_group(spl_comp_t *ctx) {
static void emit_load_or_addr_type(spl_comp_t *ctx, spl_expr_result_t *result,
spl_type_info_t *type) {
if (type->kind == TYPE_BASIC || type->kind == TYPE_PTR) {
if (spl_type_is_scalar(type)) {
if (!ctx->addr_of_mode) {
spl_type_t bt = (type->kind == TYPE_BASIC) ? type->basic_type : SPL_PTR;
spl_emit(ctx, SPL_LOAD, bt, 0);
spl_emit(ctx, SPL_LOAD, spl_type_emit_type(type), 0);
*result = (spl_expr_result_t){type, 0};
return;
}
@@ -758,14 +757,14 @@ static spl_expr_result_t parse_prefix_op(spl_comp_t *ctx) {
switch (op->type) {
case TOK_SUB:
spl_emit(ctx, SPL_NEG, SPL_I32, 0);
spl_emit(ctx, SPL_NEG, spl_type_emit_type(right.type), 0);
break;
case TOK_NOT:
spl_emit(ctx, SPL_PUSH, SPL_I32, 0);
spl_emit(ctx, SPL_EQ, SPL_I32, 0);
spl_emit(ctx, SPL_EQ, spl_type_emit_type(right.type), 0);
break;
case TOK_BIT_NOT:
spl_emit(ctx, SPL_NOT, SPL_I32, 0);
spl_emit(ctx, SPL_NOT, spl_type_emit_type(right.type), 0);
break;
case TOK_AND:
if (!right.is_lvalue) {
@@ -1193,9 +1192,7 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
ctx->addr_of_mode = saved_addr_of_mode;
if (left.is_lvalue) {
spl_type_t bt = left.type
? (left.type->kind == TYPE_BASIC ? left.type->basic_type : SPL_PTR)
: SPL_I32;
spl_type_t bt = spl_type_emit_type(left.type);
if (op == TOK_ASSIGN) {
spl_emit(ctx, SPL_STORE, bt, 0);
} else {
@@ -1213,12 +1210,20 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
/* Regular binary op */
spl_parse_expr(ctx, next_prec);
int sop = binop_to_sir(op, left.type ? left.type->basic_type : SPL_I32);
spl_type_t bt = left.type && left.type->kind == TYPE_BASIC ? left.type->basic_type : SPL_I32;
/* Forbid comparison of non-scalar types (struct, enum-with-data) */
if ((op == TOK_EQ || op == TOK_NEQ) && left.type && !spl_type_is_scalar(left.type)) {
spl_comp_error(ctx, "type '%s' does not support comparison", spl_type_str(left.type));
}
spl_type_t bt = spl_type_emit_type(left.type);
int sop = binop_to_sir(op, bt);
if (sop >= 0) {
spl_emit(ctx, sop, bt, 0);
}
return (spl_expr_result_t){spl_type_basic(SPL_I32), 0};
/* Comparisons return boolean (I32), other binary ops match operand type */
int is_compare = (op == TOK_EQ || op == TOK_NEQ || op == TOK_LT || op == TOK_GT ||
op == TOK_LE || op == TOK_GE);
spl_type_info_t *result_type = is_compare ? spl_type_basic(SPL_I32) : left.type;
return (spl_expr_result_t){result_type, 0};
}
/* ============================================================
@@ -1231,7 +1236,7 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
* ============================================================ */
spl_enum_variant_t *spl_emit_match_enum_cmp(spl_comp_t *ctx, spl_type_info_t *enum_type,
int val_offset) {
int val_offset, int by_value) {
char vname[256];
/* Parse variant reference, reusing the same type resolution path
@@ -1274,10 +1279,16 @@ lookup:
spl_enum_variant_t *v = &vec_at(enum_type->variants, vi);
if (strcmp(v->name, vname) == 0) {
spl_emit(ctx, SPL_LADDR, SPL_PTR, val_offset);
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
spl_emit(ctx, SPL_PUSH, SPL_USIZE, 0);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
spl_emit(ctx, SPL_LOAD, SPL_I32, 0);
if (by_value) {
/* Scalar enum: raw tag stored directly in slot */
spl_emit(ctx, SPL_LOAD, SPL_I32, 0);
} else {
/* Enum with data or *Enum: slot has a pointer, dereference it */
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
spl_emit(ctx, SPL_PUSH, SPL_USIZE, 0);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
spl_emit(ctx, SPL_LOAD, SPL_I32, 0);
}
spl_emit(ctx, SPL_PUSH, SPL_I32, v->value);
spl_emit(ctx, SPL_EQ, SPL_I32, 0);
return v;
@@ -1299,15 +1310,7 @@ void spl_emit_match_value_cmp(spl_comp_t *ctx, int val_offset) {
* ============================================================ */
void spl_emit_ret(spl_comp_t *ctx, spl_type_info_t *ret_type) {
spl_type_t rt = SPL_VOID;
if (ret_type) {
if (ret_type->kind == TYPE_BASIC) {
rt = ret_type->basic_type;
} else {
/* Pointer, struct, enum, etc: return address of value */
rt = SPL_PTR;
}
}
spl_type_t rt = ret_type ? spl_type_emit_type(ret_type) : SPL_VOID;
spl_emit(ctx, SPL_RET, rt, 0);
}
@@ -1321,14 +1324,14 @@ void spl_emit_store_init(spl_comp_t *ctx, int var_offset, spl_type_info_t *var_t
if (sz <= sizeof(spl_val_t)) {
spl_emit(ctx, SPL_LADDR, SPL_PTR, var_offset);
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
spl_emit(ctx, SPL_STORE, spl_type_emit_type(var_type), 0);
} else {
usize nslots = (sz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
spl_emit_copy_slots(ctx, var_offset, nslots);
}
} else if (var_type && var_type->kind == TYPE_ARRAY) {
spl_type_info_t *elem = var_type->elem;
spl_type_t bt = (elem && elem->kind == TYPE_BASIC) ? elem->basic_type : SPL_I32;
spl_type_t bt = spl_type_emit_type(elem);
usize stride = spl_type_elem_stride(elem);
for (int i = (int)var_type->array_len - 1; i >= 0; i--) {
spl_emit(ctx, SPL_LADDR, SPL_PTR, var_offset + (int)(i * stride));
@@ -1344,9 +1347,7 @@ void spl_emit_store_init(spl_comp_t *ctx, int var_offset, spl_type_info_t *var_t
spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
} else {
spl_emit(ctx, SPL_LADDR, SPL_PTR, var_offset);
spl_type_t bt = (var_type->kind == TYPE_BASIC) ? var_type->basic_type
: (var_type->kind == TYPE_PTR) ? SPL_PTR
: SPL_I32;
spl_type_t bt = spl_type_emit_type(var_type);
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, bt, 0);
}