1#[macro_use]
2mod macros;
3
4mod analyzer;
5pub mod ast;
6mod diagnostic;
7
8use std::iter;
9
10pub use analyzer::*;
11use ast::AnalyzedProgram;
12pub use diagnostic::*;
13
14pub use rush_parser::ast::{AssignOp, InfixOp, PrefixOp, Type};
15use rush_parser::{Lexer, Parser};
16
17pub fn analyze<'src>(
21 text: &'src str,
22 path: &'src str,
23) -> Result<(AnalyzedProgram<'src>, Vec<Diagnostic<'src>>), Vec<Diagnostic<'src>>> {
24 let lexer = Lexer::new(text, path);
25
26 let parser = Parser::new(lexer);
27 let (ast, errs) = parser.parse();
28
29 match (ast, errs.len()) {
30 (Err(critical), _) => Err(errs
31 .into_iter()
32 .map(Diagnostic::from)
33 .chain(iter::once((*critical).into()))
34 .collect()),
35 (Ok(ast), _) => {
36 let analyzer = Analyzer::new(text);
37
38 let mut parser_diagnostics: Vec<Diagnostic> =
40 errs.into_iter().map(Diagnostic::from).collect();
41
42 let (analyzed_ast, mut analyzer_diagnostics) = match analyzer.analyze(ast) {
43 Ok(res) => res,
44 Err(mut analyzer_diagnostics) => {
45 parser_diagnostics.append(&mut analyzer_diagnostics);
46 return Err(parser_diagnostics);
47 }
48 };
49
50 parser_diagnostics.append(&mut analyzer_diagnostics);
52
53 match parser_diagnostics
55 .iter()
56 .any(|diagnostic| matches!(diagnostic.level, DiagnosticLevel::Error(_)))
57 {
58 true => Err(parser_diagnostics),
59 false => Ok((analyzed_ast, parser_diagnostics)),
60 }
61 }
62 }
63}