From 14bdddbe019ec1733b36e63f64969156bde070f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Sun, 7 Mar 2021 23:13:45 +0100 Subject: unknown in operators produce some _a_ value This makes sense when type-checking. --- src/lib.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index e94eaad..5094698 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -561,7 +561,7 @@ pub enum Op { /// /// Broken out because they need to be recursive. mod op { - use super::Value; + use super::{Type, Value}; use std::rc::Rc; fn tuple_bin_op(a: &Rc>, b: &Rc>, f: fn (&Value, &Value) -> Value) -> Value { @@ -577,6 +577,7 @@ mod op { Value::Float(a) => Value::Float(-*a), Value::Int(a) => Value::Int(-*a), Value::Tuple(a) => tuple_un_op(a, neg), + Value::Unknown => Value::Unknown, _ => Value::Nil, } } @@ -585,6 +586,7 @@ mod op { match value { Value::Bool(a) => Value::Bool(!*a), Value::Tuple(a) => tuple_un_op(a, not), + Value::Unknown => Value::from(Type::Bool), _ => Value::Nil, } } @@ -596,6 +598,7 @@ mod op { (Value::Int(a), Value::Int(b)) => Value::Int(a + b), (Value::String(a), Value::String(b)) => Value::String(Rc::from(format!("{}{}", a, b))), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, add), + (Value::Unknown, a) | (a, Value::Unknown) => a.clone(), _ => Value::Nil, } } @@ -609,6 +612,7 @@ mod op { (Value::Float(a), Value::Float(b)) => Value::Float(a * b), (Value::Int(a), Value::Int(b)) => Value::Int(a * b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, mul), + (Value::Unknown, a) | (a, Value::Unknown) => a.clone(), _ => Value::Nil, } } @@ -618,6 +622,7 @@ mod op { (Value::Float(a), Value::Float(b)) => Value::Float(a / b), (Value::Int(a), Value::Int(b)) => Value::Int(a / b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, div), + (Value::Unknown, a) | (a, Value::Unknown) => a.clone(), _ => Value::Nil, } } @@ -629,6 +634,7 @@ mod op { (Value::String(a), Value::String(b)) => Value::Bool(a == b), (Value::Bool(a), Value::Bool(b)) => Value::Bool(a == b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, eq), + (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), _ => Value::Nil, } } @@ -640,6 +646,7 @@ mod op { (Value::String(a), Value::String(b)) => Value::Bool(a < b), (Value::Bool(a), Value::Bool(b)) => Value::Bool(a < b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, less), + (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), _ => Value::Nil, } } @@ -652,6 +659,7 @@ mod op { match (a, b) { (Value::Bool(a), Value::Bool(b)) => Value::Bool(*a && *b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, and), + (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), _ => Value::Nil, } } @@ -660,6 +668,7 @@ mod op { match (a, b) { (Value::Bool(a), Value::Bool(b)) => Value::Bool(*a || *b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, or), + (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), _ => Value::Nil, } } -- cgit v1.2.1 From 1ccd9b3f2ffa449a11f2348314f0dcae2e224c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Sun, 7 Mar 2021 23:42:42 +0100 Subject: document Value::{Unknown,Nil} --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 5094698..7e09dce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -178,7 +178,10 @@ pub enum Value { String(Rc), Function(Vec>>, Rc>), ExternFunction(usize), + /// This value should not be present when running, only when type checking. + /// Most operations are valid but produce funky results. Unknown, + /// Should not be present when running. Nil, } -- cgit v1.2.1 From e9282cc37813c2632b2e55329343a6ab233b4cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Mon, 8 Mar 2021 17:15:46 +0100 Subject: check other operand if one is unknown --- src/lib.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 7e09dce..a138c33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -601,7 +601,8 @@ mod op { (Value::Int(a), Value::Int(b)) => Value::Int(a + b), (Value::String(a), Value::String(b)) => Value::String(Rc::from(format!("{}{}", a, b))), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, add), - (Value::Unknown, a) | (a, Value::Unknown) => a.clone(), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => add(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } @@ -615,7 +616,8 @@ mod op { (Value::Float(a), Value::Float(b)) => Value::Float(a * b), (Value::Int(a), Value::Int(b)) => Value::Int(a * b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, mul), - (Value::Unknown, a) | (a, Value::Unknown) => a.clone(), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => mul(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } @@ -625,7 +627,8 @@ mod op { (Value::Float(a), Value::Float(b)) => Value::Float(a / b), (Value::Int(a), Value::Int(b)) => Value::Int(a / b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, div), - (Value::Unknown, a) | (a, Value::Unknown) => a.clone(), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => div(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } @@ -637,7 +640,8 @@ mod op { (Value::String(a), Value::String(b)) => Value::Bool(a == b), (Value::Bool(a), Value::Bool(b)) => Value::Bool(a == b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, eq), - (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => eq(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } @@ -649,7 +653,8 @@ mod op { (Value::String(a), Value::String(b)) => Value::Bool(a < b), (Value::Bool(a), Value::Bool(b)) => Value::Bool(a < b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, less), - (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => less(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } @@ -662,7 +667,8 @@ mod op { match (a, b) { (Value::Bool(a), Value::Bool(b)) => Value::Bool(*a && *b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, and), - (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => and(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } @@ -671,7 +677,8 @@ mod op { match (a, b) { (Value::Bool(a), Value::Bool(b)) => Value::Bool(*a || *b), (Value::Tuple(a), Value::Tuple(b)) if a.len() == b.len() => tuple_bin_op(a, b, or), - (Value::Unknown, _) | (_, Value::Unknown) => Value::from(Type::Bool), + (Value::Unknown, a) | (a, Value::Unknown) if !matches!(a, Value::Unknown) => or(a, a), + (Value::Unknown, Value::Unknown) => Value::Unknown, _ => Value::Nil, } } -- cgit v1.2.1