vicuna_compiler/
compiler.rs

1use crate::ast::Program;
2use crate::js_backend::JsBackend;
3use crate::parser::{parse, ParseError};
4use crate::type_checker::{TypeChecker, TypeError};
5use anyhow::Result;
6use tracing::debug;
7
8#[derive(Debug, Clone)]
9pub struct CompilerOutput {
10    pub js: String,
11    pub ast: Program,
12    pub errors: Errors,
13}
14
15#[derive(Debug, Clone)]
16pub struct Errors {
17    pub parse_errors: Vec<ParseError>,
18    pub type_errors: Vec<TypeError>,
19}
20
21pub fn check(source: &str) -> Errors {
22    let (program, parse_errors) = parse(source);
23
24    let Some(program) = program else {
25        return Errors {
26            parse_errors,
27            type_errors: Vec::new(),
28        }
29    };
30    debug!("AST: {:?}", program);
31
32    let type_checker = TypeChecker::new();
33    let type_errors = type_checker.check(&program);
34
35    Errors {
36        parse_errors,
37        type_errors,
38    }
39}
40
41pub fn compile(source: &str) -> Result<CompilerOutput> {
42    let (program, parse_errors) = parse(source);
43
44    let Some(program) = program else {
45        return Ok(CompilerOutput {
46            js: String::new(),
47            ast: Program::default(),
48            errors: Errors {
49                parse_errors,
50                type_errors: Vec::new(),
51            },
52        })
53    };
54    debug!("AST: {:#?}", program);
55
56    let type_checker = TypeChecker::new();
57    let type_errors = type_checker.check(&program);
58
59    let mut output = Vec::new();
60    let mut js_backend = JsBackend::new(&mut output);
61    js_backend.emit_program(&program)?;
62    let js = String::from_utf8(output)?;
63    Ok(CompilerOutput {
64        js,
65        ast: program,
66        errors: Errors {
67            parse_errors,
68            type_errors,
69        },
70    })
71}