1#![allow(dead_code)]
3#![feature(ptr_metadata)]
5
6use std::io;
7
8#[macro_use]
9mod macros;
10
11pub mod utils;
12
13pub mod source;
14pub mod lexer;
15pub mod parser;
16
17pub mod language;
18pub mod codegen;
19pub mod runtime;
20pub mod builtins;
21
22pub mod frontend;
23pub mod debug;
24
25
26use source::{SourceText, ModuleSource, ParseContext};
27use parser::ParserError;
28use parser::stmt::StmtMeta;
29use codegen::{CompiledProgram, Compiler, CompileError};
30use runtime::strings::StringInterner;
31
32#[derive(Debug)]
33pub enum BuildErrors {
34 Source(io::Error),
36 Syntax(Box<[ParserError]>),
37 Compile(Box<[CompileError]>),
38}
39
40pub fn build_module(source: &ModuleSource) -> Result<CompiledProgram, BuildErrors> {
41 let source_text = source.read_text()
42 .map_err(BuildErrors::Source)?;
43
44 build_source(source_text)
45}
46
47pub fn build_source(source_text: SourceText) -> Result<CompiledProgram, BuildErrors> {
48 let mut interner = StringInterner::new();
49
50 let parse_result = parse_source(&mut interner, source_text);
52
53 if let Err(errors) = parse_result {
54 return Err(BuildErrors::Syntax(errors.into_boxed_slice()));
55 }
56
57 let compile_result = compile_ast(interner, parse_result.unwrap());
59
60 if let Err(errors) = compile_result {
61 return Err(BuildErrors::Compile(errors.into_boxed_slice()));
62 }
63
64 Ok(compile_result.unwrap())
65}
66
67
68
69pub fn parse_source(interner: &mut StringInterner, source_text: SourceText) -> Result<Vec<StmtMeta>, Vec<ParserError>> {
71 let lexer_factory = language::create_default_lexer_rules();
72 let mut parse_ctx = ParseContext::new(&lexer_factory, interner);
73
74 parse_ctx.parse_ast(source_text)
75}
76
77pub fn compile_ast(interner: StringInterner, ast: Vec<StmtMeta>) -> Result<CompiledProgram, Vec<CompileError>> {
79 let compiler = Compiler::new(interner);
80 compiler.compile_program(ast.iter())
81}
82
83
84pub fn print_build_errors(errors: &BuildErrors, source: &ModuleSource) {
85 match errors {
86 BuildErrors::Source(error) => {
87 println!("Error reading source: {}.", error);
88 }
89
90 BuildErrors::Syntax(errors) => {
91 println!("Errors in {}:\n", source);
92 frontend::print_source_errors(source, errors);
93 }
94
95 BuildErrors::Compile(errors) => {
96 println!("Errors in {}:\n", source);
97 frontend::print_source_errors(source, errors);
98 }
99 }
100
101}