Box pub parsers and adjust visibility
This commit is contained in:
parent
408219073a
commit
9c8d09e3cb
9 changed files with 63 additions and 47 deletions
|
|
@ -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
|
// TODO Turn multiple calls to subparsers into clone-s
|
||||||
|
|
||||||
mod basic;
|
mod basic;
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,17 @@ pub type Error = Simple<char, Span>;
|
||||||
|
|
||||||
// TODO https://github.com/rust-lang/rust/issues/63063
|
// TODO https://github.com/rust-lang/rust/issues/63063
|
||||||
|
|
||||||
pub fn inline() -> impl Parser<char, (), Error = Error> + Clone {
|
fn inline() -> impl Parser<char, (), Error = Error> + Clone {
|
||||||
filter(|c: &char| c.is_whitespace() && *c != '\n')
|
filter(|c: &char| c.is_whitespace() && *c != '\n')
|
||||||
.repeated()
|
.repeated()
|
||||||
.to(())
|
.to(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newline() -> impl Parser<char, (), Error = Error> + Clone {
|
fn newline() -> impl Parser<char, (), Error = Error> + Clone {
|
||||||
just('\n').to(())
|
just('\n').to(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line() -> impl Parser<char, Line, Error = Error> + Clone {
|
fn line() -> impl Parser<char, Line, Error = Error> + Clone {
|
||||||
let empty = newline().to(Line::Empty);
|
let empty = newline().to(Line::Empty);
|
||||||
|
|
||||||
let comment = just('#')
|
let comment = just('#')
|
||||||
|
|
@ -32,16 +32,18 @@ pub fn line() -> impl Parser<char, Line, Error = Error> + Clone {
|
||||||
empty.or(comment)
|
empty.or(comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn space() -> impl Parser<char, Space, Error = Error> + Clone {
|
pub fn space() -> BoxedParser<'static, char, Space, Error> {
|
||||||
inline()
|
inline()
|
||||||
.ignore_then(line())
|
.ignore_then(line())
|
||||||
.repeated()
|
.repeated()
|
||||||
.then_ignore(inline())
|
.then_ignore(inline())
|
||||||
.map_with_span(|lines, span| Space { lines, span })
|
.map_with_span(|lines, span| Space { lines, span })
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident() -> impl Parser<char, Ident, Error = Error> + Clone {
|
pub fn ident() -> BoxedParser<'static, char, Ident, Error> {
|
||||||
text::ident().try_map(|name, span| {
|
text::ident()
|
||||||
|
.try_map(|name, span| {
|
||||||
if matches!(
|
if matches!(
|
||||||
&name as &str,
|
&name as &str,
|
||||||
"nil" | "true" | "false" | "local" | "not" | "and" | "or"
|
"nil" | "true" | "false" | "local" | "not" | "and" | "or"
|
||||||
|
|
@ -51,4 +53,5 @@ pub fn ident() -> impl Parser<char, Ident, Error = Error> + Clone {
|
||||||
Ok(Ident { name, span })
|
Ok(Ident { name, span })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ fn atom_paren(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atom(
|
fn atom(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
||||||
let lit = lit(expr.clone()).map(Expr::Lit);
|
let lit = lit(expr.clone()).map(Expr::Lit);
|
||||||
let var = var(expr.clone()).map(Expr::Var);
|
let var = var(expr.clone()).map(Expr::Var);
|
||||||
|
|
@ -43,9 +43,9 @@ fn atom(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn left_assoc(
|
fn left_assoc(
|
||||||
op: impl Parser<char, BinOp, Error = Error> + Clone,
|
op: impl Parser<char, BinOp, Error = Error> + Clone + 'static,
|
||||||
over: impl Parser<char, Expr, Error = Error> + Clone,
|
over: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, Expr, Error> {
|
||||||
let op_over = space()
|
let op_over = space()
|
||||||
.then(op)
|
.then(op)
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -61,11 +61,12 @@ fn left_assoc(
|
||||||
s1,
|
s1,
|
||||||
right: Box::new(right),
|
right: Box::new(right),
|
||||||
})
|
})
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr(
|
pub fn expr(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Expr, Error = Error> {
|
) -> BoxedParser<'static, char, Expr, Error> {
|
||||||
// * / %
|
// * / %
|
||||||
let prec0 = (just('*').to(BinOp::Mul))
|
let prec0 = (just('*').to(BinOp::Mul))
|
||||||
.or(just('/').to(BinOp::Div))
|
.or(just('/').to(BinOp::Div))
|
||||||
|
|
|
||||||
|
|
@ -71,21 +71,21 @@ fn num_lit_str_radix(radix: u32) -> impl Parser<char, (i64, NumLitStr), Error =
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_lit() -> impl Parser<char, NumLit, Error = Error> + Clone {
|
fn num_lit() -> impl Parser<char, NumLit, Error = Error> + Clone {
|
||||||
(just("0b").ignore_then(num_lit_str_radix(2)))
|
(just("0b").ignore_then(num_lit_str_radix(2)))
|
||||||
.or(just("0x").ignore_then(num_lit_str_radix(16)))
|
.or(just("0x").ignore_then(num_lit_str_radix(16)))
|
||||||
.or(num_lit_str_radix(10))
|
.or(num_lit_str_radix(10))
|
||||||
.map_with_span(|(value, str), span| NumLit { value, str, span })
|
.map_with_span(|(value, str), span| NumLit { value, str, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string_lit() -> impl Parser<char, StringLit, Error = Error> + Clone {
|
fn string_lit() -> impl Parser<char, StringLit, Error = Error> + Clone {
|
||||||
// TODO Parse string literals
|
// TODO Parse string literals
|
||||||
filter(|_| false).map(|_| unreachable!())
|
filter(|_| false).map(|_| unreachable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_lit_elem(
|
pub fn table_lit_elem(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, TableLitElem, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, TableLitElem, Error> {
|
||||||
let positional = expr
|
let positional = expr
|
||||||
.clone()
|
.clone()
|
||||||
.map(|value| TableLitElem::Positional(Box::new(value)));
|
.map(|value| TableLitElem::Positional(Box::new(value)));
|
||||||
|
|
@ -103,11 +103,11 @@ pub fn table_lit_elem(
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
|
|
||||||
named.or(positional)
|
named.or(positional).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_lit(
|
fn table_lit(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, TableLit, Error = Error> + Clone {
|
) -> impl Parser<char, TableLit, Error = Error> + Clone {
|
||||||
let elem = space()
|
let elem = space()
|
||||||
.then(table_lit_elem(expr))
|
.then(table_lit_elem(expr))
|
||||||
|
|
@ -129,8 +129,8 @@ pub fn table_lit(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lit(
|
pub fn lit(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Lit, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, Lit, Error> {
|
||||||
let nil = text::keyword("nil").map_with_span(|_, span| Lit::Nil(span));
|
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#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));
|
let r#false = text::keyword("false").map_with_span(|_, span| Lit::Bool(false, span));
|
||||||
|
|
@ -145,4 +145,5 @@ pub fn lit(
|
||||||
.or(num)
|
.or(num)
|
||||||
.or(string)
|
.or(string)
|
||||||
.or(table)
|
.or(table)
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ fn prefix_not() -> impl Parser<char, Prefix, Error = Error> + Clone {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prefixed(
|
pub fn prefixed(
|
||||||
suffixed: impl Parser<char, Expr, Error = Error> + Clone,
|
suffixed: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, Expr, Error> {
|
||||||
let prefix = prefix_neg()
|
let prefix = prefix_neg()
|
||||||
.or(prefix_not())
|
.or(prefix_not())
|
||||||
.map_with_span(|prefix, span| (prefix, span));
|
.map_with_span(|prefix, span| (prefix, span));
|
||||||
|
|
@ -60,4 +60,5 @@ pub fn prefixed(
|
||||||
.repeated()
|
.repeated()
|
||||||
.then(suffixed)
|
.then(suffixed)
|
||||||
.foldr(|(prefix, span), expr| prefix.into_expr(expr.span().join(span), expr))
|
.foldr(|(prefix, span), expr| prefix.into_expr(expr.span().join(span), expr))
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ fn suffix_call_no_arg() -> impl Parser<char, Suffix, Error = Error> + Clone {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suffix_call_constr(
|
fn suffix_call_constr(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Suffix, Error = Error> + Clone {
|
) -> impl Parser<char, Suffix, Error = Error> + Clone {
|
||||||
space()
|
space()
|
||||||
.then(table_constr(expr))
|
.then(table_constr(expr))
|
||||||
|
|
@ -238,9 +238,9 @@ fn suffix_field_assign_ident(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suffixed(
|
pub fn suffixed(
|
||||||
atom: impl Parser<char, Expr, Error = Error> + Clone,
|
atom: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, Expr, Error> {
|
||||||
let call_arg = suffix_call_arg(expr.clone());
|
let call_arg = suffix_call_arg(expr.clone());
|
||||||
let call_no_arg = suffix_call_no_arg();
|
let call_no_arg = suffix_call_no_arg();
|
||||||
let call_constr = suffix_call_constr(expr.clone());
|
let call_constr = suffix_call_constr(expr.clone());
|
||||||
|
|
@ -260,4 +260,5 @@ pub fn suffixed(
|
||||||
|
|
||||||
atom.then(suffix.repeated())
|
atom.then(suffix.repeated())
|
||||||
.foldl(|expr, (suffix, span)| suffix.into_expr(expr.span().join(span), expr))
|
.foldl(|expr, (suffix, span)| suffix.into_expr(expr.span().join(span), expr))
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ use crate::ast::{Expr, TableConstr, TableConstrElem};
|
||||||
use super::basic::{space, Error};
|
use super::basic::{space, Error};
|
||||||
use super::lit::table_lit_elem;
|
use super::lit::table_lit_elem;
|
||||||
|
|
||||||
pub fn table_constr_elem(
|
fn table_constr_elem(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, TableConstrElem, Error = Error> + Clone {
|
) -> impl Parser<char, TableConstrElem, Error = Error> + Clone {
|
||||||
let lit = table_lit_elem(expr.clone()).map(TableConstrElem::Lit);
|
let lit = table_lit_elem(expr.clone()).map(TableConstrElem::Lit);
|
||||||
|
|
||||||
|
|
@ -37,8 +37,8 @@ pub fn table_constr_elem(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_constr(
|
pub fn table_constr(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, TableConstr, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, TableConstr, Error> {
|
||||||
let elem = space()
|
let elem = space()
|
||||||
.then(table_constr_elem(expr))
|
.then(table_constr_elem(expr))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -56,4 +56,5 @@ pub fn table_constr(
|
||||||
trailing_comma,
|
trailing_comma,
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::ast::{Expr, TableDestr, TablePattern, TablePatternElem};
|
||||||
|
|
||||||
use super::basic::{ident, space, Error};
|
use super::basic::{ident, space, Error};
|
||||||
|
|
||||||
pub fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error> + Clone {
|
fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error> + Clone {
|
||||||
let positional = ident().map(TablePatternElem::Positional);
|
let positional = ident().map(TablePatternElem::Positional);
|
||||||
|
|
||||||
let named = ident()
|
let named = ident()
|
||||||
|
|
@ -25,7 +25,7 @@ pub fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error
|
||||||
named.or(positional)
|
named.or(positional)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> + Clone {
|
fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> + Clone {
|
||||||
let elem = space()
|
let elem = space()
|
||||||
.then(table_pattern_elem())
|
.then(table_pattern_elem())
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -46,8 +46,8 @@ pub fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> + Clone
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_destr(
|
pub fn table_destr(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, TableDestr, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, TableDestr, Error> {
|
||||||
let local = text::keyword("local").ignore_then(space()).or_not();
|
let local = text::keyword("local").ignore_then(space()).or_not();
|
||||||
|
|
||||||
local
|
local
|
||||||
|
|
@ -64,4 +64,5 @@ pub fn table_destr(
|
||||||
value: Box::new(value),
|
value: Box::new(value),
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,12 +75,12 @@ fn var_assign_ident(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var(
|
pub fn var(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||||
) -> impl Parser<char, Var, Error = Error> + Clone {
|
) -> BoxedParser<'static, char, Var, Error> {
|
||||||
let access = var_access(expr.clone());
|
let access = var_access(expr.clone());
|
||||||
let assign = var_assign(expr.clone());
|
let assign = var_assign(expr.clone());
|
||||||
let access_ident = ident().map(Var::AccessIdent);
|
let access_ident = ident().map(Var::AccessIdent);
|
||||||
let assign_ident = var_assign_ident(expr);
|
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()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue