diff --git a/lib/src/backend/lua/bytecode.rs b/lib/src/backend/lua/bytecode.rs index 476f162..08b3c87 100644 --- a/lib/src/backend/lua/bytecode.rs +++ b/lib/src/backend/lua/bytecode.rs @@ -208,6 +208,7 @@ impl Display for LuaConstants { } #[derive(Debug)] +#[allow(clippy::upper_case_acronyms)] pub enum LuaByteCode { /// A B: R[A] := R[B] Move(Reg, Reg), @@ -239,8 +240,8 @@ pub enum LuaByteCode { /// A B k: if ((R[A] == R[B]) ~= k) then pc++ Eq(Reg, Reg, u8), - /// A sB k if ((R[A] == sB) ~= k) then pc++ - Eqi(Reg, i8, bool), + /// A sB k if ((R[A] == sB) ~= k) then pc++ + EQI(Reg, i8, bool), /// A sB k: if ((R[A] > sB) ~= k) then pc++ Gti(Reg, i32, ConstIdx), /// A sB k: if ((R[A] >= sB) ~= k) then pc++ @@ -271,7 +272,7 @@ impl LuaByteCode { LuaByteCode::MMBin(..) => "MMBIN", LuaByteCode::MMBinI(..) => "MMBINI", LuaByteCode::MMBinK(..) => "MMBINK", - LuaByteCode::Eqi(..) => "EQI", + LuaByteCode::EQI(..) => "EQI", LuaByteCode::Gei(..) => "GEI", LuaByteCode::Gti(..) => "GTI", LuaByteCode::Jmp(..) => "JMP", @@ -294,7 +295,7 @@ impl LuaByteCode { LuaByteCode::MMBinI(..) => LuaOpCode::OP_MMBINI, LuaByteCode::MMBinK(..) => LuaOpCode::OP_MMBINK, LuaByteCode::Add(..) => LuaOpCode::OP_ADD, - LuaByteCode::Eqi(..) => LuaOpCode::OP_EQI, + LuaByteCode::EQI(..) => LuaOpCode::OP_EQI, LuaByteCode::Gei(..) => LuaOpCode::OP_GEI, LuaByteCode::Gti(..) => LuaOpCode::OP_GTI, LuaByteCode::Jmp(..) => LuaOpCode::OP_JMP, @@ -313,7 +314,7 @@ impl LuaByteCode { // A B k LuaByteCode::Eq(a, b, k) => (k as u32) << 17 | (b.num() as u32) << 9 | a.num() as u32, // A sB8 K(flag) - LuaByteCode::Eqi(a, sb8, k) => { + LuaByteCode::EQI(a, sb8, k) => { (excess_k!(sb8, 8)) << 9 | a.num() as u32 | (k as u32) << 8 } // A sB k @@ -398,9 +399,7 @@ impl LuaCompiledCode { write!(s, "R{} R{} R{}", a.num(), b.num(), c.num()).unwrap() } // A sB8 K(flag) - LuaByteCode::Eqi(a, sb8, k) => { - write!(s, "R{} {sb8} {}", a.num(), *k as usize).unwrap() - } + LuaByteCode::EQI(a, sb8, k) => write!(s, "R{} {sb8} {}", a.num(), *k as usize).unwrap(), // RA, KB, KC with k LuaByteCode::MMBinK(ra, kb, kc) => write!(s, "R{} {kb} {kc}", ra.num()).unwrap(), // A B k diff --git a/lib/src/backend/lua/mod.rs b/lib/src/backend/lua/mod.rs index 5f21187..3bc4377 100644 --- a/lib/src/backend/lua/mod.rs +++ b/lib/src/backend/lua/mod.rs @@ -145,7 +145,15 @@ impl LuaBackend { self.push_code(LuaByteCode::Move(to, from)) } - fn code_load(&mut self, r: Reg, v: &LiteralValue) { + #[inline] + fn code_load(&mut self, dst: Reg, rk: RK) { + match rk { + RK::R(r) => self.code_move(r, dst), + RK::K(v) => self.code_load_literal(dst, &LiteralValue::Byte(v)), + } + } + + fn code_load_literal(&mut self, r: Reg, v: &LiteralValue) { // if literal can use LoadI instructions if let Some(v) = try_fit_sbx(v) { self.push_code(LuaByteCode::LoadI(r, v)); @@ -196,8 +204,21 @@ impl LuaBackend { #[inline] fn code_eq(&mut self, dst: Reg, op0: RK, op1: RK) { - self.code_load(Reg::R(1), &LiteralValue::Byte(1)); - self.push_code(LuaByteCode::Eqi(Reg::R(1), 1, false)); + self.code_load(dst, op0); + + match op1 { + RK::R(r) => self.push_code(LuaByteCode::Eq(dst, r, 0)), + RK::K(k) => { + let r = self.reg_mgr.alloc_hard(); + + self.code_load_constant(r, k); + self.push_code(LuaByteCode::Eq(dst, r, 0)); + self.reg_mgr.free(&r); + + // TODO: convert constants to I8 value + // self.push_code(LuaByteCode::EQI(dst, kv, false)) + } + } } #[inline] @@ -486,7 +507,7 @@ impl AstVisitorMut for LuaBackend { let r = self.top_attribute().registers[0]; // TODO: Load variable value into register - self.code_load(r, &LiteralValue::SInt(0)) + self.code_load_literal(r, &LiteralValue::SInt(0)) } _ => unreachable!("{:?}", access_mode), } @@ -587,7 +608,7 @@ impl AstVisitorMut for LuaBackend { // conditional jump if let Some(lbl) = cond { - let fixup = self.code_jmp(0); + let fixup = self.code_jmp(1); } if let RK::R(r0) = rk0 { diff --git a/lib/src/backend/lua/test.rs b/lib/src/backend/lua/test.rs index a42955c..48e3dbe 100644 --- a/lib/src/backend/lua/test.rs +++ b/lib/src/backend/lua/test.rs @@ -127,7 +127,28 @@ fn test_add() { #[test] fn test_if_statement() { let decl = "PROGRAM main: VAR a: INT; END_VAR END_PROGRAM"; - let body = "a := 1; if a = 1 then a := 0; end_if"; + let body = "\ +a := 1; \ +if a = 1 then \ + a := 0; \ +end_if"; + + // Generate to buffer + let mut buf = vec![]; + generate_module(decl, body, &mut buf); + + let lua = Lua::new(); + assert!(lua.load(buf).set_mode(ChunkMode::Binary).exec().is_ok()); + + let r = lua.globals().get::<_, i32>("a"); + assert_eq!(r.unwrap(), 0); + + let decl = "PROGRAM main: VAR a: INT; END_VAR END_PROGRAM"; + let body = "\ +a := 0; \ +if a = 1 then \ + a := 1; \ +end_if"; // Generate to buffer let mut buf = vec![]; diff --git a/viewer/test_projects/example1/test_proj.xml b/viewer/test_projects/example1/test_proj.xml index 3f975ed..f55cf10 100644 --- a/viewer/test_projects/example1/test_proj.xml +++ b/viewer/test_projects/example1/test_proj.xml @@ -20,7 +20,7 @@ end_program