stage1 完成ast 定义sema

This commit is contained in:
zzy
2026-08-03 12:39:28 +08:00
parent a4ec5656d2
commit 74d7376039
19 changed files with 3857 additions and 137 deletions

156
SPL.md
View File

@@ -6,8 +6,8 @@ SPL是一个从零构建的自举编译器项目。引导链:
```
stage0/spl_vm.c — SIR 虚拟机 (C 语言实现)
stage1/splc0.c — SPLSIR 编译器 (C 语言实现,引导用)
stage1/splc1.spl — SPLSIR 编译器 (SPL 语言实现,自举第一版)
stage1/splc0.c — SPL->SIR 编译器 (C 语言实现,引导用)
stage1/splc1.spl — SPL->SIR 编译器 (SPL 语言实现,自举第一版)
...将来...
```
@@ -84,25 +84,45 @@ ParamDecl
# ================================================================
TypeDecl
<- KEYWORD_type IDENTIFIER EQUAL TypeBody (* @packed type Vec = struct { ... } *)
<- KEYWORD_type IDENTIFIER EQUAL TypeExpr (* @packed type Vec = struct { ... } *)
TypeBody
<- KEYWORD_struct LBRACE AggregateBody RBRACE
/ KEYWORD_union LBRACE AggregateBody RBRACE
/ KEYWORD_enum LBRACE AggregateBody RBRACE
/ TypeExpr (* 别名 *)
MemberDecl
<- IDENTIFIER (COLON TypeExpr)? (COMMA / SEMICOLON)?
AggregateBody <- AggregateItem*
# ================================================================
# 类型表达式 (Type Expression, LL(1), 无左递归)
# ================================================================
AggregateItem
<- ContainerDeclaration
TypeExpr <- PrefixTypeOp* AttrList? TypeBase
TypeBase
<- FnTypeExpr
/ TypePath
/ KEYWORD_struct LBRACE ContainerDeclaration* RBRACE
/ KEYWORD_union LBRACE ContainerDeclaration* RBRACE
/ KEYWORD_enum LBRACE ContainerDeclaration* RBRACE
(* struct: 字段, 必须 IDENTIFIER : TypeExpr (语义层检查)
union: 联合体字段, 同上
enum: 变体, IDENTIFIER : TypeExpr 或 纯 IDENTIFIER (朴素变体) *)
MemberDecl
<- IDENTIFIER (COLON TypeExpr)? (COMMA / SEMICOLON)?
PrefixTypeOp (* LL(1): * / [ *)
<- ASTERISK
/ LBRACKET (RBRACKET / INTEGER RBRACKET) (* [] 或 [N] *)
FnTypeExpr <- KEYWORD_fn LPAREN TypeExprList? RPAREN TypeExpr
TypeExprList <- (TypeExpr COMMA)* TypeExpr?
TypePath <- TypeAtom (DOT TypeAtom)*
TypeAtom (* LL(1): 关键词 / IDENTIFIER / _ *)
<- KEYWORD_void / KEYWORD_bool
/ KEYWORD_i8 / KEYWORD_u8 / KEYWORD_i16 / KEYWORD_u16
/ KEYWORD_i32 / KEYWORD_u32 / KEYWORD_i64 / KEYWORD_u64
/ KEYWORD_isize / KEYWORD_usize
/ KEYWORD_f32 / KEYWORD_f64 / KEYWORD_ptr
/ UNDERSCORE
/ IDENTIFIER
# ================================================================
# 变量 / 常量
@@ -140,6 +160,7 @@ Statement (* LL(1): 14 分支互
/ ContinueStatement
/ DeferStatement
/ VarDecl
/ ConstDecl
/ TypeDecl
/ ExprStatement
@@ -175,12 +196,12 @@ ForStatement
MatchStatement <- KEYWORD_match Expr LBRACE MatchArm* RBRACE
MatchArm
<- MatchPat FAT_R_ARROW Statement
/ UNDERSCORE FAT_R_ARROW Statement
<- MatchPat (COMMA MatchPat)* FAT_R_ARROW Block
MatchPat (* LL(1): . / _ / Expr *)
<- DOT IDENTIFIER (LBRACKET IDENTIFIER RBRACKET)? (* 仅允许 .Item 或 .Item[bind] *)
/ Expr (* 字面量或变量常量 *)
/ UNDERSCORE
# ---- 跳转 ----
@@ -221,7 +242,7 @@ PrefixOp <- MINUS / BANG / TILDE / AMPERSAND / ASTERISK
PostfixExpr
<- PrimaryExpr
( LPAREN ExprList RPAREN (* 函数调用 *)
/ DOT IDENTIFIER (* 字段/方法 *)
/ DOT IDENTIFIER (* 字段 *)
/ DOT ASTERISK (* 解引用 *)
/ LBRACKET Expr RBRACKET (* 索引 *)
/ LBRACKET Expr DOT2 Expr? RBRACKET (* 切片 *)
@@ -239,7 +260,8 @@ PrimaryExpr
/ CHAR_LITERAL
/ STRING_LITERAL
/ TRUE / FALSE / NULL_KW
/ IDENTIFIER (LBRACE StructInitList? RBRACE)? (* 变量引用 / 结构体字面量 *)
/ IDENTIFIER (LBRACE StructInitList? RBRACE)? (* 变量引用 / 结构体字面量 *)
/ DOT LBRACE StructInitList? RBRACE (* 匿名聚合字面量 .{ .f = e } *)
/ LPAREN Expr RPAREN
/ ArrayLiteral
/ BuiltinExpr
@@ -254,38 +276,6 @@ StructInit <- DOT IDENTIFIER (EQUAL Expr)?
BuiltinExpr
<- (AT / SHARP) IDENTIFIER LPAREN ExprList? RPAREN (* @sizeof(T) / #runtime(x) *)
# ================================================================
# 类型表达式 (Type Expression, LL(1), 无左递归)
# ================================================================
TypeExpr <- PrefixTypeOp* TypeBase
TypeBase <- FnTypeExpr / TypePath
PrefixTypeOp (* LL(1): * / [ *)
<- ASTERISK
/ LBRACKET (RBRACKET / INTEGER RBRACKET) (* [] 或 [N] *)
FnTypeExpr <- KEYWORD_fn LPAREN TypeExprList? RPAREN TypeExpr
TypeExprList <- (TypeExpr COMMA)* TypeExpr?
TypePath <- TypeAtom (DOT TypeAtom)*
TypeAtom (* LL(1): 关键词 / IDENTIFIER / _ *)
<- KEYWORD_void / KEYWORD_bool
/ KEYWORD_i8 / KEYWORD_u8 / KEYWORD_i16 / KEYWORD_u16
/ KEYWORD_i32 / KEYWORD_u32 / KEYWORD_i64 / KEYWORD_u64
/ KEYWORD_isize / KEYWORD_usize
/ KEYWORD_f32 / KEYWORD_f64 / KEYWORD_ptr
/ UNDERSCORE
/ IDENTIFIER
(* *_ = "any pointer", 唯一支持自动类型提升和隐式转换的指针类型。
语义上 *_ 可赋值给任意 *T, 任意 *T 可赋值给 *_。
# ================================================================
# 运算符
# ================================================================
@@ -324,6 +314,11 @@ KEYWORD_enum <- 'enum' !IDENTIFIER_CHAR
KEYWORD_comptime <- 'comptime' !IDENTIFIER_CHAR
KEYWORD_void <- 'void' !IDENTIFIER_CHAR
KEYWORD_bool <- 'bool' !IDENTIFIER_CHAR
KEYWORD_isize <- 'isize' !IDENTIFIER_CHAR
KEYWORD_usize <- 'usize' !IDENTIFIER_CHAR
KEYWORD_ptr <- 'ptr' !IDENTIFIER_CHAR
(* desperate 未来采用 ixx uxx fxx 表达而非关键字,启动阶段使用固定关键字 *)
KEYWORD_i8 <- 'i8' !IDENTIFIER_CHAR
KEYWORD_u8 <- 'u8' !IDENTIFIER_CHAR
KEYWORD_i16 <- 'i16' !IDENTIFIER_CHAR
@@ -332,11 +327,8 @@ KEYWORD_i32 <- 'i32' !IDENTIFIER_CHAR
KEYWORD_u32 <- 'u32' !IDENTIFIER_CHAR
KEYWORD_i64 <- 'i64' !IDENTIFIER_CHAR
KEYWORD_u64 <- 'u64' !IDENTIFIER_CHAR
KEYWORD_isize <- 'isize' !IDENTIFIER_CHAR
KEYWORD_usize <- 'usize' !IDENTIFIER_CHAR
KEYWORD_f32 <- 'f32' !IDENTIFIER_CHAR
KEYWORD_f64 <- 'f64' !IDENTIFIER_CHAR
KEYWORD_ptr <- 'ptr' !IDENTIFIER_CHAR
TRUE <- 'true' !IDENTIFIER_CHAR
FALSE <- 'false' !IDENTIFIER_CHAR
@@ -355,7 +347,7 @@ COLON <- ':' DOT <- '.'
DOT2 <- '..' DOT3 <- '...'
AT <- '@' SHARP <- '#'
FAT_R_ARROW <- '=>' FAT_D_ARROW <- '<=>'
R_ARROW <- '<-' L_ARROW <- '->' D_ARROW '<->'
THIN_R_ARROW <- '<-' THIN_L_ARROW <- '->' THIN_D_ARROW '<->'
EQUAL <- '='
COLON_ASSIGN <- ':='
@@ -407,6 +399,18 @@ BLOCK_COMMENT <- '/*' (!'*/' .)* '*/'
eof <- !.
```
## TODO
```spl
// 约束关键字,语义是`类型子集形状`
type name = shape { ... }
// 默认字段
type name = struct { x: i32 = 0, }
// 默认参数
fn name(x: i32 = 0) { ... }
```
# SPL 语义规范
## 设计总则
@@ -442,15 +446,16 @@ DirectiveBlock @id { } / #id { } 为扩展占位,无预定义行为。未识
语义: 完全由语言版本或库注册决定。当前所有均视为未识别,产生警告 (宽松) 或错误 (严格)。
## 函数
text
AttrList? fn IDENTIFIER ( ParamDeclList ) TypeExpr? ( ; | Block )
参数: 全部不可变。需要可变时通过 *T 传递。
返回类型: 省略即 void。仅有 ; 表示外部声明。
调用: 实参与形参数量、类型必须完全匹配 (无隐式可变参数)。
执行: 新作用域 形参绑定实参 执行 Block 遇 ret expr 返回 (类型匹配),或 void 函数自然结束返回。
执行: 新作用域 -> 形参绑定实参 -> 执行 Block -> 遇 ret expr 返回 (类型匹配),或 void 函数自然结束返回。
## 类型声明与聚合体
### 别名
@@ -573,7 +578,7 @@ defer { ... }: 退出作用域时以后进先出执行。
浮点 f64布尔 bool。
null ?T 隐式转换。
null -> ?T 隐式转换。
### 运算符
算术/位运算: 操作数类型必须完全一致或由字面量推导,无隐式提升。
@@ -587,12 +592,12 @@ null → ?T 隐式转换。
- 数值 同类型
! bool bool
~ 整数 同类型
& 可寻址左值 *T
解引用仅有后缀形式 .*,无前缀 * 运算符。(*ptr) 不合法。
& 可寻址左值 \*T
解引用仅有后缀形式 .\*,无前缀 \* 运算符。(\*ptr) 不合法。
后缀运算符
运算 约束 说明
expr.* expr 为 *T 解引用,得 T 左值
expr.\* expr 为 \*T 解引用,得 T 左值
expr.field struct 或指针 指针时自动解引用一层再取字段
expr[i] 数组/切片/指针i 整数 元素左值
expr[a..b] 数组/切片/指针 切片操作,产生 []T内部设置 ptr 和 len
@@ -618,9 +623,9 @@ comptime { ... } / comptime expr;: 编译时求值,不可引用运行时变量
*_ 的特殊规则:
*T *_: 允许,必须警告。
*T -> *_: 允许,必须警告。
*_ *T: 允许,必须警告。
*_ -> *T: 允许,必须警告。
这些警告无法全局关闭,未来提供显式抑制。
@@ -628,7 +633,7 @@ comptime { ... } / comptime expr;: 编译时求值,不可引用运行时变量
整数字面量适配更大类型。
null ?T。
null -> ?T。
其余必须显式 as。
@@ -740,7 +745,7 @@ fn(参数类型列表) 返回类型
null 字面量只能出现在需要 ?T 的上下文中。
### 自定义聚合类型
### 聚合类型
struct: 字段连续排列 (可能有对齐填充),每个字段有自己的类型。赋值是逐字段拷贝。
union: 所有字段共享起始地址,大小等于最大字段 (加上对齐)。直接字段读取被视为不安全,需通过 match 解构。
@@ -750,16 +755,7 @@ enum: 带标签的联合体,每个变体可有载荷。大小实现定义,
## 类型分类
### 值类型 (复制语义)
所有基本标量类型,或者说底层寄存器类型 (整数、浮点、bool)
struct
数组 [N]T
切片 []T
区间 Range
赋值、传参会复制整个值。修改副本不影响原值。
`聚合类型` `数组 [N]T` `切片[]T` `区间Range` 赋值、传参会复制整个值。修改副本不影响原值。
### 引用/指针类型
\*T、\*_
@@ -802,15 +798,15 @@ bool 整数 否 —
以下用伪代码描述每个表达式类型的推断方法。若类型检查失败,则为编译错误。
### 字面量
INTEGER i32
INTEGER -> i32
FLOAT f64
FLOAT -> f64
true / false bool
true / false -> bool
null 必须从上下文推导出 ?T无法推导则报错。
null -> 必须从上下文推导出 ?T无法推导则报错。
字符串字面量 []u8 (具体待定)
字符串字面量 -> []u8 (具体待定)
### 二元运算
算术 e1 + e2、-、*、/、%:
@@ -953,8 +949,8 @@ ForRange 提供表达式列表 [E1, E2, ...]。as 后标识符列表 [v1, v2, ..
```
for my_slice, 0.. as elem, idx { ... }
// my_slice: []T elem: T
// 0..: Range 无界 idx: i64长度由 my_slice 决定
// my_slice: []T -> elem: T
// 0..: Range 无界 -> idx: i64长度由 my_slice 决定
```
## 类型系统限制
无隐式类型提升 (除字面量整数拓宽和数组到切片外)。