summaryrefslogtreecommitdiff
path: root/src/eval/machine.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-05-25 11:46:51 +0200
committerLaurenz <laurmaedje@gmail.com>2022-05-25 11:51:28 +0200
commit6935cf8dfefff3d6cf234f077a7d61661fd5ca57 (patch)
treecf40e5c6eb99ff28c62edde75f0eab748672ba30 /src/eval/machine.rs
parent3309ff9fe5ea36134e8ddf11ac2c84613b569856 (diff)
Virtual machine
Diffstat (limited to 'src/eval/machine.rs')
-rw-r--r--src/eval/machine.rs50
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")
+ }
+ }
+ }
+}