use std::{ cmp::Ordering, collections::{BTreeMap, HashMap}, fmt::{self, Display, Formatter}, ops::Range, sync::Arc, }; use serde::{ de::Visitor, ser::{SerializeMap, SerializeSeq, SerializeTuple}, Deserialize, Deserializer, Serialize, }; use crate::{identifier::Identifier, Statement, Type}; #[derive(Clone, Debug, PartialEq)] pub struct Value(Arc); impl Value { pub fn inner(&self) -> &Arc { &self.0 } pub fn boolean(boolean: bool) -> Self { Value(Arc::new(ValueInner::Boolean(boolean))) } pub fn float(float: f64) -> Self { Value(Arc::new(ValueInner::Float(float))) } pub fn integer(integer: i64) -> Self { Value(Arc::new(ValueInner::Integer(integer))) } pub fn list(list: Vec) -> Self { Value(Arc::new(ValueInner::List(list))) } pub fn map(map: BTreeMap) -> Self { Value(Arc::new(ValueInner::Map(map))) } pub fn range(range: Range) -> Self { Value(Arc::new(ValueInner::Range(range))) } pub fn string(to_string: T) -> Self { Value(Arc::new(ValueInner::String(to_string.to_string()))) } pub fn r#type(&self, variables: &HashMap) -> Type { self.0.r#type(variables) } pub fn as_boolean(&self) -> Option { if let ValueInner::Boolean(boolean) = self.0.as_ref() { Some(*boolean) } else { None } } pub fn as_list(&self) -> Option<&Vec> { if let ValueInner::List(list) = self.inner().as_ref() { Some(list) } else { None } } pub fn as_integer(&self) -> Option { if let ValueInner::Integer(integer) = self.inner().as_ref() { Some(*integer) } else { None } } pub fn add(&self, other: &Value) -> Result { match (self.inner().as_ref(), other.inner().as_ref()) { (ValueInner::Float(left), ValueInner::Float(right)) => Ok(Value::float(left + right)), (ValueInner::Integer(left), ValueInner::Integer(right)) => { Ok(Value::integer(left + right)) } _ => Err(ValueError::CannotAdd(self.clone(), other.clone())), } } } impl Display for Value { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self.inner().as_ref() { ValueInner::Boolean(boolean) => write!(f, "{boolean}"), ValueInner::Float(float) => { write!(f, "{float}")?; if &float.floor() == float { write!(f, ".0")?; } Ok(()) } ValueInner::Function(function) => write!(f, "{function}"), ValueInner::Integer(integer) => write!(f, "{integer}"), ValueInner::List(list) => { write!(f, "[")?; for (index, value) in list.iter().enumerate() { if index == list.len() - 1 { write!(f, "{}", value)?; } else { write!(f, "{}, ", value)?; } } write!(f, "]") } ValueInner::Map(map) => { write!(f, "{{ ")?; for (index, (key, value)) in map.iter().enumerate() { write!(f, "{key} = {value}")?; if index != map.len() - 1 { write!(f, ", ")?; } } write!(f, " }}") } ValueInner::Range(range) => write!(f, "{}..{}", range.start, range.end), ValueInner::String(string) => write!(f, "{string}"), } } } impl Eq for Value {} impl PartialOrd for Value { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Value { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.0.as_ref().cmp(other.0.as_ref()) } } impl Serialize for Value { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { match self.0.as_ref() { ValueInner::Boolean(boolean) => serializer.serialize_bool(*boolean), ValueInner::Float(float) => serializer.serialize_f64(*float), ValueInner::Function(function) => function.serialize(serializer), ValueInner::Integer(integer) => serializer.serialize_i64(*integer), ValueInner::List(list) => { let mut list_ser = serializer.serialize_seq(Some(list.len()))?; for item in list { list_ser.serialize_element(&item)?; } list_ser.end() } ValueInner::Map(map) => { let mut map_ser = serializer.serialize_map(Some(map.len()))?; for (identifier, value) in map { map_ser.serialize_entry(identifier, value)?; } map_ser.end() } ValueInner::Range(range) => { let mut tuple_ser = serializer.serialize_tuple(2)?; tuple_ser.serialize_element(&range.start)?; tuple_ser.serialize_element(&range.end)?; tuple_ser.end() } ValueInner::String(string) => serializer.serialize_str(string), } } } struct ValueVisitor; impl<'de> Visitor<'de> for ValueVisitor { type Value = Value; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter .write_str("a boolean, float, function, integer, list, map, range, string or structure") } fn visit_bool(self, v: bool) -> Result where E: serde::de::Error, { Ok(Value::boolean(v)) } fn visit_i8(self, v: i8) -> Result where E: serde::de::Error, { self.visit_i64(v as i64) } fn visit_i16(self, v: i16) -> Result where E: serde::de::Error, { self.visit_i64(v as i64) } fn visit_i32(self, v: i32) -> Result where E: serde::de::Error, { self.visit_i64(v as i64) } fn visit_i64(self, v: i64) -> Result where E: serde::de::Error, { Ok(Value::integer(v)) } fn visit_i128(self, _: i128) -> Result where E: serde::de::Error, { todo!() } fn visit_u8(self, v: u8) -> Result where E: serde::de::Error, { self.visit_u64(v as u64) } fn visit_u16(self, v: u16) -> Result where E: serde::de::Error, { self.visit_u64(v as u64) } fn visit_u32(self, v: u32) -> Result where E: serde::de::Error, { self.visit_u64(v as u64) } fn visit_u64(self, v: u64) -> Result where E: serde::de::Error, { Ok(Value::integer(v as i64)) } fn visit_u128(self, _: u128) -> Result where E: serde::de::Error, { todo!() } fn visit_f32(self, v: f32) -> Result where E: serde::de::Error, { self.visit_f64(v as f64) } fn visit_f64(self, v: f64) -> Result where E: serde::de::Error, { Ok(Value::float(v)) } fn visit_char(self, v: char) -> Result where E: serde::de::Error, { self.visit_str(v.encode_utf8(&mut [0u8; 4])) } fn visit_str(self, v: &str) -> Result where E: serde::de::Error, { Ok(Value::string(v)) } fn visit_borrowed_str(self, v: &'de str) -> Result where E: serde::de::Error, { self.visit_str(v) } fn visit_string(self, v: String) -> Result where E: serde::de::Error, { self.visit_str(&v) } fn visit_bytes(self, v: &[u8]) -> Result where E: serde::de::Error, { Err(serde::de::Error::invalid_type( serde::de::Unexpected::Bytes(v), &self, )) } fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result where E: serde::de::Error, { self.visit_bytes(v) } fn visit_byte_buf(self, v: Vec) -> Result where E: serde::de::Error, { self.visit_bytes(&v) } fn visit_none(self) -> Result where E: serde::de::Error, { Err(serde::de::Error::invalid_type( serde::de::Unexpected::Option, &self, )) } fn visit_some(self, deserializer: D) -> Result where D: Deserializer<'de>, { let _ = deserializer; Err(serde::de::Error::invalid_type( serde::de::Unexpected::Option, &self, )) } fn visit_unit(self) -> Result where E: serde::de::Error, { Err(serde::de::Error::invalid_type( serde::de::Unexpected::Unit, &self, )) } fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer<'de>, { let _ = deserializer; Err(serde::de::Error::invalid_type( serde::de::Unexpected::NewtypeStruct, &self, )) } fn visit_seq(self, mut seq: A) -> Result where A: serde::de::SeqAccess<'de>, { let mut list = Vec::with_capacity(seq.size_hint().unwrap_or(10)); while let Some(element) = seq.next_element()? { list.push(element); } Ok(Value::list(list)) } fn visit_map(self, mut map: A) -> Result where A: serde::de::MapAccess<'de>, { let mut btree = BTreeMap::new(); while let Some((key, value)) = map.next_entry()? { btree.insert(key, value); } Ok(Value::map(btree)) } fn visit_enum(self, data: A) -> Result where A: serde::de::EnumAccess<'de>, { let _ = data; Err(serde::de::Error::invalid_type( serde::de::Unexpected::Enum, &self, )) } } impl<'de> Deserialize<'de> for Value { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_any(ValueVisitor) } } #[derive(Clone, Debug, PartialEq)] pub enum ValueInner { Boolean(bool), Float(f64), Function(Function), Integer(i64), List(Vec), Map(BTreeMap), Range(Range), String(String), } impl ValueInner { pub fn r#type(&self, variables: &HashMap) -> Type { match self { ValueInner::Boolean(_) => Type::Boolean, ValueInner::Float(_) => Type::Float, ValueInner::Function(function) => Type::Function { type_parameters: function.type_parameters.clone(), value_parameters: function.value_parameters.clone(), return_type: function.return_type(variables).map(Box::new), }, ValueInner::Integer(_) => Type::Integer, ValueInner::List(values) => { let item_type = values.first().unwrap().r#type(variables); Type::List { length: values.len(), item_type: Box::new(item_type), } } ValueInner::Map(value_map) => { let mut type_map = BTreeMap::new(); for (identifier, value) in value_map { let r#type = value.r#type(variables); type_map.insert(identifier.clone(), r#type); } Type::Map(type_map) } ValueInner::Range(_) => Type::Range, ValueInner::String(_) => Type::String, } } } pub trait ValueProperties<'a> {} pub struct IntegerProperties<'a>(&'a Value); impl<'a> IntegerProperties<'a> { pub fn is_even(&self) -> bool { self.0.as_integer().unwrap() % 2 == 0 } } impl<'a> ValueProperties<'a> for IntegerProperties<'a> {} impl Eq for ValueInner {} impl PartialOrd for ValueInner { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for ValueInner { fn cmp(&self, other: &Self) -> Ordering { use ValueInner::*; match (self, other) { (Boolean(left), Boolean(right)) => left.cmp(right), (Boolean(_), _) => Ordering::Greater, (Float(left), Float(right)) => left.total_cmp(right), (Float(_), _) => Ordering::Greater, (Function(left), Function(right)) => left.cmp(right), (Function(_), _) => Ordering::Greater, (Integer(left), Integer(right)) => left.cmp(right), (Integer(_), _) => Ordering::Greater, (List(left), List(right)) => left.cmp(right), (List(_), _) => Ordering::Greater, (Map(left), Map(right)) => left.cmp(right), (Map(_), _) => Ordering::Greater, (Range(left), Range(right)) => { let start_cmp = left.start.cmp(&right.start); if start_cmp.is_eq() { left.end.cmp(&right.end) } else { start_cmp } } (Range(_), _) => Ordering::Greater, (String(left), String(right)) => left.cmp(right), (String(_), _) => Ordering::Greater, } } } #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Function { pub name: Identifier, pub type_parameters: Option>, pub value_parameters: Option>, pub body: Vec>, } impl Function { pub fn return_type(&self, variables: &HashMap) -> Option { self.body.last().unwrap().expected_type(variables) } } impl Display for Function { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", self.name)?; if let Some(type_parameters) = &self.type_parameters { write!(f, "<")?; for (index, type_parameter) in type_parameters.iter().enumerate() { if index > 0 { write!(f, ", ")?; } write!(f, "{}", type_parameter)?; } write!(f, ">")?; } write!(f, "(")?; if let Some(value_paramers) = &self.value_parameters { for (index, (identifier, r#type)) in value_paramers.iter().enumerate() { if index > 0 { write!(f, ", ")?; } write!(f, "{identifier}: {type}")?; } } write!(f, ") {{")?; for statement in &self.body { write!(f, "{}", statement)?; } write!(f, "}}") } } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum ValueError { CannotAdd(Value, Value), PropertyNotFound { value: Value, property: Identifier }, IndexOutOfBounds { value: Value, index: i64 }, ExpectedList(Value), }