From 470f8001a1dba0022ec9d3e46c67c3bbc31359be Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 30 Jun 2021 11:40:27 +0200 Subject: [PATCH] No more collisions between syntax::Tree and layout::Tree --- bench/src/bench.rs | 17 ++++++++--------- src/eval/mod.rs | 10 +++++----- src/eval/value.rs | 14 +++++++------- src/exec/context.rs | 14 +++++++------- src/exec/mod.rs | 20 ++++++++++---------- src/layout/mod.rs | 10 +++++++--- src/lib.rs | 20 ++++++++++---------- src/parse/mod.rs | 10 +++++----- src/pretty.rs | 8 ++++---- src/syntax/expr.rs | 2 +- src/syntax/mod.rs | 2 +- src/syntax/node.rs | 6 +++--- src/syntax/visit.rs | 2 +- 13 files changed, 69 insertions(+), 66 deletions(-) diff --git a/bench/src/bench.rs b/bench/src/bench.rs index c86ccc899..129215fe8 100644 --- a/bench/src/bench.rs +++ b/bench/src/bench.rs @@ -8,10 +8,10 @@ use typst::cache::Cache; use typst::eval::{eval, Module, Scope}; use typst::exec::{exec, State}; use typst::export::pdf; -use typst::layout::{self, layout, Frame}; +use typst::layout::{layout, Frame, LayoutTree}; use typst::loading::FsLoader; use typst::parse::parse; -use typst::syntax; +use typst::syntax::SyntaxTree; use typst::typeset; const FONT_DIR: &str = "../fonts"; @@ -26,7 +26,6 @@ fn benchmarks(c: &mut Criterion) { let src = std::fs::read_to_string(&path).unwrap(); let case = Case::new(src, ctx.clone()); - /// Bench with all caches. macro_rules! bench { ($step:literal, setup = |$cache:ident| $setup:expr, code = $code:expr $(,)?) => { c.bench_function(&format!("{}-{}", $step, name), |b| { @@ -97,9 +96,9 @@ struct Case { src: String, scope: Scope, state: State, - ast: Rc, + ast: Rc, module: Module, - tree: layout::Tree, + tree: LayoutTree, frames: Vec>, } @@ -111,7 +110,7 @@ impl Case { let state = typst::exec::State::default(); let src = src.into(); let ast = Rc::new(parse(&src).output); - let module = eval(loader, cache, None, ast.clone(), &scope).output; + let module = eval(loader, cache, None, Rc::clone(&ast), &scope).output; let tree = exec(&module.template, state.clone()).output; let frames = layout(loader, cache, &tree); drop(borrowed); @@ -127,17 +126,17 @@ impl Case { } } - fn parse(&self) -> syntax::Tree { + fn parse(&self) -> SyntaxTree { parse(&self.src).output } fn eval(&self) -> Module { let mut borrowed = self.ctx.borrow_mut(); let Context { loader, cache } = &mut *borrowed; - eval(loader, cache, None, self.ast.clone(), &self.scope).output + eval(loader, cache, None, Rc::clone(&self.ast), &self.scope).output } - fn exec(&self) -> layout::Tree { + fn exec(&self) -> LayoutTree { exec(&self.module.template, self.state.clone()).output } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index a9fff56be..8579025fe 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -30,11 +30,11 @@ pub fn eval( loader: &mut dyn Loader, cache: &mut Cache, path: Option<&Path>, - tree: Rc, + ast: Rc, scope: &Scope, ) -> Pass { let mut ctx = EvalContext::new(loader, cache, path, scope); - let template = tree.eval(&mut ctx); + let template = ast.eval(&mut ctx); let module = Module { scope: ctx.scopes.top, template }; Pass::new(module, ctx.diags) } @@ -148,8 +148,8 @@ impl<'a> EvalContext<'a> { self.route.push(hash); // Evaluate the module. - let tree = Rc::new(parsed.output); - let template = tree.eval(self); + let ast = Rc::new(parsed.output); + let template = ast.eval(self); // Restore the old context. let new_scopes = mem::replace(&mut self.scopes, old_scopes); @@ -212,7 +212,7 @@ pub trait Eval { fn eval(&self, ctx: &mut EvalContext) -> Self::Output; } -impl Eval for Rc { +impl Eval for Rc { type Output = TemplateValue; fn eval(&self, ctx: &mut EvalContext) -> Self::Output { diff --git a/src/eval/value.rs b/src/eval/value.rs index 0da2a5be0..472df0ea1 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -10,7 +10,7 @@ use super::EvalContext; use crate::color::{Color, RgbaColor}; use crate::exec::ExecContext; use crate::geom::{Angle, Fractional, Length, Linear, Relative}; -use crate::syntax::{Expr, Span, Spanned, Tree}; +use crate::syntax::{Expr, Span, Spanned, SyntaxTree}; /// A computational value. #[derive(Debug, Clone, PartialEq)] @@ -165,8 +165,8 @@ pub enum TemplateNode { /// expression. Tree { /// The syntax tree of the corresponding template expression. - tree: Rc, - /// The evaluated expressions for the `tree`. + tree: Rc, + /// The evaluated expressions in the syntax tree. map: ExprMap, }, /// A template that was converted from a string. @@ -184,10 +184,10 @@ impl PartialEq for TemplateNode { /// A map from expressions to the values they evaluated to. /// -/// The raw pointers point into the expressions contained in some [`Tree`]. -/// Since the lifetime is erased, the tree could go out of scope while the hash -/// map still lives. Although this could lead to lookup panics, it is not unsafe -/// since the pointers are never dereferenced. +/// The raw pointers point into the expressions contained in some +/// [`SyntaxTree`]. Since the lifetime is erased, the tree could go out of scope +/// while the hash map still lives. Although this could lead to lookup panics, +/// it is not unsafe since the pointers are never dereferenced. pub type ExprMap = HashMap<*const Expr, Value>; /// A reference-counted dynamic template node that can implement custom diff --git a/src/exec/context.rs b/src/exec/context.rs index 3994fdb97..0f6d47f59 100644 --- a/src/exec/context.rs +++ b/src/exec/context.rs @@ -6,9 +6,9 @@ use crate::diag::{Diag, DiagSet, Pass}; use crate::eval::{ExprMap, TemplateValue}; use crate::geom::{Align, Dir, Gen, GenAxis, Length, Linear, Sides, Size}; use crate::layout::{ - AnyNode, PadNode, PageRun, ParChild, ParNode, StackChild, StackNode, Tree, + AnyNode, LayoutTree, PadNode, PageRun, ParChild, ParNode, StackChild, StackNode, }; -use crate::syntax::{self, Span}; +use crate::syntax::{Span, SyntaxTree}; /// The context for execution. pub struct ExecContext { @@ -17,7 +17,7 @@ pub struct ExecContext { /// Execution diagnostics. pub diags: DiagSet, /// The tree of finished page runs. - tree: Tree, + tree: LayoutTree, /// When we are building the top-level stack, this contains metrics of the /// page. While building a group stack through `exec_group`, this is `None`. page: Option, @@ -30,7 +30,7 @@ impl ExecContext { pub fn new(state: State) -> Self { Self { diags: DiagSet::new(), - tree: Tree { runs: vec![] }, + tree: LayoutTree { runs: vec![] }, page: Some(PageBuilder::new(&state, true)), stack: StackBuilder::new(&state), state, @@ -56,8 +56,8 @@ impl ExecContext { self.exec_stack(|ctx| template.exec(ctx)) } - /// Execute a tree with a map and return the result as a stack node. - pub fn exec_tree_stack(&mut self, tree: &syntax::Tree, map: &ExprMap) -> StackNode { + /// Execute a syntax tree with a map and return the result as a stack node. + pub fn exec_tree_stack(&mut self, tree: &SyntaxTree, map: &ExprMap) -> StackNode { self.exec_stack(|ctx| tree.exec_with_map(ctx, map)) } @@ -137,7 +137,7 @@ impl ExecContext { } /// Finish execution and return the created layout tree. - pub fn finish(mut self) -> Pass { + pub fn finish(mut self) -> Pass { assert!(self.page.is_some()); self.pagebreak(true, false, Span::default()); Pass::new(self.tree, self.diags) diff --git a/src/exec/mod.rs b/src/exec/mod.rs index 882f1d0b6..8e369d127 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -11,12 +11,12 @@ use std::rc::Rc; use crate::diag::Pass; use crate::eval::{ExprMap, TemplateFunc, TemplateNode, TemplateValue, Value}; use crate::geom::{Dir, Gen}; -use crate::layout::{self, StackChild, StackNode}; +use crate::layout::{LayoutTree, StackChild, StackNode}; use crate::pretty::pretty; -use crate::syntax; +use crate::syntax::*; /// Execute a template to produce a layout tree. -pub fn exec(template: &TemplateValue, state: State) -> Pass { +pub fn exec(template: &TemplateValue, state: State) -> Pass { let mut ctx = ExecContext::new(state); template.exec(&mut ctx); ctx.finish() @@ -40,7 +40,7 @@ pub trait ExecWithMap { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap); } -impl ExecWithMap for syntax::Tree { +impl ExecWithMap for SyntaxTree { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) { for node in self { node.exec_with_map(ctx, map); @@ -48,7 +48,7 @@ impl ExecWithMap for syntax::Tree { } } -impl ExecWithMap for syntax::Node { +impl ExecWithMap for Node { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) { match self { Self::Text(text) => ctx.push_text(text), @@ -66,7 +66,7 @@ impl ExecWithMap for syntax::Node { } } -impl Exec for syntax::RawNode { +impl Exec for RawNode { fn exec(&self, ctx: &mut ExecContext) { if self.block { ctx.parbreak(); @@ -83,7 +83,7 @@ impl Exec for syntax::RawNode { } } -impl ExecWithMap for syntax::HeadingNode { +impl ExecWithMap for HeadingNode { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) { ctx.parbreak(); @@ -100,20 +100,20 @@ impl ExecWithMap for syntax::HeadingNode { } } -impl ExecWithMap for syntax::ListItem { +impl ExecWithMap for ListItem { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) { exec_item(ctx, "•".to_string(), &self.body, map); } } -impl ExecWithMap for syntax::EnumItem { +impl ExecWithMap for EnumItem { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) { let label = self.number.unwrap_or(1).to_string() + "."; exec_item(ctx, label, &self.body, map); } } -fn exec_item(ctx: &mut ExecContext, label: String, body: &syntax::Tree, map: &ExprMap) { +fn exec_item(ctx: &mut ExecContext, label: String, body: &SyntaxTree, map: &ExprMap) { let label = ctx.exec_stack(|ctx| ctx.push_text(label)); let body = ctx.exec_tree_stack(body, map); let stack = StackNode { diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 7ba556a11..e8bdab62f 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -37,7 +37,11 @@ use crate::geom::*; use crate::loading::Loader; /// Layout a tree into a collection of frames. -pub fn layout(loader: &mut dyn Loader, cache: &mut Cache, tree: &Tree) -> Vec> { +pub fn layout( + loader: &mut dyn Loader, + cache: &mut Cache, + tree: &LayoutTree, +) -> Vec> { tree.layout(&mut LayoutContext { loader, cache, @@ -48,12 +52,12 @@ pub fn layout(loader: &mut dyn Loader, cache: &mut Cache, tree: &Tree) -> Vec, } -impl Tree { +impl LayoutTree { /// Layout the tree into a collection of frames. pub fn layout(&self, ctx: &mut LayoutContext) -> Vec> { self.runs.iter().flat_map(|run| run.layout(ctx)).collect() diff --git a/src/lib.rs b/src/lib.rs index 053888f4c..f083163bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,11 +20,11 @@ //! //! [tokens]: parse::Tokens //! [parsed]: parse::parse -//! [syntax tree]: syntax::Tree +//! [syntax tree]: syntax::SyntaxTree //! [evaluate]: eval::eval //! [module]: eval::Module //! [execute]: exec::exec -//! [layout tree]: layout::Tree +//! [layout tree]: layout::LayoutTree //! [layouted]: layout::layout //! [PDF]: export::pdf @@ -84,14 +84,14 @@ pub fn typeset( scope: &Scope, state: State, ) -> Pass>> { - let parsed = parse::parse(src); - let evaluated = eval::eval(loader, cache, path, Rc::new(parsed.output), scope); - let executed = exec::exec(&evaluated.output.template, state); - let layouted = layout::layout(loader, cache, &executed.output); + let ast = parse::parse(src); + let module = eval::eval(loader, cache, path, Rc::new(ast.output), scope); + let tree = exec::exec(&module.output.template, state); + let frames = layout::layout(loader, cache, &tree.output); - let mut diags = parsed.diags; - diags.extend(evaluated.diags); - diags.extend(executed.diags); + let mut diags = ast.diags; + diags.extend(module.diags); + diags.extend(tree.diags); - Pass::new(layouted, diags) + Pass::new(frames, diags) } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index e8e168033..0afcd88b1 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -19,19 +19,19 @@ use crate::syntax::visit::{mutable::visit_expr, VisitMut}; use crate::syntax::*; /// Parse a string of source code. -pub fn parse(src: &str) -> Pass { +pub fn parse(src: &str) -> Pass { let mut p = Parser::new(src); Pass::new(tree(&mut p), p.diags) } /// Parse a syntax tree. -fn tree(p: &mut Parser) -> Tree { +fn tree(p: &mut Parser) -> SyntaxTree { tree_while(p, true, &mut |_| true) } /// Parse a syntax tree that stays right of the column at the start of the next /// non-whitespace token. -fn tree_indented(p: &mut Parser) -> Tree { +fn tree_indented(p: &mut Parser) -> SyntaxTree { p.eat_while(|t| match t { Token::Space(n) => n == 0, Token::LineComment(_) | Token::BlockComment(_) => true, @@ -46,7 +46,7 @@ fn tree_indented(p: &mut Parser) -> Tree { } /// Parse a syntax tree. -fn tree_while(p: &mut Parser, mut at_start: bool, f: &mut F) -> Tree +fn tree_while(p: &mut Parser, mut at_start: bool, f: &mut F) -> SyntaxTree where F: FnMut(&mut Parser) -> bool, { @@ -72,7 +72,7 @@ where tree_while(self.p, true, self.f) } else { self.p.diag(error!(call.callee.span(), "duplicate wide call")); - Tree::default() + SyntaxTree::default() }; call.args.items.push(CallArg::Pos(Expr::Template(TemplateExpr { diff --git a/src/pretty.rs b/src/pretty.rs index 216a63702..ccf4d88d3 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -78,7 +78,7 @@ impl Write for Printer { } } -impl Pretty for Tree { +impl Pretty for SyntaxTree { fn pretty(&self, p: &mut Printer) { for node in self { node.pretty(p); @@ -630,10 +630,10 @@ mod tests { #[track_caller] fn test_parse(src: &str, exp: &str) { - let tree = parse(src).output; - let found = pretty(&tree); + let ast = parse(src).output; + let found = pretty(&ast); if exp != found { - println!("tree: {:#?}", tree); + println!("tree: {:#?}", ast); println!("expected: {}", exp); println!("found: {}", found); panic!("test failed"); diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index aabff1eaf..26ec7f487 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -158,7 +158,7 @@ pub struct TemplateExpr { /// The source code location. pub span: Span, /// The contents of the template. - pub tree: Rc, + pub tree: Rc, } /// A grouped expression: `(1 + 2)`. diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 9426090cf..6673fda64 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -16,4 +16,4 @@ pub use token::*; /// The abstract syntax tree. /// /// This type can represent a full parsed document. -pub type Tree = Vec; +pub type SyntaxTree = Vec; diff --git a/src/syntax/node.rs b/src/syntax/node.rs index 79b1e3522..1fbdb3d8b 100644 --- a/src/syntax/node.rs +++ b/src/syntax/node.rs @@ -52,7 +52,7 @@ pub struct HeadingNode { /// The section depth (numer of equals signs). pub level: usize, /// The contents of the heading. - pub body: Rc, + pub body: Rc, } /// An item in an unordered list: `- ...`. @@ -61,7 +61,7 @@ pub struct ListItem { /// The source code location. pub span: Span, /// The contents of the list item. - pub body: Tree, + pub body: SyntaxTree, } /// An item in an enumeration (ordered list): `1. ...`. @@ -72,5 +72,5 @@ pub struct EnumItem { /// The number, if any. pub number: Option, /// The contents of the list item. - pub body: Tree, + pub body: SyntaxTree, } diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs index 657b379ae..66c5f9796 100644 --- a/src/syntax/visit.rs +++ b/src/syntax/visit.rs @@ -79,7 +79,7 @@ macro_rules! impl_visitor { } impl_visitors! { - visit_tree(v, tree: Tree) { + visit_tree(v, tree: SyntaxTree) { for node in tree { v.visit_node(node); }