stage1 实现06测试

This commit is contained in:
zzy
2026-07-05 22:47:00 +08:00
parent e2e0ebc21f
commit 67c8a137dd
6 changed files with 365 additions and 132 deletions

View File

@@ -1,28 +1,30 @@
/* spl_parser.c — Top-level parser: function declarations, type declarations, etc. */
#include "spl_comp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static spl_tok_t *peek(spl_comp_t *ctx) {
return &vec_at(ctx->toks, ctx->tok_idx);
}
static spl_tok_t *peek(spl_comp_t *ctx) { return &vec_at(ctx->toks, ctx->tok_idx); }
static spl_tok_t *advance(spl_comp_t *ctx) {
spl_tok_t *t = &vec_at(ctx->toks, ctx->tok_idx);
if (t->type != TOK_EOF) ctx->tok_idx++;
if (t->type != TOK_EOF)
ctx->tok_idx++;
return t;
}
static int expect(spl_comp_t *ctx, spl_tok_type_t type) {
if (peek(ctx)->type == type) { advance(ctx); return 1; }
spl_comp_error(ctx, "expected '%s', got '%s'", spl_tok_type_name(type), spl_tok_type_name(peek(ctx)->type));
if (peek(ctx)->type == type) {
advance(ctx);
return 1;
}
spl_comp_error(ctx, "expected '%s', got '%s'", spl_tok_type_name(type),
spl_tok_type_name(peek(ctx)->type));
return 0;
}
static void skip_nl(spl_comp_t *ctx) {
while (peek(ctx)->type == TOK_ENDLINE) advance(ctx);
while (peek(ctx)->type == TOK_ENDLINE)
advance(ctx);
}
/* ============================================================
@@ -38,7 +40,8 @@ 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';
memcpy(fn_name, fname_tok->lexeme, fnl);
fn_name[fnl] = '\0';
skip_nl(ctx);
expect(ctx, TOK_L_PAREN);
@@ -65,8 +68,15 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
}
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); }
if (peek(ctx)->type == TOK_COMMA) {
advance(ctx);
skip_nl(ctx);
continue;
}
if (peek(ctx)->type == TOK_ELLIPSIS) {
advance(ctx);
skip_nl(ctx);
}
break;
}
}
@@ -77,7 +87,8 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
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);
if (!ret_type)
ret_type = spl_type_basic(SPL_VOID);
skip_nl(ctx);
}
@@ -88,7 +99,8 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
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;
found = (int)ni;
break;
}
}
if (found < 0) {
@@ -99,7 +111,8 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) {
nat.impl_fn = NULL; /* resolved by VM at runtime */
vec_push(ctx->prog.natives, nat);
}
if (peek(ctx)->type == TOK_SEMICOLON) advance(ctx);
if (peek(ctx)->type == TOK_SEMICOLON)
advance(ctx);
return;
}
@@ -170,7 +183,8 @@ void parse_type_decl(spl_comp_t *ctx) {
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';
memcpy(tname, name_tok->lexeme, tnl);
tname[tnl] = '\0';
skip_nl(ctx);
expect(ctx, TOK_ASSIGN);
@@ -192,13 +206,18 @@ void parse_type_decl(spl_comp_t *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';
memcpy(fname, ftok->lexeme, fnl);
fname[fnl] = '\0';
spl_type_add_field(st, fname, ftype);
}
skip_nl(ctx);
if (peek(ctx)->type == TOK_COMMA) { advance(ctx); skip_nl(ctx); }
if (peek(ctx)->type == TOK_COMMA) {
advance(ctx);
skip_nl(ctx);
}
}
if (peek(ctx)->type == TOK_R_BRACE) advance(ctx);
if (peek(ctx)->type == TOK_R_BRACE)
advance(ctx);
}
spl_type_compute_layout(st);
map_put(ctx->type_defs, strdup(tname), st);
@@ -218,22 +237,29 @@ void parse_type_decl(spl_comp_t *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';
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';
memcpy(vname, vtok->lexeme, vnl);
vname[vnl] = '\0';
spl_type_add_variant(et, vname, NULL);
}
skip_nl(ctx);
if (peek(ctx)->type == TOK_COMMA) { advance(ctx); skip_nl(ctx); }
if (peek(ctx)->type == TOK_COMMA) {
advance(ctx);
skip_nl(ctx);
}
}
if (peek(ctx)->type == TOK_R_BRACE) advance(ctx);
if (peek(ctx)->type == TOK_R_BRACE)
advance(ctx);
}
spl_type_compute_layout(et);
map_put(ctx->type_defs, strdup(tname), et);
} else if (peek(ctx)->type == TOK_IDENT || (peek(ctx)->type >= KW_AS && peek(ctx)->type <= KW_ANY)) {
} 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);
if (base) {
spl_type_info_t *alias = spl_type_clone(base);
@@ -244,7 +270,8 @@ void parse_type_decl(spl_comp_t *ctx) {
}
skip_nl(ctx);
if (peek(ctx)->type == TOK_SEMICOLON) advance(ctx);
if (peek(ctx)->type == TOK_SEMICOLON)
advance(ctx);
}
/* ============================================================
@@ -254,7 +281,8 @@ void parse_type_decl(spl_comp_t *ctx) {
void spl_parse_prog(spl_comp_t *ctx) {
while (peek(ctx)->type != TOK_EOF) {
skip_nl(ctx);
if (peek(ctx)->type == TOK_EOF) break;
if (peek(ctx)->type == TOK_EOF)
break;
switch (peek(ctx)->type) {
case KW_FN:
@@ -266,8 +294,10 @@ void spl_parse_prog(spl_comp_t *ctx) {
case KW_PUB: {
advance(ctx); /* skip pub */
skip_nl(ctx);
if (peek(ctx)->type == KW_FN) parse_fn_decl(ctx, 0, 1);
else if (peek(ctx)->type == KW_TYPE) parse_type_decl(ctx);
if (peek(ctx)->type == KW_FN)
parse_fn_decl(ctx, 0, 1);
else if (peek(ctx)->type == KW_TYPE)
parse_type_decl(ctx);
break;
}
case TOK_SHARP:
@@ -275,18 +305,22 @@ void spl_parse_prog(spl_comp_t *ctx) {
advance(ctx); /* # */
if (peek(ctx)->type == TOK_L_BRACKET) {
advance(ctx); /* [ */
while (peek(ctx)->type != TOK_R_BRACKET && peek(ctx)->type != TOK_EOF) advance(ctx);
if (peek(ctx)->type == TOK_R_BRACKET) advance(ctx);
while (peek(ctx)->type != TOK_R_BRACKET && peek(ctx)->type != TOK_EOF)
advance(ctx);
if (peek(ctx)->type == TOK_R_BRACKET)
advance(ctx);
}
skip_nl(ctx);
if (peek(ctx)->type == KW_FN) parse_fn_decl(ctx, 1, 0);
if (peek(ctx)->type == KW_FN)
parse_fn_decl(ctx, 1, 0);
break;
default: {
int prev = ctx->tok_idx;
/* Try to parse as a statement */
spl_parse_stmt(ctx);
/* Safety: prevent infinite loop on unrecognized tokens */
if (ctx->tok_idx == prev) advance(ctx);
if (ctx->tok_idx == prev)
advance(ctx);
break;
}
}