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:
@@ -397,6 +397,100 @@ static bool test_case04() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- 10. 用例 05:WHILE 回环(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. 用例 08:TIME 字面量进常量表 ----
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user