diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-11-23 12:45:20 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-11-23 12:45:20 +0100 |
| commit | 4f9e5819bbab1f93ad4f4b789038c60487a76368 (patch) | |
| tree | 488a4e0422db4531d9882cf08f0b5cc21ae55a23 /src/eval | |
| parent | d3f6040cedacad1b6c323be721c9086f6c5d9a44 (diff) | |
2d alignments with plus operator
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/mod.rs | 2 | ||||
| -rw-r--r-- | src/eval/ops.rs | 23 | ||||
| -rw-r--r-- | src/eval/value.rs | 6 |
3 files changed, 25 insertions, 6 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 1ff497e8..6b28e5ab 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -422,7 +422,7 @@ impl Eval for CallArgs { } v => { if let Value::Dyn(dynamic) = &v { - if let Some(args) = dynamic.downcast_ref::<Args>() { + if let Some(args) = dynamic.downcast::<Args>() { items.extend(args.items.iter().cloned()); continue; } diff --git a/src/eval/ops.rs b/src/eval/ops.rs index e40fa78d..6fac354d 100644 --- a/src/eval/ops.rs +++ b/src/eval/ops.rs @@ -1,8 +1,9 @@ use std::cmp::Ordering; use std::convert::TryFrom; -use super::Value; +use super::{Dynamic, Value}; use crate::diag::StrResult; +use crate::geom::{Align, Get, Spec}; use crate::util::EcoString; use Value::*; @@ -87,7 +88,25 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> { (Template(a), Str(b)) => Template(a + b), (Str(a), Template(b)) => Template(a + b), - (a, b) => mismatch!("cannot add {} and {}", a, b), + (a, b) => { + if let (Dyn(a), Dyn(b)) = (&a, &b) { + // 1D alignments can be summed into 2D alignments. + if let (Some(&a), Some(&b)) = + (a.downcast::<Align>(), b.downcast::<Align>()) + { + if a.axis() == b.axis() { + return Err(format!("cannot add two {:?} alignments", a.axis())); + } + + let mut aligns = Spec::default(); + aligns.set(a.axis(), Some(a)); + aligns.set(b.axis(), Some(b)); + return Ok(Dyn(Dynamic::new(aligns))); + } + } + + mismatch!("cannot add {} and {}", a, b); + } }) } diff --git a/src/eval/value.rs b/src/eval/value.rs index dec5c6c0..16e8b810 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -188,7 +188,7 @@ impl Dynamic { } /// Try to downcast to a reference to a specific type. - pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { + pub fn downcast<T: 'static>(&self) -> Option<&T> { self.0.as_any().downcast_ref() } @@ -225,7 +225,7 @@ where } fn dyn_eq(&self, other: &Dynamic) -> bool { - if let Some(other) = other.downcast_ref::<Self>() { + if let Some(other) = other.downcast::<Self>() { self == other } else { false @@ -334,7 +334,7 @@ macro_rules! castable { let found = match value { $($pattern => return Ok($out),)* $crate::eval::Value::Dyn(dynamic) => { - $(if let Some($dyn_in) = dynamic.downcast_ref::<$dyn_type>() { + $(if let Some($dyn_in) = dynamic.downcast::<$dyn_type>() { return Ok($dyn_out); })* dynamic.type_name() |
