Added Undefined type

This commit is contained in:
Erin 2022-05-06 20:19:35 +02:00 committed by ondra05
parent 5d48bd8df4
commit e85f766a1d

View file

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