diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 0a5fbb6..91c3c77 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -28,6 +28,7 @@ impl Abool { } } } + impl Display for Abool { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -140,6 +141,7 @@ pub type Cart = HashMap; #[derive(Debug, Clone)] pub enum Value { Nul, + Undefined, Str(String), Int(isize), Abool(Abool), @@ -157,7 +159,7 @@ impl Hash for Value { fn hash(&self, state: &mut H) { discriminant(self).hash(state); match self { - Value::Nul => (), + Value::Nul | Value::Undefined => (), Value::Str(v) => v.hash(state), Value::Int(v) => v.hash(state), Value::Abool(v) => v.to_string().hash(state), @@ -211,6 +213,7 @@ impl Value { }, Value::Int(i) => i, Value::Nul => consts::ANSWER, + Value::Undefined => todo!("undefined -> isize coercion"), Value::Str(text) => text .parse() .unwrap_or_else(|_| text.chars().map(|cr| cr as isize).sum()), @@ -225,6 +228,7 @@ impl Value { pub fn into_abool(self) -> Abool { match self { Value::Nul => Abool::Never, + Value::Undefined => Abool::Sometimes, Value::Str(s) => match s.to_lowercase().as_str() { "never" | "no" | "🇳🇴" => Abool::Never, "sometimes" => Abool::Sometimes, @@ -292,6 +296,7 @@ impl Value { body: vec![], params: vec![], }, + Value::Undefined => todo!("undefined -> functio coercion"), Value::Str(s) => Functio::Eval(s), Value::Int(i) => Functio::Bf { instructions: { @@ -345,6 +350,7 @@ impl Value { pub fn into_cart(self) -> Cart { match self { Value::Nul => HashMap::new(), + Value::Undefined => todo!("undefined -> cart coercion"), Value::Str(s) => s .chars() .enumerate() @@ -452,6 +458,7 @@ impl Value { pub fn length(&self) -> isize { match self { Value::Nul => 0, + Value::Undefined => todo!("undefined length"), Value::Str(s) => s.len() as _, Value::Int(i) => i.count_zeros() as _, Value::Abool(a) => match a { @@ -502,8 +509,9 @@ impl ops::Add for Value { fn add(self, rhs: Self) -> Self::Output { match self { - Value::Nul => match rhs { + Value::Nul | Value::Undefined => match rhs { Value::Nul => Value::Nul, + Value::Undefined => Value::Undefined, Value::Str(_) => Value::Str(self.to_string()) + rhs, Value::Int(_) => Value::Int(self.into_isize()) + rhs, Value::Abool(_) => Value::Abool(self.into_abool()) + rhs, @@ -531,8 +539,9 @@ impl ops::Sub for Value { fn sub(self, rhs: Self) -> Self::Output { match self { - Value::Nul => match rhs { + Value::Nul | Value::Undefined => match rhs { Value::Nul => Value::Nul, + Value::Undefined => Value::Undefined, Value::Str(_) => Value::Str(self.to_string()) - rhs, Value::Int(_) => Value::Int(self.into_isize()) - rhs, Value::Abool(_) => Value::Abool(self.into_abool()) - rhs, @@ -648,8 +657,9 @@ impl ops::Mul for Value { fn mul(self, rhs: Self) -> Self::Output { match self { - Value::Nul => match rhs { + Value::Nul | Value::Undefined => match rhs { Value::Nul => Value::Nul, + Value::Undefined => Value::Undefined, Value::Str(_) => Value::Str(self.to_string()) * rhs, Value::Int(_) => Value::Int(self.into_isize()) * rhs, Value::Abool(_) => Value::Abool(self.into_abool()) * rhs, @@ -689,8 +699,9 @@ impl ops::Div for Value { fn div(self, rhs: Self) -> Self::Output { match self { - Value::Nul => match rhs { + Value::Nul | Value::Undefined => match rhs { Value::Nul => Value::Nul, + Value::Undefined => Value::Undefined, Value::Str(_) => Value::Str(self.to_string()) / rhs, Value::Int(_) => Value::Int(self.into_isize()) / rhs, Value::Abool(_) => Value::Abool(self.into_abool()) / rhs, @@ -793,7 +804,8 @@ impl ops::Not for Value { fn not(self) -> Self::Output { match self { - Value::Nul => Value::Nul, + Value::Nul => Value::Undefined, + Value::Undefined => Value::Nul, Value::Str(s) => Value::Str(s.chars().rev().collect()), Value::Int(i) => Value::Int(i.swap_bytes()), Value::Abool(a) => Value::Abool(match a { @@ -856,6 +868,7 @@ impl PartialEq for Value { match self { Value::Nul => matches!(other, Value::Nul), + Value::Undefined => matches!(other, Value::Undefined), Value::Str(s) => *s == other.to_string(), Value::Int(i) => *i == other.into_isize(), Value::Abool(a) => *a == other.into_abool(), @@ -873,18 +886,14 @@ impl PartialOrd for Value { let other = other.clone(); match self { - Value::Nul => { - if other == Value::Nul { - Some(Equal) - } else { - None - } - } + Value::Nul if other == Value::Nul => Some(Equal), + Value::Undefined if other == Value::Undefined => Some(Equal), Value::Str(s) => Some(s.cmp(&other.to_string())), Value::Int(i) => Some(i.cmp(&other.into_isize())), Value::Abool(a) => a.partial_cmp(&other.into_abool()), Value::Functio(_) => self.clone().into_isize().partial_cmp(&other.into_isize()), Value::Cart(c) => Some(c.len().cmp(&other.into_cart().len())), + Value::Nul | Value::Undefined => None, } } } @@ -893,6 +902,7 @@ impl Display for Value { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Value::Nul => write!(f, "nul"), + Value::Undefined => write!(f, "undefined"), Value::Str(v) => write!(f, "{}", v), Value::Int(v) => write!(f, "{}", v), Value::Abool(v) => write!(f, "{}", v),