use core::fmt; use std::{collections::LinkedList, mem::discriminant}; use super::{expr::Expr, Identifier, evaluation::EvaluateError}; #[derive(Clone, Debug)] pub enum Value { Int(usize), String(String), Function(Vec, LinkedList), Structural(Identifier, Vec), } impl fmt::Display for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Int(v) => write!(f, "{}", v), Self::String(val) => write!(f, "\"{val}\""), Self::Function(args, exprs) => write!(f, "function({}):{}", args.into_iter() .map(|a| a.to_string()) .collect::>() .join(", "), exprs.into_iter() .map(|e| format!("\n\t{e}")) .collect::(), ), Self::Structural(_, _) => todo!(), } } } impl TryInto for &Value { type Error = EvaluateError; fn try_into(self) -> Result { if let Value::Int(v) = self { Ok(*v) } else { Err(EvaluateError::TypeMismatch( discriminant(&Value::Int(0)), discriminant(&self), )) } } } impl TryInto for &Value { type Error = EvaluateError; fn try_into(self) -> Result { if let Value::Int(v) = self { Ok(*v != 0) } else { Err(EvaluateError::TypeMismatch( discriminant(&Value::Int(0)), discriminant(&self), )) } } }