pub mod debug;
pub mod ir;
pub mod program;
use crate::parser::Ast;
pub fn compile(ast: &Ast) -> program::Program {
let mut p = program::Program::new();
match p.compile(ast) {
Ok(_) => p,
Err(e) => panic!("{}", e),
}
}
#[cfg(test)]
pub mod tests {
use crate::compiler::program;
use crate::parser;
use insta;
macro_rules! _snap {
($desc:tt,$res:tt) => {{
let mut settings = insta::Settings::clone_current();
settings.set_description($desc);
settings.set_snapshot_path("../../tests/snapshots");
settings.bind(|| {
insta::assert_snapshot!($res);
});
}};
}
macro_rules! snap {
($name:tt, $desc: tt ) => {
#[test]
fn $name() {
let path = format!("tests/inputs/compiler/{}.sh", stringify!($name));
let program_as_str = crate::compiler::tests::compile(&path).unwrap().to_string();
crate::compiler::tests::_snap!($desc, program_as_str)
}
};
}
macro_rules! snaperr {
($_name:tt ) => {
#[test]
fn $_name() {
let name = stringify!($_name);
let path = format!("tests/inputs/compiler/{}.sh", name);
let compiled = compile(&path);
let error = match compiled {
Ok(_) => unreachable!(""),
Err(e) => e,
};
let desc = String::from(format!("calling method with {}", name));
_snap!(desc, error)
}
};
}
pub(crate) use {_snap, snap};
pub fn compile(path: &str) -> Result<program::Program, String> {
let msg = format!("unable to read path '{}'", path);
let src_code = std::fs::read(path).expect(&msg);
let l = parser::lexer::Lexer::new();
let tokens = l.tokenize(&src_code).unwrap();
let ast = parser::parse(&tokens).unwrap();
let mut p = program::Program::new();
p.compile(&ast)?;
Ok(p)
}
snaperr!(missing_args);
snaperr!(too_many_args);
}