From 8ae453add7a625ae06d251746fd58cc5f557fbd3 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 16 Aug 2024 17:07:49 -0400 Subject: [PATCH] Continue value overhaul --- dust-lang/src/ast/expression.rs | 18 +- dust-lang/src/lib.rs | 2 +- dust-lang/src/type.rs | 310 ++--- dust-lang/src/value.rs | 1904 ++++++++++--------------------- dust-lang/src/vm.rs | 11 +- 5 files changed, 745 insertions(+), 1500 deletions(-) diff --git a/dust-lang/src/ast/expression.rs b/dust-lang/src/ast/expression.rs index eb53e56..9c670d9 100644 --- a/dust-lang/src/ast/expression.rs +++ b/dust-lang/src/ast/expression.rs @@ -5,7 +5,7 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::{Context, Identifier, Span, StructType, Type, Value}; +use crate::{Context, FunctionType, Identifier, Span, StructType, Type, Value}; use super::{Node, Statement}; @@ -236,7 +236,7 @@ impl Expression { let invoker_type = invoker.return_type(context)?; - if let Type::Function { return_type, .. } = invoker_type { + if let Type::Function(FunctionType { return_type, .. }) = invoker_type { return_type.map(|r#type| *r#type) } else if let Type::Struct(_) = invoker_type { Some(invoker_type) @@ -276,7 +276,7 @@ impl Expression { } ListExpression::Ordered(expressions) => { if expressions.is_empty() { - return Some(Type::EmptyList); + return Some(Type::ListEmpty); } let item_type = expressions.last().unwrap().return_type(context)?; @@ -304,7 +304,6 @@ impl Expression { LiteralExpression::Float(_) => Some(Type::Float), LiteralExpression::Integer(_) => Some(Type::Integer), LiteralExpression::String(_) => Some(Type::String), - LiteralExpression::Value(value) => Some(value.r#type()), }, Expression::Loop(loop_expression) => match loop_expression.inner.as_ref() { LoopExpression::For { block, .. } => block.inner.return_type(context), @@ -326,19 +325,19 @@ impl Expression { StructExpression::Fields { name, fields } => { let mut field_types = Vec::with_capacity(fields.len()); - for (name, expression) in fields { + for (field_name, expression) in fields { let r#type = expression.return_type(context)?; - field_types.push((name.inner.clone(), r#type)); + field_types.push((field_name.inner.clone(), r#type)); } Some(Type::Struct(StructType::Fields { - name: name.inner.clone(), + identifier: name.inner.clone(), fields: field_types, })) } StructExpression::Unit { name } => Some(Type::Struct(StructType::Unit { - name: name.inner.clone(), + identifier: name.inner.clone(), })), }, Expression::TupleAccess(tuple_access_expression) => { @@ -502,7 +501,6 @@ pub enum LiteralExpression { Float(f64), Integer(i64), String(String), - Value(Value), } impl Display for LiteralExpression { @@ -512,7 +510,6 @@ impl Display for LiteralExpression { LiteralExpression::Float(float) => write!(f, "{}", float), LiteralExpression::Integer(integer) => write!(f, "{}", integer), LiteralExpression::String(string) => write!(f, "{}", string), - LiteralExpression::Value(value) => write!(f, "{}", value), } } } @@ -538,7 +535,6 @@ impl Ord for LiteralExpression { left.cmp(right) } (LiteralExpression::String(left), LiteralExpression::String(right)) => left.cmp(right), - (LiteralExpression::Value(left), LiteralExpression::Value(right)) => left.cmp(right), _ => unreachable!(), } } diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index 4766ef9..1493807 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -36,7 +36,7 @@ pub use dust_error::DustError; pub use identifier::Identifier; pub use lexer::{lex, LexError, Lexer}; pub use parser::{parse, ParseError, Parser}; -pub use r#type::{StructType, Type}; +pub use r#type::{EnumType, FunctionType, StructType, Type}; pub use token::{Token, TokenKind, TokenOwned}; pub use value::{Struct, Value, ValueError}; pub use vm::{run, run_with_context, Vm, VmError}; diff --git a/dust-lang/src/type.rs b/dust-lang/src/type.rs index 300e007..8f60d46 100644 --- a/dust-lang/src/type.rs +++ b/dust-lang/src/type.rs @@ -10,19 +10,13 @@ //! library's "length" function does not care about the type of item in the list, only the list //! itself. So the input is defined as `[any]`, i.e. `Type::ListOf(Box::new(Type::Any))`. use std::{ - collections::BTreeMap, fmt::{self, Display, Formatter}, + sync::Arc, }; use serde::{Deserialize, Serialize}; -use crate::Identifier; - -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct TypeConflict { - pub expected: Type, - pub actual: Type, -} +use crate::{value::Function, Identifier}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] /// Description of a kind of value. @@ -31,18 +25,11 @@ pub struct TypeConflict { pub enum Type { Any, Boolean, - EmptyList, - Enum { - name: Identifier, - type_parameters: Option>, - variants: Vec<(Identifier, Option>)>, - }, + Byte, + Character, + Enum(EnumType), Float, - Function { - type_parameters: Option>, - value_parameters: Option>, - return_type: Option>, - }, + Function(FunctionType), Generic { identifier: Identifier, concrete_type: Option>, @@ -52,14 +39,15 @@ pub enum Type { item_type: Box, length: usize, }, + ListEmpty, ListOf { item_type: Box, }, - Map(BTreeMap), Number, Range, String, Struct(StructType), + Tuple(Vec), } impl Type { @@ -189,17 +177,26 @@ impl Type { } } ( - Type::Function { + Type::Function(FunctionType { + name: left_name, type_parameters: left_type_parameters, value_parameters: left_value_parameters, return_type: left_return, - }, - Type::Function { + }), + Type::Function(FunctionType { + name: right_name, type_parameters: right_type_parameters, value_parameters: right_value_parameters, return_type: right_return, - }, + }), ) => { + if left_name != right_name { + return Err(TypeConflict { + actual: other.clone(), + expected: self.clone(), + }); + } + if left_return == right_return { for (left_parameter, right_parameter) in left_type_parameters .iter() @@ -228,11 +225,6 @@ impl Type { return Ok(()); } } - (Type::Map(left), Type::Map(right)) => { - if left == right { - return Ok(()); - } - } (Type::Number, Type::Number | Type::Integer | Type::Float) | (Type::Integer | Type::Float, Type::Number) => { return Ok(()); @@ -252,29 +244,11 @@ impl Display for Type { match self { Type::Any => write!(f, "any"), Type::Boolean => write!(f, "bool"), - Type::EmptyList => write!(f, "[]"), - Type::Enum { variants, .. } => { - write!(f, "enum ")?; - - write!(f, " {{")?; - - for (identifier, types) in variants { - writeln!(f, "{identifier}")?; - - if let Some(types) = types { - write!(f, "(")?; - - for r#type in types { - write!(f, "{}", r#type)?; - } - } - - write!(f, ")")?; - } - - write!(f, "}}") - } + Type::Byte => write!(f, "byte"), + Type::Character => write!(f, "char"), + Type::Enum(enum_type) => write!(f, "{enum_type}"), Type::Float => write!(f, "float"), + Type::Function(function_type) => write!(f, "{function_type}"), Type::Generic { concrete_type, .. } => { match concrete_type.clone().map(|r#box| *r#box) { Some(Type::Generic { identifier, .. }) => write!(f, "{identifier}"), @@ -284,82 +258,14 @@ impl Display for Type { } Type::Integer => write!(f, "int"), Type::List { item_type, length } => write!(f, "[{item_type}; {length}]"), + Type::ListEmpty => write!(f, "[]"), Type::ListOf { item_type } => write!(f, "[{item_type}]"), - Type::Map(map) => { - write!(f, "{{ ")?; - - for (index, (key, r#type)) in map.iter().enumerate() { - write!(f, "{key}: {type}")?; - - if index != map.len() - 1 { - write!(f, ", ")?; - } - } - - write!(f, " }}") - } Type::Number => write!(f, "num"), Type::Range => write!(f, "range"), Type::String => write!(f, "str"), - Type::Function { - type_parameters, - value_parameters, - return_type, - } => { - write!(f, "fn ")?; - - if let Some(type_parameters) = type_parameters { - write!(f, "<")?; - - for identifier in type_parameters { - write!(f, "{}, ", identifier)?; - } - - write!(f, ">")?; - } - - write!(f, "(")?; - - if let Some(value_parameters) = value_parameters { - for (identifier, r#type) in value_parameters { - write!(f, "{identifier}: {type}")?; - } - } - - write!(f, ")")?; - - if let Some(r#type) = return_type { - write!(f, " -> {type}") - } else { - Ok(()) - } - } Type::Struct(struct_type) => write!(f, "{struct_type}"), - } - } -} - -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] -pub enum StructType { - Unit { - name: Identifier, - }, - Tuple { - name: Identifier, - fields: Vec, - }, - Fields { - name: Identifier, - fields: Vec<(Identifier, Type)>, - }, -} - -impl Display for StructType { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - StructType::Unit { name } => write!(f, "struct {name}"), - StructType::Tuple { name, fields } => { - write!(f, "struct {name}(")?; + Type::Tuple(fields) => { + write!(f, "(")?; for (index, r#type) in fields.iter().enumerate() { write!(f, "{type}")?; @@ -371,8 +277,94 @@ impl Display for StructType { write!(f, ")") } - StructType::Fields { name, fields } => { - write!(f, "struct {name} {{")?; + } + } +} + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct FunctionType { + pub name: Identifier, + pub type_parameters: Option>, + pub value_parameters: Option>, + pub return_type: Option>, +} + +impl Display for FunctionType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "fn ")?; + + if let Some(type_parameters) = &self.type_parameters { + write!(f, "<")?; + + for (index, type_parameter) in type_parameters.iter().enumerate() { + write!(f, "{type_parameter}")?; + + if index != type_parameters.len() - 1 { + write!(f, ", ")?; + } + } + + write!(f, ">")?; + } + + write!(f, "(")?; + + if let Some(value_parameters) = &self.value_parameters { + for (index, (identifier, r#type)) in value_parameters.iter().enumerate() { + write!(f, "{identifier}: {type}")?; + + if index != value_parameters.len() - 1 { + write!(f, ", ")?; + } + } + } + + write!(f, ")")?; + + if let Some(return_type) = &self.return_type { + write!(f, " -> {return_type}")?; + } + + Ok(()) + } +} + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub enum StructType { + Unit { + identifier: Identifier, + }, + Tuple { + identifier: Identifier, + fields: Vec, + }, + Fields { + identifier: Identifier, + fields: Vec<(Identifier, Type)>, + }, +} + +impl Display for StructType { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + StructType::Unit { .. } => write!(f, "()"), + StructType::Tuple { fields, .. } => { + write!(f, "(")?; + + for (index, r#type) in fields.iter().enumerate() { + write!(f, "{type}")?; + + if index != fields.len() - 1 { + write!(f, ", ")?; + } + } + + write!(f, ")") + } + StructType::Fields { + identifier, fields, .. + } => { + write!(f, "{identifier} {{ ")?; for (index, (identifier, r#type)) in fields.iter().enumerate() { write!(f, "{identifier}: {type}")?; @@ -382,43 +374,64 @@ impl Display for StructType { } } - write!(f, "}}") + write!(f, " }}") } } } } +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct EnumType { + name: Identifier, + variants: Vec, +} + +impl Display for EnumType { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}", self.name) + } +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct TypeConflict { + pub expected: Type, + pub actual: Type, +} + #[cfg(test)] mod tests { use super::*; #[test] - fn check_same_types() { - assert_eq!(Type::Any.check(&Type::Any), Ok(())); - assert_eq!(Type::Boolean.check(&Type::Boolean), Ok(())); - assert_eq!(Type::Float.check(&Type::Float), Ok(())); - assert_eq!(Type::Integer.check(&Type::Integer), Ok(())); - assert_eq!( - Type::List { - item_type: Box::new(Type::Boolean), - length: 42 - } - .check(&Type::List { - item_type: Box::new(Type::Boolean), - length: 42 - }), - Ok(()) - ); + fn check_type_any() { + let foo = Type::Any; + let bar = Type::Any; - let mut map = BTreeMap::new(); + foo.check(&bar).unwrap(); + } - map.insert(Identifier::from("x"), Type::Integer); - map.insert(Identifier::from("y"), Type::String); - map.insert(Identifier::from("z"), Type::Map(map.clone())); + #[test] + fn check_type_boolean() { + let foo = Type::Boolean; + let bar = Type::Boolean; - assert_eq!(Type::Map(map.clone()).check(&Type::Map(map)), Ok(())); - assert_eq!(Type::Range.check(&Type::Range), Ok(())); - assert_eq!(Type::String.check(&Type::String), Ok(())); + foo.check(&bar).unwrap(); + } + + #[test] + fn check_type_byte() { + let foo = Type::Byte; + let bar = Type::Byte; + + foo.check(&bar).unwrap(); + } + + #[test] + fn check_type_character() { + let foo = Type::Character; + let bar = Type::Character; + + foo.check(&bar).unwrap(); } #[test] @@ -449,7 +462,6 @@ mod tests { item_type: Box::new(Type::Integer), length: 42, }, - Type::Map(BTreeMap::new()), Type::Range, Type::String, ]; diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index d5b4fa5..ddc2e1b 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -5,16 +5,19 @@ use std::{ error::Error, fmt::{self, Display, Formatter}, ops::{Range, RangeInclusive}, + ptr, sync::{Arc, RwLock, RwLockWriteGuard}, }; use serde::{ - de::Visitor, - ser::{SerializeMap, SerializeSeq, SerializeTuple}, + de::{self, MapAccess, SeqAccess, Visitor}, + ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple}, Deserialize, Deserializer, Serialize, Serializer, }; -use crate::{AbstractSyntaxTree, Context, Identifier, StructType, Type, Vm, VmError}; +use crate::{ + AbstractSyntaxTree, Context, EnumType, FunctionType, Identifier, StructType, Type, Vm, VmError, +}; /// Dust value representation /// @@ -50,317 +53,176 @@ use crate::{AbstractSyntaxTree, Context, Identifier, StructType, Type, Vm, VmErr /// ``` #[derive(Clone, Debug)] pub enum Value { - Immutable(Arc), - Mutable(Arc>), + Boolean(bool), + Byte(u8), + Character(char), + Enum { name: Identifier, r#type: EnumType }, + Float(f64), + Function(Arc), + Integer(i64), + List(Vec), + Mutable(Arc>), + Range(Range), + RangeInclusive(RangeInclusive), + String(String), + Struct(Struct), + Tuple(Vec), } impl Value { - pub fn boolean(boolean: bool) -> Self { - Value::Immutable(Arc::new(ValueData::Boolean(boolean))) + pub fn byte_range(start: u8, end: u8) -> Value { + Value::Range(Rangeable::Byte(start)..Rangeable::Byte(end)) } - pub fn float(float: f64) -> Self { - Value::Immutable(Arc::new(ValueData::Float(float))) + pub fn character_range(start: char, end: char) -> Value { + Value::Range(Rangeable::Character(start)..Rangeable::Character(end)) } - pub fn function(function: Function) -> Self { - Value::Immutable(Arc::new(ValueData::Function(function))) + pub fn float_range(start: f64, end: f64) -> Value { + Value::Range(Rangeable::Float(start)..Rangeable::Float(end)) } - pub fn integer(integer: i64) -> Self { - Value::Immutable(Arc::new(ValueData::Integer(integer))) + pub fn integer_range(start: i64, end: i64) -> Value { + Value::Range(Rangeable::Integer(start)..Rangeable::Integer(end)) } - pub fn list(list: Vec) -> Self { - Value::Immutable(Arc::new(ValueData::List(list))) - } - - pub fn map(map: BTreeMap) -> Self { - Value::Immutable(Arc::new(ValueData::Map(map))) - } - - pub fn range(range: Range) -> Self { - Value::Immutable(Arc::new(ValueData::RangeExclusive(range))) - } - - pub fn string(to_string: T) -> Self { - Value::Immutable(Arc::new(ValueData::String(to_string.to_string()))) - } - - pub fn r#struct(r#struct: Struct) -> Self { - Value::Immutable(Arc::new(ValueData::Struct(r#struct))) - } - - pub fn boolean_mut(boolean: bool) -> Self { - Value::Mutable(Arc::new(RwLock::new(ValueData::Boolean(boolean)))) - } - - pub fn string_mut(to_string: T) -> Self { - Value::Mutable(Arc::new(RwLock::new(ValueData::String( - to_string.to_string(), - )))) + pub fn into_mutable(self) -> Value { + match self { + Value::Mutable(_) => self, + immutable => Value::Mutable(Arc::new(RwLock::new(immutable))), + } } pub fn is_mutable(&self) -> bool { matches!(self, Value::Mutable(_)) } - pub fn to_mut(self) -> Result { - if let Value::Immutable(arc) = self { - let value_data = if let Some(value_data) = Arc::into_inner(arc) { - value_data - } else { - return Err(ValueError::CannotMakeMutable); - }; - - Ok(Value::Mutable(Arc::new(RwLock::new(value_data)))) - } else { - Ok(self) + pub fn as_mutable(&self) -> Result<&Arc>, ValueError> { + match self { + Value::Mutable(inner) => Ok(inner), + _ => Err(ValueError::CannotMutate(self.clone())), } } pub fn mutate(&self, other: Value) -> Result<(), ValueError> { - let mut inner = match self { - Value::Immutable(_) => return Err(ValueError::CannotMutate(self.clone())), - Value::Mutable(inner) => inner.write().unwrap(), + match self { + Value::Mutable(inner) => *inner.write().unwrap() = other, + _ => return Err(ValueError::CannotMutate(self.clone())), }; - match other { - Value::Immutable(other) => *inner = other.as_ref().clone(), - Value::Mutable(other) => *inner = other.read().unwrap().clone(), - } - Ok(()) } pub fn r#type(&self) -> Type { match self { - Value::Immutable(inner) => inner.r#type(), - Value::Mutable(inner_locked) => inner_locked.read().unwrap().r#type(), - } - } + Value::Boolean(_) => Type::Boolean, + Value::Byte(_) => Type::Byte, + Value::Character(_) => Type::Character, + Value::Enum { r#type, .. } => Type::Enum(r#type.clone()), + Value::Float(_) => Type::Float, + Value::Function(function) => Type::Function(function.r#type.clone()), + Value::Integer(_) => Type::Integer, + Value::List(values) => { + let item_type = values.first().unwrap().r#type(); - pub fn as_boolean(&self) -> Option { - match self { - Value::Immutable(arc) => match arc.as_ref() { - ValueData::Boolean(boolean) => Some(*boolean), - _ => None, - }, - Value::Mutable(arc_rw_lock) => match *arc_rw_lock.read().unwrap() { - ValueData::Boolean(boolean) => Some(boolean), - _ => None, - }, - } - } - - pub fn as_float(&self) -> Option { - match self { - Value::Immutable(arc) => match arc.as_ref() { - ValueData::Float(float) => Some(*float), - _ => None, - }, - Value::Mutable(arc_rw_lock) => match *arc_rw_lock.read().unwrap() { - ValueData::Float(float) => Some(float), - _ => None, - }, - } - } - - pub fn as_function(&self) -> Option<&Function> { - if let Value::Immutable(arc) = self { - if let ValueData::Function(function) = arc.as_ref() { - return Some(function); + Type::List { + item_type: Box::new(item_type), + length: values.len(), + } } - } - - None - } - - pub fn as_list(&self) -> Option<&Vec> { - if let Value::Immutable(arc) = self { - if let ValueData::List(list) = arc.as_ref() { - return Some(list); - } - } - - None - } - - pub fn as_map(&self) -> Option<&BTreeMap> { - if let Value::Immutable(arc) = self { - if let ValueData::Map(map) = arc.as_ref() { - return Some(map); - } - } - - None - } - - pub fn as_integer(&self) -> Option { - match self { - Value::Immutable(arc) => match arc.as_ref() { - ValueData::Integer(integer) => Some(*integer), - _ => None, + Value::Mutable(locked) => locked.read().unwrap().r#type(), + Value::Range(_) => Type::Range, + Value::RangeInclusive(_) => Type::Range, + Value::String(_) => Type::String, + Value::Struct(r#struct) => match r#struct { + Struct::Unit { r#type } => r#type.clone(), + Struct::Tuple { r#type, .. } => r#type.clone(), + Struct::Fields { r#type, .. } => r#type.clone(), }, - Value::Mutable(arc_rw_lock) => match *arc_rw_lock.read().unwrap() { - ValueData::Integer(integer) => Some(integer), - _ => None, - }, - } - } + Value::Tuple(values) => { + let item_types = values.iter().map(Value::r#type).collect(); - pub fn as_string(&self) -> Option<&String> { - if let Value::Immutable(arc) = self { - if let ValueData::String(string) = arc.as_ref() { - return Some(string); + Type::Tuple(item_types) } } - - None - } - - pub fn as_struct(&self) -> Option<&Struct> { - if let Value::Immutable(arc) = self { - if let ValueData::Struct(r#struct) = arc.as_ref() { - return Some(r#struct); - } - } - - None - } - - pub fn value_data_immutable(&self) -> Option<&ValueData> { - if let Value::Immutable(inner) = self { - Some(inner.as_ref()) - } else { - None - } - } - - pub fn value_data_mutable(&self) -> Option> { - if let Value::Mutable(inner) = self { - Some(inner.write().unwrap()) - } else { - None - } } pub fn get_field(&self, field: &Identifier) -> Option { match self { - Value::Immutable(inner) => inner.get_field(field), - Value::Mutable(inner) => inner.read().unwrap().get_field(field), + Value::Struct(Struct::Fields { fields, .. }) => { + fields.iter().find_map(|(identifier, value)| { + if identifier == field { + Some(value.clone()) + } else { + None + } + }) + } + Value::Mutable(inner) => inner.clone().read().unwrap().get_field(field), + _ => None, } } pub fn get_index(&self, index: usize) -> Option { match self { - Value::Immutable(inner) => inner.get_index(index), + Value::List(values) => values.get(index).cloned(), Value::Mutable(inner) => inner.read().unwrap().get_index(index), + _ => None, } } pub fn add(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left + right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_add(*right))); - } - (ValueData::String(left), ValueData::String(right)) => { - return Ok(Value::string(left.to_string() + right)); - } - _ => {} - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Float(left + right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Integer(left + right)), + (Value::String(left), Value::String(right)) => { + Ok(Value::String(format!("{}{}", left, right))) } (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left + right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_add(*right))); - } - (ValueData::String(left), ValueData::String(right)) => { - return Ok(Value::string(left.to_string() + right)); - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left + right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_add(*right))); - } - (ValueData::String(left), ValueData::String(right)) => { - return Ok(Value::string(left.to_string() + right)); - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left + right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_add(*right))); - } - (ValueData::String(left), ValueData::String(right)) => { - return Ok(Value::string(left.to_string() + right)); - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotAdd(self.clone(), other.clone())) + left.add(&right) + } + _ => Err(ValueError::CannotAdd(self.clone(), other.clone())), + } } pub fn add_assign(&self, other: &Value) -> Result<(), ValueError> { match (self, other) { (Value::Mutable(left), Value::Mutable(right)) => { match (&mut *left.write().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { + (Value::Float(left), Value::Float(right)) => { *left += right; return Ok(()); } - (ValueData::Integer(left), ValueData::Integer(right)) => { + (Value::Integer(left), Value::Integer(right)) => { *left = left.saturating_add(*right); return Ok(()); } - (ValueData::String(left), ValueData::String(right)) => { - left.push_str(right); + (Value::String(left), Value::String(right)) => { + (*left).push_str(right); return Ok(()); } _ => {} } } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&mut *left.write().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - *left += right; - return Ok(()); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - *left = left.saturating_add(*right); - return Ok(()); - } - (ValueData::String(left), ValueData::String(right)) => { - left.push_str(right); - return Ok(()); - } - _ => {} + (Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) { + (Value::Float(left), Value::Float(right)) => { + *left += right; + return Ok(()); } - } - (Value::Immutable(_), _) => { - return Err(ValueError::CannotMutate(self.clone())); - } + (Value::Integer(left), Value::Integer(right)) => { + *left = left.saturating_add(*right); + return Ok(()); + } + (Value::String(left), Value::String(right)) => { + left.push_str(right); + return Ok(()); + } + _ => {} + }, + _ => {} } Err(ValueError::CannotAdd(self.clone(), other.clone())) @@ -368,86 +230,45 @@ impl Value { pub fn subtract(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left - right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_sub(*right))); - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Float(left - right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Integer(left - right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left - right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_sub(*right))); - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left - right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_sub(*right))); - } - _ => {} - } - } - (Value::Mutable(right), Value::Immutable(left)) => { - match (&*right.read().unwrap(), left.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left - right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_sub(*right))); - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotSubtract(self.clone(), other.clone())) + left.subtract(&right) + } + _ => Err(ValueError::CannotSubtract(self.clone(), other.clone())), + } } pub fn subtract_assign(&self, other: &Value) -> Result<(), ValueError> { match (self, other) { (Value::Mutable(left), Value::Mutable(right)) => { match (&mut *left.write().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { + (Value::Float(left), Value::Float(right)) => { *left -= right; return Ok(()); } - (ValueData::Integer(left), ValueData::Integer(right)) => { + (Value::Integer(left), Value::Integer(right)) => { *left = left.saturating_sub(*right); return Ok(()); } _ => {} } } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&mut *left.write().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - *left -= right; - return Ok(()); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - *left = left.saturating_sub(*right); - return Ok(()); - } - _ => {} + (Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) { + (Value::Float(left), Value::Float(right)) => { + *left -= right; + return Ok(()); } - } - (Value::Immutable(_), _) => { - return Err(ValueError::CannotMutate(self.clone())); - } + (Value::Integer(left), Value::Integer(right)) => { + *left = left.saturating_sub(*right); + return Ok(()); + } + _ => {} + }, + _ => {} } Err(ValueError::CannotSubtract(self.clone(), other.clone())) @@ -455,76 +276,45 @@ impl Value { pub fn multiply(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left * right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_mul(*right))); - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Float(left * right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Integer(left * right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left * right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_mul(*right))); - } - _ => {} - } - } - (Value::Immutable(data), Value::Mutable(data_locked)) - | (Value::Mutable(data_locked), Value::Immutable(data)) => { - match (&*data_locked.read().unwrap(), data.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left * right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::integer(left.saturating_mul(*right))); - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotMultiply(self.clone(), other.clone())) + left.multiply(&right) + } + _ => Err(ValueError::CannotMultiply(self.clone(), other.clone())), + } } pub fn multiply_assign(&self, other: &Value) -> Result<(), ValueError> { match (self, other) { (Value::Mutable(left), Value::Mutable(right)) => { match (&mut *left.write().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { + (Value::Float(left), Value::Float(right)) => { *left *= right; return Ok(()); } - (ValueData::Integer(left), ValueData::Integer(right)) => { + (Value::Integer(left), Value::Integer(right)) => { *left = left.saturating_mul(*right); return Ok(()); } _ => {} } } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&mut *left.write().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - *left *= right; - return Ok(()); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - *left = left.saturating_mul(*right); - return Ok(()); - } - _ => {} + (Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) { + (Value::Float(left), Value::Float(right)) => { + *left *= right; + return Ok(()); } - } - (Value::Immutable(_), _) => { - return Err(ValueError::CannotMutate(self.clone())); - } + (Value::Integer(left), Value::Integer(right)) => { + *left = left.saturating_mul(*right); + return Ok(()); + } + _ => {} + }, + _ => {} } Err(ValueError::CannotMultiply(self.clone(), other.clone())) @@ -532,122 +322,47 @@ impl Value { pub fn divide(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - if *right == 0.0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::float(left / right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left / right)); - } - _ => {} - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Float(left / right)), + (Value::Integer(left), Value::Integer(right)) => { + Ok(Value::Float((*left as f64) / (*right as f64))) } (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - if *right == 0.0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::float(left / right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left / right)); - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - if *right == 0.0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::float(left / right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left / right)); - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - if *right == 0.0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::float(left / right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left / right)); - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotDivide(self.clone(), other.clone())) + left.divide(&right) + } + _ => Err(ValueError::CannotDivide(self.clone(), other.clone())), + } } pub fn divide_assign(&self, other: &Value) -> Result<(), ValueError> { match (self, other) { (Value::Mutable(left), Value::Mutable(right)) => { match (&mut *left.write().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - if *right == 0.0 { - return Err(ValueError::DivisionByZero); - } + (Value::Float(left), Value::Float(right)) => { *left /= right; return Ok(()); } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - *left = left.saturating_div(*right); + (Value::Integer(left), Value::Integer(right)) => { + *left = (*left as f64 / *right as f64) as i64; return Ok(()); } _ => {} } } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&mut *left.write().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - if *right == 0.0 { - return Err(ValueError::DivisionByZero); - } - *left /= right; - return Ok(()); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - *left = left.saturating_div(*right); - return Ok(()); - } - _ => {} + (Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) { + (Value::Float(left), Value::Float(right)) => { + *left /= right; + return Ok(()); } - } - (Value::Immutable(_), _) => { - return Err(ValueError::CannotMutate(self.clone())); - } + (Value::Integer(left), Value::Integer(right)) => { + *left = (*left as f64 / *right as f64) as i64; + return Ok(()); + } + _ => {} + }, + _ => {} } Err(ValueError::CannotDivide(self.clone(), other.clone())) @@ -655,104 +370,45 @@ impl Value { pub fn modulo(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left % right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left % right)); - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Float(left % right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Integer(left % right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left % right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left % right)); - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left % right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left % right)); - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::float(left % right)); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - return Ok(Value::integer(left % right)); - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotModulo(self.clone(), other.clone())) + left.modulo(&right) + } + _ => Err(ValueError::CannotModulo(self.clone(), other.clone())), + } } pub fn modulo_assign(&self, other: &Value) -> Result<(), ValueError> { match (self, other) { (Value::Mutable(left), Value::Mutable(right)) => { match (&mut *left.write().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { + (Value::Float(left), Value::Float(right)) => { *left %= right; return Ok(()); } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } + (Value::Integer(left), Value::Integer(right)) => { *left %= right; return Ok(()); } _ => {} } } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&mut *left.write().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - *left %= right; - return Ok(()); - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - if *right == 0 { - return Err(ValueError::DivisionByZero); - } - *left %= right; - return Ok(()); - } - _ => {} + (Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) { + (Value::Float(left), Value::Float(right)) => { + *left %= right; + return Ok(()); } - } - (Value::Immutable(_), _) => { - return Err(ValueError::CannotMutate(self.clone())); - } + (Value::Integer(left), Value::Integer(right)) => { + *left %= right; + return Ok(()); + } + _ => {} + }, + _ => {} } Err(ValueError::CannotModulo(self.clone(), other.clone())) @@ -760,312 +416,187 @@ impl Value { pub fn equal(&self, other: &Value) -> Value { let is_equal = match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => left == right, + (Value::Boolean(left), Value::Boolean(right)) => left == right, + (Value::Byte(left), Value::Byte(right)) => left == right, + (Value::Character(left), Value::Character(right)) => left == right, + (Value::Float(left), Value::Float(right)) => left == right, + (Value::Function(left), Value::Function(right)) => left == right, + (Value::Integer(left), Value::Integer(right)) => left == right, + (Value::List(left), Value::List(right)) => { + if left.len() != right.len() { + return Value::Boolean(false); + } + + for (left, right) in left.iter().zip(right.iter()) { + if let Value::Boolean(false) = left.equal(right) { + return Value::Boolean(false); + } + } + + true + } + (Value::Range(left), Value::Range(right)) => { + left.start == right.start && left.end == right.end + } + (Value::RangeInclusive(left), Value::RangeInclusive(right)) => { + left.start() == right.start() && left.end() == right.end() + } + (Value::String(left), Value::String(right)) => left == right, + (Value::Struct(left), Value::Struct(right)) => left == right, (Value::Mutable(left), Value::Mutable(right)) => { - *left.read().unwrap() == *right.read().unwrap() + let left = left.read().unwrap(); + let right = right.read().unwrap(); + + return left.equal(&right); } - (Value::Immutable(arc), Value::Mutable(arc_locked)) - | (Value::Mutable(arc_locked), Value::Immutable(arc)) => { - *arc_locked.read().unwrap() == *arc.as_ref() + (Value::Mutable(locked), immutable) | (immutable, Value::Mutable(locked)) => { + let locked = locked.read().unwrap(); + + return locked.equal(immutable); } + _ => false, }; - Value::boolean(is_equal) + Value::Boolean(is_equal) } pub fn not_equal(&self, other: &Value) -> Value { - let is_not_equal = match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => left != right, - (Value::Mutable(left), Value::Mutable(right)) => { - *left.read().unwrap() != *right.read().unwrap() - } - (Value::Immutable(arc), Value::Mutable(arc_locked)) - | (Value::Mutable(arc_locked), Value::Immutable(arc)) => { - *arc_locked.read().unwrap() != *arc.as_ref() - } - }; - - Value::boolean(is_not_equal) + if let Value::Boolean(is_equal) = self.equal(other) { + Value::Boolean(!is_equal) + } else { + Value::Boolean(true) + } } pub fn less_than(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left < right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left < right)) - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left < right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left < right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left < right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left < right)) - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left < right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left < right)) - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left < right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left < right)) - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotLessThan(self.clone(), other.clone())) + left.less_than(&right) + } + _ => Err(ValueError::CannotLessThan(self.clone(), other.clone())), + } } pub fn less_than_or_equal(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left <= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left <= right)) - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left <= right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left <= right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left <= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left <= right)) - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left <= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left <= right)) - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left <= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left <= right)) - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotLessThanOrEqual( - self.clone(), - other.clone(), - )) + left.less_than_or_equal(&right) + } + _ => Err(ValueError::CannotLessThanOrEqual( + self.clone(), + other.clone(), + )), + } } pub fn greater_than(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left > right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left > right)) - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left > right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left > right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left > right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left > right)) - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left > right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left > right)) - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left > right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left > right)) - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotGreaterThan(self.clone(), other.clone())) + left.greater_than(&right) + } + _ => Err(ValueError::CannotGreaterThan(self.clone(), other.clone())), + } } pub fn greater_than_or_equal(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - match (left.as_ref(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left >= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left >= right)) - } - _ => {} - } - } + (Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left >= right)), + (Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left >= right)), (Value::Mutable(left), Value::Mutable(right)) => { - match (&*left.read().unwrap(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left >= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left >= right)) - } - _ => {} - } - } - (Value::Immutable(left), Value::Mutable(right)) => { - match (left.as_ref(), &*right.read().unwrap()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left >= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left >= right)) - } - _ => {} - } - } - (Value::Mutable(left), Value::Immutable(right)) => { - match (&*left.read().unwrap(), right.as_ref()) { - (ValueData::Float(left), ValueData::Float(right)) => { - return Ok(Value::boolean(left >= right)) - } - (ValueData::Integer(left), ValueData::Integer(right)) => { - return Ok(Value::boolean(left >= right)) - } - _ => {} - } - } - } + let left = left.read().unwrap(); + let right = right.read().unwrap(); - Err(ValueError::CannotGreaterThanOrEqual( - self.clone(), - other.clone(), - )) + left.greater_than_or_equal(&right) + } + _ => Err(ValueError::CannotGreaterThanOrEqual( + self.clone(), + other.clone(), + )), + } } pub fn and(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - if let (ValueData::Boolean(left), ValueData::Boolean(right)) = - (left.as_ref(), right.as_ref()) - { - return Ok(Value::boolean(*left && *right)); - } - } - (Value::Mutable(left), Value::Mutable(right)) => { - if let (ValueData::Boolean(left), ValueData::Boolean(right)) = - (&*left.read().unwrap(), &*right.read().unwrap()) - { - return Ok(Value::boolean(*left && *right)); - } - } - (Value::Mutable(locked), Value::Immutable(data)) - | (Value::Immutable(data), Value::Mutable(locked)) => { - if let (ValueData::Boolean(left), ValueData::Boolean(right)) = - (&*locked.read().unwrap(), data.as_ref()) - { - return Ok(Value::boolean(*left && *right)); - } - } + (Value::Boolean(left), Value::Boolean(right)) => Ok(Value::Boolean(*left && *right)), + _ => Err(ValueError::CannotAnd(self.clone(), other.clone())), } - - Err(ValueError::CannotAnd(self.clone(), other.clone())) } pub fn or(&self, other: &Value) -> Result { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => { - if let (ValueData::Boolean(left), ValueData::Boolean(right)) = - (left.as_ref(), right.as_ref()) - { - return Ok(Value::boolean(*left || *right)); - } - } - (Value::Mutable(left), Value::Mutable(right)) => { - if let (ValueData::Boolean(left), ValueData::Boolean(right)) = - (&*left.read().unwrap(), &*right.read().unwrap()) - { - return Ok(Value::boolean(*left || *right)); - } - } - (Value::Mutable(locked), Value::Immutable(data)) - | (Value::Immutable(data), Value::Mutable(locked)) => { - if let (ValueData::Boolean(left), ValueData::Boolean(right)) = - (&*locked.read().unwrap(), data.as_ref()) - { - return Ok(Value::boolean(*left || *right)); - } - } + (Value::Boolean(left), Value::Boolean(right)) => Ok(Value::Boolean(*left || *right)), + _ => Err(ValueError::CannotOr(self.clone(), other.clone())), } - - Err(ValueError::CannotOr(self.clone(), other.clone())) } } impl Display for Value { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Value::Immutable(inner) => write!(f, "{inner}"), Value::Mutable(inner_locked) => { let inner = inner_locked.read().unwrap(); write!(f, "{inner}") } + Value::Boolean(boolean) => write!(f, "{boolean}"), + Value::Byte(byte) => write!(f, "{byte}"), + Value::Character(character) => write!(f, "{character}"), + Value::Enum { name, r#type } => write!(f, "{name}::{type}"), + Value::Float(float) => write!(f, "{float}"), + Value::Function(function) => write!(f, "{function}"), + Value::Integer(integer) => write!(f, "{integer}"), + Value::List(list) => { + write!(f, "[")?; + + for (index, value) in list.iter().enumerate() { + write!(f, "{}", value)?; + + if index < list.len() - 1 { + write!(f, ", ")?; + } + } + + write!(f, "]") + } + Value::Range(Range { start, end }) => { + write!(f, "{start}..{end}") + } + Value::RangeInclusive(inclusive) => { + let start = inclusive.start(); + let end = inclusive.end(); + + write!(f, "{start}..={end}") + } + Value::String(string) => write!(f, "{string}"), + Value::Struct(structure) => write!(f, "{structure}"), + Value::Tuple(fields) => { + write!(f, "(")?; + + for (index, field) in fields.iter().enumerate() { + write!(f, "{}", field)?; + + if index < fields.len() - 1 { + write!(f, ", ")?; + } + } + + write!(f, ")") + } } } } @@ -1075,35 +606,85 @@ impl Eq for Value {} impl PartialEq for Value { fn eq(&self, other: &Self) -> bool { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => left == right, + (Value::Boolean(left), Value::Boolean(right)) => left == right, + (Value::Byte(left), Value::Byte(right)) => left == right, + (Value::Character(left), Value::Character(right)) => left == right, + (Value::Float(left), Value::Float(right)) => left == right, + (Value::Function(left), Value::Function(right)) => left == right, + (Value::Integer(left), Value::Integer(right)) => left == right, + (Value::List(left), Value::List(right)) => left == right, (Value::Mutable(left), Value::Mutable(right)) => { - *left.read().unwrap() == *right.read().unwrap() - } - (Value::Immutable(inner), Value::Mutable(inner_locked)) - | (Value::Mutable(inner_locked), Value::Immutable(inner)) => { - **inner == *inner_locked.read().unwrap() + let left = &*left.read().unwrap(); + let right = &*right.read().unwrap(); + + left == right } + (Value::Range(left), Value::Range(right)) => left == right, + (Value::RangeInclusive(left), Value::RangeInclusive(right)) => left == right, + (Value::String(left), Value::String(right)) => left == right, + (Value::Struct(left), Value::Struct(right)) => left == right, + (Value::Tuple(left), Value::Tuple(right)) => left == right, + _ => false, } } } impl PartialOrd for Value { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Value { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> Ordering { match (self, other) { - (Value::Immutable(left), Value::Immutable(right)) => left.cmp(right), + (Value::Boolean(left), Value::Boolean(right)) => left.cmp(right), + (Value::Boolean(_), _) => Ordering::Greater, + (Value::Byte(left), Value::Byte(right)) => left.cmp(right), + (Value::Byte(_), _) => Ordering::Greater, + (Value::Character(left), Value::Character(right)) => left.cmp(right), + (Value::Character(_), _) => Ordering::Greater, + (Value::Float(left), Value::Float(right)) => left.partial_cmp(right).unwrap(), + (Value::Float(_), _) => Ordering::Greater, + (Value::Function(left), Value::Function(right)) => left.cmp(right), + (Value::Function(_), _) => Ordering::Greater, + (Value::Integer(left), Value::Integer(right)) => left.cmp(right), + (Value::Integer(_), _) => Ordering::Greater, + (Value::List(left), Value::List(right)) => left.cmp(right), + (Value::List(_), _) => Ordering::Greater, (Value::Mutable(left), Value::Mutable(right)) => { - left.read().unwrap().cmp(&right.read().unwrap()) + let left = left.read().unwrap(); + let right = right.read().unwrap(); + + left.cmp(&right) } - (Value::Immutable(inner), Value::Mutable(inner_locked)) - | (Value::Mutable(inner_locked), Value::Immutable(inner)) => { - inner_locked.read().unwrap().cmp(inner) + (Value::Mutable(_), _) => Ordering::Greater, + (Value::Range(left), Value::Range(right)) => { + let start_cmp = left.start.cmp(&right.start); + + if start_cmp.is_eq() { + left.end.cmp(&right.end) + } else { + start_cmp + } } + (Value::Range(_), _) => Ordering::Greater, + (Value::RangeInclusive(left), Value::RangeInclusive(right)) => { + let start_cmp = left.start().cmp(right.start()); + + if start_cmp.is_eq() { + left.end().cmp(right.end()) + } else { + start_cmp + } + } + (Value::RangeInclusive(_), _) => Ordering::Greater, + (Value::String(left), Value::String(right)) => left.cmp(right), + (Value::String(_), _) => Ordering::Greater, + (Value::Struct(left), Value::Struct(right)) => left.cmp(right), + (Value::Struct(_), _) => Ordering::Greater, + (Value::Tuple(left), Value::Tuple(right)) => left.cmp(right), + _ => Ordering::Greater, } } } @@ -1114,8 +695,31 @@ impl Serialize for Value { S: Serializer, { match self { - Value::Immutable(inner) => inner.serialize(serializer), - Value::Mutable(inner_locked) => inner_locked.read().unwrap().serialize(serializer), + Value::Mutable(inner_locked) => { + let inner = inner_locked.read().unwrap(); + + inner.serialize(serializer) + } + Value::Boolean(boolean) => serializer.serialize_bool(*boolean), + Value::Byte(byte) => serializer.serialize_u8(*byte), + Value::Character(character) => serializer.serialize_char(*character), + Value::Enum { name, r#type } => { + let mut ser = serializer.serialize_struct_variant("Value", 4, "Enum", 2)?; + + ser.serialize_field("name", name)?; + ser.serialize_field("type", r#type)?; + + ser.end() + } + Value::Float(float) => serializer.serialize_f64(*float), + Value::Function(function) => function.serialize(serializer), + Value::Integer(integer) => serializer.serialize_i64(*integer), + Value::List(list) => list.serialize(serializer), + Value::Range(range) => range.serialize(serializer), + Value::RangeInclusive(inclusive) => inclusive.serialize(serializer), + Value::String(string) => serializer.serialize_str(string), + Value::Struct(r#struct) => r#struct.serialize(serializer), + Value::Tuple(tuple) => tuple.serialize(serializer), } } } @@ -1125,514 +729,49 @@ impl<'de> Deserialize<'de> for Value { where D: Deserializer<'de>, { - ValueData::deserialize(deserializer).map(|data| Value::Immutable(Arc::new(data))) + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a value") + } + + fn visit_bool(self, value: bool) -> Result { + Ok(Value::Boolean(value)) + } + + fn visit_u8(self, value: u8) -> Result { + Ok(Value::Byte(value)) + } + + fn visit_char(self, value: char) -> Result { + Ok(Value::Character(value)) + } + + fn visit_f64(self, value: f64) -> Result { + Ok(Value::Float(value)) + } + + fn visit_i64(self, value: i64) -> Result { + Ok(Value::Integer(value)) + } + + fn visit_str(self, value: &str) -> Result { + Ok(Value::String(value.to_string())) + } + } + + deserializer.deserialize_any(ValueVisitor) } } -#[derive(Clone, Debug, PartialEq)] -pub enum ValueData { - Boolean(bool), - Float(f64), - Function(Function), - Integer(i64), - List(Vec), - Map(BTreeMap), - RangeExclusive(Range), - RangeInclusive(RangeInclusive), - String(String), - Struct(Struct), -} - -impl ValueData { - fn r#type(&self) -> Type { - match self { - ValueData::Boolean(_) => Type::Boolean, - ValueData::Float(_) => Type::Float, - ValueData::Function(function) => Type::Function { - type_parameters: function.type_parameters.clone(), - value_parameters: function.value_parameters.clone(), - return_type: function.return_type.as_ref().cloned().map(Box::new), - }, - ValueData::Integer(_) => Type::Integer, - ValueData::List(values) => { - let item_type = values.first().unwrap().r#type(); - - Type::List { - item_type: Box::new(item_type), - length: values.len(), - } - } - ValueData::Map(value_map) => { - let mut type_map = BTreeMap::new(); - - for (identifier, value) in value_map { - let r#type = value.r#type(); - - type_map.insert(identifier.clone(), r#type); - } - - Type::Map(type_map) - } - ValueData::RangeExclusive(_) => Type::Range, - ValueData::RangeInclusive(_) => Type::Range, - ValueData::String(_) => Type::String, - ValueData::Struct(r#struct) => match r#struct { - Struct::Unit { name } => Type::Struct(StructType::Unit { name: name.clone() }), - Struct::Tuple { .. } => todo!(), - Struct::Fields { .. } => todo!(), - }, - } - } - - fn get_field(&self, property: &Identifier) -> Option { - if let ValueData::Struct(Struct::Fields { fields, .. }) = self { - fields.iter().find_map(|(identifier, value)| { - if identifier == property { - Some(value.clone()) - } else { - None - } - }) - } else { - None - } - } - - fn get_index(&self, index: Value) -> Option { - if let ValueData::List(list) = self { - return list.get(index).cloned(); - } - - if let ValueData::RangeExclusive(range) = self { - if range.contains(&(index as i64)) { - return Some(Value::integer(index as i64)); - } - } - - if let ValueData::String(string) = self { - return string - .chars() - .nth(index) - .map(|character| Value::string(character.to_string())); - } - - if let ValueData::Struct(Struct::Tuple { fields, .. }) = self { - return fields.get(index).cloned(); - } - - None - } -} - -impl Display for ValueData { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - ValueData::Boolean(boolean) => write!(f, "{boolean}"), - ValueData::Float(float) => { - if float == &f64::INFINITY { - return write!(f, "Infinity"); - } - - if float == &f64::NEG_INFINITY { - return write!(f, "-Infinity"); - } - - write!(f, "{float}")?; - - if &float.floor() == float { - write!(f, ".0")?; - } - - Ok(()) - } - ValueData::Function(function) => write!(f, "{function}"), - ValueData::Integer(integer) => write!(f, "{integer}"), - ValueData::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, "]") - } - ValueData::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, " }}") - } - ValueData::RangeExclusive(range) => write!(f, "{}..{}", range.start, range.end), - ValueData::RangeInclusive(range) => write!(f, "{}..={}", range.start(), range.end()), - ValueData::String(string) => write!(f, "{string}"), - ValueData::Struct(r#struct) => write!(f, "{struct}"), - } - } -} - -impl Eq for ValueData {} - -impl PartialOrd for ValueData { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for ValueData { - fn cmp(&self, other: &Self) -> Ordering { - use ValueData::*; - - 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, - (RangeExclusive(left), RangeExclusive(right)) => { - let start_cmp = left.start.cmp(&right.start); - - if start_cmp.is_eq() { - left.end.cmp(&right.end) - } else { - start_cmp - } - } - (RangeExclusive(_), _) => Ordering::Greater, - (RangeInclusive(left), RangeInclusive(right)) => { - let start_cmp = left.start().cmp(right.start()); - - if start_cmp.is_eq() { - left.end().cmp(right.end()) - } else { - start_cmp - } - } - (RangeInclusive(_), _) => Ordering::Greater, - (String(left), String(right)) => left.cmp(right), - (String(_), _) => Ordering::Greater, - (Struct(left), Struct(right)) => left.cmp(right), - (Struct(_), _) => Ordering::Greater, - } - } -} - -impl Serialize for ValueData { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self { - ValueData::Boolean(boolean) => serializer.serialize_bool(*boolean), - ValueData::Float(float) => serializer.serialize_f64(*float), - ValueData::Function(function) => function.serialize(serializer), - ValueData::Integer(integer) => serializer.serialize_i64(*integer), - ValueData::List(list) => { - let mut list_ser = serializer.serialize_seq(Some(list.len()))?; - - for item in list { - list_ser.serialize_element(&item)?; - } - - list_ser.end() - } - ValueData::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() - } - ValueData::RangeExclusive(range) => { - let mut tuple_ser = serializer.serialize_tuple(2)?; - - tuple_ser.serialize_element(&range.start)?; - tuple_ser.serialize_element(&range.end)?; - - tuple_ser.end() - } - ValueData::RangeInclusive(range) => { - let mut tuple_ser = serializer.serialize_tuple(2)?; - - tuple_ser.serialize_element(&range.start())?; - tuple_ser.serialize_element(&range.end())?; - - tuple_ser.end() - } - ValueData::String(string) => serializer.serialize_str(string), - ValueData::Struct(r#struct) => r#struct.serialize(serializer), - } - } -} - -struct ValueInnerVisitor; - -impl<'de> Visitor<'de> for ValueInnerVisitor { - type Value = ValueData; - - 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(ValueData::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(ValueData::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(ValueData::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(ValueData::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(ValueData::String(v.to_string())) - } - - 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(ValueData::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(ValueData::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 ValueData { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(ValueInnerVisitor) - } -} - -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct Function { pub name: Identifier, - pub type_parameters: Option>, - pub value_parameters: Option>, - pub return_type: Option, - pub body: AbstractSyntaxTree, + pub r#type: FunctionType, + pub body: Arc, } impl Function { @@ -1645,14 +784,14 @@ impl Function { let new_context = Context::with_variables_from(context); if let (Some(value_parameters), Some(value_arguments)) = - (&self.value_parameters, value_arguments) + (&self.r#type.value_parameters, value_arguments) { for ((identifier, _), value) in value_parameters.iter().zip(value_arguments) { new_context.set_value(identifier.clone(), value); } } - let mut vm = Vm::new(self.body.clone(), new_context); + let mut vm = Vm::new(self.body.as_ref().clone(), new_context); vm.run() } @@ -1660,9 +799,9 @@ impl Function { impl Display for Function { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{}", self.name)?; + write!(f, "fn {}", self.name)?; - if let Some(type_parameters) = &self.type_parameters { + if let Some(type_parameters) = &self.r#type.type_parameters { write!(f, "<")?; for (index, type_parameter) in type_parameters.iter().enumerate() { @@ -1678,7 +817,7 @@ impl Display for Function { write!(f, "(")?; - if let Some(value_paramers) = &self.value_parameters { + if let Some(value_paramers) = &self.r#type.value_parameters { for (index, (identifier, r#type)) in value_paramers.iter().enumerate() { if index > 0 { write!(f, ", ")?; @@ -1698,37 +837,105 @@ impl Display for Function { } } +impl Serialize for Function { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut ser = serializer.serialize_struct("Function", 3)?; + + ser.serialize_field("name", &self.name)?; + ser.serialize_field("type", &self.r#type)?; + ser.serialize_field("body", self.body.as_ref())?; + + ser.end() + } +} + +impl<'de> Deserialize<'de> for Function { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FunctionVisitor; + + impl<'de> Visitor<'de> for FunctionVisitor { + type Value = Function; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a function") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut name = None; + let mut r#type = None; + let mut body = None; + + while let Some(key) = map.next_key()? { + match key { + "name" => { + if name.is_some() { + return Err(de::Error::duplicate_field("name")); + } + + name = Some(map.next_value()?); + } + "type" => { + if r#type.is_some() { + return Err(de::Error::duplicate_field("type")); + } + + r#type = Some(map.next_value()?); + } + "body" => { + if body.is_some() { + return Err(de::Error::duplicate_field("body")); + } + + body = Some(map.next_value().map(|ast| Arc::new(ast))?); + } + _ => { + return Err(de::Error::unknown_field(key, &["name", "type", "body"])); + } + } + } + + let name = name.ok_or_else(|| de::Error::missing_field("name"))?; + let r#type = r#type.ok_or_else(|| de::Error::missing_field("type"))?; + let body = body.ok_or_else(|| de::Error::missing_field("body"))?; + + Ok(Function { name, r#type, body }) + } + } + + deserializer.deserialize_struct("Function", &["name", "type", "body"], FunctionVisitor) + } +} + #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub enum Struct { Unit { - name: Identifier, + r#type: Type, }, Tuple { - name: Identifier, + r#type: Type, fields: Vec, }, Fields { - name: Identifier, + r#type: Type, fields: Vec<(Identifier, Value)>, }, } -impl Struct { - pub fn name(&self) -> &Identifier { - match self { - Struct::Unit { name } => name, - Struct::Tuple { name, .. } => name, - Struct::Fields { name, .. } => name, - } - } -} - impl Display for Struct { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Struct::Unit { name } => write!(f, "{}", name), - Struct::Tuple { name, fields } => { - write!(f, "{}(", name)?; + Struct::Unit { .. } => write!(f, "()"), + Struct::Tuple { fields, .. } => { + write!(f, "(")?; for (index, field) in fields.iter().enumerate() { if index > 0 { @@ -1740,8 +947,8 @@ impl Display for Struct { write!(f, ")") } - Struct::Fields { name, fields } => { - write!(f, "{} {{", name)?; + Struct::Fields { fields, .. } => { + write!(f, "{{ ")?; for (index, (identifier, r#type)) in fields.iter().enumerate() { if index > 0 { @@ -1751,12 +958,47 @@ impl Display for Struct { write!(f, "{}: {}", identifier, r#type)?; } - write!(f, "}}") + write!(f, " }}") } } } } +#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)] +enum Rangeable { + Byte(u8), + Character(char), + Float(f64), + Integer(i64), +} + +impl Display for Rangeable { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Rangeable::Byte(byte) => write!(f, "{byte}"), + Rangeable::Character(character) => write!(f, "{character}"), + Rangeable::Float(float) => write!(f, "{float}"), + Rangeable::Integer(integer) => write!(f, "{integer}"), + } + } +} + +impl Eq for Rangeable {} + +impl Ord for Rangeable { + fn cmp(&self, other: &Self) -> Ordering { + match (self, other) { + (Rangeable::Byte(left), Rangeable::Byte(right)) => left.cmp(right), + (Rangeable::Character(left), Rangeable::Character(right)) => left.cmp(right), + (Rangeable::Float(left), Rangeable::Float(right)) => { + left.to_bits().cmp(&right.to_bits()) + } + (Rangeable::Integer(left), Rangeable::Integer(right)) => left.cmp(right), + _ => unreachable!(), + } + } +} + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum ValueError { CannotAdd(Value, Value), diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 42ee329..08e8121 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -6,7 +6,6 @@ //! - `Vm` struct that can be used to run an abstract syntax tree use std::{ fmt::{self, Display, Formatter}, - ops::Range, sync::{Arc, Mutex}, }; @@ -151,14 +150,10 @@ impl Vm { } LetStatement::LetMut { identifier, value } => { let value_position = value.position(); - let value = self + let mutable_value = self .run_expression(value, collect_garbage)? - .expect_value(value_position)?; - let mutable_value = value.to_mut().map_err(|error| VmError::ValueError { - error, - left_position: identifier.position, - right_position: value_position, - })?; + .expect_value(value_position)? + .into_mutable(); self.context.set_value(identifier.inner, mutable_value);