Add CLI and a --bytecode command to print the generated code for a given source file.
This commit is contained in:
parent
f8f58d70e0
commit
d0561826c2
|
@ -6,3 +6,4 @@ edition = "2021"
|
|||
[dependencies]
|
||||
zaia = { path = "../zaia" }
|
||||
clap = { version = "3.2.5", features = ["derive"] }
|
||||
anyhow = "1.0.58"
|
||||
|
|
|
@ -1,18 +1,39 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use zaia::Lua;
|
||||
use std::fs;
|
||||
use zaia::{Lua, Script};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
file: PathBuf,
|
||||
|
||||
#[clap(short, long)]
|
||||
bytecode: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
let source = fs::read_to_string(&args.file).unwrap();
|
||||
let mut lua = Lua::new();
|
||||
let script = lua.load(&source);
|
||||
lua.execute(&script).unwrap();
|
||||
|
||||
if args.bytecode {
|
||||
action_bytecode(lua, script)?;
|
||||
} else {
|
||||
action_run(lua, script)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn action_run(mut lua: Lua, script: Script) -> Result<()> {
|
||||
lua.execute(&script)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn action_bytecode(lua: Lua, script: Script) -> Result<()> {
|
||||
println!("{}", lua.bytecode(&script));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -249,6 +249,13 @@ pub fn compile(
|
|||
chunk_alloc: &mut dyn FnMut(Chunk) -> u32,
|
||||
string_alloc: &mut dyn FnMut(&[u8]) -> ObjectPtr,
|
||||
) -> Result<ScriptData, Error> {
|
||||
let mut chunks = Vec::new();
|
||||
let chunk_alloc = &mut |chunk: Chunk| {
|
||||
let id = chunk_alloc(chunk);
|
||||
chunks.push(id);
|
||||
id
|
||||
};
|
||||
|
||||
let chunk = compile_chunk(
|
||||
interner,
|
||||
chunk_alloc,
|
||||
|
@ -260,7 +267,12 @@ pub fn compile(
|
|||
)?;
|
||||
|
||||
let root = heap.allocate_function(chunk, 0, &mut iter::empty());
|
||||
Ok(ScriptData { id, root, env })
|
||||
Ok(ScriptData {
|
||||
id,
|
||||
root,
|
||||
env,
|
||||
chunks,
|
||||
})
|
||||
}
|
||||
|
||||
fn compile_chunk(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
message: String,
|
||||
|
@ -17,3 +19,15 @@ impl Error {
|
|||
&self.message
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,13 +77,23 @@ impl Lua {
|
|||
self.script_id += 1;
|
||||
let data = Rc::new(data);
|
||||
self.scripts.insert(data.id, Rc::downgrade(&data));
|
||||
Script { data, referenced: Rc::clone(&self.referenced) }
|
||||
Script {
|
||||
data,
|
||||
referenced: Rc::clone(&self.referenced),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(&mut self, script: &Script) -> Result<api::Value, Error> {
|
||||
let raw = self.vm.run(&script.data, &self.chunks, &self.heap)?;
|
||||
Ok(api::Value::new(raw, Rc::clone(&self.referenced)))
|
||||
}
|
||||
|
||||
pub fn bytecode(&self, script: &Script) -> String {
|
||||
let mut chunks = script.data.chunks.iter().map(|&id| &self.chunks[&id]);
|
||||
let mut out = Vec::new();
|
||||
disasm::disasm(&mut out, &mut chunks);
|
||||
String::from_utf8(out).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Lua {
|
||||
|
@ -96,6 +106,7 @@ pub struct ScriptData {
|
|||
pub id: u32,
|
||||
pub root: ObjectPtr,
|
||||
pub env: ObjectPtr,
|
||||
pub chunks: Vec<u32>,
|
||||
}
|
||||
|
||||
pub struct Script {
|
||||
|
|
|
@ -14,7 +14,7 @@ pub use userdata::Userdata;
|
|||
|
||||
use super::{gc::ObjectPtr, Error};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum ValueType {
|
||||
Nil,
|
||||
Bool,
|
||||
|
|
|
@ -4,4 +4,8 @@
|
|||
mod engine;
|
||||
pub mod parser;
|
||||
|
||||
pub use engine::{Lua, Script, api::{Value, Table}};
|
||||
pub use engine::{
|
||||
api::{Table, Value},
|
||||
Lua,
|
||||
Script,
|
||||
};
|
||||
|
|
|
@ -318,7 +318,7 @@ impl BinaryOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum BinaryOperator {
|
||||
And,
|
||||
Or,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2022-03-19"
|
||||
channel = "nightly-2022-06-19"
|
||||
components = ["clippy", "rustfmt"]
|
||||
profile = "minimal"
|
||||
|
|
Loading…
Reference in a new issue