june_lang/
driver.rs

1use crate::analyzer;
2use crate::builtins;
3use crate::emitter;
4use crate::parser;
5use crate::scanner;
6use crate::translator;
7use std::fs;
8use std::io;
9use std::path;
10use std::result;
11use thiserror::Error;
12use wasmtime;
13
14#[derive(Error, Debug)]
15pub enum Error {
16    #[error("can't create output path: {0}")]
17    OutputPathError(path::PathBuf),
18    #[error("io: {path}: {err}")]
19    IOError { path: path::PathBuf, err: io::Error },
20    #[error("scanner: {0}")]
21    ScannerError(#[from] scanner::Error),
22    #[error("parser: {0}")]
23    ParserError(#[from] parser::Error),
24    #[error("analyzer: {0}")]
25    AnalyzerError(#[from] analyzer::Error),
26    #[error("translator: {0}")]
27    TranslatorError(#[from] translator::Error),
28    #[error("emitter: {0}")]
29    EmitterError(#[from] emitter::Error),
30    #[error("wasmtime: {0}")]
31    Wasmtime(#[from] wasmtime::Error),
32}
33
34pub type Result<T> = result::Result<T, Error>;
35
36fn make_output_path(p: &path::Path) -> Result<path::PathBuf> {
37    let mut output_path = p.to_owned();
38    if output_path.set_extension("wasm") {
39        Ok(output_path)
40    } else {
41        Err(Error::OutputPathError(output_path))
42    }
43}
44
45pub fn compile<W: io::Write, R: io::Read>(mut w: W, r: R) -> Result<()> {
46    let toks = scanner::scan(io::BufReader::new(r));
47    let ast = parser::parse(toks)?;
48    let typed_ast = analyzer::analyze(ast)?;
49    let wasm = translator::translate(typed_ast)?;
50    Ok(emitter::emit(&mut w, wasm)?)
51}
52
53pub fn compile_file<P: Into<path::PathBuf>>(input_path: P) -> Result<()> {
54    let input_path = input_path.into();
55    let output_path = make_output_path(&input_path)?;
56    let f = fs::File::open(&input_path)
57        .map_err(|err| Error::IOError { path: input_path, err })?;
58    let r = io::BufReader::new(f);
59    let w = fs::File::create(&output_path)
60        .map_err(|err| Error::IOError { path: output_path, err })?;
61    compile(w, r)
62}
63
64pub fn execute<P: AsRef<path::Path>>(input_path: P) -> Result<()> {
65    let engine = wasmtime::Engine::default();
66    let module = wasmtime::Module::from_file(&engine, input_path)?;
67    let mut store = wasmtime::Store::new(&engine, ());
68    let imports = builtins::make_imports(&mut store);
69    wasmtime::Instance::new(&mut store, &module, &imports)?;
70    Ok(())
71}