12.8 切片 5:WHILE 回环与四则运算。

- WHILE 编成 L_loop: <cond→t> JF t, L_end <body> JMP L_loop L_end:,JF/JMP 双回填
- 四则 ADD/SUB/MUL/DIV(用例 5 循环体自增需要,同模式实现,用例 7 顺带点亮)
- codegen_test:115 断言(用例 05 回环 JMP -8、07 四则+比较、08 TIME 常量表),ctest 9/9
This commit is contained in:
2026-08-21 11:45:32 +08:00
parent 6f1bf61c7f
commit 31ba557627
2 changed files with 168 additions and 9 deletions
+97
View File
@@ -397,6 +397,100 @@ static bool test_case04() {
return true;
}
// ---- 10. 用例 05WHILE 回环(JF 出口 + JMP 回填)----
static bool test_case05() {
std::vector<uint8_t> img;
std::string err;
CHECK(compile_case("05_while_normal", &img, &err));
const isa::ImageView v = isa::ImageView::from(img);
CHECK(v.ok());
const isa::FuncRow r = v.func_row(0);
CHECK(r.nregs == 4); // n + 3 临时(CMP 目的 + 两操作数)
CHECK(r.code_len == 10);
char buf[64];
const uint8_t* base = v.code_bytes();
const uint32_t* ins = reinterpret_cast<const uint32_t*>(base);
isa::disasm(ins[0], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r0, 0") == 0); // n := 0
// L_loop [1]n < 10 → r1
isa::disasm(ins[1], buf, sizeof buf);
CHECK(std::strcmp(buf, "MOVE r2, r0") == 0);
isa::disasm(ins[2], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r3, 1") == 0); // 常量 1 = 10
isa::disasm(ins[3], buf, sizeof buf);
CHECK(std::strcmp(buf, "CMP_LT r1, r2, r3") == 0);
isa::disasm(ins[4], buf, sizeof buf);
CHECK(std::strcmp(buf, "JF r1, +4") == 0); // 假 → RET[9]
// n := n + 1(体语句临时复用 r1/r2)
isa::disasm(ins[5], buf, sizeof buf);
CHECK(std::strcmp(buf, "MOVE r1, r0") == 0);
isa::disasm(ins[6], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r2, 2") == 0); // 常量 2 = 1
isa::disasm(ins[7], buf, sizeof buf);
CHECK(std::strcmp(buf, "ADD r0, r1, r2") == 0);
isa::disasm(ins[8], buf, sizeof buf);
CHECK(std::strcmp(buf, "JMP -8") == 0); // 回 L_loop[1]
isa::disasm(ins[9], buf, sizeof buf);
CHECK(std::strcmp(buf, "RET") == 0);
return true;
}
// ---- 11. 用例 07:四则 + 比较 ----
static bool test_case07() {
std::vector<uint8_t> img;
std::string err;
CHECK(compile_case("07_int_arith", &img, &err));
const isa::ImageView v = isa::ImageView::from(img);
CHECK(v.ok());
const isa::FuncRow r = v.func_row(0);
CHECK(r.nregs == 6); // a b c eq + 2 临时(语句间复用)
char buf[64];
const uint8_t* base = v.code_bytes();
const uint32_t* ins = reinterpret_cast<const uint32_t*>(base);
bool saw_mul = false, saw_div = false, saw_sub = false, saw_gt = false;
for (uint32_t i = 0; i < r.code_len; ++i) {
isa::disasm(ins[i], buf, sizeof buf);
if (std::strstr(buf, "MUL r0, ")) saw_mul = true;
if (std::strstr(buf, "DIV r1, ")) saw_div = true;
if (std::strstr(buf, "SUB r2, ")) saw_sub = true;
if (std::strstr(buf, "CMP_GT r3, ")) saw_gt = true;
}
CHECK(saw_mul && saw_div && saw_sub && saw_gt);
return true;
}
// ---- 12. 用例 08TIME 字面量进常量表 ----
static bool test_case08() {
std::vector<uint8_t> img;
std::string err;
CHECK(compile_case("08_time_literal", &img, &err));
const isa::ImageView v = isa::ImageView::from(img);
CHECK(v.ok());
CHECK(v.header().n_consts == 2);
const isa::ConstEntry c0 = v.const_entry(0);
CHECK(c0.tag == isa::types::Time && c0.value == 10); // T#10ms
const isa::ConstEntry c1 = v.const_entry(1);
CHECK(c1.tag == isa::types::Time && c1.value == 1250); // T#1s250ms
const isa::FuncRow r = v.func_row(0);
CHECK(r.nregs == 2);
char buf[64];
const uint32_t* ins = reinterpret_cast<const uint32_t*>(v.code_bytes());
isa::disasm(ins[0], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r0, 0") == 0);
isa::disasm(ins[1], buf, sizeof buf);
CHECK(std::strcmp(buf, "LOADK r1, 1") == 0);
return true;
}
int main() {
if (!test_case01()) return 1;
if (!test_case02()) return 1;
@@ -407,6 +501,9 @@ int main() {
if (!test_case03()) return 1;
if (!test_not()) return 1;
if (!test_case04()) return 1;
if (!test_case05()) return 1;
if (!test_case07()) return 1;
if (!test_case08()) return 1;
std::printf("codegen_test: %d checks passed\n", g_checks);
return 0;
}