⭐ for loops with integer counters counting up only
parent
fcfd9397ff
commit
9811d265f6
|
@ -10,6 +10,10 @@ pub enum Instruction {
|
|||
|
||||
ExtraArg (u32),
|
||||
|
||||
ForLoop (u8, u32),
|
||||
|
||||
ForPrep (u8, u32),
|
||||
|
||||
GetField (u8, u8, u8),
|
||||
|
||||
// Get Immediate?
|
||||
|
|
|
@ -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 ()),
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -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,
|
||||
|
|
21
src/state.rs
21
src/state.rs
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
for i = 1, 50 do
|
||||
print (i)
|
||||
end
|
Loading…
Reference in New Issue