// 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 ) -> Result , 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); }, } } }