2024-08-09 01:59:09 +00:00
|
|
|
//! Dust value representation
|
2024-02-25 18:49:26 +00:00
|
|
|
use std::{
|
2024-02-25 19:26:22 +00:00
|
|
|
cmp::Ordering,
|
2024-08-17 08:06:13 +00:00
|
|
|
collections::HashMap,
|
2024-08-09 00:58:56 +00:00
|
|
|
error::Error,
|
2024-03-06 20:36:58 +00:00
|
|
|
fmt::{self, Display, Formatter},
|
2024-08-20 15:07:13 +00:00
|
|
|
ops::{Range, RangeInclusive},
|
2024-08-17 02:43:29 +00:00
|
|
|
sync::{Arc, RwLock},
|
2024-02-25 18:49:26 +00:00
|
|
|
};
|
|
|
|
|
2024-08-20 15:07:13 +00:00
|
|
|
use serde::{de::Visitor, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
|
2024-06-04 18:47:15 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
use crate::{
|
2024-08-20 21:01:30 +00:00
|
|
|
AbstractSyntaxTree, BuiltInFunction, BuiltInFunctionError, Context, ContextError, EnumType,
|
|
|
|
FunctionType, Identifier, RangeableType, RuntimeError, StructType, Type, Vm,
|
2024-08-16 21:07:49 +00:00
|
|
|
};
|
2024-02-25 18:49:26 +00:00
|
|
|
|
2024-08-07 23:12:40 +00:00
|
|
|
/// Dust value representation
|
|
|
|
///
|
|
|
|
/// Each type of value has a corresponding constructor, here are some simple examples:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use dust_lang::Value;
|
|
|
|
/// let boolean = Value::boolean(true);
|
|
|
|
/// let float = Value::float(3.14);
|
|
|
|
/// let integer = Value::integer(42);
|
|
|
|
/// let string = Value::string("Hello, world!");
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Values can be combined into more complex values:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use dust_lang::Value;
|
|
|
|
/// let list = Value::list(vec![
|
|
|
|
/// Value::integer(1),
|
|
|
|
/// Value::integer(2),
|
|
|
|
/// Value::integer(3),
|
|
|
|
/// ]);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Values have a type, which can be retrieved using the `type` method:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use std::collections::HashMap;
|
2024-08-10 08:32:27 +00:00
|
|
|
/// # use dust_lang::*;
|
2024-08-07 23:12:40 +00:00
|
|
|
/// let value = Value::integer(42);
|
|
|
|
///
|
2024-08-13 16:23:25 +00:00
|
|
|
/// assert_eq!(value.r#type(), Type::Integer);
|
2024-08-07 23:12:40 +00:00
|
|
|
/// ```
|
2024-08-14 05:03:46 +00:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub enum Value {
|
2024-08-16 21:07:49 +00:00
|
|
|
Boolean(bool),
|
|
|
|
Byte(u8),
|
|
|
|
Character(char),
|
2024-08-20 04:15:19 +00:00
|
|
|
Enum(Enum),
|
2024-08-16 21:07:49 +00:00
|
|
|
Float(f64),
|
2024-08-17 02:43:29 +00:00
|
|
|
Function(Function),
|
2024-08-16 21:07:49 +00:00
|
|
|
Integer(i64),
|
|
|
|
List(Vec<Value>),
|
2024-08-17 14:07:38 +00:00
|
|
|
Map(HashMap<Identifier, Value>),
|
2024-08-16 21:07:49 +00:00
|
|
|
Mutable(Arc<RwLock<Value>>),
|
|
|
|
Range(Range<Rangeable>),
|
|
|
|
RangeInclusive(RangeInclusive<Rangeable>),
|
|
|
|
String(String),
|
|
|
|
Struct(Struct),
|
|
|
|
Tuple(Vec<Value>),
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-02-25 18:49:26 +00:00
|
|
|
|
|
|
|
impl Value {
|
2024-08-17 14:07:38 +00:00
|
|
|
pub fn map<T: Into<HashMap<Identifier, Value>>>(pairs: T) -> Value {
|
|
|
|
Value::Map(pairs.into())
|
|
|
|
}
|
|
|
|
|
2024-08-17 02:43:29 +00:00
|
|
|
pub fn mutable(value: Value) -> Value {
|
|
|
|
Value::Mutable(Arc::new(RwLock::new(value)))
|
|
|
|
}
|
|
|
|
|
2024-08-20 04:15:19 +00:00
|
|
|
pub fn mutable_from<T: Into<Value>>(into_value: T) -> Value {
|
|
|
|
Value::Mutable(Arc::new(RwLock::new(into_value.into())))
|
|
|
|
}
|
|
|
|
|
2024-08-20 15:07:13 +00:00
|
|
|
pub fn range<T: Into<Rangeable>>(start: T, end: T) -> Value {
|
|
|
|
Value::Range(start.into()..end.into())
|
2024-08-13 17:28:22 +00:00
|
|
|
}
|
|
|
|
|
2024-08-20 15:07:13 +00:00
|
|
|
pub fn range_inclusive<T: Into<Rangeable>>(start: T, end: T) -> Value {
|
|
|
|
Value::RangeInclusive(start.into()..=end.into())
|
2024-08-17 02:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn string<T: ToString>(to_string: T) -> Value {
|
|
|
|
Value::String(to_string.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_boolean(&self) -> Option<bool> {
|
2024-08-16 21:07:49 +00:00
|
|
|
match self {
|
2024-08-17 02:43:29 +00:00
|
|
|
Value::Boolean(value) => Some(*value),
|
|
|
|
Value::Mutable(locked) => locked.read().unwrap().as_boolean(),
|
|
|
|
_ => None,
|
2024-08-16 21:07:49 +00:00
|
|
|
}
|
2024-08-14 08:59:27 +00:00
|
|
|
}
|
|
|
|
|
2024-08-17 02:43:29 +00:00
|
|
|
pub fn as_byte(&self) -> Option<u8> {
|
|
|
|
match self {
|
|
|
|
Value::Byte(value) => Some(*value),
|
|
|
|
Value::Mutable(locked) => locked.read().unwrap().as_byte(),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_character(&self) -> Option<char> {
|
|
|
|
match self {
|
|
|
|
Value::Character(value) => Some(*value),
|
|
|
|
Value::Mutable(locked) => locked.read().unwrap().as_character(),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_float(&self) -> Option<f64> {
|
|
|
|
match self {
|
|
|
|
Value::Float(value) => Some(*value),
|
|
|
|
Value::Mutable(locked) => locked.read().unwrap().as_float(),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_integer(&self) -> Option<i64> {
|
|
|
|
match self {
|
|
|
|
Value::Integer(value) => Some(*value),
|
|
|
|
Value::Mutable(locked) => locked.read().unwrap().as_integer(),
|
|
|
|
_ => None,
|
|
|
|
}
|
2024-08-14 08:59:27 +00:00
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
pub fn as_mutable(&self) -> Result<&Arc<RwLock<Value>>, ValueError> {
|
|
|
|
match self {
|
|
|
|
Value::Mutable(inner) => Ok(inner),
|
|
|
|
_ => Err(ValueError::CannotMutate(self.clone())),
|
2024-08-14 07:53:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-17 02:43:29 +00:00
|
|
|
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(_))
|
|
|
|
}
|
|
|
|
|
2024-08-16 10:43:29 +00:00
|
|
|
pub fn mutate(&self, other: Value) -> Result<(), ValueError> {
|
2024-08-16 21:07:49 +00:00
|
|
|
match self {
|
|
|
|
Value::Mutable(inner) => *inner.write().unwrap() = other,
|
|
|
|
_ => return Err(ValueError::CannotMutate(self.clone())),
|
2024-08-14 07:53:15 +00:00
|
|
|
};
|
|
|
|
|
2024-08-16 10:43:29 +00:00
|
|
|
Ok(())
|
2024-08-14 07:53:15 +00:00
|
|
|
}
|
|
|
|
|
2024-08-13 16:23:25 +00:00
|
|
|
pub fn r#type(&self) -> Type {
|
2024-08-14 05:03:46 +00:00
|
|
|
match self {
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Boolean(_) => Type::Boolean,
|
|
|
|
Value::Byte(_) => Type::Byte,
|
|
|
|
Value::Character(_) => Type::Character,
|
2024-08-20 04:15:19 +00:00
|
|
|
Value::Enum(Enum { r#type, .. }) => Type::Enum(r#type.clone()),
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Float(_) => Type::Float,
|
2024-08-20 11:20:44 +00:00
|
|
|
Value::Function(Function::BuiltIn(built_in_function)) => Type::Function(FunctionType {
|
|
|
|
name: Identifier::new(built_in_function.name()),
|
|
|
|
type_parameters: built_in_function.type_parameters(),
|
|
|
|
value_parameters: built_in_function.value_parameters(),
|
|
|
|
return_type: built_in_function.return_type().map(Box::new),
|
|
|
|
}),
|
2024-08-20 15:07:13 +00:00
|
|
|
Value::Function(Function::Parsed { r#type, .. }) => Type::Function(r#type.clone()),
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Integer(_) => Type::Integer,
|
|
|
|
Value::List(values) => {
|
|
|
|
let item_type = values.first().unwrap().r#type();
|
2024-03-07 17:29:07 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
Type::List {
|
|
|
|
item_type: Box::new(item_type),
|
|
|
|
length: values.len(),
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-08-17 14:07:38 +00:00
|
|
|
Value::Map(map) => {
|
|
|
|
let pairs = map
|
|
|
|
.iter()
|
|
|
|
.map(|(key, value)| (key.clone(), value.r#type()))
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
Type::Map { pairs }
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Mutable(locked) => locked.read().unwrap().r#type(),
|
2024-08-17 14:07:38 +00:00
|
|
|
Value::Range(range) => Type::Range {
|
|
|
|
r#type: range.start.r#type(),
|
|
|
|
},
|
|
|
|
Value::RangeInclusive(range_inclusive) => {
|
|
|
|
let rangeable_type = range_inclusive.start().r#type();
|
|
|
|
|
|
|
|
Type::Range {
|
|
|
|
r#type: rangeable_type,
|
|
|
|
}
|
|
|
|
}
|
2024-08-20 22:48:25 +00:00
|
|
|
Value::String(string) => Type::String {
|
|
|
|
length: Some(string.len()),
|
|
|
|
},
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Struct(r#struct) => match r#struct {
|
2024-08-20 04:15:19 +00:00
|
|
|
Struct::Unit { name } => Type::Struct(StructType::Unit { name: name.clone() }),
|
|
|
|
Struct::Tuple { name, fields } => {
|
2024-08-17 08:06:13 +00:00
|
|
|
let types = fields.iter().map(|field| field.r#type()).collect();
|
|
|
|
|
2024-08-20 04:15:19 +00:00
|
|
|
Type::Struct(StructType::Tuple {
|
|
|
|
name: name.clone(),
|
|
|
|
fields: types,
|
|
|
|
})
|
2024-08-17 08:06:13 +00:00
|
|
|
}
|
2024-08-20 04:15:19 +00:00
|
|
|
Struct::Fields { name, fields } => {
|
2024-08-17 08:06:13 +00:00
|
|
|
let types = fields
|
|
|
|
.iter()
|
|
|
|
.map(|(identifier, value)| (identifier.clone(), value.r#type()))
|
|
|
|
.collect();
|
|
|
|
|
2024-08-20 04:15:19 +00:00
|
|
|
Type::Struct(StructType::Fields {
|
|
|
|
name: name.clone(),
|
|
|
|
fields: types,
|
|
|
|
})
|
2024-08-17 08:06:13 +00:00
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
},
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Tuple(values) => {
|
2024-08-17 08:06:13 +00:00
|
|
|
let fields = values.iter().map(|value| value.r#type()).collect();
|
2024-08-05 02:15:31 +00:00
|
|
|
|
2024-08-20 04:15:19 +00:00
|
|
|
Type::Tuple(fields)
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-08-12 14:43:18 +00:00
|
|
|
}
|
2024-08-16 03:17:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_field(&self, field: &Identifier) -> Option<Value> {
|
2024-08-20 23:44:22 +00:00
|
|
|
if let Value::Mutable(locked) = self {
|
|
|
|
return locked.read().unwrap().get_field(field);
|
|
|
|
}
|
2024-08-20 11:20:44 +00:00
|
|
|
|
2024-08-20 23:44:22 +00:00
|
|
|
match field.as_str() {
|
|
|
|
"is_even" => match self {
|
|
|
|
Value::Integer(integer) => Some(Value::Boolean(integer % 2 == 0)),
|
|
|
|
Value::Float(float) => Some(Value::Boolean(float % 2.0 == 0.0)),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
"is_odd" => match self {
|
|
|
|
Value::Integer(integer) => Some(Value::Boolean(integer % 2 != 0)),
|
|
|
|
Value::Float(float) => Some(Value::Boolean(float % 2.0 != 0.0)),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
"to_string" => Some(Value::Function(Function::BuiltIn(
|
|
|
|
BuiltInFunction::ToString,
|
|
|
|
))),
|
|
|
|
"length" => match self {
|
|
|
|
Value::List(values) => Some(Value::Integer(values.len() as i64)),
|
|
|
|
Value::String(string) => Some(Value::Integer(string.len() as i64)),
|
|
|
|
Value::Map(map) => Some(Value::Integer(map.len() as i64)),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
_ => match self {
|
|
|
|
Value::Struct(Struct::Fields { fields, .. }) => fields.get(field).cloned(),
|
|
|
|
Value::Map(pairs) => pairs.get(field).cloned(),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
}
|
2024-08-16 03:17:49 +00:00
|
|
|
}
|
|
|
|
|
2024-08-17 14:07:38 +00:00
|
|
|
pub fn get_index(&self, index: Value) -> Result<Option<Value>, ValueError> {
|
|
|
|
match (self, index) {
|
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
|
|
|
return left
|
|
|
|
.read()
|
|
|
|
.unwrap()
|
|
|
|
.get_index(right.read().unwrap().clone());
|
|
|
|
}
|
|
|
|
(Value::Mutable(locked), index) => {
|
|
|
|
return locked.read().unwrap().get_index(index);
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(locked)) => {
|
|
|
|
return left.get_index(locked.read().unwrap().clone());
|
|
|
|
}
|
|
|
|
(Value::List(values), Value::Integer(integer)) => {
|
|
|
|
let index = integer as usize;
|
|
|
|
|
|
|
|
return Ok(values.get(index).cloned());
|
|
|
|
}
|
|
|
|
(Value::List(values), Value::Range(range)) => match (range.start, range.end) {
|
|
|
|
(Rangeable::Integer(start), Rangeable::Integer(end)) => {
|
|
|
|
let start = start as usize;
|
|
|
|
let end = end as usize;
|
|
|
|
|
|
|
|
return Ok(values
|
|
|
|
.get(start..end)
|
|
|
|
.map(|values| Value::List(values.to_vec())));
|
|
|
|
}
|
|
|
|
(start, end) => Err(ValueError::CannotIndex {
|
|
|
|
value: self.clone(),
|
|
|
|
index: Value::Range(start..end),
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
(Value::String(string), Value::Range(range)) => match (range.start, range.end) {
|
|
|
|
(Rangeable::Integer(start), Rangeable::Integer(end)) => {
|
|
|
|
let start = start as usize;
|
|
|
|
let end = end as usize;
|
|
|
|
|
|
|
|
return Ok(string.get(start..end).map(Value::string));
|
|
|
|
}
|
|
|
|
(start, end) => Err(ValueError::CannotIndex {
|
|
|
|
value: self.clone(),
|
|
|
|
index: Value::Range(start..end),
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
(Value::Range(range), Value::Integer(index)) => match (range.start, range.end) {
|
|
|
|
(Rangeable::Integer(start), Rangeable::Integer(end)) => {
|
|
|
|
Ok((start..end).nth(index as usize).map(Value::Integer))
|
|
|
|
}
|
|
|
|
(start, end) => Err(ValueError::CannotIndex {
|
|
|
|
value: self.clone(),
|
|
|
|
index: Value::Range(start..end),
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
(Value::String(string), Value::Integer(integer)) => {
|
|
|
|
let index = integer as usize;
|
|
|
|
|
|
|
|
return Ok(string.chars().nth(index).map(Value::Character));
|
|
|
|
}
|
|
|
|
(value, index) => Err(ValueError::CannotIndex {
|
|
|
|
value: value.clone(),
|
|
|
|
index,
|
|
|
|
}),
|
2024-08-16 09:14:00 +00:00
|
|
|
}
|
2024-08-16 03:17:49 +00:00
|
|
|
}
|
|
|
|
|
2024-08-05 02:15:31 +00:00
|
|
|
pub fn add(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Float(left + right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Integer(left.saturating_add(*right)))
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::String(left), Value::String(right)) => {
|
|
|
|
Ok(Value::String(format!("{}{}", left, right)))
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.add(&right)
|
2024-08-09 04:49:17 +00:00
|
|
|
}
|
2024-08-20 15:40:37 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.add(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.add(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotAdd(self.clone(), other.clone())),
|
2024-08-05 02:15:31 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-09 03:28:47 +00:00
|
|
|
|
2024-08-16 13:22:36 +00:00
|
|
|
pub fn add_assign(&self, other: &Value) -> Result<(), ValueError> {
|
2024-08-14 08:59:27 +00:00
|
|
|
match (self, other) {
|
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
|
|
|
match (&mut *left.write().unwrap(), &*right.read().unwrap()) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
2024-08-14 08:59:27 +00:00
|
|
|
*left += right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
2024-08-14 08:59:27 +00:00
|
|
|
*left = left.saturating_add(*right);
|
|
|
|
return Ok(());
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::String(left), Value::String(right)) => {
|
|
|
|
(*left).push_str(right);
|
2024-08-14 08:59:27 +00:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) {
|
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
|
|
|
*left += right;
|
|
|
|
return Ok(());
|
2024-08-14 08:59:27 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(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(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
_ => {}
|
2024-08-14 08:59:27 +00:00
|
|
|
}
|
|
|
|
|
2024-08-17 14:07:38 +00:00
|
|
|
Err(ValueError::CannotMutate(self.clone()))
|
2024-08-14 08:59:27 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 03:28:47 +00:00
|
|
|
pub fn subtract(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Float(left - right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Integer(left.saturating_sub(*right)))
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.subtract(&right)
|
2024-08-09 03:28:47 +00:00
|
|
|
}
|
2024-08-20 15:40:37 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.subtract(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.subtract(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotSubtract(self.clone(), other.clone())),
|
2024-08-09 03:28:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 13:22:36 +00:00
|
|
|
pub fn subtract_assign(&self, other: &Value) -> Result<(), ValueError> {
|
2024-08-14 18:28:39 +00:00
|
|
|
match (self, other) {
|
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
|
|
|
match (&mut *left.write().unwrap(), &*right.read().unwrap()) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
2024-08-14 18:28:39 +00:00
|
|
|
*left -= right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
2024-08-14 18:28:39 +00:00
|
|
|
*left = left.saturating_sub(*right);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) {
|
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
|
|
|
*left -= right;
|
|
|
|
return Ok(());
|
2024-08-14 18:28:39 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
*left = left.saturating_sub(*right);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
_ => {}
|
2024-08-14 18:28:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(ValueError::CannotSubtract(self.clone(), other.clone()))
|
|
|
|
}
|
|
|
|
|
2024-08-09 03:28:47 +00:00
|
|
|
pub fn multiply(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Float(left * right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Integer(left.saturating_mul(*right)))
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.multiply(&right)
|
2024-08-09 03:28:47 +00:00
|
|
|
}
|
2024-08-20 15:40:37 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.multiply(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.multiply(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotMultiply(self.clone(), other.clone())),
|
2024-08-09 03:28:47 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-09 07:00:48 +00:00
|
|
|
|
2024-08-16 13:22:36 +00:00
|
|
|
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()) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
2024-08-16 13:22:36 +00:00
|
|
|
*left *= right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
2024-08-16 13:22:36 +00:00
|
|
|
*left = left.saturating_mul(*right);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) {
|
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
|
|
|
*left *= right;
|
|
|
|
return Ok(());
|
2024-08-16 13:22:36 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
*left = left.saturating_mul(*right);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
_ => {}
|
2024-08-16 13:22:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(ValueError::CannotMultiply(self.clone(), other.clone()))
|
|
|
|
}
|
|
|
|
|
2024-08-09 10:46:24 +00:00
|
|
|
pub fn divide(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Float(left / right)),
|
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
2024-08-17 02:43:29 +00:00
|
|
|
Ok(Value::Integer(left.saturating_div(*right)))
|
2024-08-09 10:46:24 +00:00
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.divide(&right)
|
2024-08-09 10:46:24 +00:00
|
|
|
}
|
2024-08-20 15:40:37 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.divide(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.divide(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotDivide(self.clone(), other.clone())),
|
2024-08-09 10:46:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 13:22:36 +00:00
|
|
|
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()) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
2024-08-16 13:22:36 +00:00
|
|
|
*left /= right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
*left = (*left as f64 / *right as f64) as i64;
|
2024-08-16 13:22:36 +00:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) {
|
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
|
|
|
*left /= right;
|
|
|
|
return Ok(());
|
2024-08-16 13:22:36 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
*left = (*left as f64 / *right as f64) as i64;
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
_ => {}
|
2024-08-16 13:22:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(ValueError::CannotDivide(self.clone(), other.clone()))
|
|
|
|
}
|
|
|
|
|
2024-08-09 11:02:55 +00:00
|
|
|
pub fn modulo(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Float(left % right)),
|
|
|
|
(Value::Integer(left), Value::Integer(right)) => Ok(Value::Integer(left % right)),
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.modulo(&right)
|
2024-08-09 11:02:55 +00:00
|
|
|
}
|
2024-08-20 15:40:37 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.modulo(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.modulo(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotModulo(self.clone(), other.clone())),
|
2024-08-09 11:02:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 13:22:36 +00:00
|
|
|
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()) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
2024-08-16 13:22:36 +00:00
|
|
|
*left %= right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
2024-08-16 13:22:36 +00:00
|
|
|
*left %= right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(left), right) => match (&mut *left.write().unwrap(), right) {
|
|
|
|
(Value::Float(left), Value::Float(right)) => {
|
|
|
|
*left %= right;
|
|
|
|
return Ok(());
|
2024-08-16 13:22:36 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Integer(left), Value::Integer(right)) => {
|
|
|
|
*left %= right;
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
_ => {}
|
2024-08-16 13:22:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Err(ValueError::CannotModulo(self.clone(), other.clone()))
|
|
|
|
}
|
|
|
|
|
2024-08-16 10:43:29 +00:00
|
|
|
pub fn equal(&self, other: &Value) -> Value {
|
|
|
|
let is_equal = match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(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,
|
2024-08-16 10:43:29 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
return left.equal(&right);
|
2024-08-16 10:43:29 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(locked), immutable) | (immutable, Value::Mutable(locked)) => {
|
|
|
|
let locked = locked.read().unwrap();
|
|
|
|
|
|
|
|
return locked.equal(immutable);
|
2024-08-16 10:43:29 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => false,
|
2024-08-16 10:43:29 +00:00
|
|
|
};
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Boolean(is_equal)
|
2024-08-16 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn not_equal(&self, other: &Value) -> Value {
|
2024-08-16 21:07:49 +00:00
|
|
|
if let Value::Boolean(is_equal) = self.equal(other) {
|
|
|
|
Value::Boolean(!is_equal)
|
|
|
|
} else {
|
|
|
|
Value::Boolean(true)
|
|
|
|
}
|
2024-08-16 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2024-08-09 07:00:48 +00:00
|
|
|
pub fn less_than(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left < right)),
|
|
|
|
(Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left < right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Float(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Boolean(*left < *right as f64))
|
|
|
|
}
|
|
|
|
(Value::Integer(left), Value::Float(right)) => {
|
|
|
|
Ok(Value::Boolean((*left as f64) < *right))
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.less_than(&right)
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.less_than(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.less_than(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotLessThan(self.clone(), other.clone())),
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn less_than_or_equal(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left <= right)),
|
|
|
|
(Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left <= right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Float(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Boolean(*left <= *right as f64))
|
|
|
|
}
|
|
|
|
(Value::Integer(left), Value::Float(right)) => {
|
|
|
|
Ok(Value::Boolean(*left as f64 <= *right))
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.less_than_or_equal(&right)
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.less_than_or_equal(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.less_than_or_equal(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotLessThanOrEqual(
|
|
|
|
self.clone(),
|
|
|
|
other.clone(),
|
|
|
|
)),
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn greater_than(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left > right)),
|
|
|
|
(Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left > right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Float(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Boolean(*left > *right as f64))
|
|
|
|
}
|
|
|
|
(Value::Integer(left), Value::Float(right)) => {
|
|
|
|
Ok(Value::Boolean(*left as f64 > *right))
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.greater_than(&right)
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.greater_than(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.greater_than(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotGreaterThan(self.clone(), other.clone())),
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn greater_than_or_equal(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-14 05:03:46 +00:00
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Float(left), Value::Float(right)) => Ok(Value::Boolean(left >= right)),
|
|
|
|
(Value::Integer(left), Value::Integer(right)) => Ok(Value::Boolean(left >= right)),
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Float(left), Value::Integer(right)) => {
|
|
|
|
Ok(Value::Boolean(*left >= *right as f64))
|
|
|
|
}
|
|
|
|
(Value::Integer(left), Value::Float(right)) => {
|
|
|
|
Ok(Value::Boolean(*left as f64 >= *right))
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
2024-08-16 21:07:49 +00:00
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.greater_than_or_equal(&right)
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
2024-08-17 02:43:29 +00:00
|
|
|
(Value::Mutable(left), right) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
|
|
|
|
left.greater_than_or_equal(right)
|
|
|
|
}
|
|
|
|
(left, Value::Mutable(right)) => {
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.greater_than_or_equal(&right)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotGreaterThanOrEqual(
|
|
|
|
self.clone(),
|
|
|
|
other.clone(),
|
|
|
|
)),
|
2024-08-09 07:00:48 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-09 08:56:24 +00:00
|
|
|
|
|
|
|
pub fn and(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-20 19:16:06 +00:00
|
|
|
match (self, other) {
|
|
|
|
(Value::Boolean(left), Value::Boolean(right)) => Ok(Value::Boolean(*left && *right)),
|
|
|
|
(Value::Mutable(locked), value) | (value, Value::Mutable(locked)) => {
|
|
|
|
let locked = locked.read().unwrap();
|
|
|
|
|
|
|
|
locked.and(value)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotAnd(self.clone(), other.clone())),
|
2024-08-09 08:56:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn or(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-08-20 19:16:06 +00:00
|
|
|
match (self, other) {
|
|
|
|
(Value::Boolean(left), Value::Boolean(right)) => Ok(Value::Boolean(*left || *right)),
|
|
|
|
(Value::Mutable(locked), value) | (value, Value::Mutable(locked)) => {
|
|
|
|
let locked = locked.read().unwrap();
|
|
|
|
|
|
|
|
locked.or(value)
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
_ => Err(ValueError::CannotOr(self.clone(), other.clone())),
|
2024-08-09 08:56:24 +00:00
|
|
|
}
|
|
|
|
}
|
2024-03-06 20:36:58 +00:00
|
|
|
}
|
|
|
|
|
2024-08-20 04:15:19 +00:00
|
|
|
impl From<bool> for Value {
|
|
|
|
fn from(value: bool) -> Self {
|
|
|
|
Value::Boolean(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<u8> for Value {
|
|
|
|
fn from(value: u8) -> Self {
|
|
|
|
Value::Byte(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<char> for Value {
|
|
|
|
fn from(value: char) -> Self {
|
|
|
|
Value::Character(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<f64> for Value {
|
|
|
|
fn from(value: f64) -> Self {
|
|
|
|
Value::Float(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<i32> for Value {
|
|
|
|
fn from(value: i32) -> Self {
|
|
|
|
Value::Integer(value as i64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<i64> for Value {
|
|
|
|
fn from(value: i64) -> Self {
|
|
|
|
Value::Integer(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<String> for Value {
|
|
|
|
fn from(value: String) -> Self {
|
|
|
|
Value::String(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&str> for Value {
|
|
|
|
fn from(value: &str) -> Self {
|
|
|
|
Value::String(value.to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-06 20:36:58 +00:00
|
|
|
impl Display for Value {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
2024-08-14 05:03:46 +00:00
|
|
|
match self {
|
|
|
|
Value::Mutable(inner_locked) => {
|
|
|
|
let inner = inner_locked.read().unwrap();
|
|
|
|
|
|
|
|
write!(f, "{inner}")
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Boolean(boolean) => write!(f, "{boolean}"),
|
|
|
|
Value::Byte(byte) => write!(f, "{byte}"),
|
|
|
|
Value::Character(character) => write!(f, "{character}"),
|
2024-08-20 04:15:19 +00:00
|
|
|
Value::Enum(r#enum) => write!(f, "{enum}"),
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Float(float) => write!(f, "{float}"),
|
|
|
|
Value::Function(function) => write!(f, "{function}"),
|
|
|
|
Value::Integer(integer) => write!(f, "{integer}"),
|
2024-08-17 14:07:38 +00:00
|
|
|
Value::Map(pairs) => {
|
|
|
|
write!(f, "{{ ")?;
|
|
|
|
|
|
|
|
for (index, (key, value)) in pairs.iter().enumerate() {
|
|
|
|
write!(f, "{key}: {value}")?;
|
|
|
|
|
|
|
|
if index < pairs.len() - 1 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, " }}")
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::List(list) => {
|
|
|
|
write!(f, "[")?;
|
2024-08-14 05:03:46 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
for (index, value) in list.iter().enumerate() {
|
|
|
|
write!(f, "{}", value)?;
|
2024-08-14 05:03:46 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
if index < list.len() - 1 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
write!(f, "]")
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Range(Range { start, end }) => {
|
|
|
|
write!(f, "{start}..{end}")
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::RangeInclusive(inclusive) => {
|
|
|
|
let start = inclusive.start();
|
|
|
|
let end = inclusive.end();
|
2024-08-14 05:03:46 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
write!(f, "{start}..={end}")
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::String(string) => write!(f, "{string}"),
|
2024-08-20 04:15:19 +00:00
|
|
|
Value::Struct(r#struct) => write!(f, "{struct}"),
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Tuple(fields) => {
|
|
|
|
write!(f, "(")?;
|
2024-08-14 05:03:46 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
for (index, field) in fields.iter().enumerate() {
|
|
|
|
write!(f, "{}", field)?;
|
2024-08-14 05:03:46 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
if index < fields.len() - 1 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-08-16 03:17:49 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
write!(f, ")")
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl Eq for Value {}
|
2024-03-07 21:19:24 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl PartialEq for Value {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
match (self, other) {
|
|
|
|
(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,
|
2024-08-17 14:07:38 +00:00
|
|
|
(Value::Map(left), Value::Map(right)) => left == right,
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Mutable(left), Value::Mutable(right)) => {
|
|
|
|
let left = &*left.read().unwrap();
|
|
|
|
let right = &*right.read().unwrap();
|
2024-03-07 21:19:24 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
left == right
|
2024-03-07 21:19:24 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(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,
|
2024-03-06 20:36:58 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-25 19:26:22 +00:00
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl PartialOrd for Value {
|
2024-08-14 05:03:46 +00:00
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
2024-02-25 19:26:22 +00:00
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl Ord for Value {
|
2024-08-14 05:03:46 +00:00
|
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
|
|
match (self, other) {
|
2024-08-16 21:07:49 +00:00
|
|
|
(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)) => {
|
|
|
|
let left = left.read().unwrap();
|
|
|
|
let right = right.read().unwrap();
|
|
|
|
|
|
|
|
left.cmp(&right)
|
|
|
|
}
|
|
|
|
(Value::Mutable(_), _) => Ordering::Greater,
|
|
|
|
(Value::Range(left), Value::Range(right)) => {
|
2024-08-14 05:03:46 +00:00
|
|
|
let start_cmp = left.start.cmp(&right.start);
|
|
|
|
|
|
|
|
if start_cmp.is_eq() {
|
|
|
|
left.end.cmp(&right.end)
|
|
|
|
} else {
|
|
|
|
start_cmp
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Value::Range(_), _) => Ordering::Greater,
|
|
|
|
(Value::RangeInclusive(left), Value::RangeInclusive(right)) => {
|
2024-08-16 15:21:20 +00:00
|
|
|
let start_cmp = left.start().cmp(right.start());
|
|
|
|
|
|
|
|
if start_cmp.is_eq() {
|
|
|
|
left.end().cmp(right.end())
|
|
|
|
} else {
|
|
|
|
start_cmp
|
|
|
|
}
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(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,
|
2024-08-14 05:03:46 +00:00
|
|
|
}
|
2024-02-25 19:26:22 +00:00
|
|
|
}
|
2024-02-25 18:49:26 +00:00
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl Serialize for Value {
|
2024-06-19 07:32:51 +00:00
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
2024-06-04 18:47:15 +00:00
|
|
|
where
|
2024-08-14 05:03:46 +00:00
|
|
|
S: Serializer,
|
2024-06-19 07:32:51 +00:00
|
|
|
{
|
2024-08-14 05:03:46 +00:00
|
|
|
match self {
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Mutable(inner_locked) => {
|
|
|
|
let inner = inner_locked.read().unwrap();
|
2024-06-19 07:32:51 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
inner.serialize(serializer)
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
Value::Boolean(boolean) => serializer.serialize_bool(*boolean),
|
|
|
|
Value::Byte(byte) => serializer.serialize_u8(*byte),
|
|
|
|
Value::Character(character) => serializer.serialize_char(*character),
|
2024-08-20 04:15:19 +00:00
|
|
|
Value::Enum(r#emum) => r#emum.serialize(serializer),
|
2024-08-16 21:07:49 +00:00
|
|
|
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),
|
2024-08-17 14:07:38 +00:00
|
|
|
Value::Map(pairs) => {
|
|
|
|
let mut ser = serializer.serialize_map(Some(pairs.len()))?;
|
|
|
|
|
|
|
|
for (key, value) in pairs {
|
|
|
|
ser.serialize_entry(key, value)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
ser.end()
|
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
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),
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl<'de> Deserialize<'de> for Value {
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
|
2024-06-19 07:32:51 +00:00
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
2024-08-16 21:07:49 +00:00
|
|
|
struct ValueVisitor;
|
2024-06-19 07:32:51 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
impl<'de> Visitor<'de> for ValueVisitor {
|
|
|
|
type Value = Value;
|
2024-06-19 07:32:51 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
formatter.write_str("a value")
|
|
|
|
}
|
2024-06-19 08:56:56 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
|
|
|
|
Ok(Value::Boolean(value))
|
|
|
|
}
|
2024-06-19 08:56:56 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn visit_u8<E>(self, value: u8) -> Result<Value, E> {
|
|
|
|
Ok(Value::Byte(value))
|
|
|
|
}
|
2024-06-19 07:32:51 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn visit_char<E>(self, value: char) -> Result<Value, E> {
|
|
|
|
Ok(Value::Character(value))
|
|
|
|
}
|
2024-06-19 08:56:56 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
|
|
|
|
Ok(Value::Float(value))
|
|
|
|
}
|
2024-06-19 08:56:56 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
|
|
|
|
Ok(Value::Integer(value))
|
|
|
|
}
|
2024-06-19 07:32:51 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
fn visit_str<E>(self, value: &str) -> Result<Value, E> {
|
|
|
|
Ok(Value::String(value.to_string()))
|
|
|
|
}
|
|
|
|
}
|
2024-06-04 18:47:15 +00:00
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
deserializer.deserialize_any(ValueVisitor)
|
2024-06-22 17:55:43 +00:00
|
|
|
}
|
2024-03-09 13:10:54 +00:00
|
|
|
}
|
2024-08-05 02:15:31 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
|
|
|
pub enum Function {
|
|
|
|
BuiltIn(BuiltInFunction),
|
|
|
|
Parsed {
|
|
|
|
name: Identifier,
|
|
|
|
r#type: FunctionType,
|
|
|
|
body: AbstractSyntaxTree,
|
|
|
|
},
|
2024-08-07 14:03:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Function {
|
2024-08-07 22:24:25 +00:00
|
|
|
pub fn call(
|
2024-08-20 11:20:44 +00:00
|
|
|
self,
|
2024-08-07 22:46:40 +00:00
|
|
|
_type_arguments: Option<Vec<Type>>,
|
2024-08-07 22:24:25 +00:00
|
|
|
value_arguments: Option<Vec<Value>>,
|
2024-08-12 12:54:21 +00:00
|
|
|
context: &Context,
|
2024-08-20 21:01:30 +00:00
|
|
|
) -> Result<Option<Value>, FunctionCallError> {
|
2024-08-20 11:20:44 +00:00
|
|
|
match self {
|
|
|
|
Function::BuiltIn(built_in_function) => built_in_function
|
|
|
|
.call(_type_arguments, value_arguments)
|
2024-08-20 21:01:30 +00:00
|
|
|
.map_err(FunctionCallError::BuiltInFunction),
|
2024-08-20 11:20:44 +00:00
|
|
|
Function::Parsed { r#type, body, .. } => {
|
2024-08-20 21:01:30 +00:00
|
|
|
let new_context =
|
|
|
|
Context::with_data_from(context).map_err(FunctionCallError::Context)?;
|
2024-08-20 11:20:44 +00:00
|
|
|
|
|
|
|
if let (Some(value_parameters), Some(value_arguments)) =
|
|
|
|
(&r#type.value_parameters, value_arguments)
|
|
|
|
{
|
|
|
|
for ((identifier, _), value) in value_parameters.iter().zip(value_arguments) {
|
2024-08-20 21:01:30 +00:00
|
|
|
new_context
|
|
|
|
.set_variable_value(identifier.clone(), value)
|
|
|
|
.map_err(FunctionCallError::Context)?;
|
2024-08-20 11:20:44 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-07 22:24:25 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
let mut vm = Vm::new(body, new_context);
|
|
|
|
|
|
|
|
vm.run()
|
2024-08-20 21:01:30 +00:00
|
|
|
.map_err(|error| FunctionCallError::Runtime(Box::new(error)))
|
2024-08-07 22:24:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-07 14:03:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for Function {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
2024-08-20 11:20:44 +00:00
|
|
|
match self {
|
|
|
|
Function::BuiltIn(built_in_function) => write!(f, "{}", built_in_function),
|
|
|
|
Function::Parsed { name, r#type, body } => {
|
|
|
|
write!(f, "fn {}", name)?;
|
2024-08-07 14:03:33 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
if let Some(type_parameters) = &r#type.type_parameters {
|
|
|
|
write!(f, "<")?;
|
2024-08-07 14:03:33 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
for (index, type_parameter) in type_parameters.iter().enumerate() {
|
|
|
|
if index > 0 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
2024-08-07 14:03:33 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
write!(f, "{}", type_parameter)?;
|
|
|
|
}
|
2024-08-07 14:03:33 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
write!(f, ">")?;
|
2024-08-07 14:03:33 +00:00
|
|
|
}
|
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
write!(f, "(")?;
|
2024-08-16 21:07:49 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
if let Some(value_paramers) = &r#type.value_parameters {
|
|
|
|
for (index, (identifier, r#type)) in value_paramers.iter().enumerate() {
|
|
|
|
if index > 0 {
|
|
|
|
write!(f, ", ")?;
|
2024-08-16 21:07:49 +00:00
|
|
|
}
|
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
write!(f, "{identifier}: {type}")?;
|
2024-08-16 21:07:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
write!(f, ") {{")?;
|
2024-08-16 21:07:49 +00:00
|
|
|
|
2024-08-20 11:20:44 +00:00
|
|
|
for statement in &body.statements {
|
|
|
|
write!(f, "{}", statement)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "}}")
|
2024-08-16 21:07:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-20 21:01:30 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub enum FunctionCallError {
|
|
|
|
BuiltInFunction(BuiltInFunctionError),
|
|
|
|
Context(ContextError),
|
|
|
|
Runtime(Box<RuntimeError>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for FunctionCallError {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
FunctionCallError::BuiltInFunction(error) => write!(f, "{}", error),
|
|
|
|
FunctionCallError::Context(error) => write!(f, "{}", error),
|
|
|
|
FunctionCallError::Runtime(error) => write!(f, "{}", error),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-17 08:06:13 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
2024-08-12 19:02:04 +00:00
|
|
|
pub enum Struct {
|
|
|
|
Unit {
|
2024-08-17 08:06:13 +00:00
|
|
|
name: Identifier,
|
2024-08-12 19:02:04 +00:00
|
|
|
},
|
|
|
|
Tuple {
|
2024-08-17 08:06:13 +00:00
|
|
|
name: Identifier,
|
2024-08-12 19:02:04 +00:00
|
|
|
fields: Vec<Value>,
|
|
|
|
},
|
|
|
|
Fields {
|
2024-08-17 08:06:13 +00:00
|
|
|
name: Identifier,
|
|
|
|
fields: HashMap<Identifier, Value>,
|
2024-08-12 19:02:04 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-08-17 08:06:13 +00:00
|
|
|
impl PartialOrd for Struct {
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Ord for Struct {
|
|
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
|
|
match (self, other) {
|
|
|
|
(Struct::Unit { name: left }, Struct::Unit { name: right }) => left.cmp(right),
|
|
|
|
(Struct::Unit { .. }, _) => Ordering::Greater,
|
|
|
|
(
|
|
|
|
Struct::Tuple {
|
|
|
|
name: left_name,
|
|
|
|
fields: left_fields,
|
|
|
|
},
|
|
|
|
Struct::Tuple {
|
|
|
|
name: right_name,
|
|
|
|
fields: right_fields,
|
|
|
|
},
|
|
|
|
) => {
|
|
|
|
let type_cmp = left_name.cmp(right_name);
|
|
|
|
|
|
|
|
if type_cmp != Ordering::Equal {
|
|
|
|
return type_cmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
left_fields.cmp(right_fields)
|
|
|
|
}
|
|
|
|
(Struct::Tuple { .. }, _) => Ordering::Greater,
|
|
|
|
(
|
|
|
|
Struct::Fields {
|
|
|
|
name: left_name,
|
|
|
|
fields: left_fields,
|
|
|
|
},
|
|
|
|
Struct::Fields {
|
|
|
|
name: right_name,
|
|
|
|
fields: right_fields,
|
|
|
|
},
|
|
|
|
) => {
|
|
|
|
let type_cmp = left_name.cmp(right_name);
|
|
|
|
|
|
|
|
if type_cmp != Ordering::Equal {
|
|
|
|
return type_cmp;
|
|
|
|
}
|
|
|
|
|
2024-08-20 15:07:13 +00:00
|
|
|
left_fields.iter().cmp(right_fields.iter())
|
2024-08-17 08:06:13 +00:00
|
|
|
}
|
|
|
|
(Struct::Fields { .. }, _) => Ordering::Greater,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-12 19:02:04 +00:00
|
|
|
impl Display for Struct {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
|
|
match self {
|
2024-08-20 04:15:19 +00:00
|
|
|
Struct::Unit { name } => write!(f, "{name}"),
|
|
|
|
Struct::Tuple { name, fields } => {
|
|
|
|
write!(f, "{name}(")?;
|
2024-08-12 19:02:04 +00:00
|
|
|
|
|
|
|
for (index, field) in fields.iter().enumerate() {
|
|
|
|
if index > 0 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "{}", field)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, ")")
|
|
|
|
}
|
2024-08-20 04:15:19 +00:00
|
|
|
Struct::Fields { name, fields } => {
|
|
|
|
write!(f, "{name} {{ ")?;
|
2024-08-12 19:02:04 +00:00
|
|
|
|
2024-08-17 08:06:13 +00:00
|
|
|
for (index, (identifier, value)) in fields.iter().enumerate() {
|
2024-08-12 19:02:04 +00:00
|
|
|
if index > 0 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
|
2024-08-17 02:43:29 +00:00
|
|
|
write!(f, "{}: {}", identifier, value)?;
|
2024-08-12 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
write!(f, " }}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-17 14:07:38 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
2024-08-17 08:06:13 +00:00
|
|
|
pub enum Rangeable {
|
2024-08-16 21:07:49 +00:00
|
|
|
Byte(u8),
|
|
|
|
Character(char),
|
|
|
|
Float(f64),
|
|
|
|
Integer(i64),
|
|
|
|
}
|
|
|
|
|
2024-08-20 15:07:13 +00:00
|
|
|
impl From<u8> for Rangeable {
|
|
|
|
fn from(value: u8) -> Self {
|
|
|
|
Rangeable::Byte(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<char> for Rangeable {
|
|
|
|
fn from(value: char) -> Self {
|
|
|
|
Rangeable::Character(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<f64> for Rangeable {
|
|
|
|
fn from(value: f64) -> Self {
|
|
|
|
Rangeable::Float(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<i32> for Rangeable {
|
|
|
|
fn from(value: i32) -> Self {
|
|
|
|
Rangeable::Integer(value as i64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<i64> for Rangeable {
|
|
|
|
fn from(value: i64) -> Self {
|
|
|
|
Rangeable::Integer(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-17 14:07:38 +00:00
|
|
|
impl Rangeable {
|
|
|
|
fn r#type(&self) -> RangeableType {
|
|
|
|
match self {
|
|
|
|
Rangeable::Byte(_) => RangeableType::Byte,
|
|
|
|
Rangeable::Character(_) => RangeableType::Character,
|
|
|
|
Rangeable::Float(_) => RangeableType::Float,
|
|
|
|
Rangeable::Integer(_) => RangeableType::Integer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
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 {}
|
|
|
|
|
2024-08-17 02:43:29 +00:00
|
|
|
impl PartialOrd for Rangeable {
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-16 21:07:49 +00:00
|
|
|
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())
|
2024-08-12 19:02:04 +00:00
|
|
|
}
|
2024-08-16 21:07:49 +00:00
|
|
|
(Rangeable::Integer(left), Rangeable::Integer(right)) => left.cmp(right),
|
|
|
|
_ => unreachable!(),
|
2024-08-12 19:02:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-20 04:15:19 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Enum {
|
|
|
|
pub r#type: EnumType,
|
|
|
|
pub name: Identifier,
|
|
|
|
pub variant_data: Struct,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for Enum {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
|
|
let Enum {
|
|
|
|
name, variant_data, ..
|
|
|
|
} = self;
|
|
|
|
|
|
|
|
match &variant_data {
|
|
|
|
Struct::Unit { name: variant_name } => write!(f, "{name}::{variant_name}"),
|
|
|
|
Struct::Tuple {
|
|
|
|
name: variant_name,
|
|
|
|
fields,
|
|
|
|
} => {
|
|
|
|
write!(f, "{name}::{variant_name}(")?;
|
|
|
|
|
|
|
|
for (index, field) in fields.iter().enumerate() {
|
|
|
|
if index > 0 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "{}", field)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, ")")
|
|
|
|
}
|
|
|
|
Struct::Fields {
|
|
|
|
name: variant_name,
|
|
|
|
fields,
|
|
|
|
} => {
|
|
|
|
write!(f, "{name}::{variant_name} {{ ")?;
|
|
|
|
|
|
|
|
for (index, (identifier, value)) in fields.iter().enumerate() {
|
|
|
|
if index > 0 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "{}: {}", identifier, value)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, " }}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-07 14:03:33 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2024-08-05 02:15:31 +00:00
|
|
|
pub enum ValueError {
|
|
|
|
CannotAdd(Value, Value),
|
2024-08-09 08:56:24 +00:00
|
|
|
CannotAnd(Value, Value),
|
2024-08-09 10:46:24 +00:00
|
|
|
CannotDivide(Value, Value),
|
2024-08-09 07:00:48 +00:00
|
|
|
CannotGreaterThan(Value, Value),
|
|
|
|
CannotGreaterThanOrEqual(Value, Value),
|
2024-08-16 15:21:20 +00:00
|
|
|
CannotIndex { value: Value, index: Value },
|
2024-08-09 08:56:24 +00:00
|
|
|
CannotLessThan(Value, Value),
|
|
|
|
CannotLessThanOrEqual(Value, Value),
|
2024-08-16 13:22:36 +00:00
|
|
|
CannotMakeMutable,
|
2024-08-09 11:02:55 +00:00
|
|
|
CannotModulo(Value, Value),
|
2024-08-09 08:56:24 +00:00
|
|
|
CannotMultiply(Value, Value),
|
2024-08-14 05:13:43 +00:00
|
|
|
CannotMutate(Value),
|
2024-08-09 08:56:24 +00:00
|
|
|
CannotSubtract(Value, Value),
|
|
|
|
CannotOr(Value, Value),
|
2024-08-09 10:46:24 +00:00
|
|
|
DivisionByZero,
|
2024-08-05 18:58:58 +00:00
|
|
|
ExpectedList(Value),
|
2024-08-09 07:00:48 +00:00
|
|
|
IndexOutOfBounds { value: Value, index: i64 },
|
2024-08-05 02:15:31 +00:00
|
|
|
}
|
2024-08-09 00:58:56 +00:00
|
|
|
|
|
|
|
impl Error for ValueError {}
|
|
|
|
|
|
|
|
impl Display for ValueError {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
ValueError::CannotAdd(left, right) => write!(f, "Cannot add {} and {}", left, right),
|
2024-08-09 08:56:24 +00:00
|
|
|
ValueError::CannotAnd(left, right) => write!(
|
|
|
|
f,
|
|
|
|
"Cannot use logical and operation on {} and {}",
|
|
|
|
left, right
|
|
|
|
),
|
2024-08-09 10:46:24 +00:00
|
|
|
ValueError::CannotDivide(left, right) => {
|
|
|
|
write!(f, "Cannot divide {} by {}", left, right)
|
|
|
|
}
|
2024-08-16 15:21:20 +00:00
|
|
|
ValueError::CannotIndex { value, index } => {
|
|
|
|
write!(f, "Cannot index {} with {}", value, index)
|
|
|
|
}
|
2024-08-09 11:02:55 +00:00
|
|
|
ValueError::CannotModulo(left, right) => {
|
|
|
|
write!(f, "Cannot modulo {} by {}", left, right)
|
|
|
|
}
|
2024-08-09 03:28:47 +00:00
|
|
|
ValueError::CannotMultiply(left, right) => {
|
|
|
|
write!(f, "Cannot multiply {} and {}", left, right)
|
|
|
|
}
|
2024-08-16 13:22:36 +00:00
|
|
|
ValueError::CannotMakeMutable => write!(
|
|
|
|
f,
|
|
|
|
"Failed to make mutable value because the value has an immutable reference to it"
|
|
|
|
),
|
2024-08-14 05:13:43 +00:00
|
|
|
ValueError::CannotMutate(value) => write!(f, "Cannot mutate {}", value),
|
2024-08-09 03:28:47 +00:00
|
|
|
ValueError::CannotSubtract(left, right) => {
|
|
|
|
write!(f, "Cannot subtract {} and {}", left, right)
|
|
|
|
}
|
2024-08-09 07:00:48 +00:00
|
|
|
ValueError::CannotLessThan(left, right)
|
|
|
|
| ValueError::CannotLessThanOrEqual(left, right)
|
|
|
|
| ValueError::CannotGreaterThan(left, right)
|
|
|
|
| ValueError::CannotGreaterThanOrEqual(left, right) => {
|
|
|
|
write!(f, "Cannot compare {} and {}", left, right)
|
|
|
|
}
|
2024-08-09 08:56:24 +00:00
|
|
|
ValueError::CannotOr(left, right) => {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Cannot use logical or operation on {} and {}",
|
|
|
|
left, right
|
|
|
|
)
|
2024-08-09 00:58:56 +00:00
|
|
|
}
|
2024-08-09 10:46:24 +00:00
|
|
|
ValueError::DivisionByZero => write!(f, "Division by zero"),
|
2024-08-09 00:58:56 +00:00
|
|
|
ValueError::IndexOutOfBounds { value, index } => {
|
|
|
|
write!(f, "{} does not have an index of {}", value, index)
|
|
|
|
}
|
|
|
|
ValueError::ExpectedList(value) => write!(f, "{} is not a list", value),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|