diff options
Diffstat (limited to 'src/eval/mod.rs')
| -rw-r--r-- | src/eval/mod.rs | 84 |
1 files changed, 37 insertions, 47 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index ae330134..d05f2ddf 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -34,9 +34,10 @@ use std::path::PathBuf; use unicode_segmentation::UnicodeSegmentation; use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypResult}; -use crate::geom::{Angle, Fractional, Length, Relative, Spec}; +use crate::geom::{Angle, Fractional, Length, Relative}; use crate::image::ImageStore; -use crate::library::{GridNode, TextNode, TrackSizing}; +use crate::layout::RootNode; +use crate::library::{self, TextNode}; use crate::loading::Loader; use crate::source::{SourceId, SourceStore}; use crate::syntax::ast::*; @@ -44,15 +45,9 @@ use crate::syntax::{Span, Spanned}; use crate::util::{EcoString, RefMutExt}; use crate::Context; -/// Evaluate a parsed source file into a module. -pub fn eval(ctx: &mut Context, source: SourceId, markup: &Markup) -> TypResult<Module> { - let mut ctx = EvalContext::new(ctx, source); - let node = markup.eval(&mut ctx)?; - Ok(Module { scope: ctx.scopes.top, node }) -} - -/// An evaluated module, ready for importing or instantiation. -#[derive(Debug, Clone)] +/// An evaluated module, ready for importing or conversion to a root layout +/// tree. +#[derive(Debug, Default, Clone)] pub struct Module { /// The top-level definitions that were bound in this module. pub scope: Scope, @@ -60,6 +55,22 @@ pub struct Module { pub node: Node, } +impl Module { + /// Convert this module's node into a layout tree. + pub fn into_root(self) -> RootNode { + self.node.into_root() + } +} + +/// Evaluate an expression. +pub trait Eval { + /// The output of evaluating the expression. + type Output; + + /// Evaluate the expression to the output value. + fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output>; +} + /// The context for evaluation. pub struct EvalContext<'a> { /// The loader from which resources (files and images) are loaded. @@ -124,7 +135,7 @@ impl<'a> EvalContext<'a> { self.route.push(id); // Evaluate the module. - let template = ast.eval(self).trace(|| Tracepoint::Import, span)?; + let node = ast.eval(self).trace(|| Tracepoint::Import, span)?; // Restore the old context. let new_scopes = mem::replace(&mut self.scopes, prev_scopes); @@ -132,7 +143,7 @@ impl<'a> EvalContext<'a> { self.route.pop().unwrap(); // Save the evaluated module. - let module = Module { scope: new_scopes.top, node: template }; + let module = Module { scope: new_scopes.top, node }; self.modules.insert(id, module); Ok(id) @@ -151,15 +162,6 @@ impl<'a> EvalContext<'a> { } } -/// Evaluate an expression. -pub trait Eval { - /// The output of evaluating the expression. - type Output; - - /// Evaluate the expression to the output value. - fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output>; -} - impl Eval for Markup { type Output = Node; @@ -231,13 +233,10 @@ impl Eval for HeadingNode { type Output = Node; fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> { - let upscale = (1.6 - 0.1 * self.level() as f64).max(0.75); - let mut styles = Styles::new(); - styles.set(TextNode::STRONG, true); - styles.set(TextNode::SIZE, Relative::new(upscale).into()); - Ok(Node::Block( - self.body().eval(ctx)?.into_block().styled(styles), - )) + Ok(Node::block(library::HeadingNode { + child: self.body().eval(ctx)?.into_block(), + level: self.level(), + })) } } @@ -245,8 +244,10 @@ impl Eval for ListNode { type Output = Node; fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> { - let body = self.body().eval(ctx)?; - labelled(ctx, '•'.into(), body) + Ok(Node::block(library::ListNode { + child: self.body().eval(ctx)?.into_block(), + labelling: library::Unordered, + })) } } @@ -254,22 +255,11 @@ impl Eval for EnumNode { type Output = Node; fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> { - let body = self.body().eval(ctx)?; - let label = format_eco!("{}.", self.number().unwrap_or(1)); - labelled(ctx, label, body) - } -} - -/// Evaluate a labelled list / enum. -fn labelled(_: &mut EvalContext, label: EcoString, body: Node) -> TypResult<Node> { - // Create a grid containing the label, a bit of gutter space and then - // the item's body. - // TODO: Switch to em units for gutter once available. - Ok(Node::block(GridNode { - tracks: Spec::new(vec![TrackSizing::Auto; 2], vec![]), - gutter: Spec::new(vec![TrackSizing::Linear(Length::pt(5.0).into())], vec![]), - children: vec![Node::Text(label).into_block(), body.into_block()], - })) + Ok(Node::block(library::ListNode { + child: self.body().eval(ctx)?.into_block(), + labelling: library::Ordered(self.number()), + })) + } } impl Eval for Expr { |
