From 9a13848f8053fb98a039fb63a9015b0068d6a7d6 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sat, 20 Nov 2021 02:26:22 -0800 Subject: [PATCH] Parsing refactors --- schala-lang/src/parsing/combinator.rs | 20 +++++++------------- schala-lang/src/parsing/mod.rs | 20 +++++++++----------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/schala-lang/src/parsing/combinator.rs b/schala-lang/src/parsing/combinator.rs index fd2af06..740cdaf 100644 --- a/schala-lang/src/parsing/combinator.rs +++ b/schala-lang/src/parsing/combinator.rs @@ -18,8 +18,7 @@ use nom::{ use nom_locate::{position, LocatedSpan}; use crate::identifier::{Id, IdStore}; - -type StoreRef = Rc>>; +use crate::parsing::StoreRef; pub type Span<'a> = LocatedSpan<&'a str, StoreRef>; type ParseResult<'a, O> = IResult, O, VerboseError>>; @@ -66,11 +65,6 @@ fn fresh_id(span: &Span) -> Id { table_handle.fresh() } -fn fresh_id_rc(store_ref: &StoreRef) -> Id { - let mut table_handle = store_ref.borrow_mut(); - table_handle.fresh() -} - fn tok<'a, O>( input_parser: impl Parser, O, VerboseError>>, ) -> impl FnMut(Span<'a>) -> IResult, O, VerboseError>> { @@ -129,17 +123,16 @@ fn statement_delimiter(input: Span) -> ParseResult<()> { pub fn program(input: Span) -> ParseResult { let id = fresh_id(&input); - //TODO `rest` should be empty let (rest, statements) = context( "AST", terminated( map( - tuple(( + delimited( many0(statement_delimiter), separated_list0(many1(statement_delimiter), statement), many0(statement_delimiter), - )), - |(_, items, _)| items.into(), + ), + |items| items.into(), ), tok(eof), ), @@ -470,12 +463,12 @@ fn prefix_op(input: Span) -> ParseResult { fn prefix_expr(allow_struct: bool) -> impl FnMut(Span) -> ParseResult { move |input: Span| { - let handle = input.extra.clone(); + let id = fresh_id(&input); context( "prefix-expr", map(pair(opt(prefix_op), extended_expr(allow_struct)), move |(prefix, expr)| { if let Some(prefix) = prefix { - let expr = Expression::new(fresh_id_rc(&handle), expr); + let expr = Expression::new(id, expr); ExpressionKind::PrefixExp(prefix, Box::new(expr)) } else { expr @@ -968,6 +961,7 @@ impl BinopSequence { #[cfg(test)] mod test { use pretty_assertions::assert_eq; + use super::*; macro_rules! span { diff --git a/schala-lang/src/parsing/mod.rs b/schala-lang/src/parsing/mod.rs index 5a2509f..93baa3f 100644 --- a/schala-lang/src/parsing/mod.rs +++ b/schala-lang/src/parsing/mod.rs @@ -15,13 +15,15 @@ use crate::{ identifier::{Id, IdStore}, }; +pub(crate) type StoreRef = Rc>>; pub struct Parser { - id_store: IdStore, + id_store: StoreRef, } impl Parser { pub(crate) fn new() -> Self { - Self { id_store: IdStore::new() } + let id_store: IdStore = IdStore::new(); + Self { id_store: Rc::new(RefCell::new(id_store)) } } pub(crate) fn parse(&mut self, input: &str) -> Result { @@ -29,14 +31,13 @@ impl Parser { } pub(crate) fn parse_comb(&mut self, input: &str) -> Result { - let id_store: IdStore = IdStore::new(); - let span = Span::new_extra(input, Rc::new(RefCell::new(id_store))); + let span = Span::new_extra(input, self.id_store.clone()); let (rest, output) = combinator::program(span).map_err(|err| convert_err(input, err))?; if rest.fragment() != &"" { return Err(ParseError { location: Default::default(), - msg: format!("BAD STATE remaining string: `{}`", rest.fragment()), + msg: format!("Bad parse state, remaining text: `{}`", rest.fragment()), }); } @@ -50,9 +51,7 @@ impl Parser { #[cfg(test)] fn expression_comb(&mut self, input: &str) -> Result { - let id_store: IdStore = IdStore::new(); - let span = Span::new_extra(input, Rc::new(RefCell::new(id_store))); - + let span = Span::new_extra(input, self.id_store.clone()); combinator::expression(span).map_err(|err| convert_err(input, err)).map(|(rest, output)| output) } @@ -63,13 +62,12 @@ impl Parser { #[cfg(test)] fn block_comb(&mut self, input: &str) -> Result { - let id_store: IdStore = IdStore::new(); - let span = Span::new_extra(input, Rc::new(RefCell::new(id_store))); + let span = Span::new_extra(input, self.id_store.clone()); combinator::block(span).map_err(|err| convert_err(input, err)).map(|(_, output)| output) } fn fresh(&mut self) -> Id { - self.id_store.fresh() + self.id_store.borrow_mut().fresh() } }