stage1 优化重构代码
This commit is contained in:
@@ -21,6 +21,44 @@ spl_tok_t *advance(spl_comp_t *ctx) {
|
||||
|
||||
/* Shared helper: register a function, declare params, parse body, end function.
|
||||
* Used by both top-level fn decl and methods inside type bodies. */
|
||||
/* Shared helper: parse function/method parameter list: (name: type, name: type, ...)
|
||||
* Returns number of params parsed. Stores names in pnames and types in ptypes
|
||||
* (both must be MAX_PARAMS-sized arrays). */
|
||||
enum { MAX_PARAMS = 64 };
|
||||
|
||||
static int parse_params_decl(spl_comp_t *ctx, char pnames[][256], spl_type_info_t *ptypes[]) {
|
||||
int nparams = 0;
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
while (1) {
|
||||
spl_tok_t *pname = advance(ctx);
|
||||
spl_tok_copy_name(pname, pnames[nparams], 256);
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
ptypes[nparams] = spl_parse_type(ctx);
|
||||
} else {
|
||||
ptypes[nparams] = spl_type_basic(SPL_I32);
|
||||
}
|
||||
nparams++;
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
continue;
|
||||
}
|
||||
if (peek(ctx)->type == TOK_ELLIPSIS) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
return nparams;
|
||||
}
|
||||
|
||||
static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, spl_type_info_t *ret_type,
|
||||
int nparams, char pnames[][256], spl_type_info_t *ptypes[], int is_pub) {
|
||||
int fi = spl_declare_func(ctx, fn_name, ret_type, nparams, 0, is_pub);
|
||||
@@ -68,48 +106,15 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
|
||||
|
||||
spl_tok_t *fname_tok = advance(ctx);
|
||||
char fn_name[256];
|
||||
usize fnl = fname_tok->len < 255 ? fname_tok->len : 255;
|
||||
memcpy(fn_name, fname_tok->lexeme, fnl);
|
||||
fn_name[fnl] = '\0';
|
||||
spl_tok_copy_name(fname_tok, fn_name, sizeof(fn_name));
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_PAREN);
|
||||
|
||||
/* Parse parameters — collect names and types */
|
||||
int nparams = 0;
|
||||
enum { MAX_PARAMS = 64 };
|
||||
char pnames[MAX_PARAMS][256];
|
||||
spl_type_info_t *ptypes[MAX_PARAMS];
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
while (1) {
|
||||
spl_tok_t *pname = advance(ctx);
|
||||
usize pnl = pname->len < 255 ? pname->len : 255;
|
||||
memcpy(pnames[nparams], pname->lexeme, pnl);
|
||||
pnames[nparams][pnl] = '\0';
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
ptypes[nparams] = spl_parse_type(ctx);
|
||||
} else {
|
||||
ptypes[nparams] = spl_type_basic(SPL_I32);
|
||||
}
|
||||
nparams++;
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
continue;
|
||||
}
|
||||
if (peek(ctx)->type == TOK_ELLIPSIS) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
int nparams = parse_params_decl(ctx, pnames, ptypes);
|
||||
skip_nl(ctx);
|
||||
|
||||
/* Return type (default: void) */
|
||||
@@ -124,22 +129,7 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
|
||||
/* Extern function: register as native, no body */
|
||||
if (is_extern) {
|
||||
spl_declare_func(ctx, fn_name, ret_type, nparams, 1, is_pub);
|
||||
/* Add to prog->natives for NCALL dispatch */
|
||||
int found = -1;
|
||||
vec_for(ctx->prog.natives, ni) {
|
||||
if (strcmp(vec_at(ctx->prog.natives, ni).name, fn_name) == 0) {
|
||||
found = (int)ni;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found < 0) {
|
||||
spl_native_t nat;
|
||||
memset(&nat, 0, sizeof(nat));
|
||||
nat.name = strdup(fn_name);
|
||||
nat.idx_of_strtab = 0;
|
||||
nat.impl_fn = NULL; /* resolved by VM at runtime */
|
||||
vec_push(ctx->prog.natives, nat);
|
||||
}
|
||||
spl_ensure_native(ctx, fn_name);
|
||||
if (peek(ctx)->type == TOK_SEMICOLON)
|
||||
advance(ctx);
|
||||
return;
|
||||
@@ -158,22 +148,84 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Parse struct/union body (shared for struct and union containers)
|
||||
* Shared helper: parse a method declaration inside a type body.
|
||||
* Used by both struct_body and enum_body parsers.
|
||||
* fn name(params) ret-type { body }
|
||||
* ============================================================ */
|
||||
|
||||
static void parse_method_decl(spl_comp_t *ctx, spl_type_info_t *container) {
|
||||
advance(ctx); /* fn */
|
||||
skip_nl(ctx);
|
||||
spl_tok_t *mname_tok = advance(ctx);
|
||||
char mname[256];
|
||||
spl_tok_copy_name(mname_tok, mname, sizeof(mname));
|
||||
|
||||
/* Build qualified name: TypeName.method_name */
|
||||
char qualified[512];
|
||||
snprintf(qualified, sizeof(qualified), "%s.%s", container->name ? container->name : "anon",
|
||||
mname);
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_PAREN);
|
||||
|
||||
/* Parse parameters using shared helper */
|
||||
char pnames[MAX_PARAMS][256];
|
||||
spl_type_info_t *ptypes[MAX_PARAMS];
|
||||
int nparams = parse_params_decl(ctx, pnames, ptypes);
|
||||
skip_nl(ctx);
|
||||
|
||||
/* Return type (default: void) */
|
||||
spl_type_info_t *ret_type = spl_type_basic(SPL_VOID);
|
||||
if (peek(ctx)->type != TOK_SEMICOLON && peek(ctx)->type != TOK_L_BRACE) {
|
||||
ret_type = spl_parse_type(ctx);
|
||||
if (!ret_type)
|
||||
ret_type = spl_type_basic(SPL_VOID);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
|
||||
/* Set current_type_name for short-name resolution inside method body */
|
||||
const char *saved_type_name = ctx->current_type_name;
|
||||
ctx->current_type_name = container->name;
|
||||
|
||||
int fi = parse_fn_body(ctx, qualified, ret_type, nparams, pnames, ptypes, 0);
|
||||
|
||||
ctx->current_type_name = saved_type_name;
|
||||
|
||||
{
|
||||
spl_func_info_t *f = &vec_at(ctx->funcs, fi);
|
||||
f->param_types = calloc(nparams, sizeof(spl_type_info_t *));
|
||||
f->param_names = calloc(nparams, sizeof(char *));
|
||||
for (int i = 0; i < nparams; i++) {
|
||||
f->param_types[i] = ptypes[i];
|
||||
f->param_names[i] = strdup(pnames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
spl_type_add_method(container, mname, fi);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Parse type container body (shared for struct, union, enum)
|
||||
*
|
||||
* For struct/union: fields are added for identifiers
|
||||
* For enum: variants are added for identifiers
|
||||
*
|
||||
* Body supports:
|
||||
* var name: type; — field declarations
|
||||
* name: type, — field declarations (old-style)
|
||||
* var name: type; — field declarations (struct/union only)
|
||||
* name: type, — field/variant declarations
|
||||
* name: Type, — enum variant with data
|
||||
* name, — simple enum variant
|
||||
* type Name = ...; — nested type declarations
|
||||
* fn name(...) type { } — methods
|
||||
* ============================================================ */
|
||||
|
||||
static void parse_struct_body(spl_comp_t *ctx, spl_type_info_t *st) {
|
||||
static void parse_type_body(spl_comp_t *ctx, spl_type_info_t *container, int is_enum) {
|
||||
if (peek(ctx)->type != TOK_L_BRACE)
|
||||
return;
|
||||
advance(ctx); /* { */
|
||||
|
||||
/* === Pass 1: Parse all nested type declarations first ===
|
||||
* This allows field declarations to reference types defined later in the body. */
|
||||
* This allows fields/variants to reference types defined later. */
|
||||
{
|
||||
usize saved = ctx->tok_idx;
|
||||
int depth = 1;
|
||||
@@ -193,11 +245,10 @@ static void parse_struct_body(spl_comp_t *ctx, spl_type_info_t *st) {
|
||||
advance(ctx);
|
||||
}
|
||||
}
|
||||
/* Reset to start of body for second pass */
|
||||
ctx->tok_idx = saved;
|
||||
}
|
||||
|
||||
/* === Pass 2: Parse fields and methods === */
|
||||
/* === Pass 2: Parse fields/variants and methods === */
|
||||
{
|
||||
int depth = 1;
|
||||
while (depth > 0 && ctx->tok_idx < vec_size(ctx->toks)) {
|
||||
@@ -214,10 +265,10 @@ static void parse_struct_body(spl_comp_t *ctx, spl_type_info_t *st) {
|
||||
}
|
||||
advance(ctx);
|
||||
} else if (tt == KW_TYPE && depth == 1) {
|
||||
/* Nested type — already parsed in pass 1, skip by re-parsing */
|
||||
/* Nested type — already parsed in pass 1, skip */
|
||||
parse_type_decl(ctx);
|
||||
} else if (tt == KW_VAR && depth == 1) {
|
||||
/* var name: type; */
|
||||
} else if (tt == KW_VAR && depth == 1 && !is_enum) {
|
||||
/* var name: type; (struct/union only) */
|
||||
advance(ctx); /* var */
|
||||
skip_nl(ctx);
|
||||
spl_tok_t *ftok = advance(ctx);
|
||||
@@ -227,286 +278,54 @@ static void parse_struct_body(spl_comp_t *ctx, spl_type_info_t *st) {
|
||||
skip_nl(ctx);
|
||||
spl_type_info_t *ftype = spl_parse_type(ctx);
|
||||
char fname[256];
|
||||
usize fnl = ftok->len < 255 ? ftok->len : 255;
|
||||
memcpy(fname, ftok->lexeme, fnl);
|
||||
fname[fnl] = '\0';
|
||||
spl_type_add_field(st, fname, ftype);
|
||||
spl_tok_copy_name(ftok, fname, sizeof(fname));
|
||||
spl_type_add_field(container, fname, ftype);
|
||||
}
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_SEMICOLON || peek(ctx)->type == TOK_COMMA)
|
||||
advance(ctx);
|
||||
} else if (tt == TOK_IDENT && depth == 1) {
|
||||
/* Old-style field: name: type, */
|
||||
spl_tok_t *ftok = advance(ctx);
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
if (is_enum) {
|
||||
/* Variant: Name or Name: Type */
|
||||
spl_tok_t *vtok = advance(ctx);
|
||||
skip_nl(ctx);
|
||||
spl_type_info_t *ftype = spl_parse_type(ctx);
|
||||
char fname[256];
|
||||
usize fnl = ftok->len < 255 ? ftok->len : 255;
|
||||
memcpy(fname, ftok->lexeme, fnl);
|
||||
fname[fnl] = '\0';
|
||||
spl_type_add_field(st, fname, ftype);
|
||||
}
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_SEMICOLON || peek(ctx)->type == TOK_COMMA)
|
||||
advance(ctx);
|
||||
} else if (tt == KW_FN && depth == 1) {
|
||||
/* Method — parse properly using parse_fn_body */
|
||||
advance(ctx); /* fn */
|
||||
skip_nl(ctx);
|
||||
spl_tok_t *mname_tok = advance(ctx);
|
||||
char mname[256];
|
||||
usize mnl = mname_tok->len < 255 ? mname_tok->len : 255;
|
||||
memcpy(mname, mname_tok->lexeme, mnl);
|
||||
mname[mnl] = '\0';
|
||||
|
||||
/* Build qualified name: TypeName.method_name */
|
||||
char qualified[512];
|
||||
snprintf(qualified, sizeof(qualified), "%s.%s", st->name ? st->name : "anon",
|
||||
mname);
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_PAREN);
|
||||
|
||||
/* Parse parameters */
|
||||
int nparams = 0;
|
||||
enum { MAX_PARAMS = 64 };
|
||||
char pnames[MAX_PARAMS][256];
|
||||
spl_type_info_t *ptypes[MAX_PARAMS];
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
while (1) {
|
||||
spl_tok_t *pname = advance(ctx);
|
||||
usize pnl = pname->len < 255 ? pname->len : 255;
|
||||
memcpy(pnames[nparams], pname->lexeme, pnl);
|
||||
pnames[nparams][pnl] = '\0';
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
ptypes[nparams] = spl_parse_type(ctx);
|
||||
} else {
|
||||
ptypes[nparams] = spl_type_basic(SPL_I32);
|
||||
}
|
||||
nparams++;
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
spl_type_info_t *dtype = spl_parse_type(ctx);
|
||||
char vname[256];
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
spl_type_add_variant(container, vname, dtype);
|
||||
} else {
|
||||
char vname[256];
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
spl_type_add_variant(container, vname, NULL);
|
||||
}
|
||||
}
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
skip_nl(ctx);
|
||||
|
||||
/* Return type (default: void) */
|
||||
spl_type_info_t *ret_type = spl_type_basic(SPL_VOID);
|
||||
if (peek(ctx)->type != TOK_SEMICOLON && peek(ctx)->type != TOK_L_BRACE) {
|
||||
ret_type = spl_parse_type(ctx);
|
||||
if (!ret_type)
|
||||
ret_type = spl_type_basic(SPL_VOID);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
|
||||
/* Set current_type_name for short-name resolution inside method body */
|
||||
const char *saved_type_name = ctx->current_type_name;
|
||||
ctx->current_type_name = st->name;
|
||||
|
||||
int fi = parse_fn_body(ctx, qualified, ret_type, nparams, pnames, ptypes, 0);
|
||||
|
||||
{
|
||||
spl_func_info_t *f = &vec_at(ctx->funcs, fi);
|
||||
f->param_types = calloc(nparams, sizeof(spl_type_info_t *));
|
||||
f->param_names = calloc(nparams, sizeof(char *));
|
||||
for (int i = 0; i < nparams; i++) {
|
||||
f->param_types[i] = ptypes[i];
|
||||
f->param_names[i] = strdup(pnames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->current_type_name = saved_type_name;
|
||||
|
||||
spl_type_add_method(st, mname, fi);
|
||||
} else {
|
||||
advance(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_type_compute_layout(st);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Parse enum body
|
||||
*
|
||||
* Body supports:
|
||||
* Name — simple variant
|
||||
* Name: Type — variant with data
|
||||
* var name: type; — field-style variant
|
||||
* type Name = ...; — nested type declarations
|
||||
* fn name(...) type { } — methods (skipped)
|
||||
* ============================================================ */
|
||||
|
||||
static void parse_enum_body(spl_comp_t *ctx, spl_type_info_t *et) {
|
||||
if (peek(ctx)->type != TOK_L_BRACE)
|
||||
return;
|
||||
advance(ctx); /* { */
|
||||
|
||||
/* === Pass 1: Parse all nested type declarations first === */
|
||||
{
|
||||
usize saved = ctx->tok_idx;
|
||||
int depth = 1;
|
||||
while (depth > 0 && ctx->tok_idx < vec_size(ctx->toks)) {
|
||||
spl_tok_type_t tt = peek(ctx)->type;
|
||||
if (tt == TOK_L_BRACE) {
|
||||
depth++;
|
||||
advance(ctx);
|
||||
} else if (tt == TOK_R_BRACE) {
|
||||
depth--;
|
||||
if (depth == 0)
|
||||
break;
|
||||
advance(ctx);
|
||||
} else if (tt == KW_TYPE && depth == 1) {
|
||||
parse_type_decl(ctx);
|
||||
} else {
|
||||
advance(ctx);
|
||||
}
|
||||
}
|
||||
ctx->tok_idx = saved;
|
||||
}
|
||||
|
||||
/* === Pass 2: Parse variants and methods === */
|
||||
{
|
||||
int depth = 1;
|
||||
while (depth > 0 && ctx->tok_idx < vec_size(ctx->toks)) {
|
||||
skip_nl(ctx);
|
||||
spl_tok_type_t tt = peek(ctx)->type;
|
||||
if (tt == TOK_L_BRACE) {
|
||||
depth++;
|
||||
advance(ctx);
|
||||
} else if (tt == TOK_R_BRACE) {
|
||||
depth--;
|
||||
if (depth == 0) {
|
||||
advance(ctx);
|
||||
break;
|
||||
}
|
||||
advance(ctx);
|
||||
} else if (tt == KW_TYPE && depth == 1) {
|
||||
/* Already parsed in pass 1, re-parse to skip */
|
||||
parse_type_decl(ctx);
|
||||
} else if (tt == TOK_IDENT && depth == 1) {
|
||||
/* Variant: Name or Name: Type */
|
||||
spl_tok_t *vtok = advance(ctx);
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
spl_type_info_t *dtype = spl_parse_type(ctx);
|
||||
char vname[256];
|
||||
usize vnl = vtok->len < 255 ? vtok->len : 255;
|
||||
memcpy(vname, vtok->lexeme, vnl);
|
||||
vname[vnl] = '\0';
|
||||
spl_type_add_variant(et, vname, dtype);
|
||||
} else {
|
||||
char vname[256];
|
||||
usize vnl = vtok->len < 255 ? vtok->len : 255;
|
||||
memcpy(vname, vtok->lexeme, vnl);
|
||||
vname[vnl] = '\0';
|
||||
spl_type_add_variant(et, vname, NULL);
|
||||
/* Old-style field: name: type, */
|
||||
spl_tok_t *ftok = advance(ctx);
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
spl_type_info_t *ftype = spl_parse_type(ctx);
|
||||
char fname[256];
|
||||
spl_tok_copy_name(ftok, fname, sizeof(fname));
|
||||
spl_type_add_field(container, fname, ftype);
|
||||
}
|
||||
}
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_SEMICOLON || peek(ctx)->type == TOK_COMMA)
|
||||
advance(ctx);
|
||||
} else if (tt == KW_FN && depth == 1) {
|
||||
/* Method — parse properly using parse_fn_body */
|
||||
advance(ctx); /* fn */
|
||||
skip_nl(ctx);
|
||||
spl_tok_t *mname_tok = advance(ctx);
|
||||
char mname[256];
|
||||
usize mnl = mname_tok->len < 255 ? mname_tok->len : 255;
|
||||
memcpy(mname, mname_tok->lexeme, mnl);
|
||||
mname[mnl] = '\0';
|
||||
|
||||
/* Build qualified name: TypeName.method_name */
|
||||
char qualified[512];
|
||||
snprintf(qualified, sizeof(qualified), "%s.%s", et->name ? et->name : "anon",
|
||||
mname);
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_L_PAREN);
|
||||
|
||||
/* Parse parameters */
|
||||
int nparams = 0;
|
||||
enum { MAX_PARAMS = 64 };
|
||||
char pnames[MAX_PARAMS][256];
|
||||
spl_type_info_t *ptypes[MAX_PARAMS];
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
while (1) {
|
||||
spl_tok_t *pname = advance(ctx);
|
||||
usize pnl = pname->len < 255 ? pname->len : 255;
|
||||
memcpy(pnames[nparams], pname->lexeme, pnl);
|
||||
pnames[nparams][pnl] = '\0';
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COLON) {
|
||||
advance(ctx); /* : */
|
||||
skip_nl(ctx);
|
||||
ptypes[nparams] = spl_parse_type(ctx);
|
||||
} else {
|
||||
ptypes[nparams] = spl_type_basic(SPL_I32);
|
||||
}
|
||||
nparams++;
|
||||
skip_nl(ctx);
|
||||
if (peek(ctx)->type == TOK_COMMA) {
|
||||
advance(ctx);
|
||||
skip_nl(ctx);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(ctx, TOK_R_PAREN);
|
||||
skip_nl(ctx);
|
||||
|
||||
/* Return type (default: void) */
|
||||
spl_type_info_t *ret_type = spl_type_basic(SPL_VOID);
|
||||
if (peek(ctx)->type != TOK_SEMICOLON && peek(ctx)->type != TOK_L_BRACE) {
|
||||
ret_type = spl_parse_type(ctx);
|
||||
if (!ret_type)
|
||||
ret_type = spl_type_basic(SPL_VOID);
|
||||
skip_nl(ctx);
|
||||
}
|
||||
|
||||
/* Set current_type_name for short-name resolution inside method body */
|
||||
const char *saved_type_name = ctx->current_type_name;
|
||||
ctx->current_type_name = et->name;
|
||||
|
||||
int fi = parse_fn_body(ctx, qualified, ret_type, nparams, pnames, ptypes, 0);
|
||||
|
||||
ctx->current_type_name = saved_type_name;
|
||||
|
||||
{
|
||||
spl_func_info_t *f = &vec_at(ctx->funcs, fi);
|
||||
f->param_types = calloc(nparams, sizeof(spl_type_info_t *));
|
||||
f->param_names = calloc(nparams, sizeof(char *));
|
||||
for (int i = 0; i < nparams; i++) {
|
||||
f->param_types[i] = ptypes[i];
|
||||
f->param_names[i] = strdup(pnames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
spl_type_add_method(et, mname, fi);
|
||||
parse_method_decl(ctx, container);
|
||||
} else {
|
||||
advance(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_type_compute_layout(et);
|
||||
spl_type_compute_layout(container);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
@@ -521,9 +340,7 @@ void parse_type_decl(spl_comp_t *ctx) {
|
||||
advance(ctx); /* type */
|
||||
spl_tok_t *name_tok = advance(ctx);
|
||||
char tname[256];
|
||||
usize tnl = name_tok->len < 255 ? name_tok->len : 255;
|
||||
memcpy(tname, name_tok->lexeme, tnl);
|
||||
tname[tnl] = '\0';
|
||||
spl_tok_copy_name(name_tok, tname, sizeof(tname));
|
||||
|
||||
skip_nl(ctx);
|
||||
expect(ctx, TOK_ASSIGN);
|
||||
@@ -535,20 +352,20 @@ void parse_type_decl(spl_comp_t *ctx) {
|
||||
/* Register type early to allow self-referential fields */
|
||||
map_put(ctx->type_defs, strdup(tname), st);
|
||||
skip_nl(ctx);
|
||||
parse_struct_body(ctx, st);
|
||||
parse_type_body(ctx, st, 0);
|
||||
} else if (peek(ctx)->type == KW_UNION) {
|
||||
advance(ctx);
|
||||
spl_type_info_t *ut = spl_type_union(tname);
|
||||
map_put(ctx->type_defs, strdup(tname), ut);
|
||||
skip_nl(ctx);
|
||||
parse_struct_body(ctx, ut);
|
||||
parse_type_body(ctx, ut, 0);
|
||||
} else if (peek(ctx)->type == KW_ENUM) {
|
||||
advance(ctx);
|
||||
spl_type_info_t *et = spl_type_enum(tname);
|
||||
/* Register type early to allow self-referential variants */
|
||||
map_put(ctx->type_defs, strdup(tname), et);
|
||||
skip_nl(ctx);
|
||||
parse_enum_body(ctx, et);
|
||||
parse_type_body(ctx, et, 1);
|
||||
} else if (peek(ctx)->type == TOK_IDENT ||
|
||||
(peek(ctx)->type >= KW_AS && peek(ctx)->type <= KW_ANY)) {
|
||||
spl_type_info_t *base = spl_parse_type(ctx);
|
||||
|
||||
Reference in New Issue
Block a user