use comemo::Tracked;
use crate::engine::Engine;
use crate::eval::FlowEvent;
use crate::foundations::{Context, IntoValue, Scopes, Value};
use crate::syntax::ast::{self, AstNode};
use crate::syntax::Span;
use crate::World;
pub struct Vm<'a> {
pub(crate) engine: Engine<'a>,
pub(crate) flow: Option<FlowEvent>,
pub(crate) scopes: Scopes<'a>,
pub(crate) inspected: Option<Span>,
pub(crate) context: Tracked<'a, Context<'a>>,
}
impl<'a> Vm<'a> {
pub fn new(
engine: Engine<'a>,
context: Tracked<'a, Context<'a>>,
scopes: Scopes<'a>,
target: Span,
) -> Self {
let inspected = target.id().and_then(|id| engine.traced.get(id));
Self { engine, context, flow: None, scopes, inspected }
}
pub fn world(&self) -> Tracked<'a, dyn World + 'a> {
self.engine.world
}
pub fn define(&mut self, var: ast::Ident, value: impl IntoValue) {
let value = value.into_value();
if self.inspected == Some(var.span()) {
self.trace(value.clone());
}
self.scopes.top.define_ident(var, value);
}
#[cold]
pub fn trace(&mut self, value: Value) {
self.engine
.sink
.value(value.clone(), self.context.styles().ok().map(|s| s.to_map()));
}
}