diff --git a/src/diag.rs b/src/diag.rs index 329e9a8a9..9d1ec1603 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -7,7 +7,7 @@ use crate::syntax::{Span, Spanned}; /// Early-return with a vec-boxed [`Error`]. macro_rules! bail { ($span:expr, $message:expr $(,)?) => { - return Err($crate::diag::Error::boxed($span, $message)) + return Err($crate::diag::Error::boxed($span, $message).into()) }; ($span:expr, $fmt:expr, $($arg:expr),+ $(,)?) => { @@ -16,7 +16,10 @@ macro_rules! bail { } /// The result type for typesetting and all its subpasses. -pub type TypResult = Result>>; +pub type TypResult = Result; + +/// The error type for typesetting and all its subpasses. +pub type TypError = Box>; /// A result type with a string error message. pub type StrResult = Result; diff --git a/src/eval/mod.rs b/src/eval/mod.rs index bc6c8fc8a..be168d633 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -35,7 +35,7 @@ pub use value::*; use unicode_segmentation::UnicodeSegmentation; -use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypResult}; +use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypError, TypResult}; use crate::geom::{Angle, Fractional, Length, Relative}; use crate::library; use crate::syntax::ast::*; @@ -49,13 +49,46 @@ pub trait Eval { type Output; /// Evaluate the expression to the output value. - fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> TypResult; + 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) -> TypResult { + fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult { eval_markup(ctx, scp, &mut self.nodes()) } } @@ -65,7 +98,7 @@ fn eval_markup( ctx: &mut Context, scp: &mut Scopes, nodes: &mut impl Iterator, -) -> TypResult