12.8 切片 1:寄存器码骨架(MOVE/LOADK/RET)。

- Codegen.h/cpp:帧寄存器(0 起声明序)、常量表、函数表、小端映像拼装
- 切片 1 范围:PROGRAM 标量 + 字面量 LOADK + 变量 MOVE + RET;其余构造报 codegen error
- codegen_test:23 断言(用例 01 空 MAIN 出 RET、02 LOADK r0/r1 + 常量表),ctest 9/9
This commit is contained in:
2026-08-21 11:32:31 +08:00
parent d296a9215e
commit 66359a0a26
5 changed files with 486 additions and 1 deletions
+11
View File
@@ -67,3 +67,14 @@ target_compile_definitions(typecheck_test PRIVATE
add_test(NAME typecheck_types
COMMAND typecheck_test)
# 寄存器码测试(12.8 切片 1):用例 01/02 出映像(REPO_ROOT 注入源目录绝对路径)
add_executable(codegen_test
./src/codegen_test.cpp)
target_link_libraries(codegen_test PRIVATE compiler)
target_compile_definitions(codegen_test PRIVATE
REPO_ROOT="${CMAKE_SOURCE_DIR}")
add_test(NAME codegen_slice1
COMMAND codegen_test)
+127
View File
@@ -0,0 +1,127 @@
/**
* @file codegen_test.cpp
* @brief 寄存器码测试(12.8 切片 1):用例 01/02 出映像
* @author
* @date 2026-08-21
*/
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include "compiler/Codegen.h"
#include "compiler/Linker.h"
#include "compiler/Project.h"
#include "compiler/Typecheck.h"
#include "isa/Encode.h"
#include "isa/Image.h"
#ifndef REPO_ROOT
#define REPO_ROOT "."
#endif
static int g_checks = 0;
#define CHECK(cond) \
do { \
if (!(cond)) { \
std::printf("FAIL %s:%d: %s\n", __FILE__, __LINE__, #cond); \
return false; \
} \
++g_checks; \
} while (0)
// 从用例目录走完整编译管线(解析 → 链接 → 类型检查 → 代码生成)
static bool compile_case(const char* dir, std::vector<uint8_t>* image, std::string* err) {
using namespace compiler;
const std::string toml = std::string(REPO_ROOT) + "/tests/cases/" + dir + "/project.toml";
Project p;
if (!parse_project(toml, &p, err)) {
return false;
}
std::vector<SourceUnit> units;
for (const std::string& f : compile_files(p)) {
SourceUnit u;
if (!load_unit(p.base_dir + "/" + f, &u, err)) {
return false;
}
units.push_back(std::move(u));
}
LinkResult link;
if (!link_project(p, units, &link, err)) {
return false;
}
if (!check_project(p, units, link, err)) {
return false;
}
return codegen_project(p, units, link, image, err);
}
// ---- 1. 用例 01:空 MAIN + RET ----
static bool test_case01() {
std::vector<uint8_t> img;
std::string err;
CHECK(compile_case("01_empty_main", &img, &err));
const isa::ImageView v = isa::ImageView::from(img);
CHECK(v.ok());
CHECK(v.header().cycle_limit == 1000);
CHECK(v.header().dt_ms == 10);
CHECK(v.header().entry_fn_id == 0);
CHECK(v.header().n_funcs == 1);
CHECK(v.header().n_consts == 0);
CHECK(v.header().n_globals == 0);
CHECK(v.header().project_hash != isa::kFnvBasis);
const isa::FuncRow r = v.func_row(0);
CHECK(r.nregs == 0);
CHECK(r.code_len == 1);
char buf[32];
isa::disasm(v.code_bytes()[0], buf, sizeof buf);
CHECK(std::strcmp(buf, "RET") == 0);
return true;
}
// ---- 2. 用例 02BOOL 赋值(TRUE / FALSE → LOADK----
static bool test_case02() {
std::vector<uint8_t> img;
std::string err;
CHECK(compile_case("02_bool_assign", &img, &err));
const isa::ImageView v = isa::ImageView::from(img);
CHECK(v.ok());
CHECK(v.header().n_funcs == 1);
CHECK(v.header().n_consts == 2); // TRUE 与 FALSE
const isa::FuncRow r = v.func_row(0);
CHECK(r.nregs == 2); // a, b
CHECK(r.code_len == 3);
// 从字节码段取指令(按函数行 code_offset 定位)
const uint8_t* base = v.code_bytes();
char buf[64];
isa::disasm(reinterpret_cast<const uint32_t*>(base)[0], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r0, 0") == 0); // a := TRUE(常量 0
isa::disasm(reinterpret_cast<const uint32_t*>(base)[1], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r1, 1") == 0); // b := FALSE(常量 1
isa::disasm(reinterpret_cast<const uint32_t*>(base)[2], buf, sizeof buf);
CHECK(std::strcmp(buf, "RET") == 0);
// 常量表:0 = BOOL 11 = BOOL 0
const isa::ConstEntry c0 = v.const_entry(0);
CHECK(c0.tag == isa::types::Bool && c0.value == 1);
const isa::ConstEntry c1 = v.const_entry(1);
CHECK(c1.tag == isa::types::Bool && c1.value == 0);
return true;
}
int main() {
if (!test_case01()) return 1;
if (!test_case02()) return 1;
std::printf("codegen_test: %d checks passed\n", g_checks);
return 0;
}