diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-10-07 17:07:44 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-10-07 17:07:44 +0200 |
| commit | 537545e7f8351d7677c396456e46568f5a5e2a7a (patch) | |
| tree | f4c7614293246db06c7fa7496458da01b15c3b84 /src/eval/value.rs | |
| parent | ca1256c924f3672feb76dbc2bc2e309eb4fc4cf5 (diff) | |
Evaluation and node-based layouting 🚀
Diffstat (limited to 'src/eval/value.rs')
| -rw-r--r-- | src/eval/value.rs | 71 |
1 files changed, 25 insertions, 46 deletions
diff --git a/src/eval/value.rs b/src/eval/value.rs index 85cb261c..37fd7ead 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -4,10 +4,9 @@ use std::fmt::{self, Debug, Formatter}; use std::ops::Deref; use std::rc::Rc; -use super::{Args, Dict, SpannedEntry}; +use super::{Args, Dict, Eval, EvalContext, SpannedEntry}; use crate::color::RgbaColor; use crate::geom::Linear; -use crate::layout::{Command, LayoutContext}; use crate::syntax::{Ident, Span, SpanWith, Spanned, SynNode, SynTree}; use crate::DynFuture; @@ -45,8 +44,6 @@ pub enum Value { Content(SynTree), /// An executable function. Func(ValueFunc), - /// Layouting commands. - Commands(Vec<Command>), /// The result of invalid operations. Error, } @@ -69,59 +66,42 @@ impl Value { Self::Dict(_) => "dict", Self::Content(_) => "content", Self::Func(_) => "function", - Self::Commands(_) => "commands", Self::Error => "error", } } } -impl Default for Value { - fn default() -> Self { - Value::None - } -} +impl Eval for Value { + type Output = (); -impl Spanned<Value> { - /// Transform this value into something layoutable. - /// - /// If this is already a command-value, it is simply unwrapped, otherwise - /// the value is represented as layoutable content in a reasonable way. - pub fn into_commands(self) -> Vec<Command> { - match self.v { + /// Evaluate everything contained in this value. + fn eval(&self, ctx: &mut EvalContext) -> Self::Output { + match self { // Don't print out none values. - Value::None => vec![], + Value::None => {} - // Pass-through. - Value::Commands(commands) => commands, - Value::Content(tree) => vec![Command::LayoutSyntaxTree(tree)], + // Pass through. + Value::Content(tree) => tree.eval(ctx), - // Forward to each entry, separated with spaces. + // Forward to each dictionary entry. Value::Dict(dict) => { - let mut commands = vec![]; - let mut end = None; - for entry in dict.into_values() { - if let Some(last_end) = end { - let span = Span::new(last_end, entry.key_span.start); - let tree = vec![SynNode::Space.span_with(span)]; - commands.push(Command::LayoutSyntaxTree(tree)); - } - - end = Some(entry.value.span.end); - commands.extend(entry.value.into_commands()); + for entry in dict.values() { + entry.value.v.eval(ctx); } - commands } // Format with debug. - val => { - let fmt = format!("{:?}", val); - let tree = vec![SynNode::Text(fmt).span_with(self.span)]; - vec![Command::LayoutSyntaxTree(tree)] - } + val => ctx.push(ctx.make_text_node(format!("{:?}", val))), } } } +impl Default for Value { + fn default() -> Self { + Value::None + } +} + impl Debug for Value { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { @@ -138,7 +118,6 @@ impl Debug for Value { Self::Dict(v) => v.fmt(f), Self::Content(v) => v.fmt(f), Self::Func(v) => v.fmt(f), - Self::Commands(v) => v.fmt(f), Self::Error => f.pad("<error>"), } } @@ -157,9 +136,9 @@ pub type ValueDict = Dict<SpannedEntry<Value>>; /// The dynamic function object is wrapped in an `Rc` to keep [`Value`] /// clonable. /// -/// _Note_: This is needed because the compiler can't `derive(PartialEq)` -/// for `Value` when directly putting the boxed function in there, -/// see the [Rust Issue]. +/// _Note_: This is needed because the compiler can't `derive(PartialEq)` for +/// [`Value`] when directly putting the boxed function in there, see the +/// [Rust Issue]. /// /// [`Value`]: enum.Value.html /// [Rust Issue]: https://github.com/rust-lang/rust/issues/31740 @@ -167,13 +146,13 @@ pub type ValueDict = Dict<SpannedEntry<Value>>; pub struct ValueFunc(pub Rc<Func>); /// The signature of executable functions. -pub type Func = dyn Fn(Args, &mut LayoutContext) -> DynFuture<Value>; +type Func = dyn Fn(Args, &mut EvalContext) -> Value; impl ValueFunc { /// Create a new function value from a rust function or closure. - pub fn new<F: 'static>(f: F) -> Self + pub fn new<F>(f: F) -> Self where - F: Fn(Args, &mut LayoutContext) -> DynFuture<Value>, + F: Fn(Args, &mut EvalContext) -> Value + 'static, { Self(Rc::new(f)) } |
