步骤2:VAR_TEMP 链接层(FB 布局排除 Temp 字段 + 顶层防御校验 + scope 符号映射 Local)+ linker_test
This commit is contained in:
@@ -70,6 +70,67 @@ static bool expect_link_err(const char* dir, const char* keyword) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- 0. VAR_TEMP:FB 布局排除 Temp、scope 符号为 Local ----
|
||||
|
||||
static bool test_var_temp() {
|
||||
using namespace compiler;
|
||||
const std::string toml = std::string(REPO_ROOT) + "/tests/cases/13_function_call/project.toml";
|
||||
Project p;
|
||||
std::string err;
|
||||
CHECK(parse_project(toml, &p, &err));
|
||||
SourceUnit u;
|
||||
u.path = "main.st";
|
||||
CHECK(parse_pous("main.st",
|
||||
"FUNCTION_BLOCK Foo\n"
|
||||
"VAR_INPUT\n in : BOOL;\nEND_VAR\n"
|
||||
"VAR_OUTPUT\n out : BOOL;\nEND_VAR\n"
|
||||
"VAR\n state : BOOL;\nEND_VAR\n"
|
||||
"VAR_TEMP\n tmp : INT;\nEND_VAR\n"
|
||||
" out := tmp > 0;\n"
|
||||
"END_FUNCTION_BLOCK\n"
|
||||
"PROGRAM MAIN\nEND_PROGRAM",
|
||||
&u.ast, &err));
|
||||
compiler::MachineConfig cfg;
|
||||
std::string cerr;
|
||||
CHECK(cfg.load(std::string(REPO_ROOT) + "/compiler/machine.toml", &cerr));
|
||||
LinkResult r;
|
||||
std::vector<SourceUnit> units;
|
||||
units.push_back(std::move(u));
|
||||
CHECK(link_project(p, units, cfg, &r, &err));
|
||||
|
||||
// FB 布局:字段 = input/output/内部 var,VAR_TEMP 不是字段
|
||||
const auto it = r.fb_types.find("foo");
|
||||
CHECK(it != r.fb_types.end());
|
||||
CHECK(it->second.fields.size() == 3);
|
||||
CHECK(it->second.fields[0].name == "in");
|
||||
CHECK(it->second.fields[1].name == "out");
|
||||
CHECK(it->second.fields[2].name == "state");
|
||||
for (const FbField& f : it->second.fields) {
|
||||
CHECK(f.name != "tmp");
|
||||
}
|
||||
|
||||
// scope 符号:VAR_TEMP → Local(在 Foo 作用域)
|
||||
bool saw_tmp = false;
|
||||
bool saw_main = false;
|
||||
for (const auto& sc : r.scopes) {
|
||||
if (sc.name == "foo") {
|
||||
for (const Symbol& s : sc.syms) {
|
||||
if (s.name == "tmp") {
|
||||
saw_tmp = true;
|
||||
CHECK(s.kind == SymbolKind::Local);
|
||||
CHECK(s.type_name == "int");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sc.name == "main") {
|
||||
saw_main = true;
|
||||
}
|
||||
}
|
||||
CHECK(saw_tmp);
|
||||
CHECK(saw_main);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- 1. 用例 09:GVL + VAR_EXTERNAL 同一槽 ----
|
||||
|
||||
static bool test_case09() {
|
||||
@@ -229,6 +290,7 @@ static bool test_builtin() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
if (!test_var_temp()) return 1;
|
||||
if (!test_case09()) return 1;
|
||||
if (!test_neg_cases()) return 1;
|
||||
if (!test_case16()) return 1;
|
||||
|
||||
Reference in New Issue
Block a user