♻️ 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