summaryrefslogtreecommitdiff
path: root/src/compute/scope.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-16 22:14:27 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-16 22:39:21 +0200
commit30f16bbf6431ca0c174ca0a1abaa6a13ef50ab06 (patch)
treef5a5c0adad15840ebe24b39e77ff467862067c91 /src/compute/scope.rs
parent9f6137d8a829fe8f34554623495fa620252a0184 (diff)
Add Value type and replace dyn-nodes with call-exprs 🏗
- In addition to syntax trees there are now `Value`s, which syntax trees can be evaluated into (e.g. the tree is `5+5` and the value is `10`) - Parsing is completely pure, function calls are not parsed into nodes, but into simple call expressions, which are resolved later - Functions aren't dynamic nodes anymore, but simply functions which receive their arguments as a table and the layouting context - Functions may return any `Value` - Layouting is powered by functions which return the new `Commands` value, which informs the layouting engine what to do - When a function returns a non-`Commands` value, the layouter simply dumps the value into the document in monospace
Diffstat (limited to 'src/compute/scope.rs')
-rw-r--r--src/compute/scope.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/compute/scope.rs b/src/compute/scope.rs
new file mode 100644
index 00000000..1fd4db0b
--- /dev/null
+++ b/src/compute/scope.rs
@@ -0,0 +1,50 @@
+//! Mapping from identifiers to functions.
+
+use std::collections::HashMap;
+use std::fmt::{self, Debug, Formatter};
+
+use super::value::FuncValue;
+
+/// A map from identifiers to functions.
+pub struct Scope {
+ functions: HashMap<String, FuncValue>,
+ fallback: FuncValue,
+}
+
+impl Scope {
+ // Create a new empty scope with a fallback function that is invoked when no
+ // match is found.
+ pub fn new(fallback: FuncValue) -> Self {
+ Self {
+ functions: HashMap::new(),
+ fallback,
+ }
+ }
+
+ /// Associate the given name with the function.
+ pub fn insert(&mut self, name: impl Into<String>, function: FuncValue) {
+ self.functions.insert(name.into(), function);
+ }
+
+ /// Return the function with the given name if there is one.
+ pub fn func(&self, name: &str) -> Option<&FuncValue> {
+ self.functions.get(name)
+ }
+
+ /// Return the function with the given name or the fallback if there is no
+ /// such function.
+ pub fn func_or_fallback(&self, name: &str) -> &FuncValue {
+ self.func(name).unwrap_or_else(|| self.fallback())
+ }
+
+ /// Return the fallback function.
+ pub fn fallback(&self) -> &FuncValue {
+ &self.fallback
+ }
+}
+
+impl Debug for Scope {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.debug_set().entries(self.functions.keys()).finish()
+ }
+}