阶段3-1:编译器语言层 V2 完成(19 类型/字面量扩展/禁隐式转换/配置驱动 FB)
Lexer V2:
- 19 类型关键字(BOOL..DT);FB 名不再设关键字(IDENT)
- FLOAT_LIT(1.5/2.5e3)、进制前缀(2#/8#/16# 换算十进制)
- 日期字面量 D#/TOD#/DT#(历法换算 1970 纪元、闰年、值域检查)
Parser V2:
- TypeRef 字符串化(TypeKind{Scalar,FbBuiltin,FbUser},名字小写)
- ExprKind 增 LitReal/LitDate/LitTod/LitDt;Expr.double_value
- IDENT 类型统一 FbUser(内建判定在 Linker 查 fb 表)
Typecheck V2:
- TType 19 + Unresolved(字面量未定型)
- 禁隐式转换(赋值/算术/比较严格同型)
- resolve_to:未定型→消费点定型+值域检查(BOOL 0/1、无符号负数、
溢出、浮点仅 REAL/LREAL);算术按 kind 允许(TIME 仅 ±)
- Call 实参按函数参数类型;check_project 加 cfg
Linker V2:
- FbField.type_name 字符串化;内建 FB 布局查 machine.toml [[fb]] 表
(删 8 个硬编码布局,带缓存);link_project 加 cfg
Codegen V2:
- 浮点/日期字面量(LOADK func 8/4/4/6;LitReal 按 REAL 装载,LREAL TODO)
- 算术/比较 func 按操作数类型(expr_func)
- TypeKind 连锁适配
main.cpp:link/check 传 cfg;--disasm 头 22 字段逐行中文注释(L5)
+ slots 节;StbView 补 offset_const/offset_funcs
测试适配:parser/linker/typecheck/vm/cases 适配新接口与 V2 语义。
ctest 11/13(vm_cycles/cases_all 待阶段 4)。codegen_test 仍剥离(阶段 3-2 重写)。
This commit is contained in:
@@ -43,7 +43,12 @@ static bool link_case(const char* dir, compiler::LinkResult* out, std::string* e
|
||||
}
|
||||
units.push_back(std::move(u));
|
||||
}
|
||||
return link_project(p, units, out, err);
|
||||
compiler::MachineConfig cfg;
|
||||
std::string cerr;
|
||||
if (!cfg.load(std::string(REPO_ROOT) + "/compiler/machine.toml", &cerr)) {
|
||||
return false;
|
||||
}
|
||||
return link_project(p, units, cfg, out, err);
|
||||
}
|
||||
|
||||
static bool expect_link_err(const char* dir, const char* keyword) {
|
||||
@@ -146,7 +151,10 @@ static bool test_line1() {
|
||||
CHECK(load_unit(p.base_dir + "/" + f, &u, &err));
|
||||
units.push_back(std::move(u));
|
||||
}
|
||||
CHECK(link_project(p, units, &r, &err));
|
||||
compiler::MachineConfig cfg;
|
||||
std::string cerr;
|
||||
CHECK(cfg.load(std::string(REPO_ROOT) + "/compiler/machine.toml", &cerr));
|
||||
CHECK(link_project(p, units, cfg, &r, &err));
|
||||
|
||||
// 全局槽序 = 声明顺序
|
||||
CHECK(r.globals.size() == 4);
|
||||
@@ -162,7 +170,7 @@ static bool test_line1() {
|
||||
CHECK(it->second.fields[0].name == "start");
|
||||
CHECK(it->second.fields[1].name == "stop");
|
||||
CHECK(it->second.fields[2].name == "q");
|
||||
CHECK(it->second.fields[2].type == TypeKind::Bool);
|
||||
CHECK(it->second.fields[2].type_name == "bool");
|
||||
|
||||
// 内建 TON 布局(用例 17 的 t)
|
||||
const FbLayout* ton = nullptr;
|
||||
@@ -204,16 +212,19 @@ static bool test_builtin() {
|
||||
CHECK(load_unit(p.base_dir + "/" + f, &u, &err));
|
||||
units.push_back(std::move(u));
|
||||
}
|
||||
CHECK(link_project(p, units, &r, &err));
|
||||
compiler::MachineConfig cfg;
|
||||
std::string cerr;
|
||||
CHECK(cfg.load(std::string(REPO_ROOT) + "/compiler/machine.toml", &cerr));
|
||||
CHECK(link_project(p, units, cfg, &r, &err));
|
||||
CHECK(r.scopes.size() == 1);
|
||||
const LinkResult::PouScope& main = r.scopes[0];
|
||||
const auto it = main.fb_instances.find("t");
|
||||
CHECK(it != main.fb_instances.end());
|
||||
CHECK(it->second.fields.size() == 4);
|
||||
CHECK(it->second.fields[0].name == "in" && it->second.fields[0].type == TypeKind::Bool);
|
||||
CHECK(it->second.fields[1].name == "pt" && it->second.fields[1].type == TypeKind::Time);
|
||||
CHECK(it->second.fields[2].name == "q" && it->second.fields[2].type == TypeKind::Bool);
|
||||
CHECK(it->second.fields[3].name == "et" && it->second.fields[3].type == TypeKind::Time);
|
||||
CHECK(it->second.fields[0].name == "in" && it->second.fields[0].type_name == "bool");
|
||||
CHECK(it->second.fields[1].name == "pt" && it->second.fields[1].type_name == "time");
|
||||
CHECK(it->second.fields[2].name == "q" && it->second.fields[2].type_name == "bool");
|
||||
CHECK(it->second.fields[3].name == "et" && it->second.fields[3].type_name == "time");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user