Switch TableLit and Program to BoundedSeparated
This commit is contained in:
parent
a1867fdc4e
commit
e3fa3500d4
18 changed files with 146 additions and 129 deletions
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
|||
use crate::builtin::Builtin;
|
||||
use crate::span::{HasSpan, Span};
|
||||
|
||||
use super::{Expr, Ident, Separated, Space};
|
||||
use super::{BoundedSeparated, Expr, Ident, Space};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum NumLitStr {
|
||||
|
|
@ -129,16 +129,11 @@ impl HasSpan for TableLitElem {
|
|||
///
|
||||
/// Structure: `'{ s0 elems s1 }`
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TableLit {
|
||||
pub s0: Space,
|
||||
pub elems: Separated<TableLitElem, (Space, Space), Space>,
|
||||
pub s1: Space,
|
||||
pub span: Span,
|
||||
}
|
||||
pub struct TableLit(pub BoundedSeparated<TableLitElem>);
|
||||
|
||||
impl HasSpan for TableLit {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
self.0.span()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::span::{HasSpan, Span};
|
||||
|
||||
use super::{Expr, Separated, Space, TableLitElem};
|
||||
use super::{BoundedSeparated, Expr, Space, TableLitElem};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Program {
|
||||
|
|
@ -12,12 +12,10 @@ pub enum Program {
|
|||
span: Span,
|
||||
},
|
||||
|
||||
/// Structure: `s0 module s1 elems s2`
|
||||
/// Structure: `s0 module elems`
|
||||
Module {
|
||||
s0: Space,
|
||||
s1: Space,
|
||||
elems: Separated<TableLitElem, (Space, Space), Space>,
|
||||
s2: Space,
|
||||
elems: BoundedSeparated<TableLitElem>,
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::ast::Separated;
|
||||
use crate::ast::{BoundedSeparated, Separated};
|
||||
|
||||
impl<E, S1, S2> Separated<E, S1, S2> {
|
||||
pub fn desugar_elem(self, desugar_elem: impl Fn(E) -> (E, bool)) -> (Self, bool) {
|
||||
|
|
@ -34,3 +34,26 @@ impl<E, S1, S2> Separated<E, S1, S2> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> BoundedSeparated<E> {
|
||||
pub fn desugar(self, desugar_elem: impl Fn(E) -> (E, bool)) -> (Self, bool) {
|
||||
let mut desugared = false;
|
||||
let mut elems = vec![];
|
||||
for (s0, elem, s1) in self.elems {
|
||||
if desugared {
|
||||
elems.push((s0, elem, s1));
|
||||
} else {
|
||||
let (elem, elem_desugared) = desugar_elem(elem);
|
||||
desugared = desugared || elem_desugared;
|
||||
elems.push((s0, elem, s1));
|
||||
}
|
||||
}
|
||||
|
||||
let new = Self {
|
||||
elems,
|
||||
trailing: self.trailing,
|
||||
span: self.span,
|
||||
};
|
||||
(new, desugared)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::ast::{Call, Expr, Ident, Lit, Separated, Space, TableLit, TableLitElem};
|
||||
use crate::ast::{BoundedSeparated, Call, Expr, Ident, Lit, Space, TableLit, TableLitElem};
|
||||
|
||||
// TODO Add span for just the parentheses to ast, or limit span to parentheses
|
||||
|
||||
|
|
@ -29,18 +29,15 @@ impl Call {
|
|||
value: arg,
|
||||
span,
|
||||
};
|
||||
let elems = Separated::NonEmpty {
|
||||
first_elem: call,
|
||||
last_elems: vec![((Space::empty(span), Space::empty(span)), arg)],
|
||||
let elems = vec![
|
||||
(s0, call, Space::empty(span)),
|
||||
(Space::empty(span), arg, s2),
|
||||
];
|
||||
let new = Expr::Lit(Lit::Table(TableLit(BoundedSeparated {
|
||||
elems,
|
||||
trailing: None,
|
||||
span,
|
||||
};
|
||||
let new = Expr::Lit(Lit::Table(TableLit {
|
||||
s0,
|
||||
elems,
|
||||
s1: s2,
|
||||
span,
|
||||
}));
|
||||
})));
|
||||
(new, true)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,21 +31,8 @@ impl TableLitElem {
|
|||
|
||||
impl TableLit {
|
||||
pub fn desugar(self) -> (Self, bool) {
|
||||
let Self {
|
||||
s0,
|
||||
elems,
|
||||
s1,
|
||||
span,
|
||||
} = self;
|
||||
|
||||
let (elems, desugared) = elems.desugar_elem(|e| e.desugar());
|
||||
let new = Self {
|
||||
s0,
|
||||
elems,
|
||||
s1,
|
||||
span,
|
||||
};
|
||||
(new, desugared)
|
||||
let (elems, desugared) = self.0.desugar(|e| e.desugar());
|
||||
(Self(elems), desugared)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,24 +9,12 @@ impl Program {
|
|||
(new, desugared)
|
||||
}
|
||||
|
||||
Self::Module {
|
||||
s0,
|
||||
s1,
|
||||
elems,
|
||||
s2,
|
||||
span,
|
||||
} => {
|
||||
// `s0 module s1 elems s2`
|
||||
// -> `s0 '{ s1 elems s2 } empty`
|
||||
let table = TableLit {
|
||||
s0: s1,
|
||||
elems,
|
||||
s1: s2,
|
||||
span,
|
||||
};
|
||||
Self::Module { s0, elems, span } => {
|
||||
// `s0 module elems`
|
||||
// -> `s0 table`
|
||||
let new = Self::Expr {
|
||||
s0,
|
||||
expr: Expr::Lit(Lit::Table(table)),
|
||||
expr: Expr::Lit(Lit::Table(TableLit(elems))),
|
||||
s1: Space::empty(span),
|
||||
span,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -83,11 +83,11 @@ pub fn separated_by<E: 'static, S1: 'static, S2: 'static>(
|
|||
.boxed()
|
||||
}
|
||||
|
||||
pub fn bounded_separated<E: 'static, R1, R2, R3>(
|
||||
pub fn bounded_separated<E: 'static>(
|
||||
space: impl Parser<char, Space, Error = Error> + Clone + 'static,
|
||||
start: impl Parser<char, R1, Error = Error> + 'static,
|
||||
end: impl Parser<char, R2, Error = Error> + 'static,
|
||||
separator: impl Parser<char, R3, Error = Error> + 'static,
|
||||
start: impl Parser<char, (), Error = Error> + 'static,
|
||||
end: impl Parser<char, (), Error = Error> + 'static,
|
||||
separator: impl Parser<char, (), Error = Error> + 'static,
|
||||
elem: impl Parser<char, E, Error = Error> + Clone + 'static,
|
||||
) -> EParser<BoundedSeparated<E>> {
|
||||
start
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::ast::{
|
|||
};
|
||||
use crate::builtin::Builtin;
|
||||
|
||||
use super::basic::{separated_by, EParser, Error};
|
||||
use super::basic::{bounded_separated, EParser, Error};
|
||||
|
||||
fn builtin_lit() -> impl Parser<char, Builtin, Error = Error> {
|
||||
just('\'').ignore_then(choice((
|
||||
|
|
@ -154,20 +154,14 @@ fn table_lit(
|
|||
space: EParser<Space>,
|
||||
table_lit_elem: EParser<TableLitElem>,
|
||||
) -> impl Parser<char, TableLit, Error = Error> {
|
||||
let separator = space.clone().then_ignore(just(',')).then(space.clone());
|
||||
let trailing_separator = space.clone().then_ignore(just(','));
|
||||
|
||||
space
|
||||
.clone()
|
||||
.then(separated_by(table_lit_elem, separator, trailing_separator))
|
||||
.then(space)
|
||||
.delimited_by(just("'{"), just('}'))
|
||||
.map_with_span(|((s0, elems), s1), span| TableLit {
|
||||
s0,
|
||||
elems,
|
||||
s1,
|
||||
span,
|
||||
})
|
||||
bounded_separated(
|
||||
space,
|
||||
just("'{").to(()),
|
||||
just('}').to(()),
|
||||
just(',').to(()),
|
||||
table_lit_elem,
|
||||
)
|
||||
.map(TableLit)
|
||||
}
|
||||
|
||||
pub fn lit(space: EParser<Space>, table_lit_elem: EParser<TableLitElem>) -> EParser<Lit> {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use chumsky::prelude::*;
|
|||
|
||||
use crate::ast::{Expr, Program, Space, TableLitElem};
|
||||
|
||||
use super::basic::{separated_by, EParser};
|
||||
use super::basic::{bounded_separated, EParser};
|
||||
|
||||
pub fn program(
|
||||
space: EParser<Space>,
|
||||
|
|
@ -17,21 +17,17 @@ pub fn program(
|
|||
.then(space.clone())
|
||||
.map_with_span(|((s0, expr), s1), span| Program::Expr { s0, expr, s1, span });
|
||||
|
||||
let separator = space.clone().then_ignore(just(',')).then(space.clone());
|
||||
let trailing_separator = space.clone().then_ignore(just(','));
|
||||
let module = space
|
||||
.clone()
|
||||
.then_ignore(text::keyword("module"))
|
||||
.then(space.clone())
|
||||
.then(separated_by(table_lit_elem, separator, trailing_separator))
|
||||
.then(space.clone())
|
||||
.map_with_span(|(((s0, s1), elems), s2), span| Program::Module {
|
||||
s0,
|
||||
s1,
|
||||
elems,
|
||||
s2,
|
||||
span,
|
||||
});
|
||||
.then(bounded_separated(
|
||||
space,
|
||||
empty(),
|
||||
empty(),
|
||||
just(',').to(()),
|
||||
table_lit_elem,
|
||||
))
|
||||
.map_with_span(|(s0, elems), span| Program::Module { s0, elems, span });
|
||||
|
||||
module.or(lit).boxed()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ use pretty::{DocAllocator, DocBuilder, Pretty};
|
|||
|
||||
use crate::ast::Call;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Call {
|
||||
impl<'a, D> Pretty<'a, D> for Call
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Arg {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for BinOp {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Expr {
|
||||
impl<'a, D> Pretty<'a, D> for Expr
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Lit(lit) => lit.pretty(allocator),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ use pretty::{DocAllocator, DocBuilder, Pretty};
|
|||
|
||||
use crate::ast::Field;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Field {
|
||||
impl<'a, D> Pretty<'a, D> for Field
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Access {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ use pretty::{DocAllocator, DocBuilder, Pretty};
|
|||
|
||||
use crate::ast::FuncDef;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for FuncDef {
|
||||
impl<'a, D> Pretty<'a, D> for FuncDef
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::AnonNoArg {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ use pretty::{DocAllocator, DocBuilder, Pretty};
|
|||
|
||||
use crate::ast::{Lit, NumLit, StringLit, StringLitElem, TableLit, TableLitElem};
|
||||
|
||||
use super::NEST_DEPTH;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for NumLit {
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
allocator.text(format!("{self:?}"))
|
||||
|
|
@ -32,7 +30,11 @@ impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for StringLit {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableLitElem {
|
||||
impl<'a, D> Pretty<'a, D> for TableLitElem
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Positional(expr) => expr.pretty(allocator),
|
||||
|
|
@ -50,23 +52,27 @@ impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableLitElem {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableLit {
|
||||
impl<'a, D> Pretty<'a, D> for TableLit
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
self.elems
|
||||
.pretty(
|
||||
allocator,
|
||||
|e| allocator.line().append(e.pretty(allocator)),
|
||||
|(s0, s1)| allocator.text(","),
|
||||
|s| allocator.text(","),
|
||||
)
|
||||
.nest(NEST_DEPTH)
|
||||
.append(allocator.line())
|
||||
.enclose(allocator.text("'{"), allocator.text("}"))
|
||||
.group()
|
||||
self.0.pretty(
|
||||
allocator,
|
||||
allocator.text("'{"),
|
||||
allocator.text("}"),
|
||||
allocator.text(","),
|
||||
|e| e.pretty(allocator),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Lit {
|
||||
impl<'a, D> Pretty<'a, D> for Lit
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Nil(_) => allocator.text("nil"),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ use pretty::{DocAllocator, DocBuilder, Pretty};
|
|||
|
||||
use crate::ast::Program;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Program {
|
||||
impl<'a, D> Pretty<'a, D> for Program
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Expr {
|
||||
|
|
@ -11,22 +15,19 @@ impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Program {
|
|||
s1,
|
||||
span: _,
|
||||
} => expr.pretty(allocator),
|
||||
Self::Module {
|
||||
s0,
|
||||
s1,
|
||||
elems,
|
||||
s2,
|
||||
span: _,
|
||||
} => allocator
|
||||
.text("module")
|
||||
.append(allocator.line())
|
||||
.append(allocator.line())
|
||||
.append(elems.pretty(
|
||||
allocator,
|
||||
|e| e.pretty(allocator),
|
||||
|(s0, s1)| allocator.text(",").append(allocator.line()),
|
||||
|s| allocator.text(","),
|
||||
)),
|
||||
|
||||
Self::Module { s0, elems, span: _ } => {
|
||||
allocator.text("module").append(allocator.line()).append(
|
||||
allocator
|
||||
.intersperse(
|
||||
elems.elems.into_iter().map(|(s0, elem, s1)| {
|
||||
allocator.line().append(elem.pretty(allocator))
|
||||
}),
|
||||
allocator.text(","),
|
||||
)
|
||||
.append(elems.trailing.map(|s| allocator.text(","))),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ use crate::ast::{TableConstr, TableConstrElem};
|
|||
|
||||
use super::NEST_DEPTH;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableConstrElem {
|
||||
impl<'a, D> Pretty<'a, D> for TableConstrElem
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Lit(lit) => lit.pretty(allocator),
|
||||
|
|
@ -25,7 +29,11 @@ impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableConstrElem {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableConstr {
|
||||
impl<'a, D> Pretty<'a, D> for TableConstr
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
self.elems
|
||||
.pretty(
|
||||
|
|
|
|||
|
|
@ -38,7 +38,11 @@ impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TablePattern {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for TableDestr {
|
||||
impl<'a, D> Pretty<'a, D> for TableDestr
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
// TODO Handle spaces
|
||||
self.local
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ use pretty::{DocAllocator, DocBuilder, Pretty};
|
|||
|
||||
use crate::ast::Var;
|
||||
|
||||
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Var {
|
||||
impl<'a, D> Pretty<'a, D> for Var
|
||||
where
|
||||
D: DocAllocator<'a>,
|
||||
D::Doc: Clone,
|
||||
{
|
||||
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||
match self {
|
||||
Self::Access {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue