No more collisions between syntax::Tree and layout::Tree
This commit is contained in:
parent
45812b7001
commit
470f8001a1
@ -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<syntax::Tree>,
|
||||
ast: Rc<SyntaxTree>,
|
||||
module: Module,
|
||||
tree: layout::Tree,
|
||||
tree: LayoutTree,
|
||||
frames: Vec<Rc<Frame>>,
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,11 @@ pub fn eval(
|
||||
loader: &mut dyn Loader,
|
||||
cache: &mut Cache,
|
||||
path: Option<&Path>,
|
||||
tree: Rc<Tree>,
|
||||
ast: Rc<SyntaxTree>,
|
||||
scope: &Scope,
|
||||
) -> Pass<Module> {
|
||||
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<Tree> {
|
||||
impl Eval for Rc<SyntaxTree> {
|
||||
type Output = TemplateValue;
|
||||
|
||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
||||
|
@ -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<Tree>,
|
||||
/// The evaluated expressions for the `tree`.
|
||||
tree: Rc<SyntaxTree>,
|
||||
/// 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
|
||||
|
@ -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<PageBuilder>,
|
||||
@ -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<Tree> {
|
||||
pub fn finish(mut self) -> Pass<LayoutTree> {
|
||||
assert!(self.page.is_some());
|
||||
self.pagebreak(true, false, Span::default());
|
||||
Pass::new(self.tree, self.diags)
|
||||
|
@ -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<layout::Tree> {
|
||||
pub fn exec(template: &TemplateValue, state: State) -> Pass<LayoutTree> {
|
||||
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 {
|
||||
|
@ -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<Rc<Frame>> {
|
||||
pub fn layout(
|
||||
loader: &mut dyn Loader,
|
||||
cache: &mut Cache,
|
||||
tree: &LayoutTree,
|
||||
) -> Vec<Rc<Frame>> {
|
||||
tree.layout(&mut LayoutContext {
|
||||
loader,
|
||||
cache,
|
||||
@ -48,12 +52,12 @@ pub fn layout(loader: &mut dyn Loader, cache: &mut Cache, tree: &Tree) -> Vec<Rc
|
||||
|
||||
/// A tree of layout nodes.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Tree {
|
||||
pub struct LayoutTree {
|
||||
/// Runs of pages with the same properties.
|
||||
pub runs: Vec<PageRun>,
|
||||
}
|
||||
|
||||
impl Tree {
|
||||
impl LayoutTree {
|
||||
/// Layout the tree into a collection of frames.
|
||||
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Rc<Frame>> {
|
||||
self.runs.iter().flat_map(|run| run.layout(ctx)).collect()
|
||||
|
20
src/lib.rs
20
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<Vec<Rc<Frame>>> {
|
||||
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)
|
||||
}
|
||||
|
@ -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<Tree> {
|
||||
pub fn parse(src: &str) -> Pass<SyntaxTree> {
|
||||
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<F>(p: &mut Parser, mut at_start: bool, f: &mut F) -> Tree
|
||||
fn tree_while<F>(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 {
|
||||
|
@ -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");
|
||||
|
@ -158,7 +158,7 @@ pub struct TemplateExpr {
|
||||
/// The source code location.
|
||||
pub span: Span,
|
||||
/// The contents of the template.
|
||||
pub tree: Rc<Tree>,
|
||||
pub tree: Rc<SyntaxTree>,
|
||||
}
|
||||
|
||||
/// A grouped expression: `(1 + 2)`.
|
||||
|
@ -16,4 +16,4 @@ pub use token::*;
|
||||
/// The abstract syntax tree.
|
||||
///
|
||||
/// This type can represent a full parsed document.
|
||||
pub type Tree = Vec<Node>;
|
||||
pub type SyntaxTree = Vec<Node>;
|
||||
|
@ -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<Tree>,
|
||||
pub body: Rc<SyntaxTree>,
|
||||
}
|
||||
|
||||
/// 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<usize>,
|
||||
/// The contents of the list item.
|
||||
pub body: Tree,
|
||||
pub body: SyntaxTree,
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user