Skip to main content

flutmax_parser/
lib.rs

1pub mod lexer;
2#[cfg(any(feature = "tree-sitter-legacy", test))]
3pub mod parse;
4pub mod parser;
5pub mod tokens;
6
7/// Error type for the public parse API.
8#[derive(Debug)]
9pub enum ParseError {
10    InvalidSyntax {
11        message: String,
12        line: usize,
13        column: usize,
14    },
15}
16
17impl std::fmt::Display for ParseError {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            ParseError::InvalidSyntax {
21                message,
22                line,
23                column,
24            } => {
25                write!(f, "Syntax error at {}:{}: {}", line, column, message)
26            }
27        }
28    }
29}
30
31impl std::error::Error for ParseError {}
32
33/// Parse .flutmax source into AST (hand-written lexer + recursive descent parser).
34pub fn parse(source: &str) -> Result<flutmax_ast::Program, ParseError> {
35    parser::FlutmaxParser::parse(source).map_err(|e| ParseError::InvalidSyntax {
36        message: format!("{}", e),
37        line: match &e {
38            parser::ParseError::Syntax { line, .. } => *line,
39            parser::ParseError::Lex(le) => le.line,
40        },
41        column: match &e {
42            parser::ParseError::Syntax { column, .. } => *column,
43            parser::ParseError::Lex(le) => le.column,
44        },
45    })
46}
47
48/// Legacy: parse using tree-sitter (for comparison/migration testing).
49#[cfg(any(feature = "tree-sitter-legacy", test))]
50pub fn parse_legacy(source: &str) -> Result<flutmax_ast::Program, parse::ParseError> {
51    parse::parse(source)
52}
53
54/// Parse using the hand-written parser directly (returns parser-specific error).
55pub fn parse_new(source: &str) -> Result<flutmax_ast::Program, parser::ParseError> {
56    parser::FlutmaxParser::parse(source)
57}
58
59/// Parse with error recovery: returns a (possibly partial) AST and all errors.
60/// The parser skips to the next `;` on error and continues, collecting all diagnostics.
61pub fn parse_new_with_errors(
62    source: &str,
63) -> Result<(flutmax_ast::Program, Vec<parser::ParseError>), parser::ParseError> {
64    parser::FlutmaxParser::parse_with_errors(source)
65}