Make code generic over allocator
This way, I can use the same code with any allocator I want. More importantly, I can also use the nice DocBuilder-exclusive helper functions!
This commit is contained in:
parent
1a3772e6f7
commit
2ba56f0c92
4 changed files with 45 additions and 43 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use ::pretty::{Pretty, RcAllocator};
|
||||||
use chumsky::Parser as _;
|
use chumsky::Parser as _;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
|
|
@ -48,7 +49,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
match parser::parser().parse(stream) {
|
match parser::parser().parse(stream) {
|
||||||
Ok(program) => {
|
Ok(program) => {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
program.to_doc().render(100, &mut out)?;
|
program.pretty(&RcAllocator).render(100, &mut out)?;
|
||||||
println!("{}", String::from_utf8(out)?);
|
println!("{}", String::from_utf8(out)?);
|
||||||
}
|
}
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,36 @@
|
||||||
use pretty::RcDoc;
|
use pretty::{DocAllocator, DocBuilder};
|
||||||
|
|
||||||
use crate::ast::Separated;
|
use crate::ast::Separated;
|
||||||
|
|
||||||
impl<E, S1, S2> Separated<E, S1, S2> {
|
impl<E, S1, S2> Separated<E, S1, S2> {
|
||||||
pub fn to_doc<FE, FS1, FS2>(
|
pub fn pretty<'a, D, FE, FS1, FS2>(
|
||||||
&self,
|
self,
|
||||||
|
allocator: &'a D,
|
||||||
elem_to_doc: FE,
|
elem_to_doc: FE,
|
||||||
separator_to_doc: FS1,
|
separator_to_doc: FS1,
|
||||||
trailing_separator_to_doc: FS2,
|
trailing_separator_to_doc: FS2,
|
||||||
) -> RcDoc
|
) -> DocBuilder<'a, D>
|
||||||
where
|
where
|
||||||
FE: Fn(&E) -> RcDoc,
|
D: DocAllocator<'a>,
|
||||||
FS1: Fn(&S1) -> RcDoc,
|
FE: Fn(&'a D, E) -> DocBuilder<'a, D>,
|
||||||
FS2: Fn(&S2) -> RcDoc,
|
FS1: Fn(&'a D, S1) -> DocBuilder<'a, D>,
|
||||||
|
FS2: Fn(&'a D, S2) -> DocBuilder<'a, D>,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Separated::Empty(_) => RcDoc::nil(),
|
Separated::Empty(_) => allocator.nil(),
|
||||||
Separated::NonEmpty {
|
Separated::NonEmpty {
|
||||||
first_elem,
|
first_elem,
|
||||||
last_elems,
|
last_elems,
|
||||||
trailing,
|
trailing,
|
||||||
span: _span,
|
span: _span,
|
||||||
} => elem_to_doc(first_elem)
|
} => elem_to_doc(allocator, first_elem)
|
||||||
.append(RcDoc::concat(
|
.append(allocator.concat(last_elems.into_iter().map(|(s, e)| {
|
||||||
last_elems
|
separator_to_doc(allocator, s).append(elem_to_doc(allocator, e))
|
||||||
.iter()
|
})))
|
||||||
.map(|(s, e)| separator_to_doc(s).append(elem_to_doc(e))),
|
|
||||||
))
|
|
||||||
.append(
|
.append(
|
||||||
trailing
|
trailing
|
||||||
.as_ref()
|
.map(|s| trailing_separator_to_doc(allocator, s))
|
||||||
.map(trailing_separator_to_doc)
|
.unwrap_or_else(|| allocator.nil()),
|
||||||
.unwrap_or_else(RcDoc::nil),
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
use pretty::RcDoc;
|
use pretty::{DocAllocator, DocBuilder, Pretty};
|
||||||
|
|
||||||
use crate::ast::Expr;
|
use crate::ast::Expr;
|
||||||
|
|
||||||
impl Expr {
|
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Expr {
|
||||||
pub fn to_doc(&self) -> RcDoc {
|
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||||
match self {
|
match self {
|
||||||
Expr::Lit(lit) => RcDoc::text("<lit>"),
|
Expr::Lit(lit) => allocator.text("<lit>"),
|
||||||
Expr::Call(call) => RcDoc::text("<call>"),
|
Expr::Call(call) => allocator.text("<call>"),
|
||||||
Expr::Field(field) => RcDoc::text("<field>"),
|
Expr::Field(field) => allocator.text("<field>"),
|
||||||
Expr::Var(var) => RcDoc::text("<var>"),
|
Expr::Var(var) => allocator.text("<var>"),
|
||||||
Expr::TableConstr(constr) => RcDoc::text("<onstr>"),
|
Expr::TableConstr(constr) => allocator.text("<onstr>"),
|
||||||
Expr::TableDestr(destr) => RcDoc::text("<destr>"),
|
Expr::TableDestr(destr) => allocator.text("<destr>"),
|
||||||
Expr::FuncDef(def) => RcDoc::text("<def>"),
|
Expr::FuncDef(def) => allocator.text("<def>"),
|
||||||
Expr::Paren {
|
Expr::Paren {
|
||||||
s0,
|
s0,
|
||||||
inner,
|
inner,
|
||||||
s1,
|
s1,
|
||||||
span: _,
|
span: _,
|
||||||
} => RcDoc::text("(").append(inner.to_doc()).append(")"),
|
} => inner.pretty(allocator).parens(),
|
||||||
|
|
||||||
// TODO Check whether parentheses are necessary
|
// TODO Check whether parentheses are necessary
|
||||||
Expr::Neg {
|
Expr::Neg {
|
||||||
|
|
@ -25,7 +25,7 @@ impl Expr {
|
||||||
s0,
|
s0,
|
||||||
expr,
|
expr,
|
||||||
span: _,
|
span: _,
|
||||||
} => RcDoc::text("-").append(expr.to_doc()),
|
} => allocator.text("-").append(expr.pretty(allocator)),
|
||||||
|
|
||||||
// TODO Check whether parentheses are necessary
|
// TODO Check whether parentheses are necessary
|
||||||
Expr::Not {
|
Expr::Not {
|
||||||
|
|
@ -33,7 +33,7 @@ impl Expr {
|
||||||
s0,
|
s0,
|
||||||
expr,
|
expr,
|
||||||
span: _,
|
span: _,
|
||||||
} => RcDoc::text("not ").append(expr.to_doc()),
|
} => allocator.text("not ").append(expr.pretty(allocator)),
|
||||||
|
|
||||||
Expr::BinOp {
|
Expr::BinOp {
|
||||||
left,
|
left,
|
||||||
|
|
@ -42,7 +42,7 @@ impl Expr {
|
||||||
s1,
|
s1,
|
||||||
right,
|
right,
|
||||||
span: _,
|
span: _,
|
||||||
} => RcDoc::text("<binop>"),
|
} => allocator.text("<binop>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,31 @@
|
||||||
use pretty::RcDoc;
|
use pretty::{DocAllocator, DocBuilder, Pretty};
|
||||||
|
|
||||||
use crate::ast::Program;
|
use crate::ast::Program;
|
||||||
|
|
||||||
impl Program {
|
impl<'a, D: DocAllocator<'a>> Pretty<'a, D> for Program {
|
||||||
pub fn to_doc(&self) -> RcDoc {
|
fn pretty(self, allocator: &'a D) -> DocBuilder<'a, D> {
|
||||||
match self {
|
match self {
|
||||||
Program::Expr {
|
Program::Expr {
|
||||||
s0,
|
s0,
|
||||||
expr,
|
expr,
|
||||||
s1,
|
s1,
|
||||||
span: _,
|
span: _,
|
||||||
} => expr.to_doc(),
|
} => expr.pretty(allocator),
|
||||||
Program::Module {
|
Program::Module {
|
||||||
s0,
|
s0,
|
||||||
s1,
|
s1,
|
||||||
elems,
|
elems,
|
||||||
s2,
|
s2,
|
||||||
span: _,
|
span: _,
|
||||||
} => RcDoc::text("module")
|
} => allocator
|
||||||
.append(RcDoc::line())
|
.text("module")
|
||||||
.append(RcDoc::line())
|
.append(allocator.line())
|
||||||
.append(elems.to_doc(
|
.append(allocator.line())
|
||||||
|e| RcDoc::text("<elem>"),
|
.append(elems.pretty(
|
||||||
|(s0, s1)| RcDoc::text(",").append(RcDoc::line()),
|
allocator,
|
||||||
|s| RcDoc::text(","),
|
|a, e| a.text("<elem>"),
|
||||||
|
|a, (s0, s1)| a.text(",").append(a.line()),
|
||||||
|
|a, s| a.text(","),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue