for loops with integer counters counting up only

main
_ 2023-09-26 22:34:47 -05:00
parent fcfd9397ff
commit 9811d265f6
6 changed files with 54 additions and 2 deletions

View File

@ -10,6 +10,10 @@ pub enum Instruction {
ExtraArg (u32),
ForLoop (u8, u32),
ForPrep (u8, u32),
GetField (u8, u8, u8),
// Get Immediate?

View File

@ -88,6 +88,8 @@ pub fn parse_inst (buf: [u8; 4]) -> Option <Inst>
0x46 => Inst::Return (a, b, c, k),
0x47 => Inst::Return0,
0x48 => Inst::Return1 (a),
0x49 => Inst::ForLoop (a, bx),
0x4a => Inst::ForPrep (a, bx),
0x4e => Inst::SetList (a, b, c, k),
0x4f => Inst::Closure (a, bx),
0x51 => Inst::VarArgPrep (a.into ()),

View File

@ -1,3 +1,5 @@
// cargo run -- --script test_vectors/fizz_buzz.lua
mod instruction;
mod loader;
mod state;
@ -9,8 +11,21 @@ mod tests;
fn main () {
use state::State;
let mut script = String::from ("test_vectors/hello.lua");
let mut args = std::env::args ();
let exe_name = args.next ().unwrap ();
while let Some (arg) = args.next () {
match arg.as_str () {
"--script" => script = args.next ().unwrap (),
"--" => break,
_ => panic! ("can't parse args"),
}
}
let lua_file = {
let source = std::fs::read ("test_vectors/hello.lua").expect ("couldn't load Lua source code");
let source = std::fs::read (script).expect ("couldn't load Lua source code");
let bytecode = loader::compile_bytecode(source);
let mut rdr = std::io::Cursor::new (bytecode);
loader::parse_chunk (&mut rdr).unwrap ()
@ -21,7 +36,7 @@ fn main () {
vm.debug_print = true;
}
let upvalues = State::upvalues_from_args (std::env::args ());
let upvalues = State::upvalues_from_args ([exe_name].into_iter ().chain (args));
vm.breakpoints.push (state::Breakpoint {
block_idx: 3,

View File

@ -214,6 +214,27 @@ impl State {
assert_eq! (*ax, 0, "implemented only for ax == 0");
},
Instruction::ForLoop (a, bx) => {
let mut iter = self.reg (*a + 3).as_int ().unwrap ();
iter += 1;
*self.reg_mut (*a + 3) = iter.into ();
let stop = self.reg (*a + 1).as_int ().unwrap ();
if iter <= stop {
next_pc -= i32::try_from (*bx).unwrap ();
}
},
Instruction::ForPrep (a, bx) => {
let start = self.reg (*a).as_int ().unwrap ();
let stop = self.reg (*a + 1).as_int ().unwrap ();
if start > stop {
next_pc += i32::try_from (*bx).unwrap () + 1;
}
*self.reg_mut (*a + 3) = start.into ();
},
Instruction::GetField (a, b, c) => {
let t = match self.reg (*b) {
Value::Table (t) => t,

View File

@ -146,6 +146,13 @@ impl Value {
}
}
pub fn as_int (&self) -> Option <i64> {
match self {
Self::Integer (x) => Some (*x),
_ => None,
}
}
pub fn as_table (&self) -> Option <&Rc <RefCell <Table>>> {
match self {
Self::Table (t) => Some (t),

View File

@ -0,0 +1,3 @@
for i = 1, 50 do
print (i)
end