summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-23 10:54:25 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-23 12:00:06 +0100
commitb2a3d3f235fb5a23322435b854460f52db772114 (patch)
tree441ded5e4fcc0a702fe877fc6a3e3fedaaacabb5 /src/model
parent65aa27014d090628cfef14b0679d86dd611188b9 (diff)
More general evaluation interface
Diffstat (limited to 'src/model')
-rw-r--r--src/model/eval.rs25
-rw-r--r--src/model/func.rs8
-rw-r--r--src/model/items.rs4
-rw-r--r--src/model/vm.rs8
4 files changed, 23 insertions, 22 deletions
diff --git a/src/model/eval.rs b/src/model/eval.rs
index 7c0cffb5..7f2cea63 100644
--- a/src/model/eval.rs
+++ b/src/model/eval.rs
@@ -13,7 +13,7 @@ use super::{
use crate::diag::{bail, error, At, SourceResult, StrResult, Trace, Tracepoint};
use crate::geom::{Abs, Angle, Em, Fr, Ratio};
use crate::syntax::ast::AstNode;
-use crate::syntax::{ast, SourceId, Span, Spanned, Unit};
+use crate::syntax::{ast, Source, SourceId, Span, Spanned, Unit};
use crate::util::{format_eco, EcoString};
use crate::World;
@@ -26,9 +26,10 @@ use crate::World;
pub fn eval(
world: Tracked<dyn World>,
route: Tracked<Route>,
- id: SourceId,
+ source: &Source,
) -> SourceResult<Module> {
// Prevent cyclic evaluation.
+ let id = source.id();
if route.contains(id) {
let path = world.source(id).path().display();
panic!("Tried to cyclicly evaluate {}", path);
@@ -36,11 +37,10 @@ pub fn eval(
// Evaluate the module.
let route = unsafe { Route::insert(route, id) };
- let ast = world.source(id).ast()?;
let std = &world.config().scope;
let scopes = Scopes::new(Some(std));
- let mut vm = Vm::new(world, route.track(), Some(id), scopes);
- let result = ast.eval(&mut vm);
+ let mut vm = Vm::new(world, route.track(), id, scopes);
+ let result = source.ast()?.eval(&mut vm);
// Handle control flow.
if let Some(flow) = vm.flow {
@@ -59,9 +59,9 @@ pub struct Route {
}
impl Route {
- /// Create a new, empty route.
- pub fn new(id: Option<SourceId>) -> Self {
- Self { id, parent: None }
+ /// Create a new route with just one entry.
+ pub fn new(id: SourceId) -> Self {
+ Self { id: Some(id), parent: None }
}
/// Insert a new id into the route.
@@ -94,7 +94,7 @@ pub struct Module {
}
/// Evaluate an expression.
-pub trait Eval {
+pub(super) trait Eval {
/// The output of evaluating the expression.
type Output;
@@ -1038,10 +1038,9 @@ fn import(vm: &mut Vm, path: &str, span: Span) -> SourceResult<Module> {
}
// Evaluate the file.
- let module =
- eval(vm.world, vm.route, id).trace(vm.world, || Tracepoint::Import, span)?;
-
- Ok(module)
+ let source = vm.world.source(id);
+ let point = || Tracepoint::Import;
+ eval(vm.world, vm.route, source).trace(vm.world, point, span)
}
impl Eval for ast::LoopBreak {
diff --git a/src/model/func.rs b/src/model/func.rs
index f313dcda..d84a8170 100644
--- a/src/model/func.rs
+++ b/src/model/func.rs
@@ -97,7 +97,9 @@ impl Func {
args: Args,
) -> SourceResult<Value> {
let route = Route::default();
- let mut vm = Vm::new(world, route.track(), None, Scopes::new(None));
+ let id = SourceId::detached();
+ let scopes = Scopes::new(None);
+ let mut vm = Vm::new(world, route.track(), id, scopes);
self.call(&mut vm, args)
}
@@ -178,7 +180,7 @@ impl Hash for Native {
#[derive(Hash)]
pub struct Closure {
/// The source file where the closure was defined.
- pub location: Option<SourceId>,
+ pub location: SourceId,
/// The name of the closure.
pub name: Option<EcoString>,
/// Captured values from outer scopes.
@@ -219,7 +221,7 @@ impl Closure {
}
// Determine the route inside the closure.
- let detached = vm.location.is_none();
+ let detached = vm.location.is_detached();
let fresh = Route::new(self.location);
let route = if detached { fresh.track() } else { vm.route };
diff --git a/src/model/items.rs b/src/model/items.rs
index 771756fe..50ea8b60 100644
--- a/src/model/items.rs
+++ b/src/model/items.rs
@@ -42,7 +42,7 @@ macro_rules! item {
#[derive(Copy, Clone)]
pub struct LangItems {
/// The root layout function.
- pub root: fn(
+ pub layout: fn(
content: &Content,
world: Tracked<dyn World>,
styles: StyleChain,
@@ -104,7 +104,7 @@ impl Debug for LangItems {
impl Hash for LangItems {
fn hash<H: Hasher>(&self, state: &mut H) {
- (self.root as usize).hash(state);
+ (self.layout as usize).hash(state);
(self.em as usize).hash(state);
(self.dir as usize).hash(state);
self.space.hash(state);
diff --git a/src/model/vm.rs b/src/model/vm.rs
index db0bf77c..28885f29 100644
--- a/src/model/vm.rs
+++ b/src/model/vm.rs
@@ -15,7 +15,7 @@ pub struct Vm<'a> {
/// The route of source ids the VM took to reach its current location.
pub route: Tracked<'a, Route>,
/// The current location.
- pub location: Option<SourceId>,
+ pub location: SourceId,
/// The stack of scopes.
pub scopes: Scopes<'a>,
/// A control flow event that is currently happening.
@@ -29,7 +29,7 @@ impl<'a> Vm<'a> {
pub fn new(
world: Tracked<'a, dyn World>,
route: Tracked<'a, Route>,
- location: Option<SourceId>,
+ location: SourceId,
scopes: Scopes<'a>,
) -> Self {
Self {
@@ -45,12 +45,12 @@ impl<'a> Vm<'a> {
/// Resolve a user-entered path to be relative to the compilation
/// environment's root.
pub fn locate(&self, path: &str) -> StrResult<PathBuf> {
- if let Some(id) = self.location {
+ if !self.location.is_detached() {
if let Some(path) = path.strip_prefix('/') {
return Ok(self.world.config().root.join(path).normalize());
}
- if let Some(dir) = self.world.source(id).path().parent() {
+ if let Some(dir) = self.world.source(self.location).path().parent() {
return Ok(dir.join(path).normalize());
}
}