diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-19 20:49:01 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-19 20:49:01 +0200 |
| commit | 77dac270a8a99f24a6fc0eb9e92256bcc07c586c (patch) | |
| tree | 8e240b798a5c1aabd77c823e65828f3c6d2557f1 /src/syntax/tree.rs | |
| parent | 6d7e7d945b315469b80bca3466a96534b2a17639 (diff) | |
Make compute functions possible 💻
Ships with the amazing new `rgb` function!
Diffstat (limited to 'src/syntax/tree.rs')
| -rw-r--r-- | src/syntax/tree.rs | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/syntax/tree.rs b/src/syntax/tree.rs index e7a1eaf1..47c79117 100644 --- a/src/syntax/tree.rs +++ b/src/syntax/tree.rs @@ -5,7 +5,10 @@ use std::fmt::{self, Debug, Formatter}; use crate::color::RgbaColor; use crate::compute::table::{SpannedEntry, Table}; use crate::compute::value::{TableValue, Value}; +use crate::layout::LayoutContext; use crate::length::Length; +use crate::{DynFuture, Feedback}; +use super::decoration::Decoration; use super::span::{Spanned, SpanVec}; use super::Ident; @@ -91,7 +94,11 @@ impl Expr { } /// Evaluate the expression to a value. - pub fn eval(&self) -> Value { + pub async fn eval( + &self, + ctx: &LayoutContext<'_>, + f: &mut Feedback, + ) -> Value { use Expr::*; match self { Ident(i) => Value::Ident(i.clone()), @@ -100,9 +107,9 @@ impl Expr { &Number(n) => Value::Number(n), &Length(s) => Value::Length(s), &Color(c) => Value::Color(c), - Table(t) => Value::Table(t.eval()), + Table(t) => Value::Table(t.eval(ctx, f).await), Tree(t) => Value::Tree(t.clone()), - Call(_) => todo!("eval call"), + Call(call) => call.eval(ctx, f).await, Neg(_) => todo!("eval neg"), Add(_, _) => todo!("eval add"), Sub(_, _) => todo!("eval sub"), @@ -144,18 +151,23 @@ pub type TableExpr = Table<SpannedEntry<Expr>>; impl TableExpr { /// Evaluate the table expression to a table value. - pub fn eval(&self) -> TableValue { - let mut table = TableValue::new(); + pub fn eval<'a>( + &'a self, + ctx: &'a LayoutContext<'a>, + f: &'a mut Feedback, + ) -> DynFuture<'a, TableValue> { + Box::pin(async move { + let mut table = TableValue::new(); - for (&key, entry) in self.nums() { - table.insert(key, entry.as_ref().map(|val| val.eval())); - } - - for (key, entry) in self.strs() { - table.insert(key.clone(), entry.as_ref().map(|val| val.eval())); - } + for (key, entry) in self.iter() { + let val = entry.val.v.eval(ctx, f).await; + let spanned = Spanned::new(val, entry.val.span); + let entry = SpannedEntry::new(entry.key, spanned); + table.insert(key, entry); + } - table + table + }) } } @@ -165,3 +177,23 @@ pub struct CallExpr { pub name: Spanned<Ident>, pub args: TableExpr, } + +impl CallExpr { + /// Evaluate the call expression to a value. + pub async fn eval(&self, ctx: &LayoutContext<'_>, f: &mut Feedback) -> Value { + let name = self.name.v.as_str(); + let span = self.name.span; + let args = self.args.eval(ctx, f).await; + + if let Some(func) = ctx.scope.func(name) { + let pass = func(span, args, ctx.clone()).await; + f.extend(pass.feedback); + f.decorations.push(Spanned::new(Decoration::Resolved, span)); + pass.output + } else { + error!(@f, span, "unknown function"); + f.decorations.push(Spanned::new(Decoration::Unresolved, span)); + Value::Table(args) + } + } +} |
