⭐ for loops with integer counters counting up only
parent
fcfd9397ff
commit
9811d265f6
|
@ -10,6 +10,10 @@ pub enum Instruction {
|
||||||
|
|
||||||
ExtraArg (u32),
|
ExtraArg (u32),
|
||||||
|
|
||||||
|
ForLoop (u8, u32),
|
||||||
|
|
||||||
|
ForPrep (u8, u32),
|
||||||
|
|
||||||
GetField (u8, u8, u8),
|
GetField (u8, u8, u8),
|
||||||
|
|
||||||
// Get Immediate?
|
// Get Immediate?
|
||||||
|
|
|
@ -88,6 +88,8 @@ pub fn parse_inst (buf: [u8; 4]) -> Option <Inst>
|
||||||
0x46 => Inst::Return (a, b, c, k),
|
0x46 => Inst::Return (a, b, c, k),
|
||||||
0x47 => Inst::Return0,
|
0x47 => Inst::Return0,
|
||||||
0x48 => Inst::Return1 (a),
|
0x48 => Inst::Return1 (a),
|
||||||
|
0x49 => Inst::ForLoop (a, bx),
|
||||||
|
0x4a => Inst::ForPrep (a, bx),
|
||||||
0x4e => Inst::SetList (a, b, c, k),
|
0x4e => Inst::SetList (a, b, c, k),
|
||||||
0x4f => Inst::Closure (a, bx),
|
0x4f => Inst::Closure (a, bx),
|
||||||
0x51 => Inst::VarArgPrep (a.into ()),
|
0x51 => Inst::VarArgPrep (a.into ()),
|
||||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -1,3 +1,5 @@
|
||||||
|
// cargo run -- --script test_vectors/fizz_buzz.lua
|
||||||
|
|
||||||
mod instruction;
|
mod instruction;
|
||||||
mod loader;
|
mod loader;
|
||||||
mod state;
|
mod state;
|
||||||
|
@ -9,8 +11,21 @@ mod tests;
|
||||||
fn main () {
|
fn main () {
|
||||||
use state::State;
|
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 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 bytecode = loader::compile_bytecode(source);
|
||||||
let mut rdr = std::io::Cursor::new (bytecode);
|
let mut rdr = std::io::Cursor::new (bytecode);
|
||||||
loader::parse_chunk (&mut rdr).unwrap ()
|
loader::parse_chunk (&mut rdr).unwrap ()
|
||||||
|
@ -21,7 +36,7 @@ fn main () {
|
||||||
vm.debug_print = true;
|
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 {
|
vm.breakpoints.push (state::Breakpoint {
|
||||||
block_idx: 3,
|
block_idx: 3,
|
||||||
|
|
21
src/state.rs
21
src/state.rs
|
@ -214,6 +214,27 @@ impl State {
|
||||||
|
|
||||||
assert_eq! (*ax, 0, "implemented only for ax == 0");
|
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) => {
|
Instruction::GetField (a, b, c) => {
|
||||||
let t = match self.reg (*b) {
|
let t = match self.reg (*b) {
|
||||||
Value::Table (t) => t,
|
Value::Table (t) => t,
|
||||||
|
|
|
@ -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>>> {
|
pub fn as_table (&self) -> Option <&Rc <RefCell <Table>>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Table (t) => Some (t),
|
Self::Table (t) => Some (t),
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
for i = 1, 50 do
|
||||||
|
print (i)
|
||||||
|
end
|
Loading…
Reference in New Issue