stage1 修复bug 删除递归测试
This commit is contained in:
@@ -425,12 +425,109 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, f->offset);
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
}
|
||||
spl_expr_result_t fv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)fv;
|
||||
spl_emit(ctx, SPL_STORE, spl_store_type(f->type), 0);
|
||||
/* Handle inline slice initializer: { .ptr = expr, .len = expr } */
|
||||
if (f->type && f->type->kind == TYPE_SLICE &&
|
||||
peek(ctx)->type == TOK_L_BRACE) {
|
||||
/* Stack: [field_addr] — slice struct start addr */
|
||||
advance(ctx); /* { */
|
||||
skip_nl(ctx);
|
||||
while (peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
continue;
|
||||
}
|
||||
if (peek(ctx)->type == TOK_DOT)
|
||||
advance(ctx);
|
||||
spl_tok_t *sftok = advance(ctx);
|
||||
char sfname[256];
|
||||
usize sfnl = sftok->len < 255 ? sftok->len : 255;
|
||||
memcpy(sfname, sftok->lexeme, sfnl);
|
||||
sfname[sfnl] = '\0';
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_ASSIGN)
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
|
||||
spl_emit(ctx, SPL_DUP, SPL_VOID, 0); /* [addr, addr] */
|
||||
if (strcmp(sfname, "ptr") == 0) {
|
||||
spl_expr_result_t pv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)pv;
|
||||
/* Stack: [addr, addr, ptr_val] — STORE needs [addr, val] */
|
||||
spl_emit(ctx, SPL_STORE, SPL_PTR, 0); /* [addr] */
|
||||
} else if (strcmp(sfname, "len") == 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, sizeof(spl_val_t));
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); /* [addr, addr+8] */
|
||||
spl_expr_result_t lv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)lv;
|
||||
/* Stack: [addr, addr+8, len_val] — STORE needs [addr, val] */
|
||||
spl_emit(ctx, SPL_STORE, SPL_USIZE, 0); /* [addr] */
|
||||
}
|
||||
skip_nl(ctx);
|
||||
}
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0); /* drop addr */
|
||||
} else if (f->type && f->type->kind == TYPE_ARRAY &&
|
||||
peek(ctx)->type == TOK_L_BRACKET) {
|
||||
/* Inline array initializer: [N]Type{val1, val2, ...}
|
||||
* Stack: [field_addr] — store each element at computed offsets */
|
||||
advance(ctx); /* [ */
|
||||
skip_nl(ctx);
|
||||
spl_tok_t *len_tok = advance(ctx);
|
||||
usize arr_len = (usize)strtoull(len_tok->lexeme, NULL, 0);
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
skip_nl(ctx);
|
||||
spl_type_info_t *elem_type = spl_parse_type(ctx);
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_BRACE);
|
||||
skip_nl(ctx);
|
||||
usize stride = spl_type_elem_stride(elem_type);
|
||||
spl_type_t st = spl_store_type(elem_type);
|
||||
for (usize i = 0; i < arr_len; i++) {
|
||||
if (i > 0) {
|
||||
if (peek(ctx)->type == TOK_COMMA)
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
spl_emit(ctx, SPL_DUP, SPL_VOID, 0);
|
||||
if (i > 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, i * stride);
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
}
|
||||
spl_parse_expr(ctx, PREC_MIN);
|
||||
spl_emit(ctx, SPL_STORE, st, 0);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
if (peek(ctx)->type == TOK_COMMA)
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
} else if (f->type &&
|
||||
(f->type->kind == TYPE_STRUCT || f->type->kind == TYPE_ENUM) &&
|
||||
spl_type_size(f->type) > sizeof(spl_val_t)) {
|
||||
/* Multi-slot struct/enum value: copy temp → field slot by slot
|
||||
* Stack: [field_addr, temp_addr] */
|
||||
spl_expr_result_t fv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)fv;
|
||||
usize nslots = (spl_type_size(f->type) + sizeof(spl_val_t) - 1) /
|
||||
sizeof(spl_val_t);
|
||||
spl_emit_copy_slots(ctx, base_offset + f->offset, nslots);
|
||||
/* Drop field_addr from stack (copy_slots consumed temp_addr) */
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
} else {
|
||||
spl_expr_result_t fv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)fv;
|
||||
spl_emit(ctx, SPL_STORE, spl_store_type(f->type), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Unrecognized token (not .field or ,), advance to prevent infinite loop */
|
||||
if (peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF)
|
||||
advance(ctx);
|
||||
}
|
||||
skip_nl(ctx);
|
||||
}
|
||||
@@ -492,15 +589,85 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, byte_off);
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
}
|
||||
spl_expr_result_t sfv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)sfv;
|
||||
spl_emit(ctx, SPL_STORE, spl_store_type(sf->type), 0);
|
||||
/* Handle inline slice initializer */
|
||||
if (sf->type && sf->type->kind == TYPE_SLICE &&
|
||||
peek(ctx)->type == TOK_L_BRACE) {
|
||||
advance(ctx); /* { */
|
||||
skip_nl(ctx);
|
||||
while (peek(ctx)->type != TOK_R_BRACE &&
|
||||
peek(ctx)->type != TOK_EOF) {
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
continue;
|
||||
}
|
||||
if (peek(ctx)->type == TOK_DOT)
|
||||
advance(ctx);
|
||||
spl_tok_t *ssftok = advance(ctx);
|
||||
char ssfname[256];
|
||||
usize ssfnl = ssftok->len < 255 ? ssftok->len : 255;
|
||||
memcpy(ssfname, ssftok->lexeme, ssfnl);
|
||||
ssfname[ssfnl] = '\0';
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_ASSIGN)
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
|
||||
spl_emit(ctx, SPL_DUP, SPL_VOID, 0);
|
||||
if (strcmp(ssfname, "ptr") == 0) {
|
||||
spl_expr_result_t pv =
|
||||
spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)pv;
|
||||
spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
|
||||
} else if (strcmp(ssfname, "len") == 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE,
|
||||
sizeof(spl_val_t));
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
spl_expr_result_t lv =
|
||||
spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)lv;
|
||||
spl_emit(ctx, SPL_STORE, SPL_USIZE, 0);
|
||||
}
|
||||
skip_nl(ctx);
|
||||
}
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
} else if (sf->type &&
|
||||
(sf->type->kind == TYPE_STRUCT ||
|
||||
sf->type->kind == TYPE_ENUM) &&
|
||||
spl_type_size(sf->type) > sizeof(spl_val_t)) {
|
||||
/* Multi-slot struct field in enum variant data */
|
||||
spl_expr_result_t sfv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)sfv;
|
||||
usize nslots =
|
||||
(spl_type_size(sf->type) + sizeof(spl_val_t) - 1) /
|
||||
sizeof(spl_val_t);
|
||||
spl_emit_copy_slots(
|
||||
ctx, base_offset + (int)DATA_OFFSET + sf->offset,
|
||||
nslots);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
} else {
|
||||
spl_expr_result_t sfv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)sfv;
|
||||
spl_emit(ctx, SPL_STORE, spl_store_type(sf->type), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
skip_nl(ctx);
|
||||
}
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
} else if (v->data_type &&
|
||||
(v->data_type->kind == TYPE_STRUCT ||
|
||||
v->data_type->kind == TYPE_ENUM) &&
|
||||
spl_type_size(v->data_type) > sizeof(spl_val_t)) {
|
||||
/* Multi-slot struct/enum data: copy from temp to enum data area */
|
||||
spl_expr_result_t dv = spl_parse_expr(ctx, PREC_MIN);
|
||||
(void)dv;
|
||||
usize nslots = (spl_type_size(v->data_type) + sizeof(spl_val_t) - 1) /
|
||||
sizeof(spl_val_t);
|
||||
spl_emit_copy_slots(ctx, base_offset + (int)DATA_OFFSET, nslots);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
} else {
|
||||
/* Simple data: parse expression */
|
||||
spl_expr_result_t dv = spl_parse_expr(ctx, PREC_MIN);
|
||||
@@ -1090,11 +1257,11 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) {
|
||||
/* Stack: [struct_addr, begin, end].
|
||||
* Inline ptr/len: ptr = data_ptr + begin*stride, len = end - begin. */
|
||||
spl_emit(ctx, SPL_PICK, SPL_VOID, 2);
|
||||
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); /* [s,b,e,data_ptr] */
|
||||
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); /* [s,b,e,data_ptr] */
|
||||
spl_emit(ctx, SPL_PICK, SPL_VOID, 2); /* [s,b,e,d,begin] */
|
||||
spl_emit(ctx, SPL_PUSH, SPL_U64, stride);
|
||||
spl_emit(ctx, SPL_MUL, SPL_U64, 0);
|
||||
spl_emit(ctx, SPL_ADD, SPL_U64, 0); /* [s,b,e,ptr] */
|
||||
spl_emit(ctx, SPL_ADD, SPL_U64, 0); /* [s,b,e,ptr] */
|
||||
spl_emit(ctx, SPL_PICK, SPL_VOID, 1); /* [s,b,e,ptr,end] */
|
||||
spl_emit(ctx, SPL_PICK, SPL_VOID, 3); /* [s,b,e,ptr,end,begin] */
|
||||
spl_emit(ctx, SPL_SUB, SPL_USIZE, 0); /* [s,b,e,ptr,len] */
|
||||
@@ -1126,6 +1293,13 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) {
|
||||
emit_slice_index(ctx, elem);
|
||||
} else {
|
||||
/* Stack arrays and pointer indexing */
|
||||
if (left.type->kind == TYPE_PTR && left.is_lvalue) {
|
||||
/* Stack: [addr_of_ptr, index]. Swap to get addr on top, load ptr value,
|
||||
* swap back */
|
||||
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
|
||||
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
|
||||
}
|
||||
usize stride = spl_type_elem_stride(elem);
|
||||
spl_emit(ctx, SPL_PUSH, SPL_U64, stride);
|
||||
spl_emit(ctx, SPL_MUL, SPL_U64, 0);
|
||||
|
||||
Reference in New Issue
Block a user