From d007788db8bfc53089125456510216ea94667ff5 Mon Sep 17 00:00:00 2001 From: Martin Haug Date: Mon, 28 Feb 2022 13:18:29 +0100 Subject: Introduce `EvalResult` for control flow --- src/eval/mod.rs | 131 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 47 deletions(-) (limited to 'src/eval') diff --git a/src/eval/mod.rs b/src/eval/mod.rs index bc6c8fc8..be168d63 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