use crate::parser::lexer::tokenize;
use crate::parser::core::driver::{parse_tokens, ParseError};
use crate::parser::ast::Stmt;
pub enum ParseResult {
Incomplete,
Error(String),
Success(Vec<Stmt>),
}
pub fn attempt_parse(source: &str, verbose: bool) -> Result<ParseResult, String> {
if verbose {
eprintln!("[attempt_parse] => starting. source.len()={}", source.len());
}
let tokens = match tokenize(source, verbose) {
Ok(t) => t,
Err(lex_err) => {
let msg = lex_err.message.to_lowercase();
if msg.contains("unclosed") || msg.contains("unterminated") {
if verbose {
eprintln!("[attempt_parse] => lex error => incomplete: {}", lex_err.message);
}
return Ok(ParseResult::Incomplete);
}
if verbose {
eprintln!("[attempt_parse] => lex error => {}", lex_err.message);
}
return Err(lex_err.message);
}
};
if verbose {
eprintln!("[attempt_parse] => tokens => {:?}", tokens);
}
match parse_tokens(&tokens, verbose) {
Ok(stmts) => {
if stmts.is_empty() && !source.trim().is_empty() {
if verbose {
eprintln!("[attempt_parse] => stmts.is_empty => Incomplete");
}
Ok(ParseResult::Incomplete)
} else {
if verbose {
eprintln!("[attempt_parse] => parse success => got {} stmts", stmts.len());
}
Ok(ParseResult::Success(stmts))
}
}
Err(ParseError { msg, .. }) => {
let lower = msg.to_lowercase();
if lower.contains("eof") || lower.contains("unexpected end of input") || lower.contains("unclosed") {
if verbose {
eprintln!("[attempt_parse] => parse error => incomplete: {}", msg);
}
Ok(ParseResult::Incomplete)
} else {
if verbose {
eprintln!("[attempt_parse] => parse error => {}", msg);
}
Ok(ParseResult::Error(msg))
}
}
}
}