summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-05-28 12:44:44 +0200
committerLaurenz <laurmaedje@gmail.com>2021-05-28 12:46:43 +0200
commit0bfee5b7772338fd39bbf708d3e31ea7bcec859b (patch)
tree5f76c7d0529d6c089e8e3383356692dfce09cffb /src/eval
parenteabf28f08187bd9a10bbadbbaf9617e2bc1949aa (diff)
Refactored loading and cache architecture
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/mod.rs55
-rw-r--r--src/eval/value.rs14
2 files changed, 47 insertions, 22 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index da7fca53..d841dbae 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -10,38 +10,50 @@ pub use capture::*;
pub use scope::*;
pub use value::*;
-use std::collections::HashMap;
use std::rc::Rc;
+use crate::cache::Cache;
use crate::color::Color;
use crate::diag::{Diag, DiagSet, Pass};
-use crate::env::Env;
use crate::geom::{Angle, Length, Relative};
+use crate::loading::Loader;
use crate::syntax::visit::Visit;
use crate::syntax::*;
-/// Evaluate all nodes in a syntax tree.
+/// Evaluated a parsed source file into a module.
///
/// The `scope` consists of the base definitions that are present from the
/// beginning (typically, the standard library).
-pub fn eval(env: &mut Env, tree: &Tree, scope: &Scope) -> Pass<NodeMap> {
- let mut ctx = EvalContext::new(env, scope);
+pub fn eval(
+ loader: &mut dyn Loader,
+ cache: &mut Cache,
+ tree: Rc<Tree>,
+ base: &Scope,
+) -> Pass<Module> {
+ let mut ctx = EvalContext::new(loader, cache, base);
let map = tree.eval(&mut ctx);
- Pass::new(map, ctx.diags)
+ let module = Module {
+ scope: ctx.scopes.top,
+ template: vec![TemplateNode::Tree { tree, map }],
+ };
+ Pass::new(module, ctx.diags)
}
-/// A map from nodes to the values they evaluated to.
-///
-/// The raw pointers point into the nodes contained in some [`Tree`]. Since the
-/// lifetime is erased, the tree could go out of scope while the hash map still
-/// lives. Although this could lead to lookup panics, it is not unsafe since the
-/// pointers are never dereferenced.
-pub type NodeMap = HashMap<*const Node, Value>;
+/// An evaluated module, ready for importing or execution.
+#[derive(Debug, Clone, PartialEq)]
+pub struct Module {
+ /// The top-level definitions that were bound in this module.
+ pub scope: Scope,
+ /// The template defined by this module.
+ pub template: TemplateValue,
+}
/// The context for evaluation.
pub struct EvalContext<'a> {
- /// The environment from which resources are gathered.
- pub env: &'a mut Env,
+ /// The loader from which resources (files and images) are loaded.
+ pub loader: &'a mut dyn Loader,
+ /// A cache for loaded resources.
+ pub cache: &'a mut Cache,
/// The active scopes.
pub scopes: Scopes<'a>,
/// Evaluation diagnostics.
@@ -49,11 +61,16 @@ pub struct EvalContext<'a> {
}
impl<'a> EvalContext<'a> {
- /// Create a new execution context with a base scope.
- pub fn new(env: &'a mut Env, scope: &'a Scope) -> Self {
+ /// Create a new evaluation context with a base scope.
+ pub fn new(
+ loader: &'a mut dyn Loader,
+ cache: &'a mut Cache,
+ base: &'a Scope,
+ ) -> Self {
Self {
- env,
- scopes: Scopes::with_base(scope),
+ loader,
+ cache,
+ scopes: Scopes::with_base(base),
diags: DiagSet::new(),
}
}
diff --git a/src/eval/value.rs b/src/eval/value.rs
index 0d87c28f..d10d734a 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -1,15 +1,15 @@
use std::any::Any;
use std::cmp::Ordering;
-use std::collections::BTreeMap;
+use std::collections::{BTreeMap, HashMap};
use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Deref;
use std::rc::Rc;
-use super::{EvalContext, NodeMap};
+use super::EvalContext;
use crate::color::{Color, RgbaColor};
use crate::exec::ExecContext;
use crate::geom::{Angle, Length, Linear, Relative};
-use crate::syntax::{Span, Spanned, Tree};
+use crate::syntax::{Node, Span, Spanned, Tree};
/// A computational value.
#[derive(Debug, Clone, PartialEq)]
@@ -163,6 +163,14 @@ impl PartialEq for TemplateNode {
}
}
+/// A map from nodes to the values they evaluated to.
+///
+/// The raw pointers point into the nodes contained in some [`Tree`]. Since the
+/// lifetime is erased, the tree could go out of scope while the hash map still
+/// lives. Although this could lead to lookup panics, it is not unsafe since the
+/// pointers are never dereferenced.
+pub type NodeMap = HashMap<*const Node, Value>;
+
/// A reference-counted dynamic template node that can implement custom
/// behaviour.
#[derive(Clone)]