summaryrefslogtreecommitdiff
path: root/src/eval/func.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-09-21 17:50:58 +0200
committerLaurenz <laurmaedje@gmail.com>2022-09-21 20:25:57 +0200
commitddd3b6a82b8c0353c942bfba8b89ca5476eedc58 (patch)
treea64c350f0f1f82152ff18cfb02fbfdbf39292672 /src/eval/func.rs
parent3760748fddd3b793c79c370398a9d4a3fc5afc04 (diff)
Tracked memoization
Diffstat (limited to 'src/eval/func.rs')
-rw-r--r--src/eval/func.rs24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/eval/func.rs b/src/eval/func.rs
index b8730a8a..c307b237 100644
--- a/src/eval/func.rs
+++ b/src/eval/func.rs
@@ -2,7 +2,9 @@ use std::fmt::{self, Debug, Formatter};
use std::hash::{Hash, Hasher};
use std::sync::Arc;
-use super::{Args, Eval, Flow, Scope, Scopes, Value, Vm};
+use comemo::{Track, Tracked};
+
+use super::{Args, Eval, Flow, Route, Scope, Scopes, Value, Vm};
use crate::diag::{SourceResult, StrResult};
use crate::model::{Content, NodeId, StyleMap};
use crate::source::SourceId;
@@ -100,8 +102,13 @@ impl Func {
}
/// Call the function without an existing virtual machine.
- pub fn call_detached(&self, world: &dyn World, args: Args) -> SourceResult<Value> {
- let mut vm = Vm::new(world, vec![], Scopes::new(None));
+ pub fn call_detached(
+ &self,
+ world: Tracked<dyn World>,
+ args: Args,
+ ) -> SourceResult<Value> {
+ let route = Route::default();
+ let mut vm = Vm::new(world, route.track(), None, Scopes::new(None));
self.call(&mut vm, args)
}
@@ -220,15 +227,12 @@ impl Closure {
}
// Determine the route inside the closure.
- let detached = vm.route.is_empty();
- let route = if detached {
- self.location.into_iter().collect()
- } else {
- vm.route.clone()
- };
+ let detached = vm.location.is_none();
+ let fresh = Route::new(self.location);
+ let route = if detached { fresh.track() } else { vm.route };
// Evaluate the body.
- let mut sub = Vm::new(vm.world, route, scopes);
+ let mut sub = Vm::new(vm.world, route, self.location, scopes);
let result = self.body.eval(&mut sub);
// Handle control flow.