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-19 08:56:56 +00:00
|
|
|
use chumsky::container::Container;
|
2024-06-19 07:32:51 +00:00
|
|
|
use serde::{
|
|
|
|
de::Visitor,
|
|
|
|
ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple},
|
|
|
|
Deserialize, Deserializer, Serialize,
|
|
|
|
};
|
2024-06-04 18:47:15 +00:00
|
|
|
|
2024-03-06 22:32:31 +00:00
|
|
|
use crate::{
|
2024-06-22 03:37:25 +00:00
|
|
|
abstract_tree::{AbstractNode, Block, Evaluation, Type, WithPosition},
|
2024-03-09 03:34:17 +00:00
|
|
|
context::Context,
|
2024-06-22 17:55:43 +00:00
|
|
|
error::{PoisonError, 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)))
|
|
|
|
}
|
|
|
|
|
2024-06-19 14:48:22 +00:00
|
|
|
pub fn enum_instance(
|
|
|
|
type_name: Identifier,
|
|
|
|
variant: Identifier,
|
|
|
|
content: Option<Vec<Value>>,
|
|
|
|
) -> Self {
|
|
|
|
Value(Arc::new(ValueInner::EnumInstance {
|
|
|
|
type_name,
|
|
|
|
variant,
|
|
|
|
content,
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2024-02-25 18:49:26 +00:00
|
|
|
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-06-19 08:56:56 +00:00
|
|
|
pub fn list(list: Vec<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>>,
|
2024-06-24 02:39:33 +00:00
|
|
|
value_parameters: Option<Vec<(Identifier, Type)>>,
|
2024-06-22 04:58:30 +00:00
|
|
|
return_type: Option<Type>,
|
2024-06-17 14:10:06 +00:00
|
|
|
body: Block,
|
2024-06-22 17:55:43 +00:00
|
|
|
context_template: Context,
|
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-06-22 17:55:43 +00:00
|
|
|
context_template,
|
2024-04-21 21:00:08 +00:00
|
|
|
})))
|
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-06-19 08:56:56 +00:00
|
|
|
pub fn as_list(&self) -> Option<&Vec<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}"),
|
2024-06-19 14:48:22 +00:00
|
|
|
ValueInner::EnumInstance {
|
|
|
|
type_name,
|
|
|
|
variant,
|
|
|
|
content,
|
|
|
|
} => {
|
|
|
|
if let Some(values) = content {
|
|
|
|
write!(f, "{type_name}::{variant}(")?;
|
|
|
|
|
|
|
|
for value in values {
|
|
|
|
write!(f, "{value}")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, ")")
|
|
|
|
} else {
|
|
|
|
write!(f, "{type_name}::{variant}")
|
|
|
|
}
|
|
|
|
}
|
2024-03-08 21:14:47 +00:00
|
|
|
ValueInner::Float(float) => write!(f, "{float}"),
|
|
|
|
ValueInner::Integer(integer) => write!(f, "{integer}"),
|
|
|
|
ValueInner::List(list) => {
|
2024-04-22 05:51:34 +00:00
|
|
|
write!(f, "[")?;
|
2024-03-08 03:20:59 +00:00
|
|
|
|
2024-04-22 05:51:34 +00:00
|
|
|
for (index, value) in list.into_iter().enumerate() {
|
|
|
|
if index == list.len() - 1 {
|
2024-06-19 08:56:56 +00:00
|
|
|
write!(f, "{}", value)?;
|
2024-04-22 05:51:34 +00:00
|
|
|
} else {
|
2024-06-19 08:56:56 +00:00
|
|
|
write!(f, "{}, ", value)?;
|
2024-04-22 05:51:34 +00:00
|
|
|
}
|
2024-03-08 03:20:59 +00:00
|
|
|
}
|
|
|
|
|
2024-04-22 05:51:34 +00:00
|
|
|
write!(f, "]")
|
2024-03-08 03:20:59 +00:00
|
|
|
}
|
2024-03-08 21:14:47 +00:00
|
|
|
ValueInner::Map(map) => {
|
2024-04-22 05:51:34 +00:00
|
|
|
write!(f, "[")?;
|
2024-03-07 21:19:24 +00:00
|
|
|
|
2024-04-22 05:51:34 +00:00
|
|
|
for (key, value) in map {
|
|
|
|
writeln!(f, "{key} = {value},")?;
|
2024-03-07 21:19:24 +00:00
|
|
|
}
|
|
|
|
|
2024-04-22 05:51:34 +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,
|
2024-06-24 02:39:33 +00:00
|
|
|
value_parameters,
|
2024-03-08 21:14:47 +00:00
|
|
|
return_type,
|
|
|
|
body,
|
2024-06-22 17:55:43 +00:00
|
|
|
..
|
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, "(")?;
|
|
|
|
|
2024-06-24 02:39:33 +00:00
|
|
|
if let Some(value_parameters) = value_parameters {
|
|
|
|
for (identifier, r#type) in value_parameters {
|
|
|
|
write!(f, "{identifier}: {}", r#type)?;
|
|
|
|
}
|
2024-03-08 21:14:47 +00:00
|
|
|
}
|
2024-03-08 03:20:59 +00:00
|
|
|
|
2024-06-22 04:58:30 +00:00
|
|
|
write!(f, ")")?;
|
|
|
|
|
|
|
|
if let Some(return_type) = return_type {
|
|
|
|
write!(f, "-> {return_type}")?
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, " {{ {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
|
|
|
|
2024-04-22 05:51:34 +00:00
|
|
|
for (key, value) in fields {
|
|
|
|
writeln!(f, "{key} = {value},")?;
|
2024-03-19 23:33:02 +00:00
|
|
|
}
|
|
|
|
|
2024-04-22 05:51:34 +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-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
|
|
|
|
S: serde::Serializer,
|
2024-06-19 07:32:51 +00:00
|
|
|
{
|
|
|
|
match self.0.as_ref() {
|
|
|
|
ValueInner::Boolean(boolean) => serializer.serialize_bool(*boolean),
|
2024-06-19 14:48:22 +00:00
|
|
|
ValueInner::EnumInstance {
|
|
|
|
type_name,
|
|
|
|
variant,
|
|
|
|
content,
|
|
|
|
} => {
|
|
|
|
let mut struct_ser = serializer.serialize_struct("EnumInstance", 3)?;
|
|
|
|
|
|
|
|
struct_ser.serialize_field("type_name", type_name)?;
|
|
|
|
struct_ser.serialize_field("variant", variant)?;
|
|
|
|
struct_ser.serialize_field("content", content)?;
|
|
|
|
|
|
|
|
struct_ser.end()
|
|
|
|
}
|
2024-06-19 07:32:51 +00:00
|
|
|
ValueInner::Float(float) => serializer.serialize_f64(*float),
|
|
|
|
ValueInner::Function(Function {
|
|
|
|
type_parameters,
|
|
|
|
value_parameters,
|
|
|
|
return_type,
|
|
|
|
body,
|
2024-06-22 17:55:43 +00:00
|
|
|
..
|
2024-06-19 07:32:51 +00:00
|
|
|
}) => {
|
|
|
|
let mut struct_ser = serializer.serialize_struct("Function", 4)?;
|
|
|
|
|
|
|
|
struct_ser.serialize_field("type_parameters", type_parameters)?;
|
|
|
|
struct_ser.serialize_field("value_parameters", value_parameters)?;
|
|
|
|
struct_ser.serialize_field("return_type", return_type)?;
|
|
|
|
struct_ser.serialize_field("body", body)?;
|
|
|
|
|
|
|
|
struct_ser.end()
|
|
|
|
}
|
|
|
|
ValueInner::Integer(integer) => serializer.serialize_i64(*integer),
|
|
|
|
ValueInner::List(list) => {
|
|
|
|
let mut list_ser = serializer.serialize_seq(Some(list.len()))?;
|
|
|
|
|
|
|
|
for item in list {
|
2024-06-19 08:56:56 +00:00
|
|
|
list_ser.serialize_element(&item)?;
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
list_ser.end()
|
|
|
|
}
|
|
|
|
ValueInner::Map(map) => {
|
|
|
|
let mut map_ser = serializer.serialize_map(Some(map.len()))?;
|
|
|
|
|
|
|
|
for (identifier, value) in map {
|
|
|
|
map_ser.serialize_entry(identifier, value)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
map_ser.end()
|
|
|
|
}
|
|
|
|
ValueInner::Range(range) => {
|
|
|
|
let mut tuple_ser = serializer.serialize_tuple(2)?;
|
|
|
|
|
|
|
|
tuple_ser.serialize_element(&range.start)?;
|
|
|
|
tuple_ser.serialize_element(&range.end)?;
|
|
|
|
|
|
|
|
tuple_ser.end()
|
|
|
|
}
|
|
|
|
ValueInner::String(string) => serializer.serialize_str(string),
|
|
|
|
ValueInner::Structure { name, fields } => {
|
|
|
|
let mut struct_ser = serializer.serialize_struct("Structure", 2)?;
|
|
|
|
|
|
|
|
struct_ser.serialize_field("name", name)?;
|
|
|
|
struct_ser.serialize_field("fields", fields)?;
|
|
|
|
|
|
|
|
struct_ser.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ValueVisitor;
|
|
|
|
|
|
|
|
impl<'de> Visitor<'de> for ValueVisitor {
|
|
|
|
type Value = Value;
|
|
|
|
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
formatter
|
|
|
|
.write_str("a boolean, float, function, integer, list, map, range, string or structure")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
2024-06-19 08:56:56 +00:00
|
|
|
Ok(Value::boolean(v))
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_i64(v as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_i64(v as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_i64(v as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
Ok(Value::integer(v))
|
|
|
|
}
|
|
|
|
|
2024-06-19 08:56:56 +00:00
|
|
|
fn visit_i128<E>(self, _: i128) -> Result<Self::Value, E>
|
2024-06-19 07:32:51 +00:00
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_u64(v as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_u64(v as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_u64(v as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
Ok(Value::integer(v as i64))
|
|
|
|
}
|
|
|
|
|
2024-06-19 08:56:56 +00:00
|
|
|
fn visit_u128<E>(self, _: u128) -> Result<Self::Value, E>
|
2024-06-19 07:32:51 +00:00
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
2024-06-04 18:47:15 +00:00
|
|
|
{
|
|
|
|
todo!()
|
|
|
|
}
|
2024-06-19 07:32:51 +00:00
|
|
|
|
|
|
|
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_f64(v as f64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
2024-06-19 08:56:56 +00:00
|
|
|
Ok(Value::float(v))
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_str(v.encode_utf8(&mut [0u8; 4]))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
2024-06-19 08:56:56 +00:00
|
|
|
Ok(Value::string(v))
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_str(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_str(&v)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
Err(serde::de::Error::invalid_type(
|
|
|
|
serde::de::Unexpected::Bytes(v),
|
|
|
|
&self,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_bytes(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
self.visit_bytes(&v)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_none<E>(self) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
Err(serde::de::Error::invalid_type(
|
|
|
|
serde::de::Unexpected::Option,
|
|
|
|
&self,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
|
|
|
let _ = deserializer;
|
|
|
|
Err(serde::de::Error::invalid_type(
|
|
|
|
serde::de::Unexpected::Option,
|
|
|
|
&self,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
Err(serde::de::Error::invalid_type(
|
|
|
|
serde::de::Unexpected::Unit,
|
|
|
|
&self,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
|
|
|
let _ = deserializer;
|
|
|
|
Err(serde::de::Error::invalid_type(
|
|
|
|
serde::de::Unexpected::NewtypeStruct,
|
|
|
|
&self,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2024-06-19 08:56:56 +00:00
|
|
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
2024-06-19 07:32:51 +00:00
|
|
|
where
|
|
|
|
A: serde::de::SeqAccess<'de>,
|
|
|
|
{
|
2024-06-19 08:56:56 +00:00
|
|
|
let mut list = Vec::with_capacity(seq.size_hint().unwrap_or(10));
|
|
|
|
|
|
|
|
while let Some(element) = seq.next_element()? {
|
|
|
|
list.push(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Value::list(list))
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
|
2024-06-19 08:56:56 +00:00
|
|
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
2024-06-19 07:32:51 +00:00
|
|
|
where
|
|
|
|
A: serde::de::MapAccess<'de>,
|
|
|
|
{
|
2024-06-19 08:56:56 +00:00
|
|
|
let mut btree = BTreeMap::with_capacity(map.size_hint().unwrap_or(10));
|
|
|
|
|
|
|
|
while let Some((key, value)) = map.next_entry()? {
|
|
|
|
btree.insert(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Value::map(btree))
|
2024-06-19 07:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
|
|
|
where
|
|
|
|
A: serde::de::EnumAccess<'de>,
|
|
|
|
{
|
|
|
|
let _ = data;
|
|
|
|
Err(serde::de::Error::invalid_type(
|
|
|
|
serde::de::Unexpected::Enum,
|
|
|
|
&self,
|
|
|
|
))
|
|
|
|
}
|
2024-06-04 18:47:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de> Deserialize<'de> for Value {
|
2024-06-19 07:32:51 +00:00
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
2024-06-04 18:47:15 +00:00
|
|
|
where
|
2024-06-19 07:32:51 +00:00
|
|
|
D: Deserializer<'de>,
|
2024-06-04 18:47:15 +00:00
|
|
|
{
|
2024-06-19 07:32:51 +00:00
|
|
|
deserializer.deserialize_any(ValueVisitor)
|
2024-06-04 18:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-22 17:55:43 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2024-02-25 18:49:26 +00:00
|
|
|
pub enum ValueInner {
|
|
|
|
Boolean(bool),
|
2024-06-19 14:48:22 +00:00
|
|
|
EnumInstance {
|
|
|
|
type_name: Identifier,
|
|
|
|
variant: Identifier,
|
|
|
|
content: Option<Vec<Value>>,
|
|
|
|
},
|
2024-02-25 18:49:26 +00:00
|
|
|
Float(f64),
|
2024-03-08 21:14:47 +00:00
|
|
|
Function(Function),
|
2024-02-25 18:49:26 +00:00
|
|
|
Integer(i64),
|
2024-06-19 08:56:56 +00:00
|
|
|
List(Vec<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,
|
2024-06-19 14:48:22 +00:00
|
|
|
ValueInner::EnumInstance { type_name, .. } => {
|
|
|
|
if let Some(r#type) = context.get_type(type_name)? {
|
|
|
|
r#type
|
|
|
|
} else {
|
2024-06-20 00:14:51 +00:00
|
|
|
return Err(ValidationError::EnumDefinitionNotFound {
|
|
|
|
identifier: type_name.clone(),
|
|
|
|
position: None,
|
|
|
|
});
|
2024-06-19 14:48:22 +00:00
|
|
|
}
|
|
|
|
}
|
2024-03-20 12:36:18 +00:00
|
|
|
ValueInner::Float(_) => Type::Float,
|
|
|
|
ValueInner::Integer(_) => Type::Integer,
|
|
|
|
ValueInner::List(values) => {
|
2024-06-19 08:56:56 +00:00
|
|
|
let item_type = values.first().unwrap().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-06-19 02:01:18 +00:00
|
|
|
ValueInner::Function(function) => {
|
2024-06-22 04:58:30 +00:00
|
|
|
let return_type = function.return_type.clone().map(|r#type| Box::new(r#type));
|
2024-06-19 02:01:18 +00:00
|
|
|
|
|
|
|
Type::Function {
|
|
|
|
type_parameters: function.type_parameters().clone(),
|
2024-06-24 02:39:33 +00:00
|
|
|
value_parameters: function.value_parameters().clone(),
|
2024-06-22 04:58:30 +00:00
|
|
|
return_type,
|
2024-06-19 02:01:18 +00:00
|
|
|
}
|
|
|
|
}
|
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-06-19 14:48:22 +00:00
|
|
|
(
|
|
|
|
EnumInstance {
|
|
|
|
type_name: left_name,
|
|
|
|
variant: left_variant,
|
|
|
|
content: left_content,
|
|
|
|
},
|
|
|
|
EnumInstance {
|
|
|
|
type_name: right_name,
|
|
|
|
variant: right_variant,
|
|
|
|
content: right_content,
|
|
|
|
},
|
|
|
|
) => {
|
|
|
|
let name_cmp = left_name.cmp(right_name);
|
|
|
|
|
|
|
|
if name_cmp.is_eq() {
|
|
|
|
let variant_cmp = left_variant.cmp(right_variant);
|
|
|
|
|
|
|
|
if variant_cmp.is_eq() {
|
|
|
|
left_content.cmp(right_content)
|
|
|
|
} else {
|
|
|
|
variant_cmp
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
name_cmp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(EnumInstance { .. }, _) => 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-22 17:55:43 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2024-04-21 21:00:08 +00:00
|
|
|
pub struct Function {
|
2024-06-17 14:10:06 +00:00
|
|
|
type_parameters: Option<Vec<Identifier>>,
|
2024-06-24 02:39:33 +00:00
|
|
|
value_parameters: Option<Vec<(Identifier, Type)>>,
|
2024-06-22 04:58:30 +00:00
|
|
|
return_type: Option<Type>,
|
2024-06-17 14:10:06 +00:00
|
|
|
body: Block,
|
2024-06-22 17:55:43 +00:00
|
|
|
context_template: Context,
|
2024-03-09 03:34:17 +00:00
|
|
|
}
|
|
|
|
|
2024-03-09 13:10:54 +00:00
|
|
|
impl Function {
|
2024-06-22 21:17:35 +00:00
|
|
|
pub fn new(
|
|
|
|
type_parameters: Option<Vec<Identifier>>,
|
2024-06-24 02:39:33 +00:00
|
|
|
value_parameters: Option<Vec<(Identifier, Type)>>,
|
2024-06-22 21:17:35 +00:00
|
|
|
return_type: Option<Type>,
|
|
|
|
body: Block,
|
|
|
|
context_template: Context,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
type_parameters,
|
|
|
|
value_parameters,
|
|
|
|
return_type,
|
|
|
|
body,
|
|
|
|
context_template,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-22 17:55:43 +00:00
|
|
|
pub fn context_template(&self) -> &Context {
|
|
|
|
&self.context_template
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2024-06-24 02:39:33 +00:00
|
|
|
pub fn value_parameters(&self) -> &Option<Vec<(Identifier, Type)>> {
|
2024-06-19 02:01:18 +00:00
|
|
|
&self.value_parameters
|
|
|
|
}
|
|
|
|
|
2024-06-19 06:32:17 +00:00
|
|
|
pub fn body(&self) -> &Block {
|
|
|
|
&self.body
|
|
|
|
}
|
|
|
|
|
2024-04-22 05:51:34 +00:00
|
|
|
pub fn call(
|
|
|
|
self,
|
2024-06-22 10:36:59 +00:00
|
|
|
context: &Context,
|
2024-06-22 03:37:25 +00:00
|
|
|
manage_memory: bool,
|
|
|
|
) -> Result<Option<Evaluation>, RuntimeError> {
|
2024-06-22 17:55:43 +00:00
|
|
|
self.body.evaluate(context, manage_memory)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn populate_context_template(&self) -> Result<(), PoisonError> {
|
|
|
|
if let Some(type_parameters) = &self.type_parameters {
|
|
|
|
for identifier in type_parameters {
|
|
|
|
self.context_template.set_type(
|
|
|
|
identifier.clone(),
|
|
|
|
Type::Generic {
|
|
|
|
identifier: identifier.clone(),
|
|
|
|
concrete_type: None,
|
|
|
|
},
|
|
|
|
)?;
|
|
|
|
}
|
2024-04-21 21:00:08 +00:00
|
|
|
}
|
2024-03-09 13:10:54 +00:00
|
|
|
|
2024-06-24 02:39:33 +00:00
|
|
|
if let Some(value_parameters) = &self.value_parameters {
|
|
|
|
for (identifier, r#type) in value_parameters {
|
|
|
|
self.context_template
|
|
|
|
.set_type(identifier.clone(), r#type.clone())?;
|
|
|
|
}
|
2024-06-22 17:55:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Eq for Function {}
|
|
|
|
|
|
|
|
impl PartialEq for Function {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
2024-06-22 23:44:33 +00:00
|
|
|
self.type_parameters == other.type_parameters
|
|
|
|
&& self.value_parameters == other.value_parameters
|
|
|
|
&& self.return_type == other.return_type
|
|
|
|
&& self.body == other.body
|
2024-06-22 17:55:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialOrd for Function {
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
2024-06-22 23:44:33 +00:00
|
|
|
Some(self.cmp(other))
|
2024-06-22 17:55:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Ord for Function {
|
|
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
2024-06-22 23:44:33 +00:00
|
|
|
let type_params_cmp = self.type_parameters.cmp(&other.type_parameters);
|
|
|
|
|
|
|
|
if type_params_cmp.is_eq() {
|
|
|
|
let value_params_cmp = self.value_parameters.cmp(&other.value_parameters);
|
|
|
|
|
|
|
|
if value_params_cmp.is_eq() {
|
|
|
|
let return_cmp = self.return_type.cmp(&other.return_type);
|
|
|
|
|
|
|
|
if return_cmp.is_eq() {
|
|
|
|
self.body.cmp(&other.body)
|
|
|
|
} else {
|
|
|
|
return_cmp
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
value_params_cmp
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
type_params_cmp
|
|
|
|
}
|
2024-03-09 13:10:54 +00:00
|
|
|
}
|
|
|
|
}
|