tci/
lib.rs

1#![allow(dead_code)]
2#![allow(unused_variables)]
3#![allow(incomplete_features)]
4
5extern crate alloc;
6
7#[macro_use]
8mod util;
9
10#[macro_use]
11mod runtime;
12
13mod assembler;
14mod ast;
15mod filedb;
16mod lexer;
17mod parser;
18mod tc_ast;
19mod tc_structs;
20mod type_checker;
21
22#[cfg(target_arch = "wasm32")]
23mod wasm;
24
25#[cfg(test)]
26extern crate std;
27
28#[cfg(test)]
29mod test;
30
31use filedb::FileDb;
32use runtime::*;
33use util::*;
34
35#[cfg(target_arch = "wasm32")]
36pub use wasm::run;
37
38fn compile_filter<'a, In, T>(
39    mut a: impl FnMut(In) -> Result<T, Error> + 'a,
40    errs: &'a mut Vec<Error>,
41) -> impl FnMut(In) -> Option<T> + 'a {
42    return move |idx| match a(idx) {
43        Ok(t) => return Some(t),
44        Err(e) => {
45            errs.push(e);
46            return None;
47        }
48    };
49}
50
51fn compile(env: &FileDb) -> Result<BinaryData, Vec<Error>> {
52    let mut errors: Vec<Error> = Vec::new();
53    let mut lexer = lexer::Lexer::new(env);
54
55    let files = env.impls().into_iter();
56    let lexed: Vec<_> = files
57        .filter_map(compile_filter(|idx| lexer.lex(idx), &mut errors))
58        .collect();
59
60    if errors.len() != 0 {
61        return Err(errors);
62    }
63
64    let parsed: Vec<_> = lexed
65        .into_iter()
66        .filter_map(compile_filter(
67            |(id, toks, locs)| parser::parse(id, toks, locs),
68            &mut errors,
69        ))
70        .collect();
71
72    let symbols = lexer.symbols();
73
74    if errors.len() != 0 {
75        return Err(errors);
76    }
77
78    let map = |env: parser::ParseEnv| type_checker::check_tree(env.file, &symbols, &env.tree);
79    let checked: Vec<_> = parsed
80        .into_iter()
81        .filter_map(compile_filter(map, &mut errors))
82        .collect();
83
84    if errors.len() != 0 {
85        return Err(errors);
86    }
87
88    let mut assembler = assembler::Assembler::new();
89    for tu in checked {
90        match assembler.add_file(tu) {
91            Ok(_) => {}
92            Err(err) => return Err(vec![err]),
93        }
94    }
95
96    let program = match assembler.assemble(env) {
97        Ok(x) => x,
98        Err(err) => return Err(vec![err]),
99    };
100
101    return Ok(program);
102}
103
104fn emit_err(errs: &[Error], files: &FileDb, writer: &mut impl core::fmt::Write) {
105    for err in errs {
106        err.render(files, writer).unwrap();
107    }
108}