diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-25 11:46:51 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-05-25 11:51:28 +0200 |
| commit | 6935cf8dfefff3d6cf234f077a7d61661fd5ca57 (patch) | |
| tree | cf40e5c6eb99ff28c62edde75f0eab748672ba30 /src/eval/machine.rs | |
| parent | 3309ff9fe5ea36134e8ddf11ac2c84613b569856 (diff) | |
Virtual machine
Diffstat (limited to 'src/eval/machine.rs')
| -rw-r--r-- | src/eval/machine.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/eval/machine.rs b/src/eval/machine.rs new file mode 100644 index 00000000..168cedcb --- /dev/null +++ b/src/eval/machine.rs @@ -0,0 +1,50 @@ +use super::{Scopes, Value}; +use crate::diag::TypError; +use crate::syntax::Span; +use crate::Context; + +/// A virtual machine. +pub struct Machine<'a> { + /// The core context. + pub ctx: &'a mut Context, + /// The stack of scopes. + pub scopes: Scopes<'a>, + /// A control flow event that is currently happening. + pub flow: Option<Flow>, +} + +impl<'a> Machine<'a> { + /// Create a new virtual machine. + pub fn new(ctx: &'a mut Context, scopes: Scopes<'a>) -> Self { + Self { ctx, scopes, flow: None } + } +} + +/// A control flow event that occurred during evaluation. +#[derive(Debug, Clone, PartialEq)] +pub enum Flow { + /// Stop iteration in a loop. + Break(Span), + /// Skip the remainder of the current iteration in a loop. + Continue(Span), + /// Stop execution of a function early, optionally returning an explicit + /// value. + Return(Span, Option<Value>), +} + +impl Flow { + /// Return an error stating that this control flow is forbidden. + pub fn forbidden(&self) -> TypError { + match *self { + Self::Break(span) => { + error!(span, "cannot break outside of loop") + } + Self::Continue(span) => { + error!(span, "cannot continue outside of loop") + } + Self::Return(span, _) => { + error!(span, "cannot return outside of function") + } + } + } +} |
