summaryrefslogtreecommitdiff
path: root/src/eval/ops.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-07-08 23:36:20 +0200
committerLaurenz <laurmaedje@gmail.com>2021-07-08 23:36:20 +0200
commit0c74290519ee999002e9cc99ba3d272d68e1014f (patch)
tree8134b8aeabb9d5af4c50667de6b2c6532c6b8422 /src/eval/ops.rs
parent02b586cc36fad58a622ecb439e1cf3a76a347207 (diff)
Compare functions and templates by identity
Diffstat (limited to 'src/eval/ops.rs')
-rw-r--r--src/eval/ops.rs97
1 files changed, 44 insertions, 53 deletions
diff --git a/src/eval/ops.rs b/src/eval/ops.rs
index 01044842..3b48140c 100644
--- a/src/eval/ops.rs
+++ b/src/eval/ops.rs
@@ -1,35 +1,9 @@
use std::cmp::Ordering::*;
+use std::rc::Rc;
use super::{TemplateNode, Value};
use Value::*;
-/// Join a value with another value.
-pub fn join(lhs: Value, rhs: Value) -> Result<Value, Value> {
- Ok(match (lhs, rhs) {
- (_, Error) => Error,
- (Error, _) => Error,
-
- (a, None) => a,
- (None, b) => b,
-
- (Str(a), Str(b)) => Str(a + &b),
- (Array(a), Array(b)) => Array(concat(a, b)),
- (Dict(a), Dict(b)) => Dict(concat(a, b)),
-
- (Template(a), Template(b)) => Template(concat(a, b)),
- (Template(mut a), Str(b)) => Template({
- a.push(TemplateNode::Str(b));
- a
- }),
- (Str(a), Template(mut b)) => Template({
- b.insert(0, TemplateNode::Str(a));
- b
- }),
-
- (a, _) => return Err(a),
- })
-}
-
/// Apply the plus operator to a value.
pub fn pos(value: Value) -> Value {
match value {
@@ -82,21 +56,7 @@ pub fn add(lhs: Value, rhs: Value) -> Value {
(Fractional(a), Fractional(b)) => Fractional(a + b),
- (Str(a), Str(b)) => Str(a + &b),
- (Array(a), Array(b)) => Array(concat(a, b)),
- (Dict(a), Dict(b)) => Dict(concat(a, b)),
-
- (Template(a), Template(b)) => Template(concat(a, b)),
- (Template(mut a), Str(b)) => Template({
- a.push(TemplateNode::Str(b));
- a
- }),
- (Str(a), Template(mut b)) => Template({
- b.insert(0, TemplateNode::Str(a));
- b
- }),
-
- _ => Error,
+ (a, b) => concat(a, b).unwrap_or(Value::Error),
}
}
@@ -130,6 +90,11 @@ pub fn sub(lhs: Value, rhs: Value) -> Value {
/// Compute the product of two values.
pub fn mul(lhs: Value, rhs: Value) -> Value {
+ fn repeat<T: Clone>(vec: Vec<T>, n: usize) -> Vec<T> {
+ let len = n * vec.len();
+ vec.into_iter().cycle().take(len).collect()
+ }
+
match (lhs, rhs) {
(Int(a), Int(b)) => Int(a * b),
(Int(a), Float(b)) => Float(a as f64 * b),
@@ -258,17 +223,43 @@ pub fn range(lhs: Value, rhs: Value) -> Value {
}
}
-/// Concatenate two collections.
-fn concat<T, A>(mut a: T, b: T) -> T
-where
- T: Extend<A> + IntoIterator<Item = A>,
-{
- a.extend(b);
- a
+/// Join a value with another value.
+pub fn join(lhs: Value, rhs: Value) -> Result<Value, Value> {
+ Ok(match (lhs, rhs) {
+ (_, Error) => Error,
+ (Error, _) => Error,
+
+ (a, None) => a,
+ (None, b) => b,
+
+ (a, b) => return concat(a, b),
+ })
}
-/// Repeat a vector `n` times.
-fn repeat<T: Clone>(vec: Vec<T>, n: usize) -> Vec<T> {
- let len = n * vec.len();
- vec.into_iter().cycle().take(len).collect()
+/// Concatentate two values.
+fn concat(lhs: Value, rhs: Value) -> Result<Value, Value> {
+ Ok(match (lhs, rhs) {
+ (Str(a), Str(b)) => Str(a + &b),
+ (Array(mut a), Array(b)) => Array({
+ a.extend(b);
+ a
+ }),
+ (Dict(mut a), Dict(b)) => Dict({
+ a.extend(b);
+ a
+ }),
+ (Template(mut a), Template(b)) => Template({
+ Rc::make_mut(&mut a).extend(b.iter().cloned());
+ a
+ }),
+ (Template(mut a), Str(b)) => Template({
+ Rc::make_mut(&mut a).push(TemplateNode::Str(b));
+ a
+ }),
+ (Str(a), Template(mut b)) => Template({
+ Rc::make_mut(&mut b).insert(0, TemplateNode::Str(a));
+ b
+ }),
+ (a, _) => return Err(a),
+ })
}