mirror of
https://github.com/Dummi26/mers.git
synced 2026-03-04 08:36:33 +01:00
add objects and object types
This commit is contained in:
@@ -19,6 +19,24 @@ pub fn assign(from: &Data, target: &Data) {
|
||||
for (from, target) in from.0.iter().zip(target.0.iter()) {
|
||||
assign(from, target);
|
||||
}
|
||||
} else if let (Some(from), Some(target)) = (
|
||||
from.get()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::object::Object>(),
|
||||
target
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::object::Object>(),
|
||||
) {
|
||||
for (field, target) in target.0.iter() {
|
||||
for (name, from) in from.0.iter() {
|
||||
// TODO: do string comparison at compile-time instead!
|
||||
if field == name {
|
||||
assign(from, target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!("invalid assignment")
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod bool;
|
||||
pub mod float;
|
||||
pub mod function;
|
||||
pub mod int;
|
||||
pub mod object;
|
||||
pub mod reference;
|
||||
pub mod string;
|
||||
pub mod tuple;
|
||||
|
||||
131
mers_lib/src/data/object.rs
Normal file
131
mers_lib/src/data/object.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Object(pub Vec<(String, Data)>);
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ObjectT(pub Vec<(String, Type)>);
|
||||
|
||||
impl MersData for Object {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
self == other
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> Type {
|
||||
Type::new(ObjectT(
|
||||
self.0
|
||||
.iter()
|
||||
.map(|(n, v)| (n.clone(), v.get().as_type()))
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn mut_any(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn to_any(self) -> Box<dyn std::any::Any> {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl MersType for ObjectT {
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some_and(|other| {
|
||||
self.0.len() == other.0.len()
|
||||
&& self
|
||||
.0
|
||||
.iter()
|
||||
.zip(other.0.iter())
|
||||
.all(|((s1, t1), (s2, t2))| s1 == s2 && t1.is_same_type_as(t2))
|
||||
})
|
||||
}
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
target
|
||||
.as_any()
|
||||
.downcast_ref::<Self>()
|
||||
.is_some_and(|target| {
|
||||
self.0.len() >= target.0.len()
|
||||
&& self
|
||||
.0
|
||||
.iter()
|
||||
.zip(target.0.iter())
|
||||
.all(|((s1, t1), (s2, t2))| s1 == s2 && t1.is_included_in(t2))
|
||||
})
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.0.len()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn mut_any(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn to_any(self) -> Box<dyn std::any::Any> {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Object {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut comma_sep = false;
|
||||
write!(f, "{{")?;
|
||||
for (name, val) in self.0.iter() {
|
||||
if comma_sep {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{name}: {}", val.get())?;
|
||||
comma_sep = true;
|
||||
}
|
||||
write!(f, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Display for ObjectT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut comma_sep = false;
|
||||
write!(f, "{{")?;
|
||||
for (name, t) in self.0.iter() {
|
||||
if comma_sep {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{name}: {t}")?;
|
||||
comma_sep = true;
|
||||
}
|
||||
write!(f, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectT {
|
||||
pub fn gen_subtypes_recursively(
|
||||
&self,
|
||||
acc: &mut Type,
|
||||
types: &mut Vec<(String, Arc<dyn MersType>)>,
|
||||
) {
|
||||
if types.len() >= self.0.len() {
|
||||
let nt = Self(
|
||||
types
|
||||
.iter()
|
||||
.map(|(s, v)| (s.clone(), Type::newm(vec![Arc::clone(v)])))
|
||||
.collect(),
|
||||
);
|
||||
acc.add(Arc::new(nt));
|
||||
} else {
|
||||
for t in self.0[types.len()].1.subtypes_type().types {
|
||||
types.push((self.0[types.len()].0.clone(), t));
|
||||
self.gen_subtypes_recursively(acc, types);
|
||||
types.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user