stage1 修复错误 提供类型检查
This commit is contained in:
@@ -93,7 +93,12 @@ static int spl_resolve_type_member(spl_comp_t *ctx, int type_idx, const char *fi
|
||||
continue;
|
||||
if (strcmp(it->name, field) == 0) {
|
||||
emit_push_i32(&ctx->emit, it->enum_field.value);
|
||||
*result = (spl_expr_result_t){type_idx, 0};
|
||||
int data_type = it->enum_field.type_idx;
|
||||
if (data_type >= 0) {
|
||||
*result = (spl_expr_result_t){data_type, 0};
|
||||
} else {
|
||||
*result = (spl_expr_result_t){type_idx, 0};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -278,14 +283,17 @@ static spl_expr_result_t parse_array_literal(spl_comp_t *ctx) {
|
||||
|
||||
int len_val;
|
||||
if (!spl_parse_int_literal(ctx, &len_val)) {
|
||||
spl_comp_error(ctx, "expected array length");
|
||||
spl_comp_err_tok(ctx, peek(ctx), "expected array length");
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
usize len = (usize)len_val;
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
if (!expect(ctx, TOK_R_BRACKET)) {
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
skip_nl(ctx);
|
||||
|
||||
int elem_type_idx = spl_type_parse(&ctx->tctx, ctx);
|
||||
@@ -295,7 +303,10 @@ static spl_expr_result_t parse_array_literal(spl_comp_t *ctx) {
|
||||
}
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_BRACE);
|
||||
if (!expect(ctx, TOK_L_BRACE)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
skip_nl(ctx);
|
||||
|
||||
for (usize i = 0; i < len; i++) {
|
||||
@@ -311,7 +322,10 @@ static spl_expr_result_t parse_array_literal(spl_comp_t *ctx) {
|
||||
advance(ctx);
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
if (!expect(ctx, TOK_R_BRACE)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
|
||||
int arr_type_idx = spl_type_array(&ctx->tctx, elem_type_idx, len);
|
||||
return (spl_expr_result_t){arr_type_idx, 0};
|
||||
@@ -320,7 +334,8 @@ static spl_expr_result_t parse_array_literal(spl_comp_t *ctx) {
|
||||
static void parse_slice_inline(spl_comp_t *ctx) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
while (peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
skip_nl(ctx);
|
||||
while (!ctx->has_error && peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
@@ -347,7 +362,8 @@ static void parse_slice_inline(spl_comp_t *ctx) {
|
||||
}
|
||||
skip_nl(ctx);
|
||||
}
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
if (!expect(ctx, TOK_R_BRACE))
|
||||
return;
|
||||
emit_drop(&ctx->emit);
|
||||
}
|
||||
|
||||
@@ -363,11 +379,13 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
|
||||
int found = 0;
|
||||
vec_for(*items, fi) {
|
||||
spl_type_item_t *it = &vec_at(*items, fi);
|
||||
if (it->item_kind != ITEM_FIELD)
|
||||
continue;
|
||||
if (strcmp(it->name, fname) == 0) {
|
||||
found = 1;
|
||||
emit_laddr(&ctx->emit, base_offset);
|
||||
usize byte_off = extra_offset + it->aggregate_field.offset;
|
||||
emit_ptr_add(&ctx->emit, byte_off);
|
||||
@@ -381,16 +399,17 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
skip_nl(ctx);
|
||||
int len_val;
|
||||
if (!spl_parse_int_literal(ctx, &len_val)) {
|
||||
spl_comp_error(ctx, "expected array length");
|
||||
spl_comp_err_tok(ctx, peek(ctx), "expected array length");
|
||||
return;
|
||||
}
|
||||
usize arr_len = (usize)len_val;
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
if (!expect(ctx, TOK_R_BRACKET))
|
||||
return;
|
||||
skip_nl(ctx);
|
||||
int elem_type_idx = spl_type_parse(&ctx->tctx, ctx);
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_BRACE);
|
||||
int elem_type_idx = spl_type_elem_type(&ctx->tctx, ft_idx);
|
||||
if (!expect(ctx, TOK_L_BRACE))
|
||||
return;
|
||||
skip_nl(ctx);
|
||||
usize stride = spl_type_elem_stride(&ctx->tctx, elem_type_idx);
|
||||
spl_type_t st = spl_type_emit_type(&ctx->tctx, elem_type_idx);
|
||||
@@ -417,7 +436,8 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
if (peek(ctx)->type == TOK_COMMA)
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
if (!expect(ctx, TOK_R_BRACE))
|
||||
return;
|
||||
emit_drop(&ctx->emit);
|
||||
} else if (ft_idx >= 0 &&
|
||||
(spl_type_kind(&ctx->tctx, ft_idx) == TYPE_STRUCT ||
|
||||
@@ -444,6 +464,9 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
spl_comp_error(ctx, "unknown field '%s' in struct literal", fname);
|
||||
}
|
||||
}
|
||||
|
||||
spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
@@ -454,7 +477,7 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
skip_nl(ctx);
|
||||
|
||||
if (spl_type_kind(&ctx->tctx, type_idx) == TYPE_STRUCT) {
|
||||
while (peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
while (!ctx->has_error && peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
@@ -470,14 +493,8 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
skip_nl(ctx);
|
||||
}
|
||||
} else if (spl_type_kind(&ctx->tctx, type_idx) == TYPE_SLICE) {
|
||||
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);
|
||||
while (!ctx->has_error && peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
advance(ctx);
|
||||
spl_tok_t *ftok = advance(ctx);
|
||||
char fname[256];
|
||||
spl_tok_copy_name(ftok, fname, sizeof(fname));
|
||||
@@ -535,7 +552,8 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
peek(ctx)->type == TOK_L_BRACE) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
while (peek(ctx)->type != TOK_R_BRACE && peek(ctx)->type != TOK_EOF) {
|
||||
while (!ctx->has_error && peek(ctx)->type != TOK_R_BRACE &&
|
||||
peek(ctx)->type != TOK_EOF) {
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
@@ -547,7 +565,10 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
base_offset, DATA_OFFSET);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
if (!expect(ctx, TOK_R_BRACE)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
} else if (dt_idx >= 0 &&
|
||||
(spl_type_kind(&ctx->tctx, dt_idx) == TYPE_STRUCT ||
|
||||
spl_type_kind(&ctx->tctx, dt_idx) == TYPE_ENUM) &&
|
||||
@@ -577,11 +598,14 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
spl_comp_error(ctx, "unknown enum variant '%s'", vname);
|
||||
spl_comp_err_tok(ctx, vtok, "unknown enum variant '%s'", vname);
|
||||
}
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_R_BRACE);
|
||||
if (!expect(ctx, TOK_R_BRACE)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
|
||||
if (sz <= sizeof(spl_val_t)) {
|
||||
emit_laddr(&ctx->emit, base_offset);
|
||||
@@ -596,7 +620,7 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
static int parse_call_args(spl_comp_t *ctx) {
|
||||
int nargs = 0;
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
for (;;) {
|
||||
while (!ctx->has_error) {
|
||||
spl_parse_expr(ctx, PREC_MIN);
|
||||
nargs++;
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
@@ -708,8 +732,8 @@ static void spl_check_arg_type(spl_comp_t *ctx, const char *fname, int arg_type_
|
||||
type_mismatch:;
|
||||
const char *as = spl_type_str(&ctx->tctx, arg_type_idx);
|
||||
const char *ps = spl_type_str(&ctx->tctx, param_type_idx);
|
||||
spl_comp_error(ctx, "argument %d of '%s' type mismatch: expected '%s', got '%s'", arg_idx + 1,
|
||||
fname, ps, as);
|
||||
spl_comp_err_tok(ctx, peek(ctx), "argument %d of '%s' type mismatch: expected '%s', got '%s'",
|
||||
arg_idx + 1, fname, ps, as);
|
||||
}
|
||||
|
||||
static int parse_call_args_checked(spl_comp_t *ctx, const char *fname, int *param_type_indices,
|
||||
@@ -717,11 +741,20 @@ static int parse_call_args_checked(spl_comp_t *ctx, const char *fname, int *para
|
||||
int nargs = 0;
|
||||
int nlogical = 0;
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
for (;;) {
|
||||
while (!ctx->has_error) {
|
||||
spl_expr_result_t arg = spl_parse_expr(ctx, PREC_MIN);
|
||||
if (param_type_indices && nlogical < nparams && param_type_indices[nlogical] >= 0)
|
||||
if (param_type_indices && nlogical < nparams && param_type_indices[nlogical] >= 0) {
|
||||
int param_u = spl_type_resolve_underlying(&ctx->tctx, param_type_indices[nlogical]);
|
||||
int arg_u = spl_type_resolve_underlying(&ctx->tctx, arg.type_idx);
|
||||
if (arg.type_idx >= 0 && spl_type_kind(&ctx->tctx, param_u) == TYPE_BASIC &&
|
||||
spl_type_is_integer(spl_type_basic_type(&ctx->tctx, param_u)) &&
|
||||
spl_type_kind(&ctx->tctx, arg_u) == TYPE_BASIC &&
|
||||
spl_type_is_integer(spl_type_basic_type(&ctx->tctx, arg_u))) {
|
||||
arg.type_idx = param_type_indices[nlogical];
|
||||
}
|
||||
spl_check_arg_type(ctx, fname, arg.type_idx, param_type_indices[nlogical],
|
||||
nlogical);
|
||||
}
|
||||
|
||||
int arg_slots = 1;
|
||||
if (param_type_indices && nlogical < nparams && param_type_indices[nlogical] >= 0 &&
|
||||
@@ -761,7 +794,7 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
|
||||
if (peek(ctx)->type == TOK_L_PAREN) {
|
||||
int fi = spl_lookup_func(ctx, name);
|
||||
if (fi < 0) {
|
||||
spl_comp_error(ctx, "unknown function '%s'", name);
|
||||
spl_comp_err_tok(ctx, t, "unknown function '%s'", name);
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
@@ -769,12 +802,19 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
|
||||
advance(ctx);
|
||||
|
||||
int nargs = parse_call_args_checked(ctx, f->name, f->param_type_indices, f->nparams);
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
if (!expect(ctx, TOK_R_PAREN)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
|
||||
if (f->is_extern) {
|
||||
int nidx = spl_ensure_native(ctx, f->name);
|
||||
emit_push_i32(&ctx->emit, nidx);
|
||||
emit_ncall(&ctx->emit, nargs);
|
||||
if (spl_type_kind(&ctx->tctx, f->ret_type_idx) == TYPE_BASIC &&
|
||||
spl_type_basic_type(&ctx->tctx, f->ret_type_idx) == SPL_VOID) {
|
||||
emit_drop(&ctx->emit);
|
||||
}
|
||||
} else {
|
||||
emit_call_with_fixup(&ctx->emit, nargs, f->func_idx);
|
||||
}
|
||||
@@ -805,7 +845,12 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
|
||||
emit_laddr(&ctx->emit, v->offset);
|
||||
|
||||
spl_expr_result_t r;
|
||||
emit_load_or_addr_type(ctx, &r, vt_idx);
|
||||
spl_tok_type_t next_type = peek(ctx)->type;
|
||||
if (next_type == TOK_DOT) {
|
||||
r = (spl_expr_result_t){vt_idx, 1};
|
||||
} else {
|
||||
emit_load_or_addr_type(ctx, &r, vt_idx);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -820,7 +865,7 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
|
||||
return r;
|
||||
}
|
||||
|
||||
spl_comp_error(ctx, "undefined variable '%s'", name);
|
||||
spl_comp_err_tok(ctx, t, "undefined variable '%s'", name);
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
@@ -828,7 +873,8 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) {
|
||||
static spl_expr_result_t parse_group(spl_comp_t *ctx) {
|
||||
advance(ctx);
|
||||
spl_expr_result_t r = spl_parse_expr(ctx, PREC_MIN);
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
if (!expect(ctx, TOK_R_PAREN))
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -865,7 +911,9 @@ static spl_expr_result_t parse_prefix_op(spl_comp_t *ctx) {
|
||||
break;
|
||||
case TOK_AND:
|
||||
if (!right.is_lvalue) {
|
||||
spl_comp_error(ctx, "cannot take address of rvalue");
|
||||
spl_comp_err_tok(ctx, peek(ctx), "cannot take address of rvalue");
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
right.type_idx = spl_type_ptr(&ctx->tctx, right.type_idx);
|
||||
break;
|
||||
@@ -935,7 +983,7 @@ static spl_expr_result_t parse_primary_expr(spl_comp_t *ctx) {
|
||||
skip_nl(ctx);
|
||||
tok = peek(ctx);
|
||||
if (!tok || tok->type != TOK_IDENT) {
|
||||
spl_comp_error(ctx, "expected builtin name after '@'");
|
||||
spl_comp_err_tok(ctx, tok, "expected builtin name after '@'");
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
@@ -947,7 +995,10 @@ static spl_expr_result_t parse_primary_expr(spl_comp_t *ctx) {
|
||||
if (peek(ctx)->type == TOK_L_PAREN) {
|
||||
advance(ctx);
|
||||
int nargs = parse_call_args(ctx);
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
if (!expect(ctx, TOK_R_PAREN)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
for (int i = 0; i < nargs; i++) {
|
||||
emit_dbg_usize(&ctx->emit);
|
||||
emit_drop(&ctx->emit);
|
||||
@@ -959,11 +1010,17 @@ static spl_expr_result_t parse_primary_expr(spl_comp_t *ctx) {
|
||||
}
|
||||
return (spl_expr_result_t){spl_type_basic(&ctx->tctx, SPL_VOID), 0};
|
||||
} else if (strcmp(bname, "sizeof") == 0) {
|
||||
expect(ctx, TOK_L_PAREN);
|
||||
if (!expect(ctx, TOK_L_PAREN)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
int ti = spl_type_parse(&ctx->tctx, ctx);
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
if (!expect(ctx, TOK_R_PAREN)) {
|
||||
spl_expr_result_t _r = {-1, 0};
|
||||
return _r;
|
||||
}
|
||||
if (ti < 0) {
|
||||
spl_comp_error(ctx, "@sizeof: invalid type");
|
||||
spl_comp_err_tok(ctx, peek(ctx), "@sizeof: invalid type");
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
@@ -971,13 +1028,13 @@ static spl_expr_result_t parse_primary_expr(spl_comp_t *ctx) {
|
||||
emit_push_usize(&ctx->emit, sz);
|
||||
return (spl_expr_result_t){spl_type_basic(&ctx->tctx, SPL_USIZE), 0};
|
||||
} else {
|
||||
spl_comp_error(ctx, "unknown builtin '@%s'", bname);
|
||||
spl_comp_err_tok(ctx, peek(ctx), "unknown builtin '@%s'", bname);
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
return r;
|
||||
}
|
||||
}
|
||||
default:
|
||||
if (peek(ctx)->type >= KW_AS && peek(ctx)->type <= KW_ANY) {
|
||||
if (peek(ctx)->type > KW_AS && peek(ctx)->type <= KW_ANY) {
|
||||
return parse_ident(ctx);
|
||||
}
|
||||
spl_expr_result_t r = {-1, 0};
|
||||
@@ -990,6 +1047,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
return left;
|
||||
|
||||
for (;;) {
|
||||
if (ctx->has_error)
|
||||
break;
|
||||
skip_nl(ctx);
|
||||
spl_tok_type_t opt = peek(ctx)->type;
|
||||
|
||||
@@ -1044,8 +1103,9 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
|
||||
if (is_instance) {
|
||||
if (!left.is_lvalue && !is_ptr_self) {
|
||||
spl_comp_error(ctx, "cannot call instance method '%s' on type",
|
||||
fname);
|
||||
spl_comp_err_tok(ctx, field,
|
||||
"cannot call instance method '%s' on type", fname);
|
||||
return left;
|
||||
}
|
||||
emit_drop(&ctx->emit);
|
||||
nargs = 0;
|
||||
@@ -1056,7 +1116,10 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
int cn = func->nparams;
|
||||
nargs += parse_call_args_checked(ctx, func->name, cp, cn);
|
||||
}
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
if (!expect(ctx, TOK_R_PAREN)) {
|
||||
spl_expr_result_t _r = left;
|
||||
return _r;
|
||||
}
|
||||
|
||||
if (func->func_idx < 0) {
|
||||
fprintf(stderr, "WARN: method call '%s.' with invalid func_idx=%d\n",
|
||||
@@ -1083,6 +1146,7 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
|
||||
if (left.type_idx >= 0 && spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_STRUCT) {
|
||||
spl_type_item_vec_t *f_items = spl_type_items(&ctx->tctx, left.type_idx);
|
||||
int found = 0;
|
||||
vec_for(*f_items, fi) {
|
||||
spl_type_item_t *fit = &vec_at(*f_items, fi);
|
||||
if (fit->item_kind != ITEM_FIELD)
|
||||
@@ -1090,10 +1154,12 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
if (strcmp(fit->name, fname) == 0) {
|
||||
emit_ptr_add(&ctx->emit, fit->aggregate_field.offset);
|
||||
emit_load_or_addr_type(ctx, &left, fit->aggregate_field.type_idx);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
if (found)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (left.type_idx >= 0 && spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_PTR) {
|
||||
@@ -1103,6 +1169,7 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
emit_load_ptr(&ctx->emit);
|
||||
}
|
||||
spl_type_item_vec_t *st_items = spl_type_items(&ctx->tctx, elem_idx);
|
||||
int found = 0;
|
||||
vec_for(*st_items, si) {
|
||||
spl_type_item_t *sit = &vec_at(*st_items, si);
|
||||
if (sit->item_kind != ITEM_FIELD)
|
||||
@@ -1110,10 +1177,12 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
if (strcmp(sit->name, fname) == 0) {
|
||||
emit_ptr_add(&ctx->emit, sit->aggregate_field.offset);
|
||||
emit_load_or_addr_type(ctx, &left, sit->aggregate_field.type_idx);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
if (found)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,7 +1228,7 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
continue;
|
||||
}
|
||||
|
||||
spl_comp_error(ctx, "unknown field '%s'", fname);
|
||||
spl_comp_err_tok(ctx, field, "unknown field '%s'", fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1186,7 +1255,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
ctx->addr_of_mode = saved_aom;
|
||||
}
|
||||
(void)end_expr;
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
if (!expect(ctx, TOK_R_BRACKET))
|
||||
return left;
|
||||
|
||||
if (!has_explicit_end) {
|
||||
if (left.type_idx >= 0 &&
|
||||
@@ -1235,7 +1305,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
continue;
|
||||
}
|
||||
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
if (!expect(ctx, TOK_R_BRACKET))
|
||||
break;
|
||||
|
||||
if (left.type_idx >= 0 && (spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_ARRAY ||
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_PTR ||
|
||||
@@ -1304,8 +1375,7 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) {
|
||||
spl_expr_result_t left = parse_primary_expr(ctx);
|
||||
if (left.type_idx < 0)
|
||||
return left;
|
||||
|
||||
while (1) {
|
||||
while (!ctx->has_error) {
|
||||
left = parse_postfix_expr(ctx, left);
|
||||
|
||||
skip_nl(ctx);
|
||||
@@ -1378,8 +1448,8 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
spl_parse_expr(ctx, next_prec);
|
||||
if ((op == TOK_EQ || op == TOK_NEQ) && left.type_idx >= 0 &&
|
||||
!spl_type_is_scalar(&ctx->tctx, left.type_idx)) {
|
||||
spl_comp_error(ctx, "type '%s' does not support comparison",
|
||||
spl_type_str(&ctx->tctx, left.type_idx));
|
||||
spl_comp_err_tok(ctx, peek(ctx), "type '%s' does not support comparison",
|
||||
spl_type_str(&ctx->tctx, left.type_idx));
|
||||
}
|
||||
spl_type_t bt = spl_type_emit_type(&ctx->tctx, left.type_idx);
|
||||
int sop = binop_to_sir(op, bt);
|
||||
@@ -1394,29 +1464,27 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
|
||||
int spl_emit_match_enum_cmp(spl_comp_t *ctx, int enum_type_idx, int val_offset, int by_value) {
|
||||
char vname[256];
|
||||
spl_tok_t *vtok = NULL;
|
||||
|
||||
if (peek(ctx)->type == TOK_DOT) {
|
||||
advance(ctx);
|
||||
vtok = advance(ctx);
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
} else {
|
||||
spl_tok_t *tok = advance(ctx);
|
||||
spl_tok_copy_name(tok, vname, sizeof(vname));
|
||||
vtok = advance(ctx);
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
|
||||
while (peek(ctx)->type == TOK_DOT) {
|
||||
int qt_idx = spl_type_resolve(&ctx->tctx, vname);
|
||||
(void)qt_idx;
|
||||
advance(ctx);
|
||||
tok = advance(ctx);
|
||||
spl_tok_copy_name(tok, vname, sizeof(vname));
|
||||
vtok = advance(ctx);
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
}
|
||||
|
||||
goto lookup;
|
||||
}
|
||||
|
||||
{
|
||||
spl_tok_t *vtok = advance(ctx);
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
}
|
||||
|
||||
lookup: {
|
||||
spl_type_item_vec_t *e_items = spl_type_items(&ctx->tctx, enum_type_idx);
|
||||
vec_for(*e_items, vi) {
|
||||
@@ -1438,7 +1506,7 @@ lookup: {
|
||||
}
|
||||
}
|
||||
}
|
||||
spl_comp_error(ctx, "unknown variant '%s' in match", vname);
|
||||
spl_comp_err_tok(ctx, vtok, "unknown variant '%s' in match", vname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user