diff --git a/compiler/src/Codegen.cpp b/compiler/src/Codegen.cpp index bcc7815..932c486 100644 --- a/compiler/src/Codegen.cpp +++ b/compiler/src/Codegen.cpp @@ -120,6 +120,8 @@ namespace { std::vector code; ///< 字节码(变长指令,字节流) std::map regs; ///< 变量名 → 帧寄存器 std::map reg_func; ///< 变量名 → func(类型) + std::map fb_temp; ///< FB 内联 VAR_TEMP → 帧寄存器(当前内联层) + std::map fb_temp_func; ///< FB 内联 VAR_TEMP → func uint8_t nlocals = 0; ///< 变量区终点 = 临时寄存器起始 uint8_t nregs = 0; ///< 寄存器峰值 uint8_t temp_used = 0; ///< 本语句已用临时数 @@ -266,6 +268,33 @@ namespace { return "int"; } + /// VAR_TEMP 初值装载:对 temp_map 中每个变量 emit LOADK(声明初值或 0)。 + /// temp_map 键为变量名、值为 (寄存器, func);调用点开头执行 → 每次调用重新初始化。 + void emit_temp_init(FuncCtx& f, const POU& pou, + const std::map& map, + const std::map& func_map) { + for (const VarBlock& b : pou.blocks) { + if (b.section != VarSection::Temp) { + continue; + } + for (const VarDecl& d : b.vars) { + const auto it = map.find(d.name); + if (it == map.end()) { + continue; + } + const uint8_t func = func_map.count(d.name) + ? func_map.at(d.name) + : func_of_name("INT"); + int64_t v = d.has_init ? d.init_value : 0; + if (d.has_init && d.type.name == "bool") { + v = d.init_value ? 1 : 0; + } + const size_t s = E_imm(f, "LOADK", it->second, const_id(v)); + set_func(f.code.data() + s, func); + } + } + } + bool build_function(const POU& pou, FuncCtx* f) { if (pou.kind == PouKind::FunctionBlock) { f->nlocals = 8; @@ -320,6 +349,7 @@ namespace { } map_->funcs.emplace_back(f->name, vars); } + emit_temp_init(*f, pou, f->regs, f->reg_func); for (const Stmt& st : pou.body) { begin_stmt(*f); if (!compile_stmt(*f, st)) { @@ -363,6 +393,18 @@ namespace { return true; } } + const auto tit = f.fb_temp.find(st.target); + if (tit != f.fb_temp.end()) { + const uint8_t t = alloc_temp(f); + const uint8_t tf_ = f.fb_temp_func.count(st.target) + ? f.fb_temp_func.at(st.target) + : func_of_name("INT"); + if (!compile_expr(f, *st.value, t, tf_)) { + return false; + } + E_rr(f, "MOVE", tit->second, t); + return true; + } const auto it = f.regs.find(st.target); if (it == f.regs.end()) { return store_target(f, st.target, *st.value); @@ -421,12 +463,36 @@ namespace { bool compile_fb_inline(FuncCtx& f, const POU& fb, const InstFields& inst) { const InstFields* saved = inline_fields_; inline_fields_ = &inst; + // VAR_TEMP:本调用点分配独立固定寄存器(MAIN 帧,nregs 之后), + // 内联体开头装载初值 → 每次调用重新初始化;嵌套内联 save/restore + const std::map saved_temp = f.fb_temp; + const std::map saved_temp_func = f.fb_temp_func; + f.fb_temp.clear(); + f.fb_temp_func.clear(); + for (const VarBlock& b : fb.blocks) { + if (b.section != VarSection::Temp) { + continue; + } + for (const VarDecl& d : b.vars) { + if (d.type.kind != TypeKind::Scalar) { + continue; + } + const uint8_t r = f.nregs++; + f.fb_temp[d.name] = r; + f.fb_temp_func[d.name] = func_of_name(type_name_of_var(fb, d.name)); + } + } + // 临时寄存器起点提到 Temp 区之上,避免语句内 alloc_temp 撞上 Temp 寄存器 + f.nlocals = f.nregs; + emit_temp_init(f, fb, f.fb_temp, f.fb_temp_func); for (const Stmt& s : fb.body) { begin_stmt(f); if (!compile_stmt(f, s)) { return false; } } + f.fb_temp = saved_temp; + f.fb_temp_func = saved_temp_func; inline_fields_ = saved; return true; } @@ -554,6 +620,15 @@ namespace { return true; } } + const auto tit = f.fb_temp.find(e.name); + if (tit != f.fb_temp.end()) { + const size_t s = E_rr(f, "MOVE", rd, tit->second); + const auto tf = f.fb_temp_func.find(e.name); + set_func(f.code.data() + s, + tf != f.fb_temp_func.end() ? tf->second + : func_of_name("INT")); + return true; + } const auto sit = f.regs.find(e.name); if (sit != f.regs.end()) { const size_t s = E_rr(f, "MOVE", rd, sit->second);