♻️ refactor: match the Lua CLI API more closely
							parent
							
								
									db84365c27
								
							
						
					
					
						commit
						b8dd59cd7c
					
				|  | @ -1,20 +1,28 @@ | |||
| // 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 pipe_bytecode = false; | ||||
| 	let mut script = None; | ||||
| 	let mut breakpoints = vec![]; | ||||
| 	let mut chunk = None; | ||||
| 	let mut lua_args = vec! []; | ||||
| 	
 | ||||
| 	let mut args = std::env::args (); | ||||
| 	let exe_name = args.next ().unwrap (); | ||||
| 	let mut arg_iter = args.iter (); | ||||
| 	let _exe_name = arg_iter.next ().unwrap (); | ||||
| 	
 | ||||
| 	while let Some (arg) = args.next () { | ||||
| 	while let Some (arg) = arg_iter.next () { | ||||
| 		match arg.as_str () { | ||||
| 			"--break" => { | ||||
| 				let s = args.next ().unwrap (); | ||||
| 				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 (); | ||||
|  | @ -25,31 +33,41 @@ fn main () -> Result <(), lwvm::StepError> { | |||
| 				}); | ||||
| 			}, | ||||
| 			"--list-bytecode" => list_bytecode = true, | ||||
| 			"--pipe-bytecode" => pipe_bytecode = true, | ||||
| 			"--script" => script = Some (args.next ().unwrap ()), | ||||
| 			"-" => { | ||||
| 				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, | ||||
| 			_ => panic! ("can't parse args"), | ||||
| 			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 = if let Some (script) = script { | ||||
| 		let bytecode = lwvm::compile_bytecode_from_file (&script); | ||||
| 		let mut rdr = std::io::Cursor::new (bytecode); | ||||
| 		lwvm::parse_chunk (&mut rdr).unwrap () | ||||
| 	} | ||||
| 	else if pipe_bytecode { | ||||
| 		let mut stdin = std::io::stdin ().lock (); | ||||
| 		lwvm::parse_chunk (&mut stdin).unwrap () | ||||
| 	} | ||||
| 	else { | ||||
| 		unimplemented!(); | ||||
| 	}; | ||||
| 	let chunk = chunk.unwrap (); | ||||
| 	
 | ||||
| 	if list_bytecode { | ||||
| 		dbg! (&chunk); | ||||
| 	} | ||||
| 	
 | ||||
| 	let upvalues = lwvm::State::upvalues_from_args ([exe_name].into_iter ().chain (args)); | ||||
| 	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() { | ||||
|  | @ -77,7 +95,7 @@ fn main () -> Result <(), lwvm::StepError> { | |||
| 			
 | ||||
| 			match input.as_str ().trim_end () { | ||||
| 				"c" => in_break = false, | ||||
| 				"q" => return Ok (()), | ||||
| 				"q" => return Ok (vec! []), | ||||
| 				"registers" => { | ||||
| 					dbg! (&vm.registers); | ||||
| 					continue; | ||||
|  | @ -86,8 +104,7 @@ fn main () -> Result <(), lwvm::StepError> { | |||
| 					match vm.step ()? { | ||||
| 						None => (), | ||||
| 						Some (lwvm::StepOutput::ChunkReturned (x)) => { | ||||
| 							dbg! (x); | ||||
| 							return Ok (()); | ||||
| 							return Ok (x); | ||||
| 						}, | ||||
| 					} | ||||
| 					continue; | ||||
|  | @ -99,12 +116,9 @@ fn main () -> Result <(), lwvm::StepError> { | |||
| 		match vm.step ()? { | ||||
| 			None => (), | ||||
| 			Some (lwvm::StepOutput::ChunkReturned (x)) => { | ||||
| 				dbg! (x); | ||||
| 				return Ok (()); | ||||
| 				return Ok (x); | ||||
| 			}, | ||||
| 		} | ||||
| 	} | ||||
| 	
 | ||||
| 	dbg! (vm); | ||||
| 	panic! ("Hit max iterations before block returned"); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,8 @@ mod state; | |||
| mod value; | ||||
| 
 | ||||
| pub use loader::compile_bytecode_from_file as compile_bytecode_from_file; | ||||
| pub use loader::compile_bytecode_from_stdin as compile_bytecode_from_stdin; | ||||
| pub use loader::compile_bytecode as compile_bytecode; | ||||
| pub use loader::ensure_bytecode as ensure_bytecode; | ||||
| pub use loader::parse_chunk as parse_chunk; | ||||
| pub use state::Breakpoint as Breakpoint; | ||||
| pub use state::State as State; | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ pub fn compile_bytecode_from_file (path: &str) -> Vec <u8> { | |||
| /// 
 | ||||
| /// `source` is a Vec because we move it to a worker thread
 | ||||
| 
 | ||||
| pub fn compile_bytecode_from_stdin (source: Vec <u8>) -> Vec <u8> { | ||||
| pub fn compile_bytecode (source: Vec <u8>) -> Vec <u8> { | ||||
| 	use std::{ | ||||
| 		io::Write, | ||||
| 		process::{ | ||||
|  | @ -64,6 +64,19 @@ pub fn compile_bytecode_from_stdin (source: Vec <u8>) -> Vec <u8> { | |||
| 	output.stdout.as_slice ().to_vec () | ||||
| } | ||||
| 
 | ||||
| /// Checks whether the input is already bytecode, or is possibly
 | ||||
| /// Lua source code. If it's source code, compiles and returns bytecode.
 | ||||
| /// If it's bytecode, just returns the input.
 | ||||
| 
 | ||||
| pub fn ensure_bytecode (buffer: Vec <u8>) -> Vec <u8> { | ||||
| 	let bytecode_header = &[0x1b, 0x4c, 0x75, 0x61, 0x54, 0x00, 0x19, 0x93]; | ||||
| 	if buffer.starts_with (bytecode_header) { | ||||
| 		return buffer; | ||||
| 	} | ||||
| 	
 | ||||
| 	compile_bytecode (buffer) | ||||
| } | ||||
| 
 | ||||
| fn i_sb (buf: [u8; 4]) -> Option <i8> { | ||||
| 	let b = buf [2]; | ||||
| 	i8::try_from (i32::try_from (b).ok ()? - 127).ok () | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ fn run_bytecode (args: &[&str], bc: &[u8]) -> Vec <Value> { | |||
| /// and returns the output
 | ||||
| 
 | ||||
| fn run_source (args: &[&str], s: &str) -> Vec <Value> { | ||||
| 	let bc = loader::compile_bytecode_from_stdin (s.as_bytes ().to_vec ()); | ||||
| 	let bc = loader::compile_bytecode (s.as_bytes ().to_vec ()); | ||||
| 	run_bytecode (args, &bc) | ||||
| } | ||||
| 
 | ||||
|  | @ -128,7 +128,7 @@ fn bools () { | |||
| #[test] | ||||
| fn closure () { | ||||
| 	let source = include_bytes! ("../test_vectors/closure.lua"); | ||||
| 	let bytecode = &crate::loader::compile_bytecode_from_stdin (source.to_vec ()); | ||||
| 	let bytecode = &crate::loader::compile_bytecode (source.to_vec ()); | ||||
| 	let chunk = crate::loader::parse_chunk_from_bytes (bytecode).unwrap (); | ||||
| 	
 | ||||
| 	assert_eq! (run_chunk (&["_exe_name"], chunk), vec! [Value::from (23i64)]); | ||||
|  | @ -185,7 +185,7 @@ fn floats () { | |||
| #[test] | ||||
| fn fma () { | ||||
| 	let source = include_bytes! ("../test_vectors/fma.lua"); | ||||
| 	let bytecode = &crate::loader::compile_bytecode_from_stdin (source.to_vec ()); | ||||
| 	let bytecode = &crate::loader::compile_bytecode (source.to_vec ()); | ||||
| 	let chunk = crate::loader::parse_chunk_from_bytes (bytecode).unwrap (); | ||||
| 	assert_eq! (chunk.blocks.len (), 5); | ||||
| 	
 | ||||
|  | @ -275,7 +275,7 @@ fn is_93 () { | |||
| 	end | ||||
| 	"#;
 | ||||
| 	
 | ||||
| 	let bc = loader::compile_bytecode_from_stdin (src.as_bytes ().to_vec ()); | ||||
| 	let bc = loader::compile_bytecode (src.as_bytes ().to_vec ()); | ||||
| 	let chunk = loader::parse_chunk_from_bytes (&bc).unwrap (); | ||||
| 	
 | ||||
| 	assert_eq! (chunk.blocks [0].instructions [3], Inst::EqK (0, 1, false)); | ||||
|  | @ -363,7 +363,7 @@ fn tailcall () { | |||
| 	return tonumber ("5") | ||||
| 	"#;
 | ||||
| 	
 | ||||
| 	let bc = loader::compile_bytecode_from_stdin (src.as_bytes ().to_vec ()); | ||||
| 	let bc = loader::compile_bytecode (src.as_bytes ().to_vec ()); | ||||
| 	let chunk = loader::parse_chunk_from_bytes (&bc).unwrap (); | ||||
| 	
 | ||||
| 	assert_eq! (chunk.blocks [0].instructions [3], Instruction::TailCall (0, 2, 1, false)); | ||||
|  |  | |||
|  | @ -0,0 +1,2 @@ | |||
| print (arg [0]) | ||||
| print (arg [1]) | ||||
|  | @ -19,7 +19,7 @@ fn embedding () { | |||
| 		1 | ||||
| 	} | ||||
| 	
 | ||||
| 	let bytecode = lwvm::compile_bytecode_from_stdin (src.to_vec ()); | ||||
| 	let bytecode = lwvm::compile_bytecode (src.to_vec ()); | ||||
| 	let mut rdr = std::io::Cursor::new (bytecode); | ||||
| 	let chunk = lwvm::parse_chunk (&mut rdr).unwrap (); | ||||
| 	
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 _
						_