#![allow(clippy::upper_case_acronyms)] mod peg_parser; mod test; use std::fmt; #[cfg(test)] use crate::ast::{Block, Expression}; use crate::{ ast::{ASTItem, AST}, identifier::{Id, IdStore}, }; pub struct Parser { id_store: IdStore, } impl Parser { pub(crate) fn new() -> Self { Self { id_store: IdStore::new() } } pub(crate) fn parse(&mut self, input: &str) -> Result { peg_parser::schala_parser::program(input, self).map_err(ParseError::from_peg) } #[cfg(test)] fn expression(&mut self, input: &str) -> Result { peg_parser::schala_parser::expression(input, self).map_err(ParseError::from_peg) } #[cfg(test)] fn block(&mut self, input: &str) -> Result { peg_parser::schala_parser::block(input, self).map_err(ParseError::from_peg) } fn fresh(&mut self) -> Id { self.id_store.fresh() } } /// Represents a parsing error #[derive(Debug)] pub struct ParseError { pub msg: String, pub location: Location, } impl ParseError { fn from_peg(err: peg::error::ParseError) -> Self { let msg = err.to_string(); Self { msg, location: err.location.offset.into() } } } #[derive(Debug, Clone, Copy, PartialEq, Default)] pub struct Location { pub(crate) offset: usize, } impl From for Location { fn from(offset: usize) -> Self { Self { offset } } } impl fmt::Display for Location { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.offset) } }