vicuna_compiler/
compiler.rs1use 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}