stage1 重构代码 语法上重新实现解包语法
This commit is contained in:
1 parent
2a84b61e3d
commit
54425a50c7
10 files changed
+2681
-2478
No files matched your search
+86
-44
@@ -1,4 +1,3 @@
|
|||||||
// 顶层容器
|
|
||||||
Root = { SOI ~ ContainerMembers ~ EOI }
|
Root = { SOI ~ ContainerMembers ~ EOI }
|
||||||
ContainerMembers = { ExternalHeaderList ~ (ContainerDeclaration ~ (COMMA | SEMICOLON)*)* }
|
ContainerMembers = { ExternalHeaderList ~ (ContainerDeclaration ~ (COMMA | SEMICOLON)*)* }
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@ ContainerDeclaration = {
|
|||||||
|
|
||||||
ComptimeDecl = { KEYWORD_comptime ~ (Block | Expr) }
|
ComptimeDecl = { KEYWORD_comptime ~ (Block | Expr) }
|
||||||
|
|
||||||
// 函数声明(可带 comptime 前缀,支持修饰符)
|
|
||||||
FnDecl = {
|
FnDecl = {
|
||||||
DeclHeader ~ KEYWORD_comptime? ~ KEYWORD_fn ~ IDENTIFIER ~ LPAREN ~ ParamDeclList ~ RPAREN ~ (COLON ~ TypeExpr)? ~ (SEMICOLON | Block)
|
DeclHeader ~ KEYWORD_comptime? ~ KEYWORD_fn ~ IDENTIFIER ~ LPAREN ~ ParamDeclList ~ RPAREN ~ (COLON ~ TypeExpr)? ~ (SEMICOLON | Block)
|
||||||
}
|
}
|
||||||
@@ -30,35 +28,38 @@ FnDecl = {
|
|||||||
ParamDeclList = { (ParamDecl ~ COMMA)* ~ (ParamDecl | DOT3)? }
|
ParamDeclList = { (ParamDecl ~ COMMA)* ~ (ParamDecl | DOT3)? }
|
||||||
ParamDecl = { HeaderList? ~ BindingIdent ~ COLON ~ TypeExpr }
|
ParamDecl = { HeaderList? ~ BindingIdent ~ COLON ~ TypeExpr }
|
||||||
|
|
||||||
// 变量声明(支持修饰符、元组解构与类型推导)
|
|
||||||
VarDecl = { DeclHeader ~ KEYWORD_var ~ VarBody }
|
VarDecl = { DeclHeader ~ KEYWORD_var ~ VarBody }
|
||||||
ConstDecl = { DeclHeader ~ KEYWORD_const ~ VarBody }
|
ConstDecl = { DeclHeader ~ KEYWORD_const ~ VarBody }
|
||||||
VarBody = { VarPattern ~ (COLON ~ TypeExpr)? ~ (EQUAL ~ Expr)? }
|
VarBody = { Pattern ~ (COLON ~ TypeExpr)? ~ (EQUAL ~ Expr)? }
|
||||||
|
|
||||||
// 类型声明(支持修饰符)
|
|
||||||
TypeDecl = { DeclHeader ~ KEYWORD_type ~ IDENTIFIER ~ EQUAL ~ TypeExpr }
|
TypeDecl = { DeclHeader ~ KEYWORD_type ~ IDENTIFIER ~ EQUAL ~ TypeExpr }
|
||||||
|
|
||||||
// 容器成员(支持修饰符)
|
|
||||||
MemberDecl = { DeclHeader ~ IDENTIFIER ~ (COLON ~ TypeExpr)? ~ (EQUAL ~ Expr)? }
|
MemberDecl = { DeclHeader ~ IDENTIFIER ~ (COLON ~ TypeExpr)? ~ (EQUAL ~ Expr)? }
|
||||||
|
|
||||||
// 变量声明左值模式(允许单独标识符)
|
Pattern = { PatternAtom ~ (COMMA ~ PatternAtom)* }
|
||||||
VarPattern = { VarPatternAtom ~ (COMMA ~ VarPatternAtom)* }
|
PatternAtom = {
|
||||||
VarPatternAtom = {
|
|
||||||
BindingIdent
|
|
||||||
| DOT ~ IDENTIFIER ~ (LBRACKET ~ VarPattern ~ RBRACKET)?
|
|
||||||
| LPAREN ~ VarPattern ~ RPAREN
|
|
||||||
}
|
|
||||||
|
|
||||||
// 匹配模式(不允许单独标识符)
|
|
||||||
MatchPattern = { MatchPatternAtom ~ (COMMA ~ MatchPatternAtom)* }
|
|
||||||
MatchPatternAtom = {
|
|
||||||
UNDERSCORE
|
UNDERSCORE
|
||||||
| Expr
|
| AnonymousAggregatePattern
|
||||||
| DOT ~ IDENTIFIER ~ (LBRACKET ~ MatchPattern ~ RBRACKET)?
|
| DOT ~ IDENTIFIER ~ (LPAREN ~ Pattern? ~ RPAREN)?
|
||||||
| LPAREN ~ MatchPattern ~ RPAREN
|
| LPAREN ~ Pattern? ~ RPAREN
|
||||||
|
| PatternLiteral
|
||||||
|
| IDENTIFIER
|
||||||
|
}
|
||||||
|
|
||||||
|
AnonymousAggregatePattern = { DOT ~ LBRACE ~ PatternFieldList? ~ RBRACE }
|
||||||
|
PatternFieldList = { PatternField ~ ((COMMA | SEMICOLON) ~ PatternField)* ~ (COMMA | SEMICOLON)? }
|
||||||
|
PatternField = { DOT ~ IDENTIFIER ~ (EQUAL ~ PatternAtom)? }
|
||||||
|
|
||||||
|
PatternLiteral = {
|
||||||
|
FLOAT_LITERAL
|
||||||
|
| INTEGER_LITERAL
|
||||||
|
| CHAR_LITERAL
|
||||||
|
| STRING_LITERAL
|
||||||
|
| KEYWORD_true
|
||||||
|
| KEYWORD_false
|
||||||
|
| KEYWORD_null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 块内语句
|
|
||||||
Block = { LBRACE ~ Statement* ~ Expr? ~ RBRACE }
|
Block = { LBRACE ~ Statement* ~ Expr? ~ RBRACE }
|
||||||
Statement = {
|
Statement = {
|
||||||
RetStatement
|
RetStatement
|
||||||
@@ -70,7 +71,6 @@ Statement = {
|
|||||||
| ComptimeStatement
|
| ComptimeStatement
|
||||||
}
|
}
|
||||||
|
|
||||||
// 声明语句(内部声明已包含 HeaderList)
|
|
||||||
DeclStatement = { (VarDecl | ConstDecl | TypeDecl) ~ (COMMA | SEMICOLON)? }
|
DeclStatement = { (VarDecl | ConstDecl | TypeDecl) ~ (COMMA | SEMICOLON)? }
|
||||||
ExprStatement = { Expr ~ (COMMA | SEMICOLON)? }
|
ExprStatement = { Expr ~ (COMMA | SEMICOLON)? }
|
||||||
ComptimeStatement = { ComptimeDecl ~ (COMMA | SEMICOLON)? }
|
ComptimeStatement = { ComptimeDecl ~ (COMMA | SEMICOLON)? }
|
||||||
@@ -80,11 +80,8 @@ BreakStatement = { KEYWORD_break ~ Label? ~ Expr? ~ (COMMA | SEMICOLON)? }
|
|||||||
ContinueStatement = { KEYWORD_continue ~ Label? ~ (COMMA | SEMICOLON)? }
|
ContinueStatement = { KEYWORD_continue ~ Label? ~ (COMMA | SEMICOLON)? }
|
||||||
DeferStatement = { KEYWORD_defer ~ (Block | Statement) ~ (COMMA | SEMICOLON)? }
|
DeferStatement = { KEYWORD_defer ~ (Block | Statement) ~ (COMMA | SEMICOLON)? }
|
||||||
|
|
||||||
// 标签定义($ 前缀)
|
|
||||||
Label = { DOLLAR ~ IDENTIFIER }
|
Label = { DOLLAR ~ IDENTIFIER }
|
||||||
|
|
||||||
// ============ 表达式 ============
|
|
||||||
|
|
||||||
Expr = { AssignExpr }
|
Expr = { AssignExpr }
|
||||||
|
|
||||||
AssignExpr = { BoolOrExpr ~ (AssignOp ~ AssignExpr)? }
|
AssignExpr = { BoolOrExpr ~ (AssignOp ~ AssignExpr)? }
|
||||||
@@ -125,8 +122,8 @@ PrimaryExpr = {
|
|||||||
| AnonymousAggregateLiteral
|
| AnonymousAggregateLiteral
|
||||||
| ArrayLiteral
|
| ArrayLiteral
|
||||||
| AnonymousArrayLiteral
|
| AnonymousArrayLiteral
|
||||||
| ComptimeCallExpr // @name(args)
|
| VariantConstruct
|
||||||
|
| ComptimeCallExpr
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
| Block
|
| Block
|
||||||
| IfExpr
|
| IfExpr
|
||||||
@@ -140,26 +137,74 @@ PrimaryExpr = {
|
|||||||
|
|
||||||
TupleLiteral = { ParenExpr }
|
TupleLiteral = { ParenExpr }
|
||||||
|
|
||||||
// ============ 聚合字面量 ============
|
|
||||||
|
|
||||||
AggregateLiteral = { IDENTIFIER ~ LBRACE ~ StructInitList? ~ RBRACE }
|
AggregateLiteral = { IDENTIFIER ~ LBRACE ~ StructInitList? ~ RBRACE }
|
||||||
AnonymousAggregateLiteral = { DOT ~ LBRACE ~ StructInitList? ~ RBRACE }
|
AnonymousAggregateLiteral = { DOT ~ LBRACE ~ StructInitList? ~ RBRACE }
|
||||||
|
|
||||||
StructInitList = { StructInit ~ ((COMMA | SEMICOLON) ~ StructInit)* ~ (COMMA | SEMICOLON)? }
|
StructInitList = { StructInit ~ ((COMMA | SEMICOLON) ~ StructInit)* ~ (COMMA | SEMICOLON)? }
|
||||||
StructInit = { DOT ~ IDENTIFIER ~ (EQUAL ~ Expr)? }
|
StructInit = { DOT ~ IDENTIFIER ~ (EQUAL ~ Expr)? }
|
||||||
|
|
||||||
// ============ 数组/切片字面量 ============
|
VariantConstruct = { DOT ~ IDENTIFIER ~ (LPAREN ~ ExprList? ~ RPAREN)? }
|
||||||
|
|
||||||
ArrayLiteral = {
|
ArrayLiteral = {
|
||||||
// 切片字面量: []T[1,2,3]
|
LBRACKET ~ RBRACKET ~ TypeExpr ~ LBRACKET ~ ExprList? ~ RBRACKET
|
||||||
// 数组字面量: [N]T[1,2,3] 或 [_]T[1,2,3]
|
| LBRACKET ~ (INTEGER_LITERAL | UNDERSCORE) ~ RBRACKET ~ TypeExpr ~ LBRACKET ~ ExprList? ~ RBRACKET
|
||||||
LBRACKET ~ (INTEGER_LITERAL | UNDERSCORE)? ~ RBRACKET ~ TypeExpr ~ LBRACKET ~ ExprList? ~ RBRACKET
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnonymousArrayLiteral = {
|
AnonymousArrayLiteral = {
|
||||||
DOT ~ LBRACKET ~ ExprList? ~ RBRACKET
|
DOT ~ LBRACKET ~ ExprList? ~ RBRACKET
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ 类型表达式(独立,限制语法) ============
|
ExprNoStruct = { AssignExprNoStruct }
|
||||||
|
|
||||||
|
AssignExprNoStruct = { BoolOrExprNoStruct ~ (AssignOp ~ AssignExprNoStruct)? }
|
||||||
|
BoolOrExprNoStruct = { BoolAndExprNoStruct ~ (BOOL_OR ~ BoolAndExprNoStruct)* }
|
||||||
|
BoolAndExprNoStruct = { BitOrExprNoStruct ~ (BOOL_AND ~ BitOrExprNoStruct)* }
|
||||||
|
BitOrExprNoStruct = { BitXorExprNoStruct ~ (PIPE ~ BitXorExprNoStruct)* }
|
||||||
|
BitXorExprNoStruct = { BitAndExprNoStruct ~ (CARET ~ BitAndExprNoStruct)* }
|
||||||
|
BitAndExprNoStruct = { CmpEqExprNoStruct ~ (AMPERSAND ~ CmpEqExprNoStruct)* }
|
||||||
|
CmpEqExprNoStruct = { CmpExprNoStruct ~ ((EQ_EQ | BANG_EQUAL) ~ CmpExprNoStruct)* }
|
||||||
|
CmpExprNoStruct = { ArrowExprNoStruct ~ ((L_ARROW_EQ | L_ARROW | R_ARROW_EQ | R_ARROW) ~ ArrowExprNoStruct)* }
|
||||||
|
|
||||||
|
ArrowExprNoStruct = { RangeExprNoStruct ~ ((THIN_R_ARROW | THIN_L_ARROW | FAT_D_ARROW | THIN_D_ARROW) ~ RangeExprNoStruct)* }
|
||||||
|
|
||||||
|
RangeExprNoStruct = { ShiftExprNoStruct ~ (DOT2 ~ ShiftExprNoStruct?)? }
|
||||||
|
ShiftExprNoStruct = { AddExprNoStruct ~ ((L_ARROW2_EQ | L_ARROW2 | R_ARROW2_EQ | R_ARROW2) ~ AddExprNoStruct)* }
|
||||||
|
AddExprNoStruct = { MulExprNoStruct ~ ((PLUS | MINUS) ~ MulExprNoStruct)* }
|
||||||
|
MulExprNoStruct = { CastExprNoStruct ~ ((ASTERISK | SLASH | PERCENT) ~ CastExprNoStruct)* }
|
||||||
|
CastExprNoStruct = { PrefixExprNoStruct ~ (KEYWORD_as ~ TypeExpr)* }
|
||||||
|
PrefixExprNoStruct = { PrefixOp* ~ PostfixExprNoStruct }
|
||||||
|
|
||||||
|
PostfixExprNoStruct = {
|
||||||
|
PrimaryExprNoStruct ~ (LPAREN ~ ExprList ~ RPAREN | DOT ~ IDENTIFIER | DOT ~ ASTERISK | LBRACKET ~ Expr ~ RBRACKET | LBRACKET ~ Expr ~ DOT2 ~ Expr? ~ RBRACKET)*
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimaryExprNoStruct = {
|
||||||
|
FLOAT_LITERAL
|
||||||
|
| INTEGER_LITERAL
|
||||||
|
| CHAR_LITERAL
|
||||||
|
| STRING_LITERAL
|
||||||
|
| KEYWORD_true
|
||||||
|
| KEYWORD_false
|
||||||
|
| KEYWORD_null
|
||||||
|
| TupleLiteral
|
||||||
|
| AnonymousAggregateLiteral
|
||||||
|
| ArrayLiteral
|
||||||
|
| AnonymousArrayLiteral
|
||||||
|
| VariantConstruct
|
||||||
|
| ComptimeCallExpr
|
||||||
|
| IDENTIFIER
|
||||||
|
| Block
|
||||||
|
| IfExpr
|
||||||
|
| IfVarExpr
|
||||||
|
| WhileExpr
|
||||||
|
| LoopExpr
|
||||||
|
| ForExpr
|
||||||
|
| MatchExpr
|
||||||
|
| FnTypeExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
VarBodyNoStruct = { Pattern ~ (COLON ~ TypeExpr)? ~ (EQUAL ~ ExprNoStruct)? }
|
||||||
|
|
||||||
TypeExpr = { HeaderList? ~ TypePrefixExpr }
|
TypeExpr = { HeaderList? ~ TypePrefixExpr }
|
||||||
|
|
||||||
TypePrefixExpr = { ASTERISK* ~ TypePostfixExpr }
|
TypePrefixExpr = { ASTERISK* ~ TypePostfixExpr }
|
||||||
@@ -208,26 +253,23 @@ FnTypeExpr = { KEYWORD_comptime? ~ KEYWORD_fn ~ LPAREN ~ TypeExprList? ~ RPAREN
|
|||||||
|
|
||||||
AggregateTypeExpr = { (KEYWORD_struct | KEYWORD_union | KEYWORD_enum | KEYWORD_shape) ~ LBRACE ~ ContainerMembers ~ RBRACE }
|
AggregateTypeExpr = { (KEYWORD_struct | KEYWORD_union | KEYWORD_enum | KEYWORD_shape) ~ LBRACE ~ ContainerMembers ~ RBRACE }
|
||||||
|
|
||||||
// ============ 控制流 ============
|
IfExpr = { KEYWORD_if ~ ExprNoStruct ~ Block ~ (KEYWORD_else ~ (Block | IfExpr | IfVarExpr))? }
|
||||||
IfExpr = { KEYWORD_if ~ Expr ~ Block ~ (KEYWORD_else ~ (Block | IfExpr | IfVarExpr))? }
|
IfVarExpr = { KEYWORD_if ~ KEYWORD_var ~ VarBodyNoStruct ~ Block ~ (KEYWORD_else ~ (Block | IfExpr | IfVarExpr))? }
|
||||||
IfVarExpr = { KEYWORD_if ~ VarBody ~ Block ~ (KEYWORD_else ~ (Block | IfExpr | IfVarExpr))? }
|
|
||||||
|
|
||||||
WhileExpr = { Label? ~ KEYWORD_while ~ Expr ~ Block ~ (KEYWORD_else ~ (Block | Expr))? }
|
WhileExpr = { Label? ~ KEYWORD_while ~ ExprNoStruct ~ Block ~ (KEYWORD_else ~ (Block | Expr))? }
|
||||||
LoopExpr = { Label? ~ KEYWORD_loop ~ Block }
|
LoopExpr = { Label? ~ KEYWORD_loop ~ Block }
|
||||||
ForExpr = { Label? ~ KEYWORD_for ~ Expr ~ (COMMA ~ Expr)* ~ KEYWORD_as ~ BindingIdent ~ (COMMA ~ BindingIdent)* ~ Block ~ (KEYWORD_else ~ (Block | Expr))? }
|
ForExpr = { Label? ~ KEYWORD_for ~ Pattern ~ COLON ~ ExprNoStruct ~ (COMMA ~ ExprNoStruct)* ~ Block ~ (KEYWORD_else ~ (Block | Expr))? }
|
||||||
|
|
||||||
MatchExpr = { KEYWORD_match ~ Expr ~ LBRACE ~ MatchArm* ~ RBRACE }
|
MatchExpr = { KEYWORD_match ~ ExprNoStruct ~ LBRACE ~ MatchArm* ~ RBRACE }
|
||||||
MatchArm = { MatchPattern ~ (COMMA ~ MatchPattern)* ~ FAT_R_ARROW ~ Block }
|
MatchArm = { Pattern ~ FAT_R_ARROW ~ Block ~ COMMA? }
|
||||||
|
|
||||||
// ============ 其他表达式 ============
|
|
||||||
ComptimeCallExpr = { AT ~ IDENTIFIER ~ LPAREN ~ ExprList? ~ RPAREN }
|
ComptimeCallExpr = { AT ~ IDENTIFIER ~ LPAREN ~ ExprList? ~ RPAREN }
|
||||||
ParenExpr = {
|
ParenExpr = {
|
||||||
|
LPAREN ~ RPAREN
|
||||||
| LPAREN ~ Expr ~ COMMA ~ (Expr ~ COMMA)* ~ Expr? ~ RPAREN
|
| LPAREN ~ Expr ~ COMMA ~ (Expr ~ COMMA)* ~ Expr? ~ RPAREN
|
||||||
| LPAREN ~ Expr ~ RPAREN
|
| LPAREN ~ Expr ~ RPAREN
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ Token 定义 ============
|
|
||||||
AssignOp = { EQUAL | PLUS_EQ | MINUS_EQ | ASTERISK_EQ | SLASH_EQ | PERCENT_EQ | AMPERSAND_EQ | PIPE_EQ | CARET_EQ | L_ARROW2_EQ | R_ARROW2_EQ }
|
AssignOp = { EQUAL | PLUS_EQ | MINUS_EQ | ASTERISK_EQ | SLASH_EQ | PERCENT_EQ | AMPERSAND_EQ | PIPE_EQ | CARET_EQ | L_ARROW2_EQ | R_ARROW2_EQ }
|
||||||
BOOL_OR = { PIPE ~ PIPE }
|
BOOL_OR = { PIPE ~ PIPE }
|
||||||
BOOL_AND = { AMPERSAND ~ AMPERSAND }
|
BOOL_AND = { AMPERSAND ~ AMPERSAND }
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ static const char *splc0_srcs[] = {
|
|||||||
"stage1/spl_tok.c",
|
"stage1/spl_tok.c",
|
||||||
"stage1/spl_lexer.c",
|
"stage1/spl_lexer.c",
|
||||||
"stage1/spl_ast.c",
|
"stage1/spl_ast.c",
|
||||||
|
"stage1/spl_parser.c",
|
||||||
"stage1/spl_dumptree.c",
|
"stage1/spl_dumptree.c",
|
||||||
"stage1/spl_type.c",
|
"stage1/spl_type.c",
|
||||||
"stage1/spl_lang_type.c",
|
"stage1/spl_lang_type.c",
|
||||||
|
|||||||
+11
-2292
File diff suppressed because it is too large.
Load diff
+51
-78
@@ -4,9 +4,6 @@
|
|||||||
#include "../stage0/include/utils.h"
|
#include "../stage0/include/utils.h"
|
||||||
#include "spl_attr.h"
|
#include "spl_attr.h"
|
||||||
#include "spl_dbg.h"
|
#include "spl_dbg.h"
|
||||||
#include "spl_diag.h"
|
|
||||||
#include "spl_lexer.h"
|
|
||||||
#include "spl_mpa.h"
|
|
||||||
#include "spl_tok.h"
|
#include "spl_tok.h"
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
@@ -74,7 +71,9 @@
|
|||||||
X(SPL_AST_PATTERN_UNDERSCORE, V0, pattern_underscore) \
|
X(SPL_AST_PATTERN_UNDERSCORE, V0, pattern_underscore) \
|
||||||
X(SPL_AST_PATTERN_DOT, V0, pattern_dot) \
|
X(SPL_AST_PATTERN_DOT, V0, pattern_dot) \
|
||||||
X(SPL_AST_PATTERN_TUPLE, V0, pattern_tuple) \
|
X(SPL_AST_PATTERN_TUPLE, V0, pattern_tuple) \
|
||||||
X(SPL_AST_PATTERN_LIST, V0, pattern_list)
|
X(SPL_AST_PATTERN_LIST, V0, pattern_list) \
|
||||||
|
X(SPL_AST_PATTERN_AGGREGATE, V0, pattern_aggregate) \
|
||||||
|
X(SPL_AST_PATTERN_FIELD, V0, pattern_field)
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -143,9 +142,6 @@ typedef enum {
|
|||||||
SPL_UNARY_OP_DEREF,
|
SPL_UNARY_OP_DEREF,
|
||||||
} spl_unary_op_t;
|
} spl_unary_op_t;
|
||||||
|
|
||||||
const char *spl_binary_op_name(spl_binary_op_t op);
|
|
||||||
const char *spl_unary_op_name(spl_unary_op_t op);
|
|
||||||
|
|
||||||
struct spl_ast_node;
|
struct spl_ast_node;
|
||||||
typedef struct spl_ast_node spl_ast_node_t;
|
typedef struct spl_ast_node spl_ast_node_t;
|
||||||
typedef usize spl_ast_node_ref_t;
|
typedef usize spl_ast_node_ref_t;
|
||||||
@@ -161,138 +157,113 @@ struct spl_ast_node {
|
|||||||
spl_attr_id_vec_t attrs;
|
spl_attr_id_vec_t attrs;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/* SPL_AST_ROOT */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t members; /* container_members 节点 */
|
spl_ast_node_ref_t members;
|
||||||
} root;
|
} root;
|
||||||
|
|
||||||
/* SPL_AST_CONTAINER_MEMBERS */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t external_tags; /* external_tag_item 节点列表 */
|
spl_ast_node_ref_vec_t external_tags;
|
||||||
spl_ast_node_ref_vec_t declarations;
|
spl_ast_node_ref_vec_t declarations;
|
||||||
} container_members;
|
} container_members;
|
||||||
|
|
||||||
/* SPL_AST_FN_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t tag_list; /* tag_item 节点 */
|
spl_ast_node_ref_vec_t tag_list;
|
||||||
bool is_comptime;
|
bool is_comptime;
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_vec_t params; /* param_decl 节点 */
|
spl_ast_node_ref_vec_t params;
|
||||||
spl_ast_node_ref_t ret_type; /* 类型节点,可空 */
|
spl_ast_node_ref_t ret_type;
|
||||||
spl_ast_node_ref_t body; /* 表达式节点,可空表示仅声明 */
|
spl_ast_node_ref_t body;
|
||||||
} fn_decl;
|
} fn_decl;
|
||||||
|
|
||||||
/* SPL_AST_VAR_DECL / SPL_AST_CONST_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list;
|
spl_ast_node_ref_vec_t attr_list;
|
||||||
spl_ast_node_ref_t pattern; /* 模式节点 */
|
spl_ast_node_ref_t pattern;
|
||||||
spl_ast_node_ref_t type; /* 类型节点,可空 */
|
spl_ast_node_ref_t type;
|
||||||
spl_ast_node_ref_t init_expr; /* 表达式节点,可空 */
|
spl_ast_node_ref_t init_expr;
|
||||||
} var_const_decl;
|
} var_const_decl;
|
||||||
|
|
||||||
/* SPL_AST_TYPE_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list;
|
spl_ast_node_ref_vec_t attr_list;
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_t type_expr; /* 类型节点 */
|
spl_ast_node_ref_t type_expr;
|
||||||
} type_decl;
|
} type_decl;
|
||||||
|
|
||||||
/* SPL_AST_MEMBER_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list;
|
spl_ast_node_ref_vec_t attr_list;
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_t type_expr; /* 可空 */
|
spl_ast_node_ref_t type_expr;
|
||||||
spl_ast_node_ref_t init_expr; /* 可空 */
|
spl_ast_node_ref_t init_expr;
|
||||||
} member_decl;
|
} member_decl;
|
||||||
|
|
||||||
/* SPL_AST_PARAM_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list;
|
spl_ast_node_ref_vec_t attr_list;
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_t type_expr;
|
spl_ast_node_ref_t type_expr;
|
||||||
} param_decl;
|
} param_decl;
|
||||||
|
|
||||||
/* SPL_AST_TAG_ITEM / SPL_AST_EXTERNAL_TAG_ITEM */
|
|
||||||
struct {
|
struct {
|
||||||
bool is_at; /* true: @, false: # */
|
bool is_at;
|
||||||
bool is_external; /* true: @!或#! */
|
bool is_external;
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_vec_t args;
|
spl_ast_node_ref_vec_t args;
|
||||||
} tag_item;
|
} tag_item;
|
||||||
|
|
||||||
/* SPL_AST_COMPTIME_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t body; /* block 或 expr 节点 */
|
spl_ast_node_ref_t body;
|
||||||
} comptime_decl;
|
} comptime_decl;
|
||||||
|
|
||||||
/* SPL_AST_TOP_LEVEL_BLOCK */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t tag_list; /* tag_item 节点列表 */
|
spl_ast_node_ref_vec_t tag_list;
|
||||||
spl_ast_node_ref_t block; /* 表达式节点block */
|
spl_ast_node_ref_t block;
|
||||||
} top_level_block;
|
} top_level_block;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_RET */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t expr; /* 可空 */
|
spl_ast_node_ref_t expr;
|
||||||
} statement_ret;
|
} statement_ret;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_BREAK */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t label; /* 可空 */
|
spl_ast_node_ref_t label;
|
||||||
spl_ast_node_ref_t expr; /* 可空 */
|
spl_ast_node_ref_t expr;
|
||||||
} statement_break;
|
} statement_break;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_CONTINUE */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t label; /* 可空 */
|
spl_ast_node_ref_t label;
|
||||||
} statement_continue;
|
} statement_continue;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_DEFER */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t body; /* block 或 statement 节点 */
|
spl_ast_node_ref_t body;
|
||||||
} statement_defer;
|
} statement_defer;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_COMPTIME */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t body; /* block 或 expr 节点 */
|
spl_ast_node_ref_t body;
|
||||||
} statement_comptime;
|
} statement_comptime;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_DECL */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t decl; /* var/const/type 声明节点 */
|
spl_ast_node_ref_t decl;
|
||||||
} statement_decl;
|
} statement_decl;
|
||||||
|
|
||||||
/* SPL_AST_STATEMENT_EXPR */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t expr;
|
spl_ast_node_ref_t expr;
|
||||||
} statement_expr;
|
} statement_expr;
|
||||||
|
|
||||||
/* SPL_AST_AGGREGATE_MEMBER */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t attr_list;
|
spl_ast_node_ref_vec_t attr_list;
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_t type_expr; /* 可空 */
|
spl_ast_node_ref_t type_expr;
|
||||||
spl_ast_node_ref_t init_expr; /* 可空 */
|
spl_ast_node_ref_t init_expr;
|
||||||
} aggregate_member;
|
} aggregate_member;
|
||||||
|
|
||||||
/* SPL_AST_STRUCT_INIT_ITEM */
|
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_t expr; /* 可空 */
|
spl_ast_node_ref_t expr;
|
||||||
} struct_init_item;
|
} struct_init_item;
|
||||||
|
|
||||||
/* SPL_AST_MATCH_ARM */
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t pattern; /* 模式节点 */
|
spl_ast_node_ref_t pattern;
|
||||||
spl_ast_node_ref_t body; /* block 或 expr 节点 */
|
spl_ast_node_ref_t body;
|
||||||
} match_arm;
|
} match_arm;
|
||||||
|
|
||||||
/* SPL_AST_LABEL */
|
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
} label;
|
} label;
|
||||||
|
|
||||||
/* ---- 表达式子类型 ---- */
|
|
||||||
spl_mpa_int_t int_lit;
|
spl_mpa_int_t int_lit;
|
||||||
spl_mpa_float_t float_lit;
|
spl_mpa_float_t float_lit;
|
||||||
struct {
|
struct {
|
||||||
@@ -305,7 +276,6 @@ struct spl_ast_node {
|
|||||||
struct {
|
struct {
|
||||||
bool val;
|
bool val;
|
||||||
} bool_lit;
|
} bool_lit;
|
||||||
/* null_lit, undefined_lit 无数据 */
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -356,13 +326,13 @@ struct spl_ast_node {
|
|||||||
bool has_len;
|
bool has_len;
|
||||||
usize len;
|
usize len;
|
||||||
bool is_underscore_len;
|
bool is_underscore_len;
|
||||||
spl_ast_node_ref_t elem_type; /* 可空 匿名时为 NULL */
|
spl_ast_node_ref_t elem_type;
|
||||||
spl_ast_node_ref_vec_t elems;
|
spl_ast_node_ref_vec_t elems;
|
||||||
} array_literal;
|
} array_literal;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *name; /* 可空 匿名时为 NULL */
|
const char *name;
|
||||||
spl_ast_node_ref_vec_t fields; /* struct_init_item 节点列表 */
|
spl_ast_node_ref_vec_t fields;
|
||||||
} aggregate_literal;
|
} aggregate_literal;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -402,14 +372,14 @@ struct spl_ast_node {
|
|||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t label;
|
spl_ast_node_ref_t label;
|
||||||
spl_ast_node_ref_vec_t iter_exprs;
|
spl_ast_node_ref_vec_t iter_exprs;
|
||||||
spl_ast_node_ref_vec_t idents;
|
spl_ast_node_ref_t pattern;
|
||||||
spl_ast_node_ref_t body;
|
spl_ast_node_ref_t body;
|
||||||
spl_ast_node_ref_t else_branch;
|
spl_ast_node_ref_t else_branch;
|
||||||
} for_expr;
|
} for_expr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_t matched_expr;
|
spl_ast_node_ref_t matched_expr;
|
||||||
spl_ast_node_ref_vec_t arms; /* match_arm 节点 */
|
spl_ast_node_ref_vec_t arms;
|
||||||
} match_expr;
|
} match_expr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -418,7 +388,6 @@ struct spl_ast_node {
|
|||||||
spl_ast_node_ref_t ret_type;
|
spl_ast_node_ref_t ret_type;
|
||||||
} fn_type;
|
} fn_type;
|
||||||
|
|
||||||
/* ---- 类型子类型 ---- */
|
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_vec_t generic_args;
|
spl_ast_node_ref_vec_t generic_args;
|
||||||
@@ -451,7 +420,7 @@ struct spl_ast_node {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *kind_name;
|
const char *kind_name;
|
||||||
spl_ast_node_ref_vec_t members; /* aggregate_member 节点 */
|
spl_ast_node_ref_vec_t members;
|
||||||
} type_aggregate;
|
} type_aggregate;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -459,13 +428,10 @@ struct spl_ast_node {
|
|||||||
spl_ast_node_ref_vec_t args;
|
spl_ast_node_ref_vec_t args;
|
||||||
} type_comptime_call;
|
} type_comptime_call;
|
||||||
|
|
||||||
/* ---- 模式子类型 ---- */
|
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
} pattern_ident;
|
} pattern_ident;
|
||||||
|
|
||||||
/* pattern_underscore 无数据 */
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
spl_ast_node_ref_t sub_pattern;
|
spl_ast_node_ref_t sub_pattern;
|
||||||
@@ -474,10 +440,18 @@ struct spl_ast_node {
|
|||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t patterns;
|
spl_ast_node_ref_vec_t patterns;
|
||||||
} pattern_tuple;
|
} pattern_tuple;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
spl_ast_node_ref_vec_t patterns;
|
spl_ast_node_ref_vec_t patterns;
|
||||||
} pattern_list;
|
} pattern_list;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
spl_ast_node_ref_vec_t fields;
|
||||||
|
} pattern_aggregate;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
spl_ast_node_ref_t pattern;
|
||||||
|
} pattern_field;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -488,8 +462,6 @@ typedef struct spl_ast {
|
|||||||
spl_ast_node_vec_t node_buckets;
|
spl_ast_node_vec_t node_buckets;
|
||||||
spl_ast_cstr_ref_vec_t str_buckets;
|
spl_ast_cstr_ref_vec_t str_buckets;
|
||||||
spl_ast_node_ref_t root;
|
spl_ast_node_ref_t root;
|
||||||
|
|
||||||
spl_diag_t *diag;
|
|
||||||
} spl_ast_t;
|
} spl_ast_t;
|
||||||
typedef VEC(spl_ast_t *) spl_ast_ptr_vec_t;
|
typedef VEC(spl_ast_t *) spl_ast_ptr_vec_t;
|
||||||
|
|
||||||
@@ -497,9 +469,10 @@ void spl_ast_init(spl_ast_t *ast, const spl_tok_vec_t *tok_vec /*move*/);
|
|||||||
void spl_ast_drop(spl_ast_t *ast);
|
void spl_ast_drop(spl_ast_t *ast);
|
||||||
|
|
||||||
spl_ast_node_t *spl_ast_node(spl_ast_t *ast, spl_ast_node_ref_t node);
|
spl_ast_node_t *spl_ast_node(spl_ast_t *ast, spl_ast_node_ref_t node);
|
||||||
const char *spl_ast_node_name(spl_ast_node_t *node);
|
|
||||||
|
|
||||||
void spl_ast_parse(spl_ast_t *ast);
|
|
||||||
void spl_ast_dump(spl_ast_t *ast, spl_ast_node_ref_t node);
|
void spl_ast_dump(spl_ast_t *ast, spl_ast_node_ref_t node);
|
||||||
|
|
||||||
|
const char *spl_ast_kind_name(spl_ast_node_kind_t kind);
|
||||||
|
const char *spl_binary_op_name(spl_binary_op_t op);
|
||||||
|
const char *spl_unary_op_name(spl_unary_op_t op);
|
||||||
|
|
||||||
#endif /* __SPL_AST_H__ */
|
#endif /* __SPL_AST_H__ */
|
||||||
+31
-8
@@ -645,10 +645,24 @@ spl_type_id_t spl_def_get_type_id(spl_lang_type_t *type, spl_def_id_t def_id) {
|
|||||||
return lang ? spl_lang_type_get_ir_type(type, lang) : 0;
|
return lang ? spl_lang_type_get_ir_type(type, lang) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spl_lang_type_dump(spl_lang_type_t *type, spl_lang_type_id_t id) {
|
static void spl_lang_type_dump_rec(spl_lang_type_t *type, spl_lang_type_id_t id,
|
||||||
|
spl_lang_type_id_vec_t *stack) {
|
||||||
|
for (usize i = 0; i < vec_size(*stack); i++) {
|
||||||
|
if (vec_at(*stack, i) == id) {
|
||||||
|
printf("<rec#%zu>", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vec_size(*stack) > 32) {
|
||||||
|
printf("...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vec_push(*stack, id);
|
||||||
|
|
||||||
spl_lang_type_node_t *n = spl_lang_type_node(type, id);
|
spl_lang_type_node_t *n = spl_lang_type_node(type, id);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
printf("none");
|
printf("none");
|
||||||
|
vec_pop(*stack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (n->kind) {
|
switch (n->kind) {
|
||||||
@@ -691,7 +705,7 @@ void spl_lang_type_dump(spl_lang_type_t *type, spl_lang_type_id_t id) {
|
|||||||
}
|
}
|
||||||
case SPL_LANG_TYPE_PTR:
|
case SPL_LANG_TYPE_PTR:
|
||||||
printf("*");
|
printf("*");
|
||||||
spl_lang_type_dump(type, n->extra.elem);
|
spl_lang_type_dump_rec(type, n->extra.elem, stack);
|
||||||
break;
|
break;
|
||||||
case SPL_LANG_TYPE_ARRAY: {
|
case SPL_LANG_TYPE_ARRAY: {
|
||||||
spl_type_node_t *tn = spl_type_node(&type->ir, n->ir_type_id);
|
spl_type_node_t *tn = spl_type_node(&type->ir, n->ir_type_id);
|
||||||
@@ -700,31 +714,31 @@ void spl_lang_type_dump(spl_lang_type_t *type, spl_lang_type_id_t id) {
|
|||||||
} break;
|
} break;
|
||||||
case SPL_LANG_TYPE_SLICE:
|
case SPL_LANG_TYPE_SLICE:
|
||||||
printf("[]");
|
printf("[]");
|
||||||
spl_lang_type_dump(type, n->extra.elem);
|
spl_lang_type_dump_rec(type, n->extra.elem, stack);
|
||||||
break;
|
break;
|
||||||
case SPL_LANG_TYPE_TUPLE:
|
case SPL_LANG_TYPE_TUPLE:
|
||||||
printf("(");
|
printf("(");
|
||||||
for (usize i = 0; i < vec_size(n->extra.elems); i++) {
|
for (usize i = 0; i < vec_size(n->extra.elems); i++) {
|
||||||
if (i)
|
if (i)
|
||||||
printf(",");
|
printf(",");
|
||||||
spl_lang_type_dump(type, vec_at(n->extra.elems, i));
|
spl_lang_type_dump_rec(type, vec_at(n->extra.elems, i), stack);
|
||||||
}
|
}
|
||||||
printf(")");
|
printf(")");
|
||||||
break;
|
break;
|
||||||
case SPL_LANG_TYPE_RANGE:
|
case SPL_LANG_TYPE_RANGE:
|
||||||
spl_lang_type_dump(type, n->extra.elem);
|
spl_lang_type_dump_rec(type, n->extra.elem, stack);
|
||||||
printf("..");
|
printf("..");
|
||||||
spl_lang_type_dump(type, n->extra.elem);
|
spl_lang_type_dump_rec(type, n->extra.elem, stack);
|
||||||
break;
|
break;
|
||||||
case SPL_LANG_TYPE_FN:
|
case SPL_LANG_TYPE_FN:
|
||||||
printf("fn(");
|
printf("fn(");
|
||||||
for (usize i = 0; i < vec_size(n->extra.fn.params); i++) {
|
for (usize i = 0; i < vec_size(n->extra.fn.params); i++) {
|
||||||
if (i)
|
if (i)
|
||||||
printf(",");
|
printf(",");
|
||||||
spl_lang_type_dump(type, vec_at(n->extra.fn.params, i));
|
spl_lang_type_dump_rec(type, vec_at(n->extra.fn.params, i), stack);
|
||||||
}
|
}
|
||||||
printf(")");
|
printf(")");
|
||||||
spl_lang_type_dump(type, n->extra.fn.ret);
|
spl_lang_type_dump_rec(type, n->extra.fn.ret, stack);
|
||||||
break;
|
break;
|
||||||
case SPL_LANG_TYPE_STRUCT:
|
case SPL_LANG_TYPE_STRUCT:
|
||||||
case SPL_LANG_TYPE_UNION:
|
case SPL_LANG_TYPE_UNION:
|
||||||
@@ -733,6 +747,15 @@ void spl_lang_type_dump(spl_lang_type_t *type, spl_lang_type_id_t id) {
|
|||||||
spl_type_pure_dump(&type->ir, n->ir_type_id);
|
spl_type_pure_dump(&type->ir, n->ir_type_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec_pop(*stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spl_lang_type_dump(spl_lang_type_t *type, spl_lang_type_id_t id) {
|
||||||
|
spl_lang_type_id_vec_t stack;
|
||||||
|
vec_init(stack);
|
||||||
|
spl_lang_type_dump_rec(type, id, &stack);
|
||||||
|
vec_free(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spl_type_def_dump(spl_lang_type_t *type, spl_def_id_t id) {
|
void spl_type_def_dump(spl_lang_type_t *type, spl_def_id_t id) {
|
||||||
|
|||||||
+2284
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef __SPL_PARSER_H__
|
||||||
|
#define __SPL_PARSER_H__
|
||||||
|
|
||||||
|
#include "spl_ast.h"
|
||||||
|
#include "spl_diag.h"
|
||||||
|
|
||||||
|
typedef struct spl_parser {
|
||||||
|
spl_ast_t *ast;
|
||||||
|
spl_diag_t *diag;
|
||||||
|
usize pos;
|
||||||
|
int failed;
|
||||||
|
int stop_agg;
|
||||||
|
usize error_count;
|
||||||
|
} spl_parser_t;
|
||||||
|
|
||||||
|
void spl_parser_init(spl_parser_t *p);
|
||||||
|
void spl_parser_drop(spl_parser_t *p);
|
||||||
|
|
||||||
|
void spl_ast_parse(spl_parser_t *p, spl_ast_t *ast);
|
||||||
|
|
||||||
|
#endif /* __SPL_PARSER_H__ */
|
||||||
+157
-46
@@ -833,6 +833,67 @@ static spl_lang_type_id_t sema_block_body(spl_sema_t *sema, spl_ast_node_t *n,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sema_bind_pattern(spl_sema_t *sema, spl_ast_node_ref_t pat_ref,
|
||||||
|
spl_lang_type_id_t matched_tid) {
|
||||||
|
if (!pat_ref)
|
||||||
|
return;
|
||||||
|
spl_ast_node_t *pat = spl_ast_node(sema->ast, pat_ref);
|
||||||
|
if (!pat)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (pat->kind) {
|
||||||
|
case SPL_AST_PATTERN_IDENT: {
|
||||||
|
const char *name = pat->pattern_ident.name;
|
||||||
|
spl_symbol_t sym = {.name = name, .kind = SPL_SYMBOL_KIND_VAR};
|
||||||
|
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, name, pat->dbg, sema->ast, pat_ref);
|
||||||
|
spl_def_resolve(sema->type, sym.node, matched_tid);
|
||||||
|
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL, &pat->dbg,
|
||||||
|
"duplicate symbol `%s`", name);
|
||||||
|
}
|
||||||
|
pat->resolved_def_id = sym.node;
|
||||||
|
pat->resolved_lang_tid = matched_tid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SPL_AST_PATTERN_UNDERSCORE:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case SPL_AST_PATTERN_TUPLE: {
|
||||||
|
spl_lang_type_node_t *tn = spl_lang_type_node(sema->type, matched_tid);
|
||||||
|
if (!tn || tn->kind != SPL_LANG_TYPE_TUPLE) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &pat->dbg,
|
||||||
|
"tuple pattern requires a tuple value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
usize natoms = vec_size(pat->pattern_tuple.patterns);
|
||||||
|
usize nelems = vec_size(tn->extra.elems);
|
||||||
|
if (natoms != nelems) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &pat->dbg,
|
||||||
|
"tuple pattern arity mismatch (expected %zu, got %zu)", nelems, natoms);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* 递归 bind 会 push lang_table,tn 会悬垂;先把元素类型拷到本地 */
|
||||||
|
spl_lang_type_id_vec_t elem_tids;
|
||||||
|
vec_init(elem_tids);
|
||||||
|
for (usize i = 0; i < nelems; ++i)
|
||||||
|
vec_push(elem_tids, vec_at(tn->extra.elems, i));
|
||||||
|
for (usize i = 0; i < natoms; ++i)
|
||||||
|
sema_bind_pattern(sema, vec_at(pat->pattern_tuple.patterns, i), vec_at(elem_tids, i));
|
||||||
|
vec_free(elem_tids);
|
||||||
|
pat->resolved_lang_tid = matched_tid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SPL_AST_PATTERN_DOT:
|
||||||
|
case SPL_AST_PATTERN_AGGREGATE:
|
||||||
|
default:
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_UNHANDLED_NODE, &pat->dbg,
|
||||||
|
"pattern kind %d not yet supported", (int)pat->kind);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||||
spl_lang_type_id_t expected) {
|
spl_lang_type_id_t expected) {
|
||||||
if (!ref || !expected)
|
if (!ref || !expected)
|
||||||
@@ -1014,23 +1075,34 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
|||||||
}
|
}
|
||||||
|
|
||||||
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, expected);
|
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, expected);
|
||||||
spl_type_node_t *irn = spl_type_node(&sema->type->ir, agg_ir);
|
|
||||||
if (!irn) {
|
/* 先把每个字段的 ir type_id 拷到本地:循环里 sema_coerce 会 push
|
||||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
type_table,irn 会悬垂。 */
|
||||||
"aggregate type unresolved");
|
spl_type_id_vec_t field_ir_ids;
|
||||||
return 0;
|
vec_init(field_ir_ids);
|
||||||
|
{
|
||||||
|
spl_type_node_t *irn = spl_type_node(&sema->type->ir, agg_ir);
|
||||||
|
if (!irn) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
||||||
|
"aggregate type unresolved");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (usize i = 0; i < vec_size(irn->agg_type.variants); i++)
|
||||||
|
vec_push(field_ir_ids, vec_at(irn->agg_type.variants, i).type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (en->kind == SPL_LANG_TYPE_ENUM) {
|
if (en->kind == SPL_LANG_TYPE_ENUM) {
|
||||||
if (vec_size(n->aggregate_literal.fields) != 1) {
|
if (vec_size(n->aggregate_literal.fields) != 1) {
|
||||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
||||||
"enum literal must have exactly one variant");
|
"enum literal must have exactly one variant");
|
||||||
|
vec_free(field_ir_ids);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spl_ast_node_t *item = spl_ast_node(sema->ast, vec_at(n->aggregate_literal.fields, 0));
|
spl_ast_node_t *item = spl_ast_node(sema->ast, vec_at(n->aggregate_literal.fields, 0));
|
||||||
if (!item || item->kind != SPL_AST_STRUCT_INIT_ITEM) {
|
if (!item || item->kind != SPL_AST_STRUCT_INIT_ITEM) {
|
||||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
||||||
"invalid enum literal");
|
"invalid enum literal");
|
||||||
|
vec_free(field_ir_ids);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
usize idx = 0;
|
usize idx = 0;
|
||||||
@@ -1038,14 +1110,22 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
|||||||
&idx)) {
|
&idx)) {
|
||||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no variant `%s`",
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no variant `%s`",
|
||||||
item->struct_init_item.name);
|
item->struct_init_item.name);
|
||||||
|
vec_free(field_ir_ids);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
if (idx >= vec_size(field_ir_ids)) {
|
||||||
|
vec_free(field_ir_ids);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
usize field_tid_ir = vec_at(field_ir_ids, idx);
|
||||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
||||||
if (ft && item->struct_init_item.expr) {
|
if (ft && item->struct_init_item.expr) {
|
||||||
if (!sema_coerce(sema, item->struct_init_item.expr, ft))
|
if (!sema_coerce(sema, item->struct_init_item.expr, ft)) {
|
||||||
|
vec_free(field_ir_ids);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
vec_free(field_ir_ids);
|
||||||
n->resolved_lang_tid = expected;
|
n->resolved_lang_tid = expected;
|
||||||
return expected;
|
return expected;
|
||||||
}
|
}
|
||||||
@@ -1061,13 +1141,18 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
|||||||
item->struct_init_item.name);
|
item->struct_init_item.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
if (idx >= vec_size(field_ir_ids))
|
||||||
|
continue;
|
||||||
|
usize field_tid_ir = vec_at(field_ir_ids, idx);
|
||||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
||||||
if (ft && item->struct_init_item.expr) {
|
if (ft && item->struct_init_item.expr) {
|
||||||
if (!sema_coerce(sema, item->struct_init_item.expr, ft))
|
if (!sema_coerce(sema, item->struct_init_item.expr, ft)) {
|
||||||
|
vec_free(field_ir_ids);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vec_free(field_ir_ids);
|
||||||
n->resolved_lang_tid = expected;
|
n->resolved_lang_tid = expected;
|
||||||
return expected;
|
return expected;
|
||||||
}
|
}
|
||||||
@@ -1671,26 +1756,41 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg);
|
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg);
|
||||||
spl_type_node_t *irn = spl_type_node(&sema->type->ir, agg_ir);
|
|
||||||
if (irn) {
|
/* 循环里 sema_coerce 会 push type_table,irn 会悬垂。
|
||||||
for (usize i = 0; i < vec_size(n->aggregate_literal.fields); ++i) {
|
先把每个字段的 ir type_id 拷到本地。 */
|
||||||
spl_ast_node_t *item =
|
spl_type_id_vec_t field_ir_ids;
|
||||||
spl_ast_node(sema->ast, vec_at(n->aggregate_literal.fields, i));
|
vec_init(field_ir_ids);
|
||||||
if (!item || item->kind != SPL_AST_STRUCT_INIT_ITEM)
|
{
|
||||||
continue;
|
spl_type_node_t *irn = spl_type_node(&sema->type->ir, agg_ir);
|
||||||
usize idx = 0;
|
if (!irn) {
|
||||||
if (!spl_type_agg_member_idx(&sema->type->ir, agg_ir, item->struct_init_item.name,
|
n->resolved_lang_tid = agg;
|
||||||
&idx)) {
|
return agg;
|
||||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no field `%s`",
|
|
||||||
item->struct_init_item.name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
|
||||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
|
||||||
if (ft && item->struct_init_item.expr)
|
|
||||||
sema_coerce(sema, item->struct_init_item.expr, ft);
|
|
||||||
}
|
}
|
||||||
|
for (usize i = 0; i < vec_size(irn->agg_type.variants); i++)
|
||||||
|
vec_push(field_ir_ids, vec_at(irn->agg_type.variants, i).type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (usize i = 0; i < vec_size(n->aggregate_literal.fields); ++i) {
|
||||||
|
spl_ast_node_t *item = spl_ast_node(sema->ast, vec_at(n->aggregate_literal.fields, i));
|
||||||
|
if (!item || item->kind != SPL_AST_STRUCT_INIT_ITEM)
|
||||||
|
continue;
|
||||||
|
usize idx = 0;
|
||||||
|
if (!spl_type_agg_member_idx(&sema->type->ir, agg_ir, item->struct_init_item.name,
|
||||||
|
&idx)) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no field `%s`",
|
||||||
|
item->struct_init_item.name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (idx >= vec_size(field_ir_ids))
|
||||||
|
continue;
|
||||||
|
usize field_tid_ir = vec_at(field_ir_ids, idx);
|
||||||
|
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
||||||
|
if (ft && item->struct_init_item.expr)
|
||||||
|
sema_coerce(sema, item->struct_init_item.expr, ft);
|
||||||
|
}
|
||||||
|
vec_free(field_ir_ids);
|
||||||
|
|
||||||
n->resolved_lang_tid = agg;
|
n->resolved_lang_tid = agg;
|
||||||
return agg;
|
return agg;
|
||||||
}
|
}
|
||||||
@@ -1793,28 +1893,39 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|||||||
vec_push(sema->label_stack, lbl);
|
vec_push(sema->label_stack, lbl);
|
||||||
|
|
||||||
sema_push_scope(sema);
|
sema_push_scope(sema);
|
||||||
for (usize i = 0; i < vec_size(n->for_expr.iter_exprs); ++i) {
|
|
||||||
spl_lang_type_id_t container_tid = sema_infer(sema, vec_at(n->for_expr.iter_exprs, i));
|
usize nsrc = vec_size(n->for_expr.iter_exprs);
|
||||||
spl_lang_type_id_t elem_tid = sema_for_elem_type(sema, container_tid);
|
spl_ast_node_ref_t pat_ref = n->for_expr.pattern;
|
||||||
if (i < vec_size(n->for_expr.idents)) {
|
spl_ast_node_t *pat = pat_ref ? spl_ast_node(sema->ast, pat_ref) : NULL;
|
||||||
spl_ast_node_t *id_node = spl_ast_node(sema->ast, vec_at(n->for_expr.idents, i));
|
|
||||||
if (id_node && id_node->kind == SPL_AST_EXPR_IDENT) {
|
if (pat && pat->kind == SPL_AST_PATTERN_LIST) {
|
||||||
const char *var_name = id_node->ident.name;
|
usize natoms = vec_size(pat->pattern_list.patterns);
|
||||||
if (strcmp(var_name, "_") != 0) {
|
for (usize i = 0; i < nsrc; ++i) {
|
||||||
spl_symbol_t sym = {.name = var_name, .kind = SPL_SYMBOL_KIND_VAR};
|
spl_lang_type_id_t container_tid =
|
||||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, var_name, id_node->dbg,
|
sema_infer(sema, vec_at(n->for_expr.iter_exprs, i));
|
||||||
sema->ast, vec_at(n->for_expr.idents, i));
|
spl_lang_type_id_t elem_tid = sema_for_elem_type(sema, container_tid);
|
||||||
spl_def_resolve(sema->type, sym.node, elem_tid);
|
if (i < natoms)
|
||||||
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
sema_bind_pattern(sema, vec_at(pat->pattern_list.patterns, i), elem_tid);
|
||||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL,
|
}
|
||||||
&id_node->dbg, "duplicate symbol `%s`", var_name);
|
if (natoms > nsrc) {
|
||||||
}
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &pat->dbg,
|
||||||
id_node->resolved_def_id = sym.node;
|
"for: pattern has %zu atoms but only %zu sources", natoms, nsrc);
|
||||||
id_node->resolved_lang_tid = elem_tid;
|
}
|
||||||
}
|
} else {
|
||||||
|
for (usize i = 0; i < nsrc; ++i) {
|
||||||
|
spl_lang_type_id_t container_tid =
|
||||||
|
sema_infer(sema, vec_at(n->for_expr.iter_exprs, i));
|
||||||
|
if (i == 0 && pat_ref) {
|
||||||
|
spl_lang_type_id_t elem_tid = sema_for_elem_type(sema, container_tid);
|
||||||
|
sema_bind_pattern(sema, pat_ref, elem_tid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (nsrc > 1 && pat_ref) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &pat->dbg,
|
||||||
|
"for: multiple sources require pattern list");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n->for_expr.body)
|
if (n->for_expr.body)
|
||||||
sema_infer(sema, n->for_expr.body);
|
sema_infer(sema, n->for_expr.body);
|
||||||
if (n->for_expr.else_branch)
|
if (n->for_expr.else_branch)
|
||||||
|
|||||||
+28
-6
@@ -205,10 +205,23 @@ bool spl_type_is_subtype(const spl_type_t *type, spl_type_id_t sub, spl_type_id_
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) {
|
static void spl_type_pure_dump_rec(spl_type_t *type, spl_type_id_t id, spl_type_id_vec_t *stack) {
|
||||||
|
for (usize i = 0; i < vec_size(*stack); i++) {
|
||||||
|
if (vec_at(*stack, i) == id) {
|
||||||
|
printf("<rec#%zu>", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vec_size(*stack) > 32) {
|
||||||
|
printf("...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vec_push(*stack, id);
|
||||||
|
|
||||||
spl_type_node_t *n = spl_type_node(type, id);
|
spl_type_node_t *n = spl_type_node(type, id);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
printf("none");
|
printf("none");
|
||||||
|
vec_pop(*stack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (n->kind) {
|
switch (n->kind) {
|
||||||
@@ -248,11 +261,11 @@ void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) {
|
|||||||
break;
|
break;
|
||||||
case SPL_TYPE_PTR:
|
case SPL_TYPE_PTR:
|
||||||
printf("*");
|
printf("*");
|
||||||
spl_type_pure_dump(type, n->ptr_type.pointee);
|
spl_type_pure_dump_rec(type, n->ptr_type.pointee, stack);
|
||||||
break;
|
break;
|
||||||
case SPL_TYPE_ARRAY:
|
case SPL_TYPE_ARRAY:
|
||||||
printf("[%zu]", n->array_type.len);
|
printf("[%zu]", n->array_type.len);
|
||||||
spl_type_pure_dump(type, n->array_type.element);
|
spl_type_pure_dump_rec(type, n->array_type.element, stack);
|
||||||
break;
|
break;
|
||||||
case SPL_TYPE_STRUCT:
|
case SPL_TYPE_STRUCT:
|
||||||
case SPL_TYPE_UNION:
|
case SPL_TYPE_UNION:
|
||||||
@@ -271,7 +284,7 @@ void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) {
|
|||||||
printf(", ");
|
printf(", ");
|
||||||
spl_type_member_t *m = &n->agg_type.variants.data[i];
|
spl_type_member_t *m = &n->agg_type.variants.data[i];
|
||||||
printf("%s:", m->name ? m->name : "?");
|
printf("%s:", m->name ? m->name : "?");
|
||||||
spl_type_pure_dump(type, m->type_id);
|
spl_type_pure_dump_rec(type, m->type_id, stack);
|
||||||
}
|
}
|
||||||
printf("}");
|
printf("}");
|
||||||
break;
|
break;
|
||||||
@@ -281,12 +294,21 @@ void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) {
|
|||||||
for (usize i = 0; i < vec_size(n->fn_type.params); i++) {
|
for (usize i = 0; i < vec_size(n->fn_type.params); i++) {
|
||||||
if (i)
|
if (i)
|
||||||
printf(",");
|
printf(",");
|
||||||
spl_type_pure_dump(type, vec_at(n->fn_type.params, i));
|
spl_type_pure_dump_rec(type, vec_at(n->fn_type.params, i), stack);
|
||||||
}
|
}
|
||||||
printf(")");
|
printf(")");
|
||||||
spl_type_pure_dump(type, n->fn_type.ret);
|
spl_type_pure_dump_rec(type, n->fn_type.ret, stack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec_pop(*stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) {
|
||||||
|
spl_type_id_vec_t stack;
|
||||||
|
vec_init(stack);
|
||||||
|
spl_type_pure_dump_rec(type, id, &stack);
|
||||||
|
vec_free(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_type_id_t spl_type_fn_param_tid(spl_type_t *type, spl_type_id_t fn_tid, usize idx) {
|
spl_type_id_t spl_type_fn_param_tid(spl_type_t *type, spl_type_id_t fn_tid, usize idx) {
|
||||||
|
|||||||
+11
-4
@@ -15,6 +15,7 @@
|
|||||||
#include "spl_diag.h"
|
#include "spl_diag.h"
|
||||||
#include "spl_ir2vm.h"
|
#include "spl_ir2vm.h"
|
||||||
#include "spl_lexer.h"
|
#include "spl_lexer.h"
|
||||||
|
#include "spl_parser.h"
|
||||||
#include "spl_sema.h"
|
#include "spl_sema.h"
|
||||||
#include "spl_tok.h"
|
#include "spl_tok.h"
|
||||||
|
|
||||||
@@ -141,8 +142,11 @@ static spl_ast_t *driver_load(void *user, const char *from_fname, const char *pa
|
|||||||
spl_tok_vec_t toks = spl_lex(src, key);
|
spl_tok_vec_t toks = spl_lex(src, key);
|
||||||
spl_ast_t *ast = malloc(sizeof *ast);
|
spl_ast_t *ast = malloc(sizeof *ast);
|
||||||
spl_ast_init(ast, &toks);
|
spl_ast_init(ast, &toks);
|
||||||
ast->diag = diag;
|
spl_parser_t parser;
|
||||||
spl_ast_parse(ast);
|
spl_parser_init(&parser);
|
||||||
|
parser.diag = diag;
|
||||||
|
spl_ast_parse(&parser, ast);
|
||||||
|
spl_parser_drop(&parser);
|
||||||
|
|
||||||
vec_at(d->modules, idx).ast = ast;
|
vec_at(d->modules, idx).ast = ast;
|
||||||
vec_at(d->modules, idx).src = src;
|
vec_at(d->modules, idx).src = src;
|
||||||
@@ -161,7 +165,6 @@ static int compile_spl(const char *src, const char *fname, const char *outpath,
|
|||||||
drv.main_path = strdup(fname);
|
drv.main_path = strdup(fname);
|
||||||
drv.main_toks = spl_lex(src, drv.main_path);
|
drv.main_toks = spl_lex(src, drv.main_path);
|
||||||
spl_ast_init(&drv.main_ast, &drv.main_toks);
|
spl_ast_init(&drv.main_ast, &drv.main_toks);
|
||||||
drv.main_ast.diag = &diag;
|
|
||||||
map_init(drv.path_to_idx, MAP_HASH_STR, MAP_CMP_STR);
|
map_init(drv.path_to_idx, MAP_HASH_STR, MAP_CMP_STR);
|
||||||
vec_init(drv.modules);
|
vec_init(drv.modules);
|
||||||
|
|
||||||
@@ -190,7 +193,11 @@ static int compile_spl(const char *src, const char *fname, const char *outpath,
|
|||||||
int sema_ok = 0, a2ir_ok = 0, irb_ok = 0, ir2vm_ok = 0;
|
int sema_ok = 0, a2ir_ok = 0, irb_ok = 0, ir2vm_ok = 0;
|
||||||
|
|
||||||
spl_diag_set_stage(&diag, SPL_STAGE_PARSE);
|
spl_diag_set_stage(&diag, SPL_STAGE_PARSE);
|
||||||
spl_ast_parse(&drv.main_ast);
|
spl_parser_t parser;
|
||||||
|
spl_parser_init(&parser);
|
||||||
|
parser.diag = &diag;
|
||||||
|
spl_ast_parse(&parser, &drv.main_ast);
|
||||||
|
spl_parser_drop(&parser);
|
||||||
if (spl_diag_has_error(&diag) || spl_diag_has_fatal(&diag)) {
|
if (spl_diag_has_error(&diag) || spl_diag_has_fatal(&diag)) {
|
||||||
spl_diag_summary(&diag);
|
spl_diag_summary(&diag);
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|||||||
Reference in new issue
Block a user