stage1 修改部分测试 完成17-19测试
This commit is contained in:
@@ -6,16 +6,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ============================================================
|
||||
* Token helpers
|
||||
* ============================================================ */
|
||||
|
||||
/* Check if current token starts a statement */
|
||||
static int is_stmt_start(spl_comp_t *ctx) {
|
||||
spl_tok_type_t t = peek(ctx)->type;
|
||||
return t == TOK_EOF || t == TOK_R_BRACE ? 0 : 1;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Precedence table
|
||||
* ============================================================ */
|
||||
@@ -71,7 +61,6 @@ static int tok_prec(spl_tok_type_t t) {
|
||||
* Forward declarations
|
||||
* ============================================================ */
|
||||
|
||||
static spl_expr_result_t parse_prefix(spl_comp_t *ctx);
|
||||
static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, spl_tok_type_t op);
|
||||
|
||||
/* Slice creation from array/slice range expression.
|
||||
@@ -544,29 +533,6 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *
|
||||
return (spl_expr_result_t){type, 1}; /* address on stack */
|
||||
}
|
||||
}
|
||||
static spl_type_info_t *parse_qualified_type(spl_comp_t *ctx, const char *name) {
|
||||
/* Check if it's a known type */
|
||||
spl_type_info_t *t = spl_resolve_type(ctx, name);
|
||||
if (t && peek(ctx)->type == TOK_DOT) {
|
||||
/* Enum type with variant: Type.variant */
|
||||
advance(ctx); /* skip . */
|
||||
spl_tok_t *vtok = advance(ctx);
|
||||
char vname[256];
|
||||
usize vn = vtok->len < 255 ? vtok->len : 255;
|
||||
memcpy(vname, vtok->lexeme, vn);
|
||||
vname[vn] = '\0';
|
||||
/* For enum values, just emit the tag as integer */
|
||||
if (t->kind == TYPE_ENUM) {
|
||||
vec_for(t->variants, vi) {
|
||||
if (strcmp(vec_at(t->variants, vi).name, vname) == 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_I32, vec_at(t->variants, vi).value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
|
||||
spl_tok_t *t = advance(ctx);
|
||||
@@ -1045,16 +1011,14 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) {
|
||||
} else if (strcmp(fname, "ptr") == 0) {
|
||||
if (ctx->addr_of_mode) {
|
||||
/* lvalue: ptr is at offset 0, address already on stack */
|
||||
left = (spl_expr_result_t){
|
||||
left.type->elem ? spl_type_ptr(left.type->elem)
|
||||
: spl_type_basic(SPL_PTR),
|
||||
1};
|
||||
left = (spl_expr_result_t){left.type->elem ? spl_type_ptr(left.type->elem)
|
||||
: spl_type_basic(SPL_PTR),
|
||||
1};
|
||||
} else {
|
||||
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
|
||||
left = (spl_expr_result_t){
|
||||
left.type->elem ? spl_type_ptr(left.type->elem)
|
||||
: spl_type_basic(SPL_PTR),
|
||||
0};
|
||||
left = (spl_expr_result_t){left.type->elem ? spl_type_ptr(left.type->elem)
|
||||
: spl_type_basic(SPL_PTR),
|
||||
0};
|
||||
}
|
||||
}
|
||||
continue;
|
||||
@@ -1094,11 +1058,8 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) {
|
||||
}
|
||||
|
||||
/* Check for slice: expr[begin..end] or expr[begin..] */
|
||||
int is_slice = 0;
|
||||
usize slice_start = ctx->tok_idx;
|
||||
spl_expr_result_t index = spl_parse_expr(ctx, PREC_MIN);
|
||||
if (peek(ctx)->type == TOK_RANGE) {
|
||||
is_slice = 1;
|
||||
advance(ctx); /* skip .. */
|
||||
spl_expr_result_t end_expr = {0};
|
||||
int has_explicit_end = (peek(ctx)->type != TOK_R_BRACKET);
|
||||
@@ -1125,16 +1086,28 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) {
|
||||
if (left.type && (left.type->kind == TYPE_ARRAY || left.type->kind == TYPE_SLICE)) {
|
||||
usize stride = spl_type_elem_stride(left.type->elem);
|
||||
|
||||
/* For TYPE_SLICE: convert [struct_addr, begin, end] → [data_ptr, begin, end] */
|
||||
if (left.type->kind == TYPE_SLICE) {
|
||||
/* 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);
|
||||
spl_emit(ctx, SPL_ROT, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_ROT, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
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_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] */
|
||||
/* cleanup: drop [s,b,e] */
|
||||
spl_emit(ctx, SPL_ROT, SPL_VOID, 0); /* [s,b,ptr,len,e] */
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0); /* [s,b,ptr,len] */
|
||||
spl_emit(ctx, SPL_ROT, SPL_VOID, 0); /* [s,ptr,len,b] */
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0); /* [s,ptr,len] */
|
||||
spl_emit(ctx, SPL_ROT, SPL_VOID, 0); /* [ptr,len,s] */
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0); /* [ptr,len] */
|
||||
} else {
|
||||
emit_slice_create(ctx, stride);
|
||||
}
|
||||
|
||||
emit_slice_create(ctx, stride);
|
||||
}
|
||||
left = (spl_expr_result_t){left.type ? spl_type_slice(left.type->elem) : NULL, 0};
|
||||
continue;
|
||||
@@ -1196,14 +1169,14 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
if (op == TOK_AND_AND) {
|
||||
/* left is already evaluated and on stack. If it's false (0), skip right. */
|
||||
spl_val_t bz_addr = spl_emit_bz(ctx);
|
||||
spl_expr_result_t right = spl_parse_expr(ctx, next_prec);
|
||||
spl_parse_expr(ctx, next_prec);
|
||||
spl_patch_to_here(ctx, bz_addr);
|
||||
return (spl_expr_result_t){spl_type_basic(SPL_I32), 0};
|
||||
}
|
||||
if (op == TOK_OR_OR) {
|
||||
/* If left is true (non-zero), skip right. */
|
||||
spl_val_t bnz_addr = spl_emit_bnz(ctx);
|
||||
spl_expr_result_t right = spl_parse_expr(ctx, next_prec);
|
||||
spl_parse_expr(ctx, next_prec);
|
||||
spl_patch_to_here(ctx, bnz_addr);
|
||||
return (spl_expr_result_t){spl_type_basic(SPL_I32), 0};
|
||||
}
|
||||
@@ -1244,7 +1217,7 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
}
|
||||
|
||||
/* Regular binary op */
|
||||
spl_expr_result_t right = spl_parse_expr(ctx, next_prec);
|
||||
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;
|
||||
if (sop >= 0) {
|
||||
|
||||
Reference in New Issue
Block a user