lunar_wave/src/main.rs

120 lines
2.6 KiB
Rust

// cargo run -- --script test_vectors/fizz_buzz.lua
mod instruction;
mod loader;
mod state;
mod value;
#[cfg (test)]
mod tests;
fn main () -> Result <(), state::StepError> {
use state::State;
let mut list_bytecode = false;
let mut pipe_bytecode = false;
let mut script = None;
let mut breakpoints = vec![];
let mut args = std::env::args ();
let exe_name = args.next ().unwrap ();
while let Some (arg) = args.next () {
match arg.as_str () {
"--break" => {
let s = args.next ().unwrap ();
let (block_idx, program_counter) = s.split_once (":").unwrap ();
let block_idx = str::parse (block_idx).unwrap ();
let program_counter = str::parse (program_counter).unwrap ();
breakpoints.push (state::Breakpoint {
block_idx,
program_counter,
});
},
"--list-bytecode" => list_bytecode = true,
"--pipe-bytecode" => pipe_bytecode = true,
"--script" => script = Some (args.next ().unwrap ()),
"--" => break,
_ => panic! ("can't parse args"),
}
}
let chunk = if let Some (script) = script {
let bytecode = loader::compile_bytecode_from_file (&script);
let mut rdr = std::io::Cursor::new (bytecode);
loader::parse_chunk (&mut rdr).unwrap ()
}
else if pipe_bytecode {
let mut stdin = std::io::stdin ().lock ();
loader::parse_chunk (&mut stdin).unwrap ()
}
else {
unimplemented!();
};
if list_bytecode {
dbg! (&chunk);
}
let upvalues = State::upvalues_from_args ([exe_name].into_iter ().chain (args));
let mut vm = State::new (&chunk, &upvalues);
if std::env::var("LWVM_DEBUG").is_ok() {
vm.debug_print = true;
}
let max_iters = 2000;
let mut in_break = false;
let mut last_input = String::new ();
for _ in 0..max_iters {
if in_break || breakpoints.iter ().any (|bp| vm.at_breakpoint (bp)) {
in_break = true;
dbg! (&vm.stack);
let mut input = Default::default ();
std::io::stdin ().read_line (&mut input).unwrap ();
let input = if input == "" {
&last_input
}
else {
last_input = input;
&last_input
};
match input.as_str ().trim_end () {
"c" => in_break = false,
"q" => return Ok (()),
"registers" => {
dbg! (&vm.registers);
continue;
}
"s" => {
match vm.step ()? {
None => (),
Some (state::StepOutput::ChunkReturned (x)) => {
dbg! (x);
return Ok (());
},
}
continue;
},
x => { dbg! (x); },
}
}
match vm.step ()? {
None => (),
Some (state::StepOutput::ChunkReturned (x)) => {
dbg! (x);
return Ok (());
},
}
}
dbg! (vm);
panic! ("Hit max iterations before block returned");
}