stage1 完成ast 定义sema
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -2,3 +2,11 @@
|
|||||||
!.gitignore
|
!.gitignore
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
*.sir
|
||||||
|
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
|||||||
154
SPL.md
154
SPL.md
@@ -6,8 +6,8 @@ SPL是一个从零构建的自举编译器项目。引导链:
|
|||||||
|
|
||||||
```
|
```
|
||||||
stage0/spl_vm.c — SIR 虚拟机 (C 语言实现)
|
stage0/spl_vm.c — SIR 虚拟机 (C 语言实现)
|
||||||
stage1/splc0.c — SPL→SIR 编译器 (C 语言实现,引导用)
|
stage1/splc0.c — SPL->SIR 编译器 (C 语言实现,引导用)
|
||||||
stage1/splc1.spl — SPL→SIR 编译器 (SPL 语言实现,自举第一版)
|
stage1/splc1.spl — SPL->SIR 编译器 (SPL 语言实现,自举第一版)
|
||||||
...将来...
|
...将来...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,25 +84,45 @@ ParamDecl
|
|||||||
# ================================================================
|
# ================================================================
|
||||||
|
|
||||||
TypeDecl
|
TypeDecl
|
||||||
<- KEYWORD_type IDENTIFIER EQUAL TypeBody (* @packed type Vec = struct { ... } *)
|
<- KEYWORD_type IDENTIFIER EQUAL TypeExpr (* @packed type Vec = struct { ... } *)
|
||||||
|
|
||||||
TypeBody
|
MemberDecl
|
||||||
<- KEYWORD_struct LBRACE AggregateBody RBRACE
|
<- IDENTIFIER (COLON TypeExpr)? (COMMA / SEMICOLON)?
|
||||||
/ KEYWORD_union LBRACE AggregateBody RBRACE
|
|
||||||
/ KEYWORD_enum LBRACE AggregateBody RBRACE
|
|
||||||
/ TypeExpr (* 别名 *)
|
|
||||||
|
|
||||||
AggregateBody <- AggregateItem*
|
# ================================================================
|
||||||
|
# 类型表达式 (Type Expression, LL(1), 无左递归)
|
||||||
|
# ================================================================
|
||||||
|
|
||||||
AggregateItem
|
TypeExpr <- PrefixTypeOp* AttrList? TypeBase
|
||||||
<- ContainerDeclaration
|
|
||||||
|
|
||||||
|
TypeBase
|
||||||
|
<- FnTypeExpr
|
||||||
|
/ TypePath
|
||||||
|
/ KEYWORD_struct LBRACE ContainerDeclaration* RBRACE
|
||||||
|
/ KEYWORD_union LBRACE ContainerDeclaration* RBRACE
|
||||||
|
/ KEYWORD_enum LBRACE ContainerDeclaration* RBRACE
|
||||||
(* struct: 字段, 必须 IDENTIFIER : TypeExpr (语义层检查)
|
(* struct: 字段, 必须 IDENTIFIER : TypeExpr (语义层检查)
|
||||||
union: 联合体字段, 同上
|
union: 联合体字段, 同上
|
||||||
enum: 变体, IDENTIFIER : TypeExpr 或 纯 IDENTIFIER (朴素变体) *)
|
enum: 变体, IDENTIFIER : TypeExpr 或 纯 IDENTIFIER (朴素变体) *)
|
||||||
|
|
||||||
MemberDecl
|
PrefixTypeOp (* LL(1): * / [ *)
|
||||||
<- IDENTIFIER (COLON TypeExpr)? (COMMA / SEMICOLON)?
|
<- 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
|
/ ContinueStatement
|
||||||
/ DeferStatement
|
/ DeferStatement
|
||||||
/ VarDecl
|
/ VarDecl
|
||||||
|
/ ConstDecl
|
||||||
/ TypeDecl
|
/ TypeDecl
|
||||||
/ ExprStatement
|
/ ExprStatement
|
||||||
|
|
||||||
@@ -175,12 +196,12 @@ ForStatement
|
|||||||
MatchStatement <- KEYWORD_match Expr LBRACE MatchArm* RBRACE
|
MatchStatement <- KEYWORD_match Expr LBRACE MatchArm* RBRACE
|
||||||
|
|
||||||
MatchArm
|
MatchArm
|
||||||
<- MatchPat FAT_R_ARROW Statement
|
<- MatchPat (COMMA MatchPat)* FAT_R_ARROW Block
|
||||||
/ UNDERSCORE FAT_R_ARROW Statement
|
|
||||||
|
|
||||||
MatchPat (* LL(1): . / _ / Expr *)
|
MatchPat (* LL(1): . / _ / Expr *)
|
||||||
<- DOT IDENTIFIER (LBRACKET IDENTIFIER RBRACKET)? (* 仅允许 .Item 或 .Item[bind] *)
|
<- DOT IDENTIFIER (LBRACKET IDENTIFIER RBRACKET)? (* 仅允许 .Item 或 .Item[bind] *)
|
||||||
/ Expr (* 字面量或变量常量 *)
|
/ Expr (* 字面量或变量常量 *)
|
||||||
|
/ UNDERSCORE
|
||||||
|
|
||||||
# ---- 跳转 ----
|
# ---- 跳转 ----
|
||||||
|
|
||||||
@@ -221,7 +242,7 @@ PrefixOp <- MINUS / BANG / TILDE / AMPERSAND / ASTERISK
|
|||||||
PostfixExpr
|
PostfixExpr
|
||||||
<- PrimaryExpr
|
<- PrimaryExpr
|
||||||
( LPAREN ExprList RPAREN (* 函数调用 *)
|
( LPAREN ExprList RPAREN (* 函数调用 *)
|
||||||
/ DOT IDENTIFIER (* 字段/方法 *)
|
/ DOT IDENTIFIER (* 字段 *)
|
||||||
/ DOT ASTERISK (* 解引用 *)
|
/ DOT ASTERISK (* 解引用 *)
|
||||||
/ LBRACKET Expr RBRACKET (* 索引 *)
|
/ LBRACKET Expr RBRACKET (* 索引 *)
|
||||||
/ LBRACKET Expr DOT2 Expr? RBRACKET (* 切片 *)
|
/ LBRACKET Expr DOT2 Expr? RBRACKET (* 切片 *)
|
||||||
@@ -240,6 +261,7 @@ PrimaryExpr
|
|||||||
/ STRING_LITERAL
|
/ STRING_LITERAL
|
||||||
/ TRUE / FALSE / NULL_KW
|
/ TRUE / FALSE / NULL_KW
|
||||||
/ IDENTIFIER (LBRACE StructInitList? RBRACE)? (* 变量引用 / 结构体字面量 *)
|
/ IDENTIFIER (LBRACE StructInitList? RBRACE)? (* 变量引用 / 结构体字面量 *)
|
||||||
|
/ DOT LBRACE StructInitList? RBRACE (* 匿名聚合字面量 .{ .f = e } *)
|
||||||
/ LPAREN Expr RPAREN
|
/ LPAREN Expr RPAREN
|
||||||
/ ArrayLiteral
|
/ ArrayLiteral
|
||||||
/ BuiltinExpr
|
/ BuiltinExpr
|
||||||
@@ -254,38 +276,6 @@ StructInit <- DOT IDENTIFIER (EQUAL Expr)?
|
|||||||
BuiltinExpr
|
BuiltinExpr
|
||||||
<- (AT / SHARP) IDENTIFIER LPAREN ExprList? RPAREN (* @sizeof(T) / #runtime(x) *)
|
<- (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_comptime <- 'comptime' !IDENTIFIER_CHAR
|
||||||
KEYWORD_void <- 'void' !IDENTIFIER_CHAR
|
KEYWORD_void <- 'void' !IDENTIFIER_CHAR
|
||||||
KEYWORD_bool <- 'bool' !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_i8 <- 'i8' !IDENTIFIER_CHAR
|
||||||
KEYWORD_u8 <- 'u8' !IDENTIFIER_CHAR
|
KEYWORD_u8 <- 'u8' !IDENTIFIER_CHAR
|
||||||
KEYWORD_i16 <- 'i16' !IDENTIFIER_CHAR
|
KEYWORD_i16 <- 'i16' !IDENTIFIER_CHAR
|
||||||
@@ -332,11 +327,8 @@ KEYWORD_i32 <- 'i32' !IDENTIFIER_CHAR
|
|||||||
KEYWORD_u32 <- 'u32' !IDENTIFIER_CHAR
|
KEYWORD_u32 <- 'u32' !IDENTIFIER_CHAR
|
||||||
KEYWORD_i64 <- 'i64' !IDENTIFIER_CHAR
|
KEYWORD_i64 <- 'i64' !IDENTIFIER_CHAR
|
||||||
KEYWORD_u64 <- 'u64' !IDENTIFIER_CHAR
|
KEYWORD_u64 <- 'u64' !IDENTIFIER_CHAR
|
||||||
KEYWORD_isize <- 'isize' !IDENTIFIER_CHAR
|
|
||||||
KEYWORD_usize <- 'usize' !IDENTIFIER_CHAR
|
|
||||||
KEYWORD_f32 <- 'f32' !IDENTIFIER_CHAR
|
KEYWORD_f32 <- 'f32' !IDENTIFIER_CHAR
|
||||||
KEYWORD_f64 <- 'f64' !IDENTIFIER_CHAR
|
KEYWORD_f64 <- 'f64' !IDENTIFIER_CHAR
|
||||||
KEYWORD_ptr <- 'ptr' !IDENTIFIER_CHAR
|
|
||||||
|
|
||||||
TRUE <- 'true' !IDENTIFIER_CHAR
|
TRUE <- 'true' !IDENTIFIER_CHAR
|
||||||
FALSE <- 'false' !IDENTIFIER_CHAR
|
FALSE <- 'false' !IDENTIFIER_CHAR
|
||||||
@@ -355,7 +347,7 @@ COLON <- ':' DOT <- '.'
|
|||||||
DOT2 <- '..' DOT3 <- '...'
|
DOT2 <- '..' DOT3 <- '...'
|
||||||
AT <- '@' SHARP <- '#'
|
AT <- '@' SHARP <- '#'
|
||||||
FAT_R_ARROW <- '=>' FAT_D_ARROW <- '<=>'
|
FAT_R_ARROW <- '=>' FAT_D_ARROW <- '<=>'
|
||||||
R_ARROW <- '<-' L_ARROW <- '->' D_ARROW '<->'
|
THIN_R_ARROW <- '<-' THIN_L_ARROW <- '->' THIN_D_ARROW '<->'
|
||||||
|
|
||||||
EQUAL <- '='
|
EQUAL <- '='
|
||||||
COLON_ASSIGN <- ':='
|
COLON_ASSIGN <- ':='
|
||||||
@@ -407,6 +399,18 @@ BLOCK_COMMENT <- '/*' (!'*/' .)* '*/'
|
|||||||
eof <- !.
|
eof <- !.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
```spl
|
||||||
|
// 约束关键字,语义是`类型子集形状`
|
||||||
|
type name = shape { ... }
|
||||||
|
|
||||||
|
// 默认字段
|
||||||
|
type name = struct { x: i32 = 0, }
|
||||||
|
|
||||||
|
// 默认参数
|
||||||
|
fn name(x: i32 = 0) { ... }
|
||||||
|
```
|
||||||
|
|
||||||
# SPL 语义规范
|
# SPL 语义规范
|
||||||
|
|
||||||
## 设计总则
|
## 设计总则
|
||||||
@@ -442,15 +446,16 @@ DirectiveBlock @id { } / #id { } 为扩展占位,无预定义行为。未识
|
|||||||
语义: 完全由语言版本或库注册决定。当前所有均视为未识别,产生警告 (宽松) 或错误 (严格)。
|
语义: 完全由语言版本或库注册决定。当前所有均视为未识别,产生警告 (宽松) 或错误 (严格)。
|
||||||
|
|
||||||
## 函数
|
## 函数
|
||||||
text
|
|
||||||
AttrList? fn IDENTIFIER ( ParamDeclList ) TypeExpr? ( ; | Block )
|
AttrList? fn IDENTIFIER ( ParamDeclList ) TypeExpr? ( ; | Block )
|
||||||
|
|
||||||
参数: 全部不可变。需要可变时通过 *T 传递。
|
参数: 全部不可变。需要可变时通过 *T 传递。
|
||||||
|
|
||||||
返回类型: 省略即 void。仅有 ; 表示外部声明。
|
返回类型: 省略即 void。仅有 ; 表示外部声明。
|
||||||
|
|
||||||
调用: 实参与形参数量、类型必须完全匹配 (无隐式可变参数)。
|
调用: 实参与形参数量、类型必须完全匹配 (无隐式可变参数)。
|
||||||
|
|
||||||
执行: 新作用域 → 形参绑定实参 → 执行 Block → 遇 ret expr 返回 (类型匹配),或 void 函数自然结束返回。
|
执行: 新作用域 -> 形参绑定实参 -> 执行 Block -> 遇 ret expr 返回 (类型匹配),或 void 函数自然结束返回。
|
||||||
|
|
||||||
## 类型声明与聚合体
|
## 类型声明与聚合体
|
||||||
### 别名
|
### 别名
|
||||||
@@ -573,7 +578,7 @@ defer { ... }: 退出作用域时以后进先出执行。
|
|||||||
|
|
||||||
浮点 f64,布尔 bool。
|
浮点 f64,布尔 bool。
|
||||||
|
|
||||||
null → ?T 隐式转换。
|
null -> ?T 隐式转换。
|
||||||
|
|
||||||
### 运算符
|
### 运算符
|
||||||
算术/位运算: 操作数类型必须完全一致或由字面量推导,无隐式提升。
|
算术/位运算: 操作数类型必须完全一致或由字面量推导,无隐式提升。
|
||||||
@@ -587,12 +592,12 @@ null → ?T 隐式转换。
|
|||||||
- 数值 同类型
|
- 数值 同类型
|
||||||
! bool bool
|
! bool bool
|
||||||
~ 整数 同类型
|
~ 整数 同类型
|
||||||
& 可寻址左值 *T
|
& 可寻址左值 \*T
|
||||||
解引用仅有后缀形式 .*,无前缀 * 运算符。(*ptr) 不合法。
|
解引用仅有后缀形式 .\*,无前缀 \* 运算符。(\*ptr) 不合法。
|
||||||
|
|
||||||
后缀运算符
|
后缀运算符
|
||||||
运算 约束 说明
|
运算 约束 说明
|
||||||
expr.* expr 为 *T 解引用,得 T 左值
|
expr.\* expr 为 \*T 解引用,得 T 左值
|
||||||
expr.field struct 或指针 指针时自动解引用一层再取字段
|
expr.field struct 或指针 指针时自动解引用一层再取字段
|
||||||
expr[i] 数组/切片/指针,i 整数 元素左值
|
expr[i] 数组/切片/指针,i 整数 元素左值
|
||||||
expr[a..b] 数组/切片/指针 切片操作,产生 []T,内部设置 ptr 和 len
|
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。
|
其余必须显式 as。
|
||||||
|
|
||||||
@@ -740,7 +745,7 @@ fn(参数类型列表) 返回类型
|
|||||||
|
|
||||||
null 字面量只能出现在需要 ?T 的上下文中。
|
null 字面量只能出现在需要 ?T 的上下文中。
|
||||||
|
|
||||||
### 自定义聚合类型
|
### 聚合类型
|
||||||
struct: 字段连续排列 (可能有对齐填充),每个字段有自己的类型。赋值是逐字段拷贝。
|
struct: 字段连续排列 (可能有对齐填充),每个字段有自己的类型。赋值是逐字段拷贝。
|
||||||
|
|
||||||
union: 所有字段共享起始地址,大小等于最大字段 (加上对齐)。直接字段读取被视为不安全,需通过 match 解构。
|
union: 所有字段共享起始地址,大小等于最大字段 (加上对齐)。直接字段读取被视为不安全,需通过 match 解构。
|
||||||
@@ -750,16 +755,7 @@ enum: 带标签的联合体,每个变体可有载荷。大小实现定义,
|
|||||||
## 类型分类
|
## 类型分类
|
||||||
### 值类型 (复制语义)
|
### 值类型 (复制语义)
|
||||||
所有基本标量类型,或者说底层寄存器类型 (整数、浮点、bool)
|
所有基本标量类型,或者说底层寄存器类型 (整数、浮点、bool)
|
||||||
|
`聚合类型` `数组 [N]T` `切片[]T` `区间Range` 赋值、传参会复制整个值。修改副本不影响原值。
|
||||||
struct
|
|
||||||
|
|
||||||
数组 [N]T
|
|
||||||
|
|
||||||
切片 []T
|
|
||||||
|
|
||||||
区间 Range
|
|
||||||
|
|
||||||
赋值、传参会复制整个值。修改副本不影响原值。
|
|
||||||
|
|
||||||
### 引用/指针类型
|
### 引用/指针类型
|
||||||
\*T、\*_
|
\*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、-、*、/、%:
|
算术 e1 + e2、-、*、/、%:
|
||||||
@@ -953,8 +949,8 @@ ForRange 提供表达式列表 [E1, E2, ...]。as 后标识符列表 [v1, v2, ..
|
|||||||
|
|
||||||
```
|
```
|
||||||
for my_slice, 0.. as elem, idx { ... }
|
for my_slice, 0.. as elem, idx { ... }
|
||||||
// my_slice: []T → elem: T
|
// my_slice: []T -> elem: T
|
||||||
// 0..: Range 无界 → idx: i64,长度由 my_slice 决定
|
// 0..: Range 无界 -> idx: i64,长度由 my_slice 决定
|
||||||
```
|
```
|
||||||
## 类型系统限制
|
## 类型系统限制
|
||||||
无隐式类型提升 (除字面量整数拓宽和数组到切片外)。
|
无隐式类型提升 (除字面量整数拓宽和数组到切片外)。
|
||||||
|
|||||||
3427
stage1/spl_ast.c
3427
stage1/spl_ast.c
File diff suppressed because it is too large
Load Diff
@@ -4,10 +4,9 @@
|
|||||||
#include "../stage0/include/utils.h"
|
#include "../stage0/include/utils.h"
|
||||||
#include "spl_lexer.h"
|
#include "spl_lexer.h"
|
||||||
#include "spl_tok.h"
|
#include "spl_tok.h"
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPL_AST_CONTAINER_MEMBER,
|
SPL_AST_CONTAINER_ITEM,
|
||||||
SPL_AST_FN_DECL,
|
SPL_AST_FN_DECL,
|
||||||
SPL_AST_FN_DEFINE,
|
SPL_AST_FN_DEFINE,
|
||||||
SPL_AST_TYPE_DECL,
|
SPL_AST_TYPE_DECL,
|
||||||
@@ -37,7 +36,11 @@ struct spl_ast_node {
|
|||||||
spl_ast_node_kind_t kind;
|
spl_ast_node_kind_t kind;
|
||||||
spl_ast_loc_t loc;
|
spl_ast_loc_t loc;
|
||||||
union {
|
union {
|
||||||
spl_ast_node_ref_vec_t container_member;
|
struct {
|
||||||
|
spl_ast_node_ref_vec_t attr_list; /* attr_item */
|
||||||
|
spl_ast_node_ref_t self; /* self */
|
||||||
|
spl_ast_node_ref_vec_t members; /* container_decl 列表 */
|
||||||
|
} container_item;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *ident;
|
const char *ident;
|
||||||
@@ -58,18 +61,8 @@ struct spl_ast_node {
|
|||||||
} param_decl;
|
} param_decl;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list; /* attr_item */
|
|
||||||
const char *name;
|
const char *name;
|
||||||
enum {
|
|
||||||
SPL_AST_TYPE_STRUCT,
|
|
||||||
SPL_AST_TYPE_UNION,
|
|
||||||
SPL_AST_TYPE_ENUM,
|
|
||||||
SPL_AST_TYPE_TYPE_EXPR,
|
|
||||||
} kind;
|
|
||||||
union {
|
|
||||||
spl_ast_node_ref_t type_expr;
|
spl_ast_node_ref_t type_expr;
|
||||||
spl_ast_node_ref_t aggregate_list;
|
|
||||||
};
|
|
||||||
} type_decl;
|
} type_decl;
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list; /* attr_item */
|
spl_ast_node_ref_vec_t attr_list; /* attr_item */
|
||||||
@@ -103,6 +96,7 @@ struct spl_ast_node {
|
|||||||
SPL_AST_CONTINUE_STATEMENT,
|
SPL_AST_CONTINUE_STATEMENT,
|
||||||
SPL_AST_DEFER_STATEMENT,
|
SPL_AST_DEFER_STATEMENT,
|
||||||
SPL_AST_VARDECL,
|
SPL_AST_VARDECL,
|
||||||
|
SPL_AST_CONSTDECL,
|
||||||
SPL_AST_TYPEDECL,
|
SPL_AST_TYPEDECL,
|
||||||
SPL_AST_EXPR_STATEMENT,
|
SPL_AST_EXPR_STATEMENT,
|
||||||
} kind;
|
} kind;
|
||||||
@@ -131,8 +125,8 @@ struct spl_ast_node {
|
|||||||
} for_statement;
|
} for_statement;
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t expr;
|
spl_ast_node_ref_t expr;
|
||||||
spl_ast_node_ref_vec_t paced_exprs;
|
spl_ast_node_ref_vec_t paced_exprs; /* packed_expr */
|
||||||
spl_ast_node_ref_vec_t statements;
|
spl_ast_node_ref_vec_t match_block; /* block_item */
|
||||||
} match_statement;
|
} match_statement;
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t expr;
|
spl_ast_node_ref_t expr;
|
||||||
@@ -145,6 +139,7 @@ struct spl_ast_node {
|
|||||||
spl_ast_node_ref_vec_t block_or_statement; /* block_item/statement */
|
spl_ast_node_ref_vec_t block_or_statement; /* block_item/statement */
|
||||||
} defer_statement;
|
} defer_statement;
|
||||||
spl_ast_node_ref_t var_decl;
|
spl_ast_node_ref_t var_decl;
|
||||||
|
spl_ast_node_ref_t const_decl;
|
||||||
spl_ast_node_ref_t type_decl;
|
spl_ast_node_ref_t type_decl;
|
||||||
spl_ast_node_ref_t expr_statement;
|
spl_ast_node_ref_t expr_statement;
|
||||||
};
|
};
|
||||||
@@ -280,10 +275,13 @@ struct spl_ast_node {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t type_prefixs; /* prefix_type */
|
spl_ast_node_ref_vec_t type_prefixs; /* prefix_type */
|
||||||
|
spl_ast_node_ref_vec_t attr_list; /* attr_item */
|
||||||
enum {
|
enum {
|
||||||
SPL_AST_BASE_TYPE_FN,
|
SPL_AST_BASE_TYPE_FN,
|
||||||
SPL_AST_BASE_TYPE_PATH,
|
SPL_AST_BASE_TYPE_PATH,
|
||||||
|
SPL_AST_TYPE_STRUCT,
|
||||||
|
SPL_AST_TYPE_UNION,
|
||||||
|
SPL_AST_TYPE_ENUM,
|
||||||
} kind;
|
} kind;
|
||||||
|
|
||||||
const char *spl_base_type;
|
const char *spl_base_type;
|
||||||
@@ -293,6 +291,7 @@ struct spl_ast_node {
|
|||||||
spl_ast_node_ref_vec_t param_list; /* param_decl */
|
spl_ast_node_ref_vec_t param_list; /* param_decl */
|
||||||
spl_ast_node_ref_t type_expr;
|
spl_ast_node_ref_t type_expr;
|
||||||
} fn_type;
|
} fn_type;
|
||||||
|
spl_ast_node_ref_vec_t aggregate_list; /* container_decl */
|
||||||
};
|
};
|
||||||
} type_expr;
|
} type_expr;
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
1
stage1/spl_ast2ir.c
Normal file
1
stage1/spl_ast2ir.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "spl_ast2ir.h"
|
||||||
4
stage1/spl_ast2ir.h
Normal file
4
stage1/spl_ast2ir.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#ifndef __SPL_AST2IR_H__
|
||||||
|
#define __SPL_AST2IR_H__
|
||||||
|
|
||||||
|
#endif /* __SPL_AST2IR_H__ */
|
||||||
26
stage1/spl_dumptree.c
Normal file
26
stage1/spl_dumptree.c
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* spl_dumptree.c 可配置的树形打印模块(只用基本 ASCII)*/
|
||||||
|
|
||||||
|
#include "spl_dumptree.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
const spl_dumptree_style_t spl_dumptree_ascii_style = {
|
||||||
|
"| ",
|
||||||
|
"|-",
|
||||||
|
"`-",
|
||||||
|
" ",
|
||||||
|
};
|
||||||
|
|
||||||
|
void spl_dumptree_print(const spl_dumptree_style_t *st, const char *prefix, int is_last,
|
||||||
|
const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
printf("%s%s ", prefix, is_last ? st->last_branch : st->branch);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void spl_dumptree_child_prefix(const spl_dumptree_style_t *st, const char *prefix, int is_last,
|
||||||
|
char *out, size_t cap) {
|
||||||
|
snprintf(out, cap, "%s%s", prefix, is_last ? st->space : st->vertical);
|
||||||
|
}
|
||||||
31
stage1/spl_dumptree.h
Normal file
31
stage1/spl_dumptree.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* spl_dumptree.h 可配置的树形打印模块(只用基本 ASCII)*/
|
||||||
|
|
||||||
|
#ifndef __SPL_DUMPTREE_H__
|
||||||
|
#define __SPL_DUMPTREE_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* 可配置的缩进字符串 */
|
||||||
|
typedef struct {
|
||||||
|
const char *vertical; /* "| " */
|
||||||
|
const char *branch; /* "|-" */
|
||||||
|
const char *last_branch; /* "`-" */
|
||||||
|
const char *space; /* " " */
|
||||||
|
} spl_dumptree_style_t;
|
||||||
|
|
||||||
|
/* 默认 ASCII 风格 */
|
||||||
|
extern const spl_dumptree_style_t spl_dumptree_ascii_style;
|
||||||
|
|
||||||
|
/* 打印一行节点标签:prefix + 分支符 + label
|
||||||
|
* prefix 已累积的缩进骨架(不含分支符)
|
||||||
|
* is_last 本节点是否为同级最后一个子节点
|
||||||
|
* fmt printf 风格 label */
|
||||||
|
void spl_dumptree_print(const spl_dumptree_style_t *st, const char *prefix, int is_last,
|
||||||
|
const char *fmt, ...);
|
||||||
|
|
||||||
|
/* 生成子节点的缩进骨架:parent_prefix + (parent_is_last ? space : vertical) */
|
||||||
|
void spl_dumptree_child_prefix(const spl_dumptree_style_t *st, const char *prefix, int is_last,
|
||||||
|
char *out, size_t cap);
|
||||||
|
|
||||||
|
#endif /* __SPL_DUMPTREE_H__ */
|
||||||
@@ -70,19 +70,39 @@
|
|||||||
X(dbg.breakpoint, V0, SPL_IR_DBG_BREAKPOINT) \
|
X(dbg.breakpoint, V0, SPL_IR_DBG_BREAKPOINT) \
|
||||||
X(dbg.declare, V0, SPL_IR_DBG_DECLARE)
|
X(dbg.declare, V0, SPL_IR_DBG_DECLARE)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
#ifdef X
|
||||||
|
#undef X
|
||||||
|
#endif
|
||||||
|
#define X(a, b, c) c,
|
||||||
|
SPL_IR_FN_TABLE
|
||||||
|
#undef X
|
||||||
|
} spl_ir_kind_t;
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum {
|
spl_ir_kind_t kind;
|
||||||
|
|
||||||
} kind;
|
|
||||||
} 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;
|
||||||
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 {
|
||||||
|
enum {
|
||||||
|
SPL_IR_ATTR_NONE,
|
||||||
|
SPL_IR_ATTR_LINK, /* 不实现 */
|
||||||
|
SPL_IR_ATTR_ABI, /* 只有 C ABI 支持 */
|
||||||
|
SPL_IR_ATTR_SYMBOL, /* 不实现 */
|
||||||
|
SPL_IR_ATTR_NAKED, /* 不实现 */
|
||||||
|
SPL_IR_ATTR_NOINLINE, /* 不实现 */
|
||||||
|
SPL_IR_ATTR_ALWAYSINLINE, /* 不实现 */
|
||||||
|
};
|
||||||
|
} spl_ir_attr_t;
|
||||||
|
typedef VEC(spl_ir_attr_t) spl_ir_attr_vec_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
spl_ir_attr_t attr;
|
||||||
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;
|
||||||
|
|||||||
1
stage1/spl_sema.c
Normal file
1
stage1/spl_sema.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "spl_sema.h"
|
||||||
33
stage1/spl_sema.h
Normal file
33
stage1/spl_sema.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __SPL_SEMA_H__
|
||||||
|
#define __SPL_SEMA_H__
|
||||||
|
|
||||||
|
#include "spl_ast.h"
|
||||||
|
#include "spl_type.h"
|
||||||
|
|
||||||
|
typedef usize spl_scope_id_t; /* 0 is error */
|
||||||
|
typedef struct {
|
||||||
|
spl_scope_id_t parent;
|
||||||
|
MAP(const char *, spl_type_id_t) symbols;
|
||||||
|
} spl_scope_node_t;
|
||||||
|
typedef VEC(spl_scope_node_t) spl_scope_node_vec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
spl_ast_t *ast;
|
||||||
|
spl_type_t type;
|
||||||
|
spl_scope_node_vec_t scopes;
|
||||||
|
spl_scope_id_t root_scope;
|
||||||
|
spl_scope_id_t current_scope;
|
||||||
|
int error_count;
|
||||||
|
} spl_sema_t;
|
||||||
|
|
||||||
|
void spl_sema_init(spl_sema_t *sema);
|
||||||
|
void spl_sema_drop(spl_sema_t *sema);
|
||||||
|
void spl_sema_run(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,
|
||||||
|
spl_type_id_t symbol_val);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* __SPL_SEMA_H__ */
|
||||||
1
stage1/spl_type.c
Normal file
1
stage1/spl_type.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "spl_type.h"
|
||||||
116
stage1/spl_type.h
Normal file
116
stage1/spl_type.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#ifndef __SPL_TYPE_H__
|
||||||
|
#define __SPL_TYPE_H__
|
||||||
|
|
||||||
|
#include "../stage0/include/utils.h"
|
||||||
|
|
||||||
|
typedef usize spl_type_id_t; /* 0 is error */
|
||||||
|
typedef VEC(spl_type_id_t) spl_type_id_vec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum {
|
||||||
|
SPL_TYPE_VOID,
|
||||||
|
SPL_TYPE_BOOL,
|
||||||
|
SPL_TYPE_INT,
|
||||||
|
SPL_TYPE_FLOAT,
|
||||||
|
SPL_TYPE_PTR,
|
||||||
|
SPL_TYPE_SLICE,
|
||||||
|
SPL_TYPE_ARRAY,
|
||||||
|
SPL_TYPE_STRUCT,
|
||||||
|
SPL_TYPE_UNION,
|
||||||
|
SPL_TYPE_ENUM,
|
||||||
|
SPL_TYPE_FN,
|
||||||
|
SPL_TYPE_ID,
|
||||||
|
} kind;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
usize bits;
|
||||||
|
int is_signed;
|
||||||
|
} int_type;
|
||||||
|
struct {
|
||||||
|
usize bits;
|
||||||
|
} float_type;
|
||||||
|
spl_type_id_t ptr_pointee;
|
||||||
|
spl_type_id_t slice_element;
|
||||||
|
struct {
|
||||||
|
spl_type_id_t element;
|
||||||
|
usize len;
|
||||||
|
} array_type;
|
||||||
|
spl_type_id_vec_t agg_field_types;
|
||||||
|
struct {
|
||||||
|
spl_type_id_vec_t variants;
|
||||||
|
spl_type_id_t tag_type;
|
||||||
|
} enum_type; // ADT
|
||||||
|
struct {
|
||||||
|
spl_type_id_vec_t params;
|
||||||
|
spl_type_id_t ret;
|
||||||
|
} fn_type;
|
||||||
|
spl_type_id_t type_id;
|
||||||
|
};
|
||||||
|
usize byte_size; /* 布局缓存 */
|
||||||
|
} spl_type_node_t;
|
||||||
|
typedef VEC(spl_type_node_t) spl_type_node_vec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
spl_type_id_t type;
|
||||||
|
usize scope_id;
|
||||||
|
} spl_var_def_t;
|
||||||
|
typedef VEC(spl_var_def_t) spl_var_def_vec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum {
|
||||||
|
SPL_DEF_NONE,
|
||||||
|
SPL_DEF_BUILTIN,
|
||||||
|
SPL_DEF_VAR,
|
||||||
|
SPL_DEF_FN_PARAMS,
|
||||||
|
SPL_DEF_AGG, // include enum variants
|
||||||
|
SPL_DEF_DISTINCT, // newtype
|
||||||
|
SPL_DEF_ALIAS, // sametypes
|
||||||
|
} kind;
|
||||||
|
union {
|
||||||
|
spl_var_def_t var_def;
|
||||||
|
spl_var_def_vec_t agg_def; // include enum variants
|
||||||
|
spl_var_def_vec_t fn_params_def;
|
||||||
|
spl_var_def_t type_def;
|
||||||
|
};
|
||||||
|
int source_loc;
|
||||||
|
enum {
|
||||||
|
SPL_FLAG_NONE,
|
||||||
|
} flag;
|
||||||
|
} spl_def_node_t;
|
||||||
|
typedef VEC(spl_def_node_t) spl_def_node_vec_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
SPL 设计是严格区分类型做到类型和名称无关即
|
||||||
|
type (类型名) = (匿名类型)
|
||||||
|
好处是递归使用可以直接操作类型名的映射的提前分配的匿名类型的id
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
spl_type_node_vec_t type_table;
|
||||||
|
spl_def_node_vec_t def_table; /* 使用type_id作为索引 */
|
||||||
|
} spl_type_t;
|
||||||
|
|
||||||
|
void spl_type_init(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_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_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_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_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_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_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_agg(spl_type_t *type, spl_type_id_vec_t fields);
|
||||||
|
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 spl_type_fn(spl_type_t *type, spl_type_id_vec_t params, spl_type_id_t ret);
|
||||||
|
|
||||||
|
#endif /* __SPL_TYPE_H__ */
|
||||||
@@ -1,8 +1,19 @@
|
|||||||
/* splc0.c — SPL compiler CLI */
|
/* splc0.c — SPL compiler CLI (stage 1, 引导用)
|
||||||
|
*
|
||||||
|
* splc0 --dump tokens|ast|all <file> dump 前端产物
|
||||||
|
* splc0 <in> <out> 编译 (阶段 B 实现)
|
||||||
|
*/
|
||||||
|
#define __SCC_LOG_IMPL_IMPORT_SRC__
|
||||||
|
#include "../stage0/include/utils.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "spl_ast.h"
|
||||||
|
#include "spl_lexer.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) {
|
||||||
FILE *f = fopen(path, "rb");
|
FILE *f = fopen(path, "rb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
@@ -24,19 +35,68 @@ static char *read_file(const char *path, long *out_len) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *const tok_type_names[] = {
|
||||||
|
#define X(name, enum_name, dummy) #enum_name,
|
||||||
|
KEYWORD_TABLE
|
||||||
|
#undef X
|
||||||
|
#define X(name, enum_name, dummy) #enum_name,
|
||||||
|
TOKEN_TABLE
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
|
||||||
|
static void dump_tokens(const char *src, const char *fname) {
|
||||||
|
spl_tok_vec_t toks = spl_lex(src, fname);
|
||||||
|
printf("tokens got (%zu)\n", toks.size);
|
||||||
|
for (usize i = 0; i < toks.size; i++) {
|
||||||
|
const spl_tok_t *t = &toks.data[i];
|
||||||
|
printf("[%s] %.*s (%zu:%zu)\n", tok_type_names[t->type], (int)t->len, t->lexeme, t->line,
|
||||||
|
t->col);
|
||||||
|
}
|
||||||
|
vec_free(toks);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_ast(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_ast_dump(&ast, ast.root);
|
||||||
|
spl_ast_drop(&ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_dump(const char *flags, const char *path) {
|
||||||
|
long len;
|
||||||
|
char *src = read_file(path, &len);
|
||||||
|
if (!src)
|
||||||
|
return 1;
|
||||||
|
int do_tokens = strstr(flags, "tokens") != NULL || strcmp(flags, "all") == 0;
|
||||||
|
int do_ast = strstr(flags, "ast") != NULL || strcmp(flags, "all") == 0;
|
||||||
|
if (do_tokens)
|
||||||
|
dump_tokens(src, path);
|
||||||
|
if (do_ast)
|
||||||
|
dump_ast(src, path);
|
||||||
|
free(src);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "Usage: splc0 [--dump <flags>] <in> [out]\n");
|
LOG_FATAL("Usage: splc0 [--dump <flags>] <in> [out]\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[1], "--dump") == 0)
|
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) {
|
||||||
// return cmd_dump(argc - 2, argv + 2);
|
LOG_INFO("splc0 <in> <out> compile (.spl -> .sir, 阶段 B)\n");
|
||||||
return 0;
|
LOG_INFO("splc0 --dump <flags> <file> dump: tokens,ast,all\n");
|
||||||
if (strcmp(argv[1], "--help") == 0) {
|
|
||||||
printf("splc0 <in> <out> compile\n");
|
|
||||||
printf("splc0 --dump <f> <file> dump: tokens,cst,ast,ir,mcode,all\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// return cmd_compile(argc - 1, argv + 1);
|
if (strcmp(argv[1], "--dump") == 0) {
|
||||||
return 0;
|
if (argc < 4) {
|
||||||
|
LOG_INFO("splc0: --dump need <flags> <file>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return cmd_dump(argv[2], argv[3]);
|
||||||
|
}
|
||||||
|
LOG_FATAL("splc0: compile todo\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* spc_vm.c 鈥?VM launcher for stage 1 */
|
/* spc_vm.c launcher for stage 1 */
|
||||||
|
|
||||||
#include "../stage0/spl_mcode.h"
|
#include "../stage0/spl_mcode.h"
|
||||||
#include "../stage0/spl_syscall.h"
|
#include "../stage0/spl_syscall.h"
|
||||||
@@ -57,13 +57,12 @@ int main(int argc, const char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
spl_vm_set_trace(&vm, trace);
|
spl_vm_set_trace(&vm, trace);
|
||||||
if (debug_addr) spl_vm_set_debug(&vm, 1);
|
if (debug_addr)
|
||||||
|
spl_vm_set_debug(&vm, 1);
|
||||||
|
|
||||||
int ret = spl_vm_run_until(&vm, 0);
|
int ret = spl_vm_run_until(&vm, 0);
|
||||||
spl_vm_drop(&vm);
|
spl_vm_drop(&vm);
|
||||||
spl_prog_drop(&prog);
|
spl_prog_drop(&prog);
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
return (int)vm.exit_code;
|
|
||||||
return (int)vm.exit_code;
|
return (int)vm.exit_code;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ type Expr = enum {
|
|||||||
|
|
||||||
fn eval(self: *Expr) i32 {
|
fn eval(self: *Expr) i32 {
|
||||||
match self {
|
match self {
|
||||||
.Int[val] => ret val,
|
.Int[val] => { ret val; },
|
||||||
.Add[.left = left, .right = right] => ret eval(left) + eval(right),
|
.Add[sub] => { ret eval(sub.left) + eval(sub.right); }
|
||||||
}
|
}
|
||||||
ret 0;
|
ret 0;
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ fn main() i32 {
|
|||||||
/* enum 方法 + match */
|
/* enum 方法 + match */
|
||||||
var expr_l := Expr { .Int = 3 };
|
var expr_l := Expr { .Int = 3 };
|
||||||
var expr_r := Expr { .Int = 4 };
|
var expr_r := Expr { .Int = 4 };
|
||||||
var expr := Expr { .Add = { .left = expr_l, .right = expr_r } };
|
var expr := Expr { .Add = .{ .left = expr_l, .right = expr_r } };
|
||||||
var result := expr.eval(&expr);
|
var result := expr.eval(&expr);
|
||||||
vm_printf("eval result: %d\n", result);
|
vm_printf("eval result: %d\n", result);
|
||||||
if result != 7 { ret 1; }
|
if result != 7 { ret 1; }
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ fn test_shape_match() i32 {
|
|||||||
.Circle[r] => {
|
.Circle[r] => {
|
||||||
if r != 10 { ret 1; }
|
if r != 10 { ret 1; }
|
||||||
},
|
},
|
||||||
.Rect[.x = w, .y = h] => {
|
.Rect[p] => {
|
||||||
ret 2;
|
ret 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,9 +127,9 @@ fn test_shape_match() i32 {
|
|||||||
s = Shape { .Rect = Point { .x = 3, .y = 4 } };
|
s = Shape { .Rect = Point { .x = 3, .y = 4 } };
|
||||||
match s {
|
match s {
|
||||||
.Circle[r] => { ret 3; },
|
.Circle[r] => { ret 3; },
|
||||||
.Rect[.x = w, .y = h] => {
|
.Rect[p] => {
|
||||||
if w != 3 { ret 4; }
|
if p.x != 3 { ret 4; }
|
||||||
if h != 4 { ret 5; }
|
if p.y != 4 { ret 5; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ fn test_string() i32 {
|
|||||||
* String test: str is []u8
|
* String test: str is []u8
|
||||||
* ============================ */
|
* ============================ */
|
||||||
var data: *u8 = "hello";
|
var data: *u8 = "hello";
|
||||||
var s: []u8 = { .ptr = data, .len = 5 };
|
var s: []u8 = .{ .ptr = data, .len = 5 };
|
||||||
|
|
||||||
if s.len != 5 { ret 100; }
|
if s.len != 5 { ret 100; }
|
||||||
if s[0] != 104 { ret 101; } /* 'h' */
|
if s[0] != 104 { ret 101; } /* 'h' */
|
||||||
@@ -147,7 +147,7 @@ fn main() i32 {
|
|||||||
var data: [5]i32;
|
var data: [5]i32;
|
||||||
data[0] = 10; data[1] = 20; data[2] = 30; data[3] = 40; data[4] = 50;
|
data[0] = 10; data[1] = 20; data[2] = 30; data[3] = 40; data[4] = 50;
|
||||||
var p: *i32 = &data[2];
|
var p: *i32 = &data[2];
|
||||||
var from_ptr: []i32 = { .ptr = p, .len = 2 };
|
var from_ptr: []i32 = .{ .ptr = p, .len = 2 };
|
||||||
var from_ptr2: []i32;
|
var from_ptr2: []i32;
|
||||||
from_ptr2.ptr = p;
|
from_ptr2.ptr = p;
|
||||||
from_ptr2.len = 2;
|
from_ptr2.len = 2;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ fn test_slice_in_struct() i32 {
|
|||||||
raw[0] = 65; raw[1] = 66; raw[2] = 67; raw[3] = 68;
|
raw[0] = 65; raw[1] = 66; raw[2] = 67; raw[3] = 68;
|
||||||
|
|
||||||
/* Bug fix: { .ptr = ..., .len = ... } inside struct literal */
|
/* Bug fix: { .ptr = ..., .len = ... } inside struct literal */
|
||||||
var b: Buffer = Buffer { .data = { .ptr = &raw[0], .len = 4 }, .len = 4 };
|
var b: Buffer = Buffer { .data = .{ .ptr = &raw[0], .len = 4 }, .len = 4 };
|
||||||
|
|
||||||
if b.len != 4 { ret 1; }
|
if b.len != 4 { ret 1; }
|
||||||
if b.data[0] != 65 { ret 2; }
|
if b.data[0] != 65 { ret 2; }
|
||||||
@@ -90,7 +90,7 @@ fn test_slice_in_struct() i32 {
|
|||||||
if raw[0] != 90 { ret 5; }
|
if raw[0] != 90 { ret 5; }
|
||||||
|
|
||||||
/* Initialize with shorter slice */
|
/* Initialize with shorter slice */
|
||||||
var b2: Buffer = Buffer { .data = { .ptr = &raw[2], .len = 2 }, .len = 2 };
|
var b2: Buffer = Buffer { .data = .{ .ptr = &raw[2], .len = 2 }, .len = 2 };
|
||||||
if b2.len != 2 { ret 6; }
|
if b2.len != 2 { ret 6; }
|
||||||
if b2.data[0] != 67 { ret 7; }
|
if b2.data[0] != 67 { ret 7; }
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ fn test_complex_nesting() i32 {
|
|||||||
|
|
||||||
var bundle: Bundle = Bundle {
|
var bundle: Bundle = Bundle {
|
||||||
.name = &str_data[0],
|
.name = &str_data[0],
|
||||||
.buf = Buffer { .data = { .ptr = &str_data[1], .len = 3 }, .len = 3 },
|
.buf = Buffer { .data = .{ .ptr = &str_data[1], .len = 3 }, .len = 3 },
|
||||||
.row = MatrixRow { .items = [4]i32{1, 2, 3, 4} },
|
.row = MatrixRow { .items = [4]i32{1, 2, 3, 4} },
|
||||||
.pt = Point { .x = -5, .y = 15 }
|
.pt = Point { .x = -5, .y = 15 }
|
||||||
};
|
};
|
||||||
@@ -259,7 +259,7 @@ fn test_enum_complex() i32 {
|
|||||||
.Inactive => {
|
.Inactive => {
|
||||||
ret 2;
|
ret 2;
|
||||||
},
|
},
|
||||||
.Pending[.x = px, .y = py] => {
|
.Pending[p] => {
|
||||||
ret 3;
|
ret 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ fn test_enum_complex() i32 {
|
|||||||
match s2 {
|
match s2 {
|
||||||
.Active[val] => {},
|
.Active[val] => {},
|
||||||
.Inactive => { is_inactive = 1; },
|
.Inactive => { is_inactive = 1; },
|
||||||
.Pending[.x = px, .y = py] => {}
|
.Pending[p] => {}
|
||||||
}
|
}
|
||||||
if is_inactive != 1 { ret 4; }
|
if is_inactive != 1 { ret 4; }
|
||||||
|
|
||||||
@@ -279,9 +279,9 @@ fn test_enum_complex() i32 {
|
|||||||
match s3 {
|
match s3 {
|
||||||
.Active[val] => { ret 5; },
|
.Active[val] => { ret 5; },
|
||||||
.Inactive => { ret 6; },
|
.Inactive => { ret 6; },
|
||||||
.Pending[.x = px, .y = py] => {
|
.Pending[p] => {
|
||||||
if px != 7 { ret 7; }
|
if p.x != 7 { ret 7; }
|
||||||
if py != 8 { ret 8; }
|
if p.y != 8 { ret 8; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user