125 lines
2.8 KiB
Rust
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);
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|