//! Evaluation of markup into modules. #[macro_use] mod array; #[macro_use] mod dict; #[macro_use] mod value; #[macro_use] mod styles; mod capture; mod class; mod collapse; mod func; mod layout; mod module; mod ops; mod scope; mod show; mod template; pub use array::*; pub use capture::*; pub use class::*; pub use collapse::*; pub use dict::*; pub use func::*; pub use layout::*; pub use module::*; pub use scope::*; pub use show::*; pub use styles::*; pub use template::*; pub use value::*; use unicode_segmentation::UnicodeSegmentation; use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypError, TypResult}; use crate::geom::{Angle, Fractional, Length, Relative}; use crate::library; use crate::syntax::ast::*; use crate::syntax::{Span, Spanned}; use crate::util::EcoString; use crate::Context; /// 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 Context, scp: &mut Scopes) -> EvalResult; } /// The result type for evaluating a syntactic construct. pub type EvalResult = Result; /// A control flow event that occurred during evaluation. #[derive(Clone, Debug, PartialEq)] pub enum Control { Break(Span), Continue(Span), Return(Option, Span), Err(TypError), } impl From for Control { fn from(error: TypError) -> Self { Self::Err(error) } } impl From for TypError { fn from(control: Control) -> Self { match control { Control::Break(span) => Error::boxed(span, "cannot break outside of loop"), Control::Continue(span) => { Error::boxed(span, "cannot continue outside of loop") } Control::Return(_, span) => { Error::boxed(span, "cannot return outside of function") } Control::Err(e) => e, } } } impl Eval for Markup { type Output = Template; fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult { eval_markup(ctx, scp, &mut self.nodes()) } } /// Evaluate a stream of markup nodes. fn eval_markup( ctx: &mut Context, scp: &mut Scopes, nodes: &mut impl Iterator, ) -> EvalResult