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