lunar_wave/lunar_wave_cli/src/main.rs

125 lines
2.8 KiB
Rust

// cargo run -- --script lunar_wave_vm/test_vectors/fizz_buzz.lua
use std::io::Read;
use lunar_wave_vm as lwvm;
fn main () -> Result <(), lwvm::StepError> {
let args: Vec <_> = std::env::args ().collect ();
lunar_wave (args)?;
Ok (())
}
fn lunar_wave (args: Vec <String>) -> Result <Vec <lwvm::Value>, lwvm::StepError> {
let mut list_bytecode = false;
let mut breakpoints = vec![];
let mut chunk = None;
let mut lua_args = vec! [];
let mut arg_iter = args.iter ();
let _exe_name = arg_iter.next ().unwrap ();
while let Some (arg) = arg_iter.next () {
match arg.as_str () {
"--break" => {
let s = arg_iter.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 (lwvm::Breakpoint {
block_idx,
program_counter,
});
},
"--list-bytecode" => list_bytecode = true,
"-" => {
let mut buf = vec! [];
std::io::stdin ().read_to_end (&mut buf).unwrap ();
let bc = lwvm::ensure_bytecode (buf);
let mut rdr = std::io::Cursor::new (bc);
chunk = Some (lwvm::parse_chunk (&mut rdr).unwrap ());
lua_args = vec! ["-".to_string ()];
},
"--" => break,
x => {
if x.starts_with ('-') {
panic! ("Unknown flag `{x}`");
}
else if chunk.is_none () {
let bc = lwvm::compile_bytecode_from_file (x);
let mut rdr = std::io::Cursor::new (bc);
chunk = Some (lwvm::parse_chunk (&mut rdr).unwrap ());
lua_args = vec! [x.to_string ()];
}
else {
lua_args.push (x.into ());
}
},
}
}
let chunk = chunk.unwrap ();
if list_bytecode {
dbg! (&chunk);
}
let upvalues = lwvm::State::upvalues_from_args (lua_args.into_iter ());
let mut vm = lwvm::State::new (chunk, upvalues);
if std::env::var("LWVM_DEBUG").is_ok() {
vm.debug_print = true;
}
let mut in_break = false;
let mut last_input = String::new ();
loop {
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 (vec! []),
"registers" => {
dbg! (&vm.registers);
continue;
}
"s" => {
match vm.step ()? {
None => (),
Some (lwvm::StepOutput::ChunkReturned (x)) => {
return Ok (x);
},
}
continue;
},
x => { dbg! (x); },
}
}
match vm.step ()? {
None => (),
Some (lwvm::StepOutput::ChunkReturned (x)) => {
return Ok (x);
},
}
}
}