mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
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::eval::{eval, Module, Scope};
|
||||||
use typst::exec::{exec, State};
|
use typst::exec::{exec, State};
|
||||||
use typst::export::pdf;
|
use typst::export::pdf;
|
||||||
use typst::layout::{self, layout, Frame};
|
use typst::layout::{layout, Frame, LayoutTree};
|
||||||
use typst::loading::FsLoader;
|
use typst::loading::FsLoader;
|
||||||
use typst::parse::parse;
|
use typst::parse::parse;
|
||||||
use typst::syntax;
|
use typst::syntax::SyntaxTree;
|
||||||
use typst::typeset;
|
use typst::typeset;
|
||||||
|
|
||||||
const FONT_DIR: &str = "../fonts";
|
const FONT_DIR: &str = "../fonts";
|
||||||
@ -26,7 +26,6 @@ fn benchmarks(c: &mut Criterion) {
|
|||||||
let src = std::fs::read_to_string(&path).unwrap();
|
let src = std::fs::read_to_string(&path).unwrap();
|
||||||
let case = Case::new(src, ctx.clone());
|
let case = Case::new(src, ctx.clone());
|
||||||
|
|
||||||
/// Bench with all caches.
|
|
||||||
macro_rules! bench {
|
macro_rules! bench {
|
||||||
($step:literal, setup = |$cache:ident| $setup:expr, code = $code:expr $(,)?) => {
|
($step:literal, setup = |$cache:ident| $setup:expr, code = $code:expr $(,)?) => {
|
||||||
c.bench_function(&format!("{}-{}", $step, name), |b| {
|
c.bench_function(&format!("{}-{}", $step, name), |b| {
|
||||||
@ -97,9 +96,9 @@ struct Case {
|
|||||||
src: String,
|
src: String,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
state: State,
|
state: State,
|
||||||
ast: Rc<syntax::Tree>,
|
ast: Rc<SyntaxTree>,
|
||||||
module: Module,
|
module: Module,
|
||||||
tree: layout::Tree,
|
tree: LayoutTree,
|
||||||
frames: Vec<Rc<Frame>>,
|
frames: Vec<Rc<Frame>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +110,7 @@ impl Case {
|
|||||||
let state = typst::exec::State::default();
|
let state = typst::exec::State::default();
|
||||||
let src = src.into();
|
let src = src.into();
|
||||||
let ast = Rc::new(parse(&src).output);
|
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 tree = exec(&module.template, state.clone()).output;
|
||||||
let frames = layout(loader, cache, &tree);
|
let frames = layout(loader, cache, &tree);
|
||||||
drop(borrowed);
|
drop(borrowed);
|
||||||
@ -127,17 +126,17 @@ impl Case {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(&self) -> syntax::Tree {
|
fn parse(&self) -> SyntaxTree {
|
||||||
parse(&self.src).output
|
parse(&self.src).output
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(&self) -> Module {
|
fn eval(&self) -> Module {
|
||||||
let mut borrowed = self.ctx.borrow_mut();
|
let mut borrowed = self.ctx.borrow_mut();
|
||||||
let Context { loader, cache } = &mut *borrowed;
|
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
|
exec(&self.module.template, self.state.clone()).output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@ pub fn eval(
|
|||||||
loader: &mut dyn Loader,
|
loader: &mut dyn Loader,
|
||||||
cache: &mut Cache,
|
cache: &mut Cache,
|
||||||
path: Option<&Path>,
|
path: Option<&Path>,
|
||||||
tree: Rc<Tree>,
|
ast: Rc<SyntaxTree>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
) -> Pass<Module> {
|
) -> Pass<Module> {
|
||||||
let mut ctx = EvalContext::new(loader, cache, path, scope);
|
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 };
|
let module = Module { scope: ctx.scopes.top, template };
|
||||||
Pass::new(module, ctx.diags)
|
Pass::new(module, ctx.diags)
|
||||||
}
|
}
|
||||||
@ -148,8 +148,8 @@ impl<'a> EvalContext<'a> {
|
|||||||
self.route.push(hash);
|
self.route.push(hash);
|
||||||
|
|
||||||
// Evaluate the module.
|
// Evaluate the module.
|
||||||
let tree = Rc::new(parsed.output);
|
let ast = Rc::new(parsed.output);
|
||||||
let template = tree.eval(self);
|
let template = ast.eval(self);
|
||||||
|
|
||||||
// Restore the old context.
|
// Restore the old context.
|
||||||
let new_scopes = mem::replace(&mut self.scopes, old_scopes);
|
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;
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eval for Rc<Tree> {
|
impl Eval for Rc<SyntaxTree> {
|
||||||
type Output = TemplateValue;
|
type Output = TemplateValue;
|
||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
|
||||||
|
@ -10,7 +10,7 @@ use super::EvalContext;
|
|||||||
use crate::color::{Color, RgbaColor};
|
use crate::color::{Color, RgbaColor};
|
||||||
use crate::exec::ExecContext;
|
use crate::exec::ExecContext;
|
||||||
use crate::geom::{Angle, Fractional, Length, Linear, Relative};
|
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.
|
/// A computational value.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -165,8 +165,8 @@ pub enum TemplateNode {
|
|||||||
/// expression.
|
/// expression.
|
||||||
Tree {
|
Tree {
|
||||||
/// The syntax tree of the corresponding template expression.
|
/// The syntax tree of the corresponding template expression.
|
||||||
tree: Rc<Tree>,
|
tree: Rc<SyntaxTree>,
|
||||||
/// The evaluated expressions for the `tree`.
|
/// The evaluated expressions in the syntax tree.
|
||||||
map: ExprMap,
|
map: ExprMap,
|
||||||
},
|
},
|
||||||
/// A template that was converted from a string.
|
/// 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.
|
/// A map from expressions to the values they evaluated to.
|
||||||
///
|
///
|
||||||
/// The raw pointers point into the expressions contained in some [`Tree`].
|
/// The raw pointers point into the expressions contained in some
|
||||||
/// Since the lifetime is erased, the tree could go out of scope while the hash
|
/// [`SyntaxTree`]. Since the lifetime is erased, the tree could go out of scope
|
||||||
/// map still lives. Although this could lead to lookup panics, it is not unsafe
|
/// while the hash map still lives. Although this could lead to lookup panics,
|
||||||
/// since the pointers are never dereferenced.
|
/// it is not unsafe since the pointers are never dereferenced.
|
||||||
pub type ExprMap = HashMap<*const Expr, Value>;
|
pub type ExprMap = HashMap<*const Expr, Value>;
|
||||||
|
|
||||||
/// A reference-counted dynamic template node that can implement custom
|
/// 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::eval::{ExprMap, TemplateValue};
|
||||||
use crate::geom::{Align, Dir, Gen, GenAxis, Length, Linear, Sides, Size};
|
use crate::geom::{Align, Dir, Gen, GenAxis, Length, Linear, Sides, Size};
|
||||||
use crate::layout::{
|
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.
|
/// The context for execution.
|
||||||
pub struct ExecContext {
|
pub struct ExecContext {
|
||||||
@ -17,7 +17,7 @@ pub struct ExecContext {
|
|||||||
/// Execution diagnostics.
|
/// Execution diagnostics.
|
||||||
pub diags: DiagSet,
|
pub diags: DiagSet,
|
||||||
/// The tree of finished page runs.
|
/// The tree of finished page runs.
|
||||||
tree: Tree,
|
tree: LayoutTree,
|
||||||
/// When we are building the top-level stack, this contains metrics of the
|
/// 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. While building a group stack through `exec_group`, this is `None`.
|
||||||
page: Option<PageBuilder>,
|
page: Option<PageBuilder>,
|
||||||
@ -30,7 +30,7 @@ impl ExecContext {
|
|||||||
pub fn new(state: State) -> Self {
|
pub fn new(state: State) -> Self {
|
||||||
Self {
|
Self {
|
||||||
diags: DiagSet::new(),
|
diags: DiagSet::new(),
|
||||||
tree: Tree { runs: vec![] },
|
tree: LayoutTree { runs: vec![] },
|
||||||
page: Some(PageBuilder::new(&state, true)),
|
page: Some(PageBuilder::new(&state, true)),
|
||||||
stack: StackBuilder::new(&state),
|
stack: StackBuilder::new(&state),
|
||||||
state,
|
state,
|
||||||
@ -56,8 +56,8 @@ impl ExecContext {
|
|||||||
self.exec_stack(|ctx| template.exec(ctx))
|
self.exec_stack(|ctx| template.exec(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a tree with a map and return the result as a stack node.
|
/// Execute a syntax 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 {
|
pub fn exec_tree_stack(&mut self, tree: &SyntaxTree, map: &ExprMap) -> StackNode {
|
||||||
self.exec_stack(|ctx| tree.exec_with_map(ctx, map))
|
self.exec_stack(|ctx| tree.exec_with_map(ctx, map))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ impl ExecContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Finish execution and return the created layout tree.
|
/// 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());
|
assert!(self.page.is_some());
|
||||||
self.pagebreak(true, false, Span::default());
|
self.pagebreak(true, false, Span::default());
|
||||||
Pass::new(self.tree, self.diags)
|
Pass::new(self.tree, self.diags)
|
||||||
|
@ -11,12 +11,12 @@ use std::rc::Rc;
|
|||||||
use crate::diag::Pass;
|
use crate::diag::Pass;
|
||||||
use crate::eval::{ExprMap, TemplateFunc, TemplateNode, TemplateValue, Value};
|
use crate::eval::{ExprMap, TemplateFunc, TemplateNode, TemplateValue, Value};
|
||||||
use crate::geom::{Dir, Gen};
|
use crate::geom::{Dir, Gen};
|
||||||
use crate::layout::{self, StackChild, StackNode};
|
use crate::layout::{LayoutTree, StackChild, StackNode};
|
||||||
use crate::pretty::pretty;
|
use crate::pretty::pretty;
|
||||||
use crate::syntax;
|
use crate::syntax::*;
|
||||||
|
|
||||||
/// Execute a template to produce a layout tree.
|
/// 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);
|
let mut ctx = ExecContext::new(state);
|
||||||
template.exec(&mut ctx);
|
template.exec(&mut ctx);
|
||||||
ctx.finish()
|
ctx.finish()
|
||||||
@ -40,7 +40,7 @@ pub trait ExecWithMap {
|
|||||||
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap);
|
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) {
|
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
|
||||||
for node in self {
|
for node in self {
|
||||||
node.exec_with_map(ctx, map);
|
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) {
|
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
|
||||||
match self {
|
match self {
|
||||||
Self::Text(text) => ctx.push_text(text),
|
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) {
|
fn exec(&self, ctx: &mut ExecContext) {
|
||||||
if self.block {
|
if self.block {
|
||||||
ctx.parbreak();
|
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) {
|
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
|
||||||
ctx.parbreak();
|
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) {
|
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
|
||||||
exec_item(ctx, "•".to_string(), &self.body, map);
|
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) {
|
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
|
||||||
let label = self.number.unwrap_or(1).to_string() + ".";
|
let label = self.number.unwrap_or(1).to_string() + ".";
|
||||||
exec_item(ctx, label, &self.body, map);
|
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 label = ctx.exec_stack(|ctx| ctx.push_text(label));
|
||||||
let body = ctx.exec_tree_stack(body, map);
|
let body = ctx.exec_tree_stack(body, map);
|
||||||
let stack = StackNode {
|
let stack = StackNode {
|
||||||
|
@ -37,7 +37,11 @@ use crate::geom::*;
|
|||||||
use crate::loading::Loader;
|
use crate::loading::Loader;
|
||||||
|
|
||||||
/// Layout a tree into a collection of frames.
|
/// 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 {
|
tree.layout(&mut LayoutContext {
|
||||||
loader,
|
loader,
|
||||||
cache,
|
cache,
|
||||||
@ -48,12 +52,12 @@ pub fn layout(loader: &mut dyn Loader, cache: &mut Cache, tree: &Tree) -> Vec<Rc
|
|||||||
|
|
||||||
/// A tree of layout nodes.
|
/// A tree of layout nodes.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Tree {
|
pub struct LayoutTree {
|
||||||
/// Runs of pages with the same properties.
|
/// Runs of pages with the same properties.
|
||||||
pub runs: Vec<PageRun>,
|
pub runs: Vec<PageRun>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tree {
|
impl LayoutTree {
|
||||||
/// Layout the tree into a collection of frames.
|
/// Layout the tree into a collection of frames.
|
||||||
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Rc<Frame>> {
|
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Rc<Frame>> {
|
||||||
self.runs.iter().flat_map(|run| run.layout(ctx)).collect()
|
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
|
//! [tokens]: parse::Tokens
|
||||||
//! [parsed]: parse::parse
|
//! [parsed]: parse::parse
|
||||||
//! [syntax tree]: syntax::Tree
|
//! [syntax tree]: syntax::SyntaxTree
|
||||||
//! [evaluate]: eval::eval
|
//! [evaluate]: eval::eval
|
||||||
//! [module]: eval::Module
|
//! [module]: eval::Module
|
||||||
//! [execute]: exec::exec
|
//! [execute]: exec::exec
|
||||||
//! [layout tree]: layout::Tree
|
//! [layout tree]: layout::LayoutTree
|
||||||
//! [layouted]: layout::layout
|
//! [layouted]: layout::layout
|
||||||
//! [PDF]: export::pdf
|
//! [PDF]: export::pdf
|
||||||
|
|
||||||
@ -84,14 +84,14 @@ pub fn typeset(
|
|||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
state: State,
|
state: State,
|
||||||
) -> Pass<Vec<Rc<Frame>>> {
|
) -> Pass<Vec<Rc<Frame>>> {
|
||||||
let parsed = parse::parse(src);
|
let ast = parse::parse(src);
|
||||||
let evaluated = eval::eval(loader, cache, path, Rc::new(parsed.output), scope);
|
let module = eval::eval(loader, cache, path, Rc::new(ast.output), scope);
|
||||||
let executed = exec::exec(&evaluated.output.template, state);
|
let tree = exec::exec(&module.output.template, state);
|
||||||
let layouted = layout::layout(loader, cache, &executed.output);
|
let frames = layout::layout(loader, cache, &tree.output);
|
||||||
|
|
||||||
let mut diags = parsed.diags;
|
let mut diags = ast.diags;
|
||||||
diags.extend(evaluated.diags);
|
diags.extend(module.diags);
|
||||||
diags.extend(executed.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::*;
|
use crate::syntax::*;
|
||||||
|
|
||||||
/// Parse a string of source code.
|
/// 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);
|
let mut p = Parser::new(src);
|
||||||
Pass::new(tree(&mut p), p.diags)
|
Pass::new(tree(&mut p), p.diags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a syntax tree.
|
/// Parse a syntax tree.
|
||||||
fn tree(p: &mut Parser) -> Tree {
|
fn tree(p: &mut Parser) -> SyntaxTree {
|
||||||
tree_while(p, true, &mut |_| true)
|
tree_while(p, true, &mut |_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a syntax tree that stays right of the column at the start of the next
|
/// Parse a syntax tree that stays right of the column at the start of the next
|
||||||
/// non-whitespace token.
|
/// non-whitespace token.
|
||||||
fn tree_indented(p: &mut Parser) -> Tree {
|
fn tree_indented(p: &mut Parser) -> SyntaxTree {
|
||||||
p.eat_while(|t| match t {
|
p.eat_while(|t| match t {
|
||||||
Token::Space(n) => n == 0,
|
Token::Space(n) => n == 0,
|
||||||
Token::LineComment(_) | Token::BlockComment(_) => true,
|
Token::LineComment(_) | Token::BlockComment(_) => true,
|
||||||
@ -46,7 +46,7 @@ fn tree_indented(p: &mut Parser) -> Tree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a syntax 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
|
where
|
||||||
F: FnMut(&mut Parser) -> bool,
|
F: FnMut(&mut Parser) -> bool,
|
||||||
{
|
{
|
||||||
@ -72,7 +72,7 @@ where
|
|||||||
tree_while(self.p, true, self.f)
|
tree_while(self.p, true, self.f)
|
||||||
} else {
|
} else {
|
||||||
self.p.diag(error!(call.callee.span(), "duplicate wide call"));
|
self.p.diag(error!(call.callee.span(), "duplicate wide call"));
|
||||||
Tree::default()
|
SyntaxTree::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
call.args.items.push(CallArg::Pos(Expr::Template(TemplateExpr {
|
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) {
|
fn pretty(&self, p: &mut Printer) {
|
||||||
for node in self {
|
for node in self {
|
||||||
node.pretty(p);
|
node.pretty(p);
|
||||||
@ -630,10 +630,10 @@ mod tests {
|
|||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn test_parse(src: &str, exp: &str) {
|
fn test_parse(src: &str, exp: &str) {
|
||||||
let tree = parse(src).output;
|
let ast = parse(src).output;
|
||||||
let found = pretty(&tree);
|
let found = pretty(&ast);
|
||||||
if exp != found {
|
if exp != found {
|
||||||
println!("tree: {:#?}", tree);
|
println!("tree: {:#?}", ast);
|
||||||
println!("expected: {}", exp);
|
println!("expected: {}", exp);
|
||||||
println!("found: {}", found);
|
println!("found: {}", found);
|
||||||
panic!("test failed");
|
panic!("test failed");
|
||||||
|
@ -158,7 +158,7 @@ pub struct TemplateExpr {
|
|||||||
/// The source code location.
|
/// The source code location.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// The contents of the template.
|
/// The contents of the template.
|
||||||
pub tree: Rc<Tree>,
|
pub tree: Rc<SyntaxTree>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A grouped expression: `(1 + 2)`.
|
/// A grouped expression: `(1 + 2)`.
|
||||||
|
@ -16,4 +16,4 @@ pub use token::*;
|
|||||||
/// The abstract syntax tree.
|
/// The abstract syntax tree.
|
||||||
///
|
///
|
||||||
/// This type can represent a full parsed document.
|
/// 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).
|
/// The section depth (numer of equals signs).
|
||||||
pub level: usize,
|
pub level: usize,
|
||||||
/// The contents of the heading.
|
/// The contents of the heading.
|
||||||
pub body: Rc<Tree>,
|
pub body: Rc<SyntaxTree>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An item in an unordered list: `- ...`.
|
/// An item in an unordered list: `- ...`.
|
||||||
@ -61,7 +61,7 @@ pub struct ListItem {
|
|||||||
/// The source code location.
|
/// The source code location.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// The contents of the list item.
|
/// The contents of the list item.
|
||||||
pub body: Tree,
|
pub body: SyntaxTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An item in an enumeration (ordered list): `1. ...`.
|
/// An item in an enumeration (ordered list): `1. ...`.
|
||||||
@ -72,5 +72,5 @@ pub struct EnumItem {
|
|||||||
/// The number, if any.
|
/// The number, if any.
|
||||||
pub number: Option<usize>,
|
pub number: Option<usize>,
|
||||||
/// The contents of the list item.
|
/// The contents of the list item.
|
||||||
pub body: Tree,
|
pub body: SyntaxTree,
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ macro_rules! impl_visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_visitors! {
|
impl_visitors! {
|
||||||
visit_tree(v, tree: Tree) {
|
visit_tree(v, tree: SyntaxTree) {
|
||||||
for node in tree {
|
for node in tree {
|
||||||
v.visit_node(node);
|
v.visit_node(node);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user