diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-16 22:14:27 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-16 22:39:21 +0200 |
| commit | 30f16bbf6431ca0c174ca0a1abaa6a13ef50ab06 (patch) | |
| tree | f5a5c0adad15840ebe24b39e77ff467862067c91 /src/compute/scope.rs | |
| parent | 9f6137d8a829fe8f34554623495fa620252a0184 (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.rs | 50 |
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() + } +} |
