pub mod ast;
pub mod error;
pub mod lexer;
pub mod parser;
mod fmt;
mod source;
#[cfg(test)]
mod tests;
use std::cell::RefCell;
use crate::symbol;
pub use ast::Ast;
pub use error::{Error, Errors};
use lexer::Lexer;
use parser::Parser;
pub use source::{Source, SourcePos};
pub use fmt::AnalysisDisplayContext;
#[derive(Debug)]
pub struct Analysis {
pub ast: Ast,
pub errors: Errors,
}
impl Analysis {
pub fn analyze(source: &Source, interner: &mut symbol::Interner) -> Self {
let cursor = lexer::Cursor::from(source);
let lexer = Lexer::new(cursor, interner);
let errors = RefCell::new(Vec::new());
let tokens = lexer.filter_map(|result| match result {
Ok(token) => Some(token),
Err(error) => {
errors.borrow_mut().push(Error::Lexer(error));
None
}
});
let parser = Parser::new(tokens, |error| {
errors.borrow_mut().push(Error::Parser(error))
});
let statements = parser.parse();
Analysis {
ast: Ast {
source: source.path,
statements
},
errors: Errors(errors.into_inner().into()),
}
}
pub fn is_ok(&self) -> bool {
self.errors.is_empty()
}
}