diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-17 16:27:40 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-17 18:18:47 +0100 |
| commit | af7fe4d76083c597ec2198a73383b9e3899d75ea (patch) | |
| tree | cb3b9766ee15dbfbecf7f9b9a2257859d7a7b3c7 /src/eval | |
| parent | 6d64d3e8e9123f3fa8166c8b710e2b2c61ed5898 (diff) | |
Hover and autocomplete in show rules
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/array.rs | 14 | ||||
| -rw-r--r-- | src/eval/func.rs | 33 | ||||
| -rw-r--r-- | src/eval/mod.rs | 33 |
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) } } |
