use crate::ast::{Expr, Stmt, Type};
use crate::ParseError;
use crate::Token;
pub type ParseResult<T> = Result<T, ParseError>;
pub trait ParserCapability {
fn parse_program(&mut self) -> ParseResult<crate::ast::Program>;
fn parse_statement(&mut self) -> ParseResult<Option<Stmt>>;
fn parse_expression(&mut self) -> ParseResult<Option<Expr>>;
fn parse_type(&mut self) -> ParseResult<Type>;
fn errors(&self) -> Vec<ParseError>;
fn has_errors(&self) -> bool;
}
pub trait DeclarationParser {
fn parse_var_decl(&mut self) -> ParseResult<Vec<crate::ast::VariableDecl>>;
fn parse_const_decl(&mut self) -> ParseResult<Vec<crate::ast::ConstDecl>>;
fn parse_type_decl(&mut self) -> ParseResult<Vec<crate::ast::TypeDecl>>;
fn parse_function_decl(&mut self) -> ParseResult<crate::ast::FunctionDecl>;
fn parse_procedure_decl(&mut self) -> ParseResult<crate::ast::ProcedureDecl>;
}
pub trait StatementParser {
fn parse_if_statement(&mut self) -> ParseResult<Stmt>;
fn parse_while_loop(&mut self) -> ParseResult<Stmt>;
fn parse_for_loop(&mut self) -> ParseResult<Stmt>;
fn parse_repeat_loop(&mut self) -> ParseResult<Stmt>;
fn parse_assignment(&mut self, target: String) -> ParseResult<Stmt>;
fn parse_procedure_call(&mut self, name: String) -> ParseResult<Stmt>;
fn parse_compound_statement(&mut self) -> ParseResult<Vec<Stmt>>;
}
pub trait ExpressionParser {
fn parse_binary_op(&mut self, precedence: u8) -> ParseResult<Option<Expr>>;
fn parse_unary_op(&mut self) -> ParseResult<Option<Expr>>;
fn parse_primary(&mut self) -> ParseResult<Option<Expr>>;
fn parse_function_call(&mut self, name: String) -> ParseResult<Expr>;
fn parse_argument_list(&mut self) -> ParseResult<Vec<Expr>>;
}
pub trait ErrorRecovery {
fn synchronize(&mut self, sync_tokens: &[Token]);
fn consume_or_skip(&mut self, expected: Token, sync_tokens: &[Token]);
fn enter_recovery_mode(&mut self);
fn exit_recovery_mode(&mut self);
fn in_recovery_mode(&self) -> bool;
}