summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-11-23 12:45:20 +0100
committerLaurenz <laurmaedje@gmail.com>2021-11-23 12:45:20 +0100
commit4f9e5819bbab1f93ad4f4b789038c60487a76368 (patch)
tree488a4e0422db4531d9882cf08f0b5cc21ae55a23 /src/eval
parentd3f6040cedacad1b6c323be721c9086f6c5d9a44 (diff)
2d alignments with plus operator
Diffstat (limited to 'src/eval')
-rw-r--r--src/eval/mod.rs2
-rw-r--r--src/eval/ops.rs23
-rw-r--r--src/eval/value.rs6
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()