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}