Add CLI and a --bytecode command to print the generated code for a given source file.

This commit is contained in:
Joel Wejdenstål 2022-06-20 18:47:56 +02:00
parent f8f58d70e0
commit d0561826c2
No known key found for this signature in database
GPG key ID: DF03CEFBB1A915AA
9 changed files with 74 additions and 11 deletions

View file

@ -6,3 +6,4 @@ edition = "2021"
[dependencies]
zaia = { path = "../zaia" }
clap = { version = "3.2.5", features = ["derive"] }
anyhow = "1.0.58"

View file

@ -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(())
}

View file

@ -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(

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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,

View file

@ -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,
};

View file

@ -318,7 +318,7 @@ impl BinaryOp {
}
}
#[derive(PartialEq)]
#[derive(PartialEq, Eq)]
pub enum BinaryOperator {
And,
Or,

View file

@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2022-03-19"
channel = "nightly-2022-06-19"
components = ["clippy", "rustfmt"]
profile = "minimal"