stage1 完成sema词法

This commit is contained in:
zzy
2026-08-04 10:20:57 +08:00
parent 74d7376039
commit 8ac59dfaa1
14 changed files with 2309 additions and 47 deletions

7
SPL.md
View File

@@ -478,6 +478,13 @@ type T = TypeExpr — 完全同义。
匹配: match 必须穷举 (或含 _),否则编译错误。 匹配: match 必须穷举 (或含 _),否则编译错误。
## 名称解析
1. 函数内部 (参数 + 块局部,每个 {} 建立子 scope)。
2. $root文件聚合的 scope所有顶层声明 (fn/type/var/const) 都是其成员。
无独立"全局"命名空间。$root 抽象不写死:@import(xxx) 返回的匿名结构即该模块当时的 $root多文件时切换。字段/变体名不在 scope map 中 (存于聚合 def 的成员列表),裸名查找天然不命中字段;路径 a.b.c 首段裸名查 scope、后续段查聚合成员。
## 变量与常量 ## 变量与常量
var x: T 或 var x := init: 可变量。 var x: T 或 var x := init: 可变量。

View File

@@ -151,10 +151,7 @@ static void parse_error(parser_t *p, spl_tok_t *t, const char *msg) {
const char *fn = (t && t->fname) ? t->fname : "<unknown>"; const char *fn = (t && t->fname) ? t->fname : "<unknown>";
usize line = t ? t->line : 0; usize line = t ? t->line : 0;
usize col = t ? t->col : 0; usize col = t ? t->col : 0;
fprintf(stderr, "%s:%llu:%llu: error: %s\n", fn, (unsigned long long)line, LOG_FATAL("%s:%llu:%llu: error: %s", fn, (unsigned long long)line, (unsigned long long)col, msg);
(unsigned long long)col, msg);
fflush(stderr);
abort();
} }
static int expect(parser_t *p, spl_tok_type_t type, const char *what) { static int expect(parser_t *p, spl_tok_type_t type, const char *what) {
@@ -1383,7 +1380,8 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
} }
} else if (t->type == TOK_L_BRACKET) { } else if (t->type == TOK_L_BRACKET) {
advance(p); advance(p);
spl_ast_node_ref_t begin = parse_expr(p); /* 切片 begin 用 parse_shift 解析:`a..b` 中 `..` 属切片标记而非 Range 表达式 */
spl_ast_node_ref_t begin = parse_shift(p);
if (peek(p) && peek(p)->type == TOK_RANGE) { if (peek(p) && peek(p)->type == TOK_RANGE) {
advance(p); advance(p);
spl_ast_node_ref_t end = 0; spl_ast_node_ref_t end = 0;
@@ -1529,7 +1527,8 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
/* 结构体字面量 T { .f1 = e1, ... } */ /* 结构体字面量 T { .f1 = e1, ... } */
spl_ast_node_ref_vec_t agg_vec = parse_aggregate_init_body(p); spl_ast_node_ref_vec_t agg_vec = parse_aggregate_init_body(p);
spl_ast_node_ref_t pr = mk_primary(p, t, SPL_AST_ARGGREGATE_INIT); spl_ast_node_ref_t pr = mk_primary(p, t, SPL_AST_ARGGREGATE_INIT);
node_at(p->ast, pr)->primary_expr.aggregate_init_expr = agg_vec; node_at(p->ast, pr)->primary_expr.aggregate_init.name = sdupn(t->lexeme, t->len);
node_at(p->ast, pr)->primary_expr.aggregate_init.expr = agg_vec;
return wrap_expr(p, pr); return wrap_expr(p, pr);
} }
spl_ast_node_ref_t pr = mk_primary(p, t, SPL_AST_IDENT); spl_ast_node_ref_t pr = mk_primary(p, t, SPL_AST_IDENT);
@@ -1543,7 +1542,8 @@ static spl_ast_node_ref_t parse_primary(parser_t *p) {
advance(p); advance(p);
spl_ast_node_ref_vec_t agg_vec = parse_aggregate_init_body(p); spl_ast_node_ref_vec_t agg_vec = parse_aggregate_init_body(p);
spl_ast_node_ref_t pr = mk_primary(p, t, SPL_AST_ARGGREGATE_INIT); spl_ast_node_ref_t pr = mk_primary(p, t, SPL_AST_ARGGREGATE_INIT);
node_at(p->ast, pr)->primary_expr.aggregate_init_expr = agg_vec; node_at(p->ast, pr)->primary_expr.aggregate_init.name = NULL;
node_at(p->ast, pr)->primary_expr.aggregate_init.expr = agg_vec;
return wrap_expr(p, pr); return wrap_expr(p, pr);
} }
parse_error(p, t, "unexpected '.' in expression"); parse_error(p, t, "unexpected '.' in expression");
@@ -2132,10 +2132,8 @@ static void expr_inline(spl_ast_t *ast, spl_ast_node_ref_t ref, char *out, size_
snprintf(tmp, sizeof tmp, "%s", STR(pn->primary_expr.ident)); snprintf(tmp, sizeof tmp, "%s", STR(pn->primary_expr.ident));
break; break;
case SPL_AST_ARGGREGATE_INIT: case SPL_AST_ARGGREGATE_INIT:
tmp[0] = '{'; snprintf(tmp, sizeof tmp, "%s{ ", STR(pn->primary_expr.aggregate_init.name));
tmp[1] = ' '; agg_items_inline(ast, &pn->primary_expr.aggregate_init.expr, tmp, sizeof tmp);
tmp[2] = '\0';
agg_items_inline(ast, &pn->primary_expr.aggregate_init_expr, tmp, sizeof tmp);
strncat(tmp, " }", sizeof tmp - strlen(tmp) - 1); strncat(tmp, " }", sizeof tmp - strlen(tmp) - 1);
break; break;
case SPL_AST_EXPR_EXPR: case SPL_AST_EXPR_EXPR:
@@ -2480,11 +2478,11 @@ static void dump_primary_expr(spl_ast_t *ast, spl_ast_node_ref_t ref, const char
node_label(prefix, is_last, "Ident %s", STR(n->primary_expr.ident)); node_label(prefix, is_last, "Ident %s", STR(n->primary_expr.ident));
break; break;
case SPL_AST_ARGGREGATE_INIT: case SPL_AST_ARGGREGATE_INIT:
node_label(prefix, is_last, "AggInit"); node_label(prefix, is_last, "AggInit %s", STR(n->primary_expr.aggregate_init.name));
spl_dumptree_child_prefix(dt, prefix, is_last, cp, sizeof cp); spl_dumptree_child_prefix(dt, prefix, is_last, cp, sizeof cp);
for (usize i = 0; i < n->primary_expr.aggregate_init_expr.size; i++) { for (usize i = 0; i < n->primary_expr.aggregate_init.expr.size; i++) {
spl_ast_node_t *it = &ast->buckets.data[n->primary_expr.aggregate_init_expr.data[i]]; spl_ast_node_t *it = &ast->buckets.data[n->primary_expr.aggregate_init.expr.data[i]];
int it_last = (int)(i == n->primary_expr.aggregate_init_expr.size - 1); int it_last = (int)(i == n->primary_expr.aggregate_init.expr.size - 1);
node_label(cp, it_last, "Field .%s", STR(it->aggregate_init_item.ident)); node_label(cp, it_last, "Field .%s", STR(it->aggregate_init_item.ident));
if (it->aggregate_init_item.expr) { if (it->aggregate_init_item.expr) {
char cq[512]; char cq[512];
@@ -3153,7 +3151,8 @@ static void drop_node(spl_ast_t *ast, spl_ast_node_ref_t ref, walk_ctx_t ctx) {
free((void *)n->primary_expr.string_lit_expr); free((void *)n->primary_expr.string_lit_expr);
break; break;
case SPL_AST_ARGGREGATE_INIT: case SPL_AST_ARGGREGATE_INIT:
drop_vec(ast, &n->primary_expr.aggregate_init_expr, CTX_AGG_ITEM); free((void *)n->primary_expr.aggregate_init.name);
drop_vec(ast, &n->primary_expr.aggregate_init.expr, CTX_AGG_ITEM);
break; break;
case SPL_AST_EXPR_EXPR: case SPL_AST_EXPR_EXPR:
drop_node(ast, n->primary_expr.expr, CTX_EXPR); drop_node(ast, n->primary_expr.expr, CTX_EXPR);
@@ -3382,7 +3381,7 @@ static void validate_node(spl_ast_t *ast, spl_ast_node_ref_t ref, walk_ctx_t ctx
printf("valid: identifier missing name\n"); printf("valid: identifier missing name\n");
break; break;
case SPL_AST_ARGGREGATE_INIT: case SPL_AST_ARGGREGATE_INIT:
validate_vec(ast, &n->primary_expr.aggregate_init_expr, CTX_AGG_ITEM); validate_vec(ast, &n->primary_expr.aggregate_init.expr, CTX_AGG_ITEM);
break; break;
case SPL_AST_EXPR_EXPR: case SPL_AST_EXPR_EXPR:
validate_node(ast, n->primary_expr.expr, CTX_EXPR); validate_node(ast, n->primary_expr.expr, CTX_EXPR);

View File

@@ -253,7 +253,10 @@ struct spl_ast_node {
const char *string_lit_expr; /* parsed c string */ const char *string_lit_expr; /* parsed c string */
const char *ident; const char *ident;
spl_ast_node_ref_vec_t aggregate_init_expr; /* aggregate_init_item */ struct {
const char *name;
spl_ast_node_ref_vec_t expr; /* aggregate_init_item */
} aggregate_init;
spl_ast_node_ref_t expr; spl_ast_node_ref_t expr;
struct { struct {

4
stage1/spl_emit.h Normal file
View File

@@ -0,0 +1,4 @@
#ifndef __SPL_EMIT_H__
#define __SPL_EMIT_H__
#endif /* __SPL_EMIT_H__ */

View File

@@ -85,7 +85,7 @@ typedef struct {
} spl_ir_node_t; } spl_ir_node_t;
typedef VEC(spl_ir_node_t) spl_ir_node_vec_t; typedef VEC(spl_ir_node_t) spl_ir_node_vec_t;
typedef usize spl_ir_node_ref_t; typedef usize spl_ir_node_ref_t; /* 0 is error */
typedef VEC(spl_ir_node_ref_t) spl_ir_node_ref_vec_t; typedef VEC(spl_ir_node_ref_t) spl_ir_node_ref_vec_t;
typedef struct { typedef struct {
@@ -106,8 +106,9 @@ typedef struct {
spl_ir_node_vec_t nodes; spl_ir_node_vec_t nodes;
spl_ir_node_ref_vec_t labels; spl_ir_node_ref_vec_t labels;
} spl_ir_func_t; } spl_ir_func_t;
typedef usize spl_ir_func_ref_t; /* 0 is error */
typedef VEC(spl_ir_func_t) spl_ir_func_vec_t; typedef VEC(spl_ir_func_t) spl_ir_func_vec_t;
typedef struct { typedef struct {
spl_ir_func_vec_t funcs; spl_ir_func_vec_t funcs;
} spl_ir_t; } spl_ir_t;
@@ -115,6 +116,12 @@ typedef struct {
void spl_ir_init(spl_ir_t *ir); void spl_ir_init(spl_ir_t *ir);
void spl_ir_drop(spl_ir_t *ir); void spl_ir_drop(spl_ir_t *ir);
spl_ir_node_ref_t spl_ir_alloc_node(spl_ir_t *ir, spl_ir_func_ref_t fn_id);
spl_ir_func_ref_t spl_ir_alloc_fn(spl_ir_t *ir);
spl_ir_node_t *spl_ir_node(spl_ir_t *ir, spl_ir_func_ref_t fn_id, spl_ir_node_ref_t node_id);
spl_ir_func_t *spl_ir_func(spl_ir_t *ir, spl_ir_func_ref_t fn_id);
void spl_ir_dump(spl_ir_t *ir); void spl_ir_dump(spl_ir_t *ir);
#endif /* __SPL_IR_H__ */ #endif /* __SPL_IR_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
typedef usize spl_scope_id_t; /* 0 is error */ typedef usize spl_scope_id_t; /* 0 is error */
typedef struct { typedef struct {
spl_scope_id_t parent; spl_scope_id_t parent;
MAP(const char *, spl_type_id_t) symbols; MAP(const char *, spl_def_id_t) symbols;
} spl_scope_node_t; } spl_scope_node_t;
typedef VEC(spl_scope_node_t) spl_scope_node_vec_t; typedef VEC(spl_scope_node_t) spl_scope_node_vec_t;
@@ -17,17 +17,19 @@ typedef struct {
spl_scope_node_vec_t scopes; spl_scope_node_vec_t scopes;
spl_scope_id_t root_scope; spl_scope_id_t root_scope;
spl_scope_id_t current_scope; spl_scope_id_t current_scope;
spl_def_id_t root_def;
int error_count; int error_count;
} spl_sema_t; } spl_sema_t;
void spl_sema_init(spl_sema_t *sema); void spl_sema_init(spl_sema_t *sema);
void spl_sema_drop(spl_sema_t *sema); void spl_sema_drop(spl_sema_t *sema);
void spl_sema_run(spl_sema_t *sema); void spl_sema_run(spl_sema_t *sema);
void spl_sema_check(spl_sema_t *sema);
spl_scope_id_t spl_sema_scope_alloc(spl_sema_t *sema); spl_scope_id_t spl_sema_scope_alloc(spl_sema_t *sema);
bool spl_sema_scope_insert(spl_sema_t *sema, spl_scope_id_t id, const char *symbol_name, bool spl_sema_scope_insert(spl_sema_t *sema, spl_scope_id_t id, const char *symbol_name,
spl_type_id_t symbol_val); spl_def_id_t symbol_val);
typedef VEC(const char *) spl_symbol_path_t; typedef VEC(const char *) spl_symbol_path_t;
spl_type_id_t spl_sema_scope_find(spl_sema_t *sema, spl_symbol_path_t path); spl_def_id_t spl_sema_scope_find(spl_sema_t *sema, spl_symbol_path_t path);
#endif /* __SPL_SEMA_H__ */ #endif /* __SPL_SEMA_H__ */

View File

@@ -1 +1,324 @@
// WRITE BY AI
/* spl_type.c SPL 类型系统type/def 两张完全独立的 arena 表 + 构造器 + dump
* type_table 按 spl_type_id_t 存匿名类型def_table 按 spl_def_id_t 存命名实体。
* 两表 id 空间互不相干0 均保留为 error。 */
#include "spl_type.h" #include "spl_type.h"
#include <stdio.h>
#include <string.h>
static spl_type_id_t type_push(spl_type_t *type) {
spl_type_node_t n;
memset(&n, 0, sizeof n);
n.kind = SPL_TYPE_VOID;
vec_push(type->type_table, n);
return type->type_table.size - 1;
}
/* 内置整型去重:同 bits/signed 复用同一 id类型唯一化 */
spl_type_id_t spl_type_int(spl_type_t *type, usize bits, int is_signed) {
for (usize i = 1; i < type->type_table.size; i++) {
spl_type_node_t *n = &type->type_table.data[i];
if (n->kind == SPL_TYPE_INT && n->int_type.bits == bits &&
n->int_type.is_signed == is_signed)
return i;
}
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_INT;
type->type_table.data[id].int_type.bits = bits;
type->type_table.data[id].int_type.is_signed = is_signed;
return id;
}
/* 内置浮点去重 */
spl_type_id_t spl_type_float(spl_type_t *type, usize bits) {
for (usize i = 1; i < type->type_table.size; i++) {
spl_type_node_t *n = &type->type_table.data[i];
if (n->kind == SPL_TYPE_FLOAT && n->float_type.bits == bits)
return i;
}
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_FLOAT;
type->type_table.data[id].float_type.bits = bits;
return id;
}
spl_type_id_t spl_type_void(spl_type_t *type) {
for (usize i = 1; i < type->type_table.size; i++)
if (type->type_table.data[i].kind == SPL_TYPE_VOID)
return i;
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_VOID;
return id;
}
spl_type_id_t spl_type_bool(spl_type_t *type) {
for (usize i = 1; i < type->type_table.size; i++)
if (type->type_table.data[i].kind == SPL_TYPE_BOOL)
return i;
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_BOOL;
return id;
}
spl_type_id_t spl_type_ptr(spl_type_t *type, spl_type_id_t val) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_PTR;
type->type_table.data[id].ptr_pointee = val;
return id;
}
spl_type_id_t spl_type_slice(spl_type_t *type, spl_type_id_t val) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_SLICE;
type->type_table.data[id].slice_element = val;
return id;
}
spl_type_id_t spl_type_range(spl_type_t *type, spl_type_id_t val) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_RANGE;
type->type_table.data[id].range_element = val;
return id;
}
spl_type_id_t spl_type_array(spl_type_t *type, spl_type_id_t val, usize len) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_ARRAY;
type->type_table.data[id].array_type.element = val;
type->type_table.data[id].array_type.len = len;
return id;
}
/* 绑定节点/别名引用type 节点指向被引用的类型 id
* (供未来"底层同型但类型系统不认"的 newtype 使用,暂不参与注册) */
spl_type_id_t spl_type_tid(spl_type_t *type, spl_type_id_t val) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_ID;
type->type_table.data[id].type_id = val;
return id;
}
/* 聚合类型:默认 STRUCT字段类型列表 */
spl_type_id_t spl_type_agg(spl_type_t *type, spl_type_id_vec_t fields) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_STRUCT;
type->type_table.data[id].agg_field_types = fields;
return id;
}
spl_type_id_t spl_type_enum(spl_type_t *type, spl_type_id_vec_t variants, spl_type_id_t tag) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_ENUM;
type->type_table.data[id].enum_type.variants = variants;
type->type_table.data[id].enum_type.tag_type = tag;
return id;
}
spl_type_id_t spl_type_fn(spl_type_t *type, spl_type_id_vec_t params, spl_type_id_t ret) {
spl_type_id_t id = type_push(type);
type->type_table.data[id].kind = SPL_TYPE_FN;
type->type_table.data[id].fn_type.params = params;
type->type_table.data[id].fn_type.ret = ret;
return id;
}
void spl_type_init(spl_type_t *type) {
vec_init(type->type_table);
vec_init(type->def_table);
/* 两表 id 0 均保留为 error */
type_push(type);
spl_type_def_alloc(type);
/* 关键字/内置类型(去重后 i8..u64 等各占一个 iddef 由 sema 登记) */
spl_type_void(type);
spl_type_bool(type);
spl_type_int(type, 8, 1);
spl_type_int(type, 8, 0);
spl_type_int(type, 16, 1);
spl_type_int(type, 16, 0);
spl_type_int(type, 32, 1);
spl_type_int(type, 32, 0);
spl_type_int(type, 64, 1);
spl_type_int(type, 64, 0);
spl_type_float(type, 32);
spl_type_float(type, 64);
}
void spl_type_drop(spl_type_t *type) {
/* type 节点持有的内嵌 vec */
for (usize i = 0; i < type->type_table.size; i++) {
spl_type_node_t *n = &type->type_table.data[i];
switch (n->kind) {
case SPL_TYPE_STRUCT:
case SPL_TYPE_UNION:
vec_free(n->agg_field_types);
break;
case SPL_TYPE_ENUM:
vec_free(n->enum_type.variants);
break;
case SPL_TYPE_FN:
vec_free(n->fn_type.params);
break;
default:
break;
}
}
/* def 节点持有的内嵌 vec */
for (usize i = 0; i < type->def_table.size; i++) {
spl_def_node_t *d = &type->def_table.data[i];
switch (d->kind) {
case SPL_DEF_AGG:
vec_free(d->agg_def);
break;
case SPL_DEF_FN_PARAMS:
vec_free(d->fn_params_def);
break;
default:
break;
}
}
vec_free(type->type_table);
vec_free(type->def_table);
}
spl_type_id_t spl_type_alloc(spl_type_t *type) { return type_push(type); }
spl_type_node_t *spl_type_node(spl_type_t *type, spl_type_id_t id) {
if (!id || id >= type->type_table.size)
return NULL;
return &type->type_table.data[id];
}
spl_def_id_t spl_type_def_alloc(spl_type_t *type) {
spl_def_node_t d;
memset(&d, 0, sizeof d);
d.kind = SPL_DEF_NONE;
vec_push(type->def_table, d);
return type->def_table.size - 1;
}
spl_def_node_t *spl_type_def(spl_type_t *type, spl_def_id_t id) {
if (!id || id >= type->def_table.size)
return NULL;
return &type->def_table.data[id];
}
static const char *def_kind_name(spl_def_node_t *d) {
switch (d->kind) {
case SPL_DEF_NONE:
return "none";
case SPL_DEF_BUILTIN:
return "builtin";
case SPL_DEF_VAR:
return "var";
case SPL_DEF_FN_PARAMS:
return "fn_params";
case SPL_DEF_AGG:
return "agg";
case SPL_DEF_DISTINCT:
return "distinct";
case SPL_DEF_ALIAS:
return "alias";
}
return "?";
}
void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) {
spl_type_node_t *n = spl_type_node(type, id);
if (!n) {
printf("(err)");
return;
}
switch (n->kind) {
case SPL_TYPE_VOID:
printf("void");
break;
case SPL_TYPE_BOOL:
printf("bool");
break;
case SPL_TYPE_INT:
printf("%s%zu", n->int_type.is_signed ? "i" : "u", n->int_type.bits);
break;
case SPL_TYPE_FLOAT:
printf("f%zu", n->float_type.bits);
break;
case SPL_TYPE_PTR:
printf("*");
spl_type_pure_dump(type, n->ptr_pointee);
break;
case SPL_TYPE_SLICE:
printf("[]");
spl_type_pure_dump(type, n->slice_element);
break;
case SPL_TYPE_RANGE:
printf("range[");
spl_type_pure_dump(type, n->range_element);
printf("]");
break;
case SPL_TYPE_ARRAY:
printf("[%zu]", n->array_type.len);
spl_type_pure_dump(type, n->array_type.element);
break;
case SPL_TYPE_STRUCT:
printf("struct{%zu fields}", n->agg_field_types.size);
break;
case SPL_TYPE_UNION:
printf("union{%zu fields}", n->agg_field_types.size);
break;
case SPL_TYPE_ENUM:
printf("enum{%zu variants}", n->enum_type.variants.size);
break;
case SPL_TYPE_FN: {
printf("fn(");
for (usize i = 0; i < n->fn_type.params.size; i++) {
if (i)
printf(",");
spl_type_pure_dump(type, n->fn_type.params.data[i]);
}
printf(") -> ");
spl_type_pure_dump(type, n->fn_type.ret);
break;
}
case SPL_TYPE_ID:
printf("id#%zu", n->type_id);
break;
}
}
void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) {
spl_def_node_t *d = spl_type_def(type, id);
if (!d) {
printf("(err)");
return;
}
printf("kind=%s type_id=%zu", def_kind_name(d), d->type_id);
switch (d->kind) {
case SPL_DEF_VAR:
printf(" var=%s", d->var_def.name ? d->var_def.name : "?");
break;
case SPL_DEF_ALIAS:
case SPL_DEF_DISTINCT:
printf(" type=%s", d->type_def.name ? d->type_def.name : "?");
break;
case SPL_DEF_AGG:
printf(" agg{");
for (usize i = 0; i < d->agg_def.size; i++) {
if (i)
printf(",");
printf("%s", d->agg_def.data[i].name ? d->agg_def.data[i].name : "?");
}
printf("}");
break;
case SPL_DEF_FN_PARAMS:
printf(" fn(");
for (usize i = 0; i < d->fn_params_def.size; i++) {
if (i)
printf(",");
printf("%s", d->fn_params_def.data[i].name ? d->fn_params_def.data[i].name : "?");
}
printf(")");
break;
default:
break;
}
}

View File

@@ -5,6 +5,8 @@
typedef usize spl_type_id_t; /* 0 is error */ typedef usize spl_type_id_t; /* 0 is error */
typedef VEC(spl_type_id_t) spl_type_id_vec_t; typedef VEC(spl_type_id_t) spl_type_id_vec_t;
typedef usize spl_def_id_t; /* 0 is error */
typedef VEC(spl_def_id_t) spl_def_id_vec_t;
typedef struct { typedef struct {
enum { enum {
@@ -14,6 +16,7 @@ typedef struct {
SPL_TYPE_FLOAT, SPL_TYPE_FLOAT,
SPL_TYPE_PTR, SPL_TYPE_PTR,
SPL_TYPE_SLICE, SPL_TYPE_SLICE,
SPL_TYPE_RANGE,
SPL_TYPE_ARRAY, SPL_TYPE_ARRAY,
SPL_TYPE_STRUCT, SPL_TYPE_STRUCT,
SPL_TYPE_UNION, SPL_TYPE_UNION,
@@ -31,6 +34,7 @@ typedef struct {
} float_type; } float_type;
spl_type_id_t ptr_pointee; spl_type_id_t ptr_pointee;
spl_type_id_t slice_element; spl_type_id_t slice_element;
spl_type_id_t range_element;
struct { struct {
spl_type_id_t element; spl_type_id_t element;
usize len; usize len;
@@ -46,13 +50,13 @@ typedef struct {
} fn_type; } fn_type;
spl_type_id_t type_id; spl_type_id_t type_id;
}; };
usize byte_size; /* 布局缓存 */
} spl_type_node_t; } spl_type_node_t;
typedef VEC(spl_type_node_t) spl_type_node_vec_t; typedef VEC(spl_type_node_t) spl_type_node_vec_t;
typedef struct { typedef struct {
const char *name; const char *name;
spl_type_id_t type; spl_def_id_t def_id;
spl_type_id_t type_id;
usize scope_id; usize scope_id;
} spl_var_def_t; } spl_var_def_t;
typedef VEC(spl_var_def_t) spl_var_def_vec_t; typedef VEC(spl_var_def_t) spl_var_def_vec_t;
@@ -67,6 +71,7 @@ typedef struct {
SPL_DEF_DISTINCT, // newtype SPL_DEF_DISTINCT, // newtype
SPL_DEF_ALIAS, // sametypes SPL_DEF_ALIAS, // sametypes
} kind; } kind;
spl_type_id_t type_id;
union { union {
spl_var_def_t var_def; spl_var_def_t var_def;
spl_var_def_vec_t agg_def; // include enum variants spl_var_def_vec_t agg_def; // include enum variants
@@ -87,19 +92,19 @@ type (类型名) = (匿名类型)
*/ */
typedef struct { typedef struct {
spl_type_node_vec_t type_table; spl_type_node_vec_t type_table;
spl_def_node_vec_t def_table; /* 使用type_id作为索引 */ spl_def_node_vec_t def_table;
} spl_type_t; } spl_type_t;
void spl_type_init(spl_type_t *type); void spl_type_init(spl_type_t *type);
void spl_type_drop(spl_type_t *type); void spl_type_drop(spl_type_t *type);
void spl_type_def_dump(spl_type_t *type, spl_type_id_t id); void spl_type_def_dump(spl_type_t *type, spl_def_id_t id);
void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id); void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id);
// alloc 时两表平行 push, 保证索引同步
spl_type_id_t spl_type_alloc(spl_type_t *type); spl_type_id_t spl_type_alloc(spl_type_t *type);
spl_type_node_t *spl_type_node(spl_type_t *type, spl_type_id_t id); spl_type_node_t *spl_type_node(spl_type_t *type, spl_type_id_t id);
spl_def_node_t *spl_type_def(spl_type_t *type, spl_type_id_t id); spl_def_id_t spl_type_def_alloc(spl_type_t *type);
spl_def_node_t *spl_type_def(spl_type_t *type, spl_def_id_t id);
spl_type_id_t spl_type_void(spl_type_t *type); spl_type_id_t spl_type_void(spl_type_t *type);
spl_type_id_t spl_type_bool(spl_type_t *type); spl_type_id_t spl_type_bool(spl_type_t *type);
@@ -107,6 +112,7 @@ spl_type_id_t spl_type_int(spl_type_t *type, usize bits, int is_signed);
spl_type_id_t spl_type_float(spl_type_t *type, usize bits); spl_type_id_t spl_type_float(spl_type_t *type, usize bits);
spl_type_id_t spl_type_ptr(spl_type_t *type, spl_type_id_t val); spl_type_id_t spl_type_ptr(spl_type_t *type, spl_type_id_t val);
spl_type_id_t spl_type_slice(spl_type_t *type, spl_type_id_t val); spl_type_id_t spl_type_slice(spl_type_t *type, spl_type_id_t val);
spl_type_id_t spl_type_range(spl_type_t *type, spl_type_id_t val);
spl_type_id_t spl_type_array(spl_type_t *type, spl_type_id_t val, usize len); spl_type_id_t spl_type_array(spl_type_t *type, spl_type_id_t val, usize len);
spl_type_id_t spl_type_tid(spl_type_t *type, spl_type_id_t val); spl_type_id_t spl_type_tid(spl_type_t *type, spl_type_id_t val);
spl_type_id_t spl_type_agg(spl_type_t *type, spl_type_id_vec_t fields); spl_type_id_t spl_type_agg(spl_type_t *type, spl_type_id_vec_t fields);

View File

@@ -12,6 +12,7 @@
#include "spl_ast.h" #include "spl_ast.h"
#include "spl_lexer.h" #include "spl_lexer.h"
#include "spl_sema.h"
#include "spl_tok.h" #include "spl_tok.h"
static char *read_file(const char *path, long *out_len) { static char *read_file(const char *path, long *out_len) {
@@ -65,6 +66,42 @@ static void dump_ast(const char *src, const char *fname) {
spl_ast_drop(&ast); spl_ast_drop(&ast);
} }
static void dump_sema(const char *src, const char *fname) {
spl_tok_vec_t toks = spl_lex(src, fname);
spl_ast_t ast;
spl_ast_init(&ast, &toks);
spl_ast_prase(&ast);
spl_ast_valid(&ast);
spl_sema_t sema;
spl_sema_init(&sema);
sema.ast = &ast;
spl_sema_run(&sema);
spl_sema_check(&sema);
printf("Sema root_scope=%zu scopes=%zu errors=%d\n", sema.root_scope, sema.scopes.size,
sema.error_count);
for (usize i = 0; i < sema.scopes.size; i++) {
printf("scope[%zu] parent=%zu\n", i, sema.scopes.data[i].parent);
map_for(sema.scopes.data[i].symbols, mi) {
printf(" %s -> def#%zu\n", sema.scopes.data[i].symbols.data[mi].key,
sema.scopes.data[i].symbols.data[mi].val);
}
}
printf("TypeTable:\n");
for (usize i = 0; i < sema.type.type_table.size; i++) {
printf(" id#%zu type=", i);
spl_type_pure_dump(&sema.type, i);
printf("\n");
}
printf("DefTable:\n");
for (usize i = 0; i < sema.type.def_table.size; i++) {
printf(" def#%zu ", i);
spl_type_def_dump(&sema.type, i);
printf("\n");
}
spl_sema_drop(&sema);
spl_ast_drop(&ast);
}
static int cmd_dump(const char *flags, const char *path) { static int cmd_dump(const char *flags, const char *path) {
long len; long len;
char *src = read_file(path, &len); char *src = read_file(path, &len);
@@ -72,10 +109,13 @@ static int cmd_dump(const char *flags, const char *path) {
return 1; return 1;
int do_tokens = strstr(flags, "tokens") != NULL || strcmp(flags, "all") == 0; int do_tokens = strstr(flags, "tokens") != NULL || strcmp(flags, "all") == 0;
int do_ast = strstr(flags, "ast") != NULL || strcmp(flags, "all") == 0; int do_ast = strstr(flags, "ast") != NULL || strcmp(flags, "all") == 0;
int do_sema = strstr(flags, "sema") != NULL || strcmp(flags, "all") == 0;
if (do_tokens) if (do_tokens)
dump_tokens(src, path); dump_tokens(src, path);
if (do_ast) if (do_ast)
dump_ast(src, path); dump_ast(src, path);
if (do_sema)
dump_sema(src, path);
free(src); free(src);
return 0; return 0;
} }
@@ -87,15 +127,20 @@ int main(int argc, char **argv) {
} }
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) {
LOG_INFO("splc0 <in> <out> compile (.spl -> .sir, 阶段 B)\n"); LOG_INFO("splc0 <in> <out> compile (.spl -> .sir, 阶段 B)\n");
LOG_INFO("splc0 --dump <flags> <file> dump: tokens,ast,all\n"); LOG_INFO("splc0 --dump <flags> <file> dump: tokens,ast,sema,all\n");
return 0; return 0;
} }
if (strcmp(argv[1], "--dump") == 0) { int argi = 1;
if (argc < 4) { if (argi >= argc) {
LOG_FATAL("Usage: splc0 [--dump <flags>] <in> [out]\n");
return 1;
}
if (strcmp(argv[argi], "--dump") == 0) {
if (argc < argi + 3) {
LOG_INFO("splc0: --dump need <flags> <file>\n"); LOG_INFO("splc0: --dump need <flags> <file>\n");
return 1; return 1;
} }
return cmd_dump(argv[2], argv[3]); return cmd_dump(argv[argi + 1], argv[argi + 2]);
} }
LOG_FATAL("splc0: compile todo\n"); LOG_FATAL("splc0: compile todo\n");
return 1; return 1;

View File

@@ -30,10 +30,10 @@ fn main() i32 {
if nl != 10 { ret 6; } if nl != 10 { ret 6; }
/* 布尔字面量 */ /* 布尔字面量 */
var t: i32 = true; var t: bool = true;
if t != 1 { ret 7; } if !t { ret 7; }
var f: i32 = false; var f: bool = false;
if f != 0 { ret 8; } if f { ret 8; }
/* null 指针 */ /* null 指针 */
var np: *i32 = null; var np: *i32 = null;

View File

@@ -16,11 +16,11 @@ fn main() i32 {
/* 比较结果为 0/1 */ /* 比较结果为 0/1 */
var eq := (42 == 42); var eq := (42 == 42);
if eq != 1 { ret 9; } if !eq { ret 9; }
var ne := (42 == 43); var ne := (42 == 43);
if ne != 0 { ret 10; } if ne { ret 10; }
var lt := (5 < 10); var lt := (5 < 10);
if lt != 1 { ret 11; } if !lt { ret 11; }
/* ---- 逻辑运算 ---- */ /* ---- 逻辑运算 ---- */
if (true) {} else { ret 12; } if (true) {} else { ret 12; }
@@ -30,9 +30,9 @@ fn main() i32 {
/* 逻辑非 */ /* 逻辑非 */
var not_t := !true; var not_t := !true;
if not_t != 0 { ret 16; } if not_t { ret 16; }
var not_f := !false; var not_f := !false;
if not_f != 1 { ret 17; } if !not_f { ret 17; }
// /* ---- 短路求值 ---- */ // /* ---- 短路求值 ---- */
// var short1 := 0; // var short1 := 0;

View File

@@ -81,7 +81,7 @@ fn test_param_pass_token() i32 {
ret 0; ret 0;
} }
fn test_get_tag(tok: Token) i32 { fn test_get_tag(tok: Token) Tag {
ret tok.tag; ret tok.tag;
} }

View File

@@ -5,8 +5,8 @@
* 字符串字面量、字符串参数传递 * 字符串字面量、字符串参数传递
*/ */
@extern(vm) fn vm_printf(fmt: *u8, ...) void; @extern(vm) fn vm_printf(fmt: *u8, ...) void;
@extern(vm) fn vm_strlen(s: *i8) i32; @extern(vm) fn vm_strlen(s: *u8) i32;
@extern(vm) fn vm_strcmp(a: *i8, b: *i8) i32; @extern(vm) fn vm_strcmp(a: *u8, b: *u8) i32;
fn main() i32 { fn main() i32 {
/* vm_printf 输出测试 */ /* vm_printf 输出测试 */