summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/array.rs14
-rw-r--r--src/eval/func.rs33
-rw-r--r--src/eval/mod.rs33
3 files changed, 43 insertions, 37 deletions
diff --git a/src/eval/array.rs b/src/eval/array.rs
index 979f15d4..e42fd28d 100644
--- a/src/eval/array.rs
+++ b/src/eval/array.rs
@@ -144,7 +144,7 @@ impl Array {
}
for item in self.iter() {
let args = Args::new(func.span(), [item.clone()]);
- if func.call(vm, args)?.cast::<bool>().at(func.span())? {
+ if func.call_vm(vm, args)?.cast::<bool>().at(func.span())? {
return Ok(Some(item.clone()));
}
}
@@ -158,7 +158,7 @@ impl Array {
}
for (i, item) in self.iter().enumerate() {
let args = Args::new(func.span(), [item.clone()]);
- if func.call(vm, args)?.cast::<bool>().at(func.span())? {
+ if func.call_vm(vm, args)?.cast::<bool>().at(func.span())? {
return Ok(Some(i as i64));
}
}
@@ -175,7 +175,7 @@ impl Array {
let mut kept = EcoVec::new();
for item in self.iter() {
let args = Args::new(func.span(), [item.clone()]);
- if func.call(vm, args)?.cast::<bool>().at(func.span())? {
+ if func.call_vm(vm, args)?.cast::<bool>().at(func.span())? {
kept.push(item.clone())
}
}
@@ -196,7 +196,7 @@ impl Array {
args.push(func.span(), Value::Int(i as i64));
}
args.push(func.span(), item.clone());
- func.call(vm, args)
+ func.call_vm(vm, args)
})
.collect()
}
@@ -209,7 +209,7 @@ impl Array {
let mut acc = init;
for item in self.iter() {
let args = Args::new(func.span(), [acc, item.clone()]);
- acc = func.call(vm, args)?;
+ acc = func.call_vm(vm, args)?;
}
Ok(acc)
}
@@ -221,7 +221,7 @@ impl Array {
}
for item in self.iter() {
let args = Args::new(func.span(), [item.clone()]);
- if func.call(vm, args)?.cast::<bool>().at(func.span())? {
+ if func.call_vm(vm, args)?.cast::<bool>().at(func.span())? {
return Ok(true);
}
}
@@ -236,7 +236,7 @@ impl Array {
}
for item in self.iter() {
let args = Args::new(func.span(), [item.clone()]);
- if !func.call(vm, args)?.cast::<bool>().at(func.span())? {
+ if !func.call_vm(vm, args)?.cast::<bool>().at(func.span())? {
return Ok(false);
}
}
diff --git a/src/eval/func.rs b/src/eval/func.rs
index a5fa6fa1..c3ec4233 100644
--- a/src/eval/func.rs
+++ b/src/eval/func.rs
@@ -13,7 +13,7 @@ use super::{
Vm,
};
use crate::diag::{bail, SourceResult, StrResult};
-use crate::model::{NodeId, Selector, StyleMap};
+use crate::model::{NodeId, Selector, StyleMap, Vt};
use crate::syntax::ast::{self, AstNode, Expr};
use crate::syntax::{SourceId, Span, SyntaxNode};
use crate::util::hash128;
@@ -82,7 +82,7 @@ impl Func {
}
/// Call the function with the given arguments.
- pub fn call(&self, vm: &mut Vm, mut args: Args) -> SourceResult<Value> {
+ pub fn call_vm(&self, vm: &mut Vm, mut args: Args) -> SourceResult<Value> {
match &**self.0 {
Repr::Native(native) => {
let value = (native.func)(vm, &mut args)?;
@@ -111,23 +111,29 @@ impl Func {
}
Repr::With(wrapped, applied) => {
args.items = applied.items.iter().cloned().chain(args.items).collect();
- return wrapped.call(vm, args);
+ return wrapped.call_vm(vm, args);
}
}
}
- /// Call the function without an existing virtual machine.
- pub fn call_detached(
+ /// Call the function with a Vt.
+ pub fn call_vt(
&self,
- world: Tracked<dyn World>,
- args: Args,
+ vt: &mut Vt,
+ args: impl IntoIterator<Item = Value>,
) -> SourceResult<Value> {
let route = Route::default();
let id = SourceId::detached();
let scopes = Scopes::new(None);
- let mut tracer = Tracer::default();
- let mut vm = Vm::new(world, route.track(), tracer.track_mut(), id, scopes, 0);
- self.call(&mut vm, args)
+ let mut vm = Vm::new(
+ vt.world,
+ route.track(),
+ TrackedMut::reborrow_mut(&mut vt.tracer),
+ id,
+ scopes,
+ );
+ let args = Args::new(self.span(), args);
+ self.call_vm(&mut vm, args)
}
/// Apply the given arguments to the function.
@@ -208,7 +214,7 @@ impl From<NodeId> for Func {
/// A native Rust function.
pub struct NativeFunc {
/// The function's implementation.
- pub func: fn(&Vm, &mut Args) -> SourceResult<Value>,
+ pub func: fn(&mut Vm, &mut Args) -> SourceResult<Value>,
/// Details about the function.
pub info: Lazy<FuncInfo>,
}
@@ -352,10 +358,11 @@ impl Closure {
args.finish()?;
// Evaluate the body.
- let mut sub = Vm::new(world, route, tracer, closure.location, scopes, depth);
- let result = closure.body.eval(&mut sub);
+ let mut sub = Vm::new(world, route, tracer, closure.location, scopes);
+ sub.depth = depth;
// Handle control flow.
+ let result = closure.body.eval(&mut sub);
match sub.flow {
Some(Flow::Return(_, Some(explicit))) => return Ok(explicit),
Some(Flow::Return(_, None)) => {}
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 127c930f..1c002c49 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -81,7 +81,7 @@ pub fn eval(
// Evaluate the module.
let route = unsafe { Route::insert(route, id) };
let scopes = Scopes::new(Some(library));
- let mut vm = Vm::new(world, route.track(), tracer, id, scopes, 0);
+ let mut vm = Vm::new(world, route.track(), tracer, id, scopes);
let root = match source.root().cast::<ast::Markup>() {
Some(markup) if vm.traced.is_some() => markup,
_ => source.ast()?,
@@ -121,7 +121,7 @@ pub fn eval_code_str(
let scopes = Scopes::new(Some(library));
let route = Route::default();
let mut tracer = Tracer::default();
- let mut vm = Vm::new(world, route.track(), tracer.track_mut(), id, scopes, 0);
+ let mut vm = Vm::new(world, route.track(), tracer.track_mut(), id, scopes);
let code = root.cast::<ast::Code>().unwrap();
let result = code.eval(&mut vm);
@@ -139,34 +139,33 @@ pub fn eval_code_str(
/// virtual machine is created for each module evaluation and function call.
pub struct Vm<'a> {
/// The compilation environment.
- pub(super) world: Tracked<'a, dyn World>,
+ world: Tracked<'a, dyn World>,
/// The language items.
- pub(super) items: LangItems,
+ items: LangItems,
/// The route of source ids the VM took to reach its current location.
- pub(super) route: Tracked<'a, Route>,
+ route: Tracked<'a, Route>,
/// The tracer for inspection of the values an expression produces.
- pub(super) tracer: TrackedMut<'a, Tracer>,
+ tracer: TrackedMut<'a, Tracer>,
/// The current location.
- pub(super) location: SourceId,
+ location: SourceId,
/// A control flow event that is currently happening.
- pub(super) flow: Option<Flow>,
+ flow: Option<Flow>,
/// The stack of scopes.
- pub(super) scopes: Scopes<'a>,
+ scopes: Scopes<'a>,
/// The current call depth.
- pub(super) depth: usize,
+ depth: usize,
/// A span that is currently traced.
- pub(super) traced: Option<Span>,
+ traced: Option<Span>,
}
impl<'a> Vm<'a> {
/// Create a new virtual machine.
- pub(super) fn new(
+ fn new(
world: Tracked<'a, dyn World>,
route: Tracked<'a, Route>,
tracer: TrackedMut<'a, Tracer>,
location: SourceId,
scopes: Scopes<'a>,
- depth: usize,
) -> Self {
let traced = tracer.span(location);
Self {
@@ -177,7 +176,7 @@ impl<'a> Vm<'a> {
location,
flow: None,
scopes,
- depth,
+ depth: 0,
traced,
}
}
@@ -358,7 +357,7 @@ fn eval_markup(
}
let tail = eval_markup(vm, exprs)?;
- seq.push(tail.styled_with_recipe(vm.world, recipe)?)
+ seq.push(tail.styled_with_recipe(vm, recipe)?)
}
expr => match expr.eval(vm)? {
Value::Label(label) => {
@@ -791,7 +790,7 @@ fn eval_code(
}
let tail = eval_code(vm, exprs)?.display();
- Value::Content(tail.styled_with_recipe(vm.world, recipe)?)
+ Value::Content(tail.styled_with_recipe(vm, recipe)?)
}
_ => expr.eval(vm)?,
};
@@ -1053,7 +1052,7 @@ impl Eval for ast::FuncCall {
let callee = callee.cast::<Func>().at(callee_span)?;
let point = || Tracepoint::Call(callee.name().map(Into::into));
- callee.call(vm, args).trace(vm.world, point, span)
+ callee.call_vm(vm, args).trace(vm.world, point, span)
}
}