From 9c8d09e3cb907c765307e8ac3658e4be6d1eb3c4 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 19 Nov 2022 13:00:43 +0100 Subject: [PATCH] Box pub parsers and adjust visibility --- src/parser.rs | 7 +++++++ src/parser/basic.rs | 33 ++++++++++++++++++--------------- src/parser/expr.rs | 13 +++++++------ src/parser/lit.rs | 19 ++++++++++--------- src/parser/prefix.rs | 5 +++-- src/parser/suffix.rs | 9 +++++---- src/parser/table_constr.rs | 9 +++++---- src/parser/table_destr.rs | 9 +++++---- src/parser/var.rs | 6 +++--- 9 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 69b147e..f7390e3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,3 +1,10 @@ +//! Parse the ast over at [`crate::ast`]. +//! +//! Rules of thumb: +//! - Everything `pub` should return a [`BoxedParser`]. +//! - Everything not used outside a module should not be `pub`. It can always be +//! made public later. + // TODO Turn multiple calls to subparsers into clone-s mod basic; diff --git a/src/parser/basic.rs b/src/parser/basic.rs index 3d3fa24..570cc83 100644 --- a/src/parser/basic.rs +++ b/src/parser/basic.rs @@ -10,17 +10,17 @@ pub type Error = Simple; // TODO https://github.com/rust-lang/rust/issues/63063 -pub fn inline() -> impl Parser + Clone { +fn inline() -> impl Parser + Clone { filter(|c: &char| c.is_whitespace() && *c != '\n') .repeated() .to(()) } -pub fn newline() -> impl Parser + Clone { +fn newline() -> impl Parser + Clone { just('\n').to(()) } -pub fn line() -> impl Parser + Clone { +fn line() -> impl Parser + Clone { let empty = newline().to(Line::Empty); let comment = just('#') @@ -32,23 +32,26 @@ pub fn line() -> impl Parser + Clone { empty.or(comment) } -pub fn space() -> impl Parser + Clone { +pub fn space() -> BoxedParser<'static, char, Space, Error> { inline() .ignore_then(line()) .repeated() .then_ignore(inline()) .map_with_span(|lines, span| Space { lines, span }) + .boxed() } -pub fn ident() -> impl Parser + Clone { - text::ident().try_map(|name, span| { - if matches!( - &name as &str, - "nil" | "true" | "false" | "local" | "not" | "and" | "or" - ) { - Err(Simple::custom(span, "identifier uses reserved name")) - } else { - Ok(Ident { name, span }) - } - }) +pub fn ident() -> BoxedParser<'static, char, Ident, Error> { + text::ident() + .try_map(|name, span| { + if matches!( + &name as &str, + "nil" | "true" | "false" | "local" | "not" | "and" | "or" + ) { + Err(Simple::custom(span, "identifier uses reserved name")) + } else { + Ok(Ident { name, span }) + } + }) + .boxed() } diff --git a/src/parser/expr.rs b/src/parser/expr.rs index 4d012ff..6ff80c6 100644 --- a/src/parser/expr.rs +++ b/src/parser/expr.rs @@ -30,7 +30,7 @@ fn atom_paren( } fn atom( - expr: impl Parser + Clone, + expr: impl Parser + Clone + 'static, ) -> impl Parser + Clone { let lit = lit(expr.clone()).map(Expr::Lit); let var = var(expr.clone()).map(Expr::Var); @@ -43,9 +43,9 @@ fn atom( } fn left_assoc( - op: impl Parser + Clone, - over: impl Parser + Clone, -) -> impl Parser + Clone { + op: impl Parser + Clone + 'static, + over: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, Expr, Error> { let op_over = space() .then(op) .then(space()) @@ -61,11 +61,12 @@ fn left_assoc( s1, right: Box::new(right), }) + .boxed() } pub fn expr( - expr: impl Parser + Clone, -) -> impl Parser { + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, Expr, Error> { // * / % let prec0 = (just('*').to(BinOp::Mul)) .or(just('/').to(BinOp::Div)) diff --git a/src/parser/lit.rs b/src/parser/lit.rs index cf0f2bb..0c56991 100644 --- a/src/parser/lit.rs +++ b/src/parser/lit.rs @@ -71,21 +71,21 @@ fn num_lit_str_radix(radix: u32) -> impl Parser impl Parser + Clone { +fn num_lit() -> impl Parser + Clone { (just("0b").ignore_then(num_lit_str_radix(2))) .or(just("0x").ignore_then(num_lit_str_radix(16))) .or(num_lit_str_radix(10)) .map_with_span(|(value, str), span| NumLit { value, str, span }) } -pub fn string_lit() -> impl Parser + Clone { +fn string_lit() -> impl Parser + Clone { // TODO Parse string literals filter(|_| false).map(|_| unreachable!()) } pub fn table_lit_elem( - expr: impl Parser + Clone, -) -> impl Parser + Clone { + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, TableLitElem, Error> { let positional = expr .clone() .map(|value| TableLitElem::Positional(Box::new(value))); @@ -103,11 +103,11 @@ pub fn table_lit_elem( span, }); - named.or(positional) + named.or(positional).boxed() } -pub fn table_lit( - expr: impl Parser + Clone, +fn table_lit( + expr: impl Parser + Clone + 'static, ) -> impl Parser + Clone { let elem = space() .then(table_lit_elem(expr)) @@ -129,8 +129,8 @@ pub fn table_lit( } pub fn lit( - expr: impl Parser + Clone, -) -> impl Parser + Clone { + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, Lit, Error> { let nil = text::keyword("nil").map_with_span(|_, span| Lit::Nil(span)); let r#true = text::keyword("true").map_with_span(|_, span| Lit::Bool(true, span)); let r#false = text::keyword("false").map_with_span(|_, span| Lit::Bool(false, span)); @@ -145,4 +145,5 @@ pub fn lit( .or(num) .or(string) .or(table) + .boxed() } diff --git a/src/parser/prefix.rs b/src/parser/prefix.rs index d99f1db..b11428a 100644 --- a/src/parser/prefix.rs +++ b/src/parser/prefix.rs @@ -50,8 +50,8 @@ fn prefix_not() -> impl Parser + Clone { } pub fn prefixed( - suffixed: impl Parser + Clone, -) -> impl Parser + Clone { + suffixed: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, Expr, Error> { let prefix = prefix_neg() .or(prefix_not()) .map_with_span(|prefix, span| (prefix, span)); @@ -60,4 +60,5 @@ pub fn prefixed( .repeated() .then(suffixed) .foldr(|(prefix, span), expr| prefix.into_expr(expr.span().join(span), expr)) + .boxed() } diff --git a/src/parser/suffix.rs b/src/parser/suffix.rs index 64666f3..aea85b9 100644 --- a/src/parser/suffix.rs +++ b/src/parser/suffix.rs @@ -156,7 +156,7 @@ fn suffix_call_no_arg() -> impl Parser + Clone { } fn suffix_call_constr( - expr: impl Parser + Clone, + expr: impl Parser + Clone + 'static, ) -> impl Parser + Clone { space() .then(table_constr(expr)) @@ -238,9 +238,9 @@ fn suffix_field_assign_ident( } pub fn suffixed( - atom: impl Parser + Clone, - expr: impl Parser + Clone, -) -> impl Parser + Clone { + atom: impl Parser + Clone + 'static, + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, Expr, Error> { let call_arg = suffix_call_arg(expr.clone()); let call_no_arg = suffix_call_no_arg(); let call_constr = suffix_call_constr(expr.clone()); @@ -260,4 +260,5 @@ pub fn suffixed( atom.then(suffix.repeated()) .foldl(|expr, (suffix, span)| suffix.into_expr(expr.span().join(span), expr)) + .boxed() } diff --git a/src/parser/table_constr.rs b/src/parser/table_constr.rs index 190cd37..1ab6c71 100644 --- a/src/parser/table_constr.rs +++ b/src/parser/table_constr.rs @@ -7,8 +7,8 @@ use crate::ast::{Expr, TableConstr, TableConstrElem}; use super::basic::{space, Error}; use super::lit::table_lit_elem; -pub fn table_constr_elem( - expr: impl Parser + Clone, +fn table_constr_elem( + expr: impl Parser + Clone + 'static, ) -> impl Parser + Clone { let lit = table_lit_elem(expr.clone()).map(TableConstrElem::Lit); @@ -37,8 +37,8 @@ pub fn table_constr_elem( } pub fn table_constr( - expr: impl Parser + Clone, -) -> impl Parser + Clone { + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, TableConstr, Error> { let elem = space() .then(table_constr_elem(expr)) .then(space()) @@ -56,4 +56,5 @@ pub fn table_constr( trailing_comma, span, }) + .boxed() } diff --git a/src/parser/table_destr.rs b/src/parser/table_destr.rs index 9803715..8490962 100644 --- a/src/parser/table_destr.rs +++ b/src/parser/table_destr.rs @@ -6,7 +6,7 @@ use crate::ast::{Expr, TableDestr, TablePattern, TablePatternElem}; use super::basic::{ident, space, Error}; -pub fn table_pattern_elem() -> impl Parser + Clone { +fn table_pattern_elem() -> impl Parser + Clone { let positional = ident().map(TablePatternElem::Positional); let named = ident() @@ -25,7 +25,7 @@ pub fn table_pattern_elem() -> impl Parser impl Parser + Clone { +fn table_pattern() -> impl Parser + Clone { let elem = space() .then(table_pattern_elem()) .then(space()) @@ -46,8 +46,8 @@ pub fn table_pattern() -> impl Parser + Clone } pub fn table_destr( - expr: impl Parser + Clone, -) -> impl Parser + Clone { + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, TableDestr, Error> { let local = text::keyword("local").ignore_then(space()).or_not(); local @@ -64,4 +64,5 @@ pub fn table_destr( value: Box::new(value), span, }) + .boxed() } diff --git a/src/parser/var.rs b/src/parser/var.rs index 8d3fd38..6f4fc62 100644 --- a/src/parser/var.rs +++ b/src/parser/var.rs @@ -75,12 +75,12 @@ fn var_assign_ident( } pub fn var( - expr: impl Parser + Clone, -) -> impl Parser + Clone { + expr: impl Parser + Clone + 'static, +) -> BoxedParser<'static, char, Var, Error> { let access = var_access(expr.clone()); let assign = var_assign(expr.clone()); let access_ident = ident().map(Var::AccessIdent); let assign_ident = var_assign_ident(expr); - assign.or(access).or(assign_ident).or(access_ident) + assign.or(access).or(assign_ident).or(access_ident).boxed() }