dust/dust-lang/src/value.rs

345 lines
9.8 KiB
Rust
Raw Normal View History

2024-02-25 18:49:26 +00:00
use std::{
2024-02-25 19:26:22 +00:00
cmp::Ordering,
2024-02-28 23:36:47 +00:00
collections::BTreeMap,
2024-03-06 20:36:58 +00:00
fmt::{self, Display, Formatter},
2024-02-25 18:49:26 +00:00
ops::Range,
2024-03-23 12:15:48 +00:00
sync::Arc,
2024-02-25 18:49:26 +00:00
};
2024-06-04 18:47:15 +00:00
use serde::{Deserialize, Serialize};
2024-03-06 22:32:31 +00:00
use crate::{
2024-06-17 14:10:06 +00:00
abstract_tree::{AbstractNode, Block, Evaluation, Type, WithPosition},
2024-03-09 03:34:17 +00:00
context::Context,
2024-03-18 12:15:30 +00:00
error::{RuntimeError, ValidationError},
2024-03-25 04:16:55 +00:00
identifier::Identifier,
2024-03-06 22:32:31 +00:00
};
2024-02-25 18:49:26 +00:00
#[derive(Clone, Debug, PartialEq)]
pub struct Value(Arc<ValueInner>);
impl Value {
pub fn inner(&self) -> &Arc<ValueInner> {
&self.0
}
pub fn boolean(boolean: bool) -> Self {
Value(Arc::new(ValueInner::Boolean(boolean)))
}
pub fn float(float: f64) -> Self {
Value(Arc::new(ValueInner::Float(float)))
}
pub fn integer(integer: i64) -> Self {
Value(Arc::new(ValueInner::Integer(integer)))
}
2024-03-24 16:21:08 +00:00
pub fn list(list: Vec<WithPosition<Value>>) -> Self {
2024-02-25 18:49:26 +00:00
Value(Arc::new(ValueInner::List(list)))
}
2024-02-28 23:36:47 +00:00
pub fn map(map: BTreeMap<Identifier, Value>) -> Self {
Value(Arc::new(ValueInner::Map(map)))
}
2024-02-25 18:49:26 +00:00
pub fn range(range: Range<i64>) -> Self {
Value(Arc::new(ValueInner::Range(range)))
}
2024-03-24 14:58:09 +00:00
pub fn string<T: ToString>(to_string: T) -> Self {
Value(Arc::new(ValueInner::String(to_string.to_string())))
2024-02-25 18:49:26 +00:00
}
2024-03-17 05:26:05 +00:00
pub fn function(
2024-06-17 14:10:06 +00:00
type_parameters: Option<Vec<Identifier>>,
value_parameters: Vec<(Identifier, Type)>,
return_type: Type,
body: Block,
2024-03-17 05:26:05 +00:00
) -> Self {
2024-04-21 21:00:08 +00:00
Value(Arc::new(ValueInner::Function(Function {
2024-06-17 14:10:06 +00:00
type_parameters,
value_parameters,
2024-04-21 21:00:08 +00:00
return_type,
body,
})))
2024-03-08 21:14:47 +00:00
}
2024-03-25 04:16:55 +00:00
pub fn structure(name: WithPosition<Identifier>, fields: Vec<(Identifier, Value)>) -> Self {
2024-03-19 23:16:33 +00:00
Value(Arc::new(ValueInner::Structure { name, fields }))
}
2024-03-19 22:31:52 +00:00
pub fn r#type(&self, context: &Context) -> Result<Type, ValidationError> {
2024-03-20 12:36:18 +00:00
self.0.r#type(context)
2024-03-06 22:32:31 +00:00
}
2024-03-17 20:59:52 +00:00
pub fn as_boolean(&self) -> Option<bool> {
2024-02-25 19:26:22 +00:00
if let ValueInner::Boolean(boolean) = self.0.as_ref() {
2024-03-17 20:59:52 +00:00
Some(*boolean)
} else {
None
2024-03-09 13:10:54 +00:00
}
}
2024-03-24 16:21:08 +00:00
pub fn as_list(&self) -> Option<&Vec<WithPosition<Value>>> {
2024-03-07 17:29:07 +00:00
if let ValueInner::List(list) = self.inner().as_ref() {
Some(list)
} else {
None
}
}
pub fn as_integer(&self) -> Option<i64> {
if let ValueInner::Integer(integer) = self.inner().as_ref() {
Some(*integer)
} else {
None
}
}
2024-03-06 20:36:58 +00:00
}
impl Display for Value {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.inner().as_ref() {
2024-03-08 21:14:47 +00:00
ValueInner::Boolean(boolean) => write!(f, "{boolean}"),
ValueInner::Float(float) => write!(f, "{float}"),
ValueInner::Integer(integer) => write!(f, "{integer}"),
ValueInner::List(list) => {
write!(f, "[")?;
2024-03-08 03:20:59 +00:00
for (index, value) in list.into_iter().enumerate() {
if index == list.len() - 1 {
2024-06-16 07:12:04 +00:00
write!(f, "{}", value.node)?;
} else {
2024-06-16 07:12:04 +00:00
write!(f, "{}, ", value.node)?;
}
2024-03-08 03:20:59 +00:00
}
write!(f, "]")
2024-03-08 03:20:59 +00:00
}
2024-03-08 21:14:47 +00:00
ValueInner::Map(map) => {
write!(f, "[")?;
2024-03-07 21:19:24 +00:00
for (key, value) in map {
writeln!(f, "{key} = {value},")?;
2024-03-07 21:19:24 +00:00
}
write!(f, "]")
2024-03-07 21:19:24 +00:00
}
2024-03-08 21:14:47 +00:00
ValueInner::Range(_) => todo!(),
ValueInner::String(string) => write!(f, "{string}"),
2024-04-21 21:00:08 +00:00
ValueInner::Function(Function {
2024-06-17 14:10:06 +00:00
type_parameters,
value_parameters: parameters,
2024-03-08 21:14:47 +00:00
return_type,
body,
2024-04-21 21:00:08 +00:00
}) => {
2024-06-17 14:10:06 +00:00
if let Some(type_parameters) = type_parameters {
2024-03-24 13:10:49 +00:00
write!(f, "(")?;
2024-06-17 14:10:06 +00:00
for (index, r#type) in type_parameters.into_iter().enumerate() {
if index == type_parameters.len() - 1 {
write!(f, "{}", r#type)?;
2024-03-24 13:10:49 +00:00
} else {
2024-06-17 14:10:06 +00:00
write!(f, "{} ", r#type)?;
2024-03-24 13:10:49 +00:00
}
}
write!(f, ")")?;
}
2024-03-08 21:14:47 +00:00
write!(f, "(")?;
for (identifier, r#type) in parameters {
2024-06-17 14:10:06 +00:00
write!(f, "{identifier}: {}", r#type)?;
2024-03-08 21:14:47 +00:00
}
2024-03-08 03:20:59 +00:00
2024-06-17 14:10:06 +00:00
write!(f, "): {} {:?}", return_type, body)
2024-03-08 21:14:47 +00:00
}
2024-03-19 23:33:02 +00:00
ValueInner::Structure { name, fields } => {
2024-06-16 07:12:04 +00:00
write!(f, "{}\n{{", name.node)?;
2024-03-19 23:33:02 +00:00
for (key, value) in fields {
writeln!(f, "{key} = {value},")?;
2024-03-19 23:33:02 +00:00
}
write!(f, "}}")
2024-03-19 23:33:02 +00:00
}
2024-03-06 20:36:58 +00:00
}
}
2024-02-25 19:26:22 +00:00
}
impl Eq for Value {}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Value {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.as_ref().cmp(other.0.as_ref())
}
2024-02-25 18:49:26 +00:00
}
2024-06-04 18:47:15 +00:00
impl Serialize for Value {
2024-06-16 07:12:04 +00:00
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
2024-06-04 18:47:15 +00:00
where
S: serde::Serializer,
{
todo!()
}
}
impl<'de> Deserialize<'de> for Value {
2024-06-16 07:12:04 +00:00
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
2024-06-04 18:47:15 +00:00
where
D: serde::Deserializer<'de>,
{
todo!()
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
2024-02-25 18:49:26 +00:00
pub enum ValueInner {
Boolean(bool),
Float(f64),
2024-03-08 21:14:47 +00:00
Function(Function),
2024-02-25 18:49:26 +00:00
Integer(i64),
2024-03-24 16:21:08 +00:00
List(Vec<WithPosition<Value>>),
2024-02-28 23:36:47 +00:00
Map(BTreeMap<Identifier, Value>),
2024-02-25 18:49:26 +00:00
Range(Range<i64>),
String(String),
2024-03-19 22:31:52 +00:00
Structure {
2024-03-25 04:16:55 +00:00
name: WithPosition<Identifier>,
2024-03-19 23:16:33 +00:00
fields: Vec<(Identifier, Value)>,
2024-03-19 22:31:52 +00:00
},
2024-02-25 18:49:26 +00:00
}
2024-03-20 12:36:18 +00:00
impl ValueInner {
pub fn r#type(&self, context: &Context) -> Result<Type, ValidationError> {
let r#type = match self {
ValueInner::Boolean(_) => Type::Boolean,
ValueInner::Float(_) => Type::Float,
ValueInner::Integer(_) => Type::Integer,
ValueInner::List(values) => {
2024-06-17 14:10:06 +00:00
let item_type = values.first().unwrap().node.r#type(context)?;
2024-03-20 12:36:18 +00:00
2024-06-17 14:10:06 +00:00
Type::List {
length: values.len(),
item_type: Box::new(item_type),
2024-03-20 12:36:18 +00:00
}
}
ValueInner::Map(_) => Type::Map,
ValueInner::Range(_) => Type::Range,
ValueInner::String(_) => Type::String,
2024-04-21 21:00:08 +00:00
ValueInner::Function(function) => Type::Function {
2024-06-17 14:10:06 +00:00
type_parameters: None,
value_parameters: function.value_parameters.clone(),
2024-04-21 21:00:08 +00:00
return_type: Box::new(function.return_type.clone()),
2024-03-20 12:36:18 +00:00
},
ValueInner::Structure { name, .. } => {
2024-06-16 07:12:04 +00:00
if let Some(r#type) = context.get_type(&name.node)? {
2024-03-20 12:36:18 +00:00
r#type
} else {
2024-03-25 04:16:55 +00:00
return Err(ValidationError::VariableNotFound {
2024-06-16 07:12:04 +00:00
identifier: name.node.clone(),
2024-03-25 04:16:55 +00:00
position: name.position,
});
2024-03-20 12:36:18 +00:00
}
}
};
Ok(r#type)
}
}
2024-02-25 19:26:22 +00:00
impl Eq for ValueInner {}
impl PartialOrd for ValueInner {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ValueInner {
fn cmp(&self, other: &Self) -> Ordering {
use ValueInner::*;
match (self, other) {
(Boolean(left), Boolean(right)) => left.cmp(right),
(Boolean(_), _) => Ordering::Greater,
(Float(left), Float(right)) => left.total_cmp(right),
(Float(_), _) => Ordering::Greater,
(Integer(left), Integer(right)) => left.cmp(right),
(Integer(_), _) => Ordering::Greater,
(List(left), List(right)) => left.cmp(right),
(List(_), _) => Ordering::Greater,
2024-02-28 23:36:47 +00:00
(Map(left), Map(right)) => left.cmp(right),
(Map(_), _) => Ordering::Greater,
2024-02-25 19:26:22 +00:00
(Range(left), Range(right)) => {
let start_cmp = left.start.cmp(&right.start);
if start_cmp.is_eq() {
left.end.cmp(&right.end)
} else {
start_cmp
}
}
(Range(_), _) => Ordering::Greater,
(String(left), String(right)) => left.cmp(right),
(String(_), _) => Ordering::Greater,
2024-03-08 21:14:47 +00:00
(Function(left), Function(right)) => left.cmp(right),
(Function(_), _) => Ordering::Greater,
2024-03-19 22:31:52 +00:00
(
Structure {
name: left_name,
fields: left_fields,
},
Structure {
name: right_name,
fields: right_fields,
},
) => {
let name_cmp = left_name.cmp(right_name);
if name_cmp.is_eq() {
left_fields.cmp(right_fields)
} else {
name_cmp
}
}
(Structure { .. }, _) => Ordering::Greater,
2024-02-25 19:26:22 +00:00
}
}
}
2024-03-08 21:14:47 +00:00
2024-06-04 18:47:15 +00:00
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
2024-04-21 21:00:08 +00:00
pub struct Function {
2024-06-17 14:10:06 +00:00
type_parameters: Option<Vec<Identifier>>,
value_parameters: Vec<(Identifier, Type)>,
return_type: Type,
body: Block,
2024-03-09 03:34:17 +00:00
}
2024-03-09 13:10:54 +00:00
impl Function {
2024-06-17 14:10:06 +00:00
pub fn type_parameters(&self) -> &Option<Vec<Identifier>> {
2024-04-21 21:00:08 +00:00
&self.type_parameters
}
2024-03-09 13:10:54 +00:00
pub fn call(
self,
arguments: Vec<Value>,
context: &mut Context,
2024-04-22 07:41:21 +00:00
clear_variables: bool,
2024-06-17 14:10:06 +00:00
) -> Result<Evaluation, RuntimeError> {
for ((identifier, _), value) in self.value_parameters.into_iter().zip(arguments.into_iter())
{
2024-04-21 21:00:08 +00:00
context.set_value(identifier.clone(), value)?;
}
2024-03-09 13:10:54 +00:00
2024-06-17 14:10:06 +00:00
self.body.evaluate(context, clear_variables)
2024-03-09 13:10:54 +00:00
}
}