mirror of
https://github.com/Dummi26/mers.git
synced 2025-12-24 23:46:32 +01:00
make objects work better, especially destructuring
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use crate::info::DisplayInfo;
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bool(pub bool);
|
||||
|
||||
impl MersData for Bool {
|
||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
@@ -43,6 +48,13 @@ pub fn bool_type() -> Type {
|
||||
Type::newm(vec![Arc::new(TrueT), Arc::new(FalseT)])
|
||||
}
|
||||
impl MersType for TrueT {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
}
|
||||
@@ -63,6 +75,13 @@ impl MersType for TrueT {
|
||||
}
|
||||
}
|
||||
impl MersType for FalseT {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use crate::info::DisplayInfo;
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Byte(pub u8);
|
||||
|
||||
impl MersData for Byte {
|
||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
@@ -33,6 +38,13 @@ impl MersData for Byte {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ByteT;
|
||||
impl MersType for ByteT {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
}
|
||||
|
||||
@@ -28,7 +28,10 @@ pub fn assign(from: &Data, target: &Data) {
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::object::Object>(),
|
||||
) {
|
||||
for ((_, from), (_, target)) in from.0.iter().zip(target.0.iter()) {
|
||||
for (field, target) in target.iter() {
|
||||
let from = from
|
||||
.get(*field)
|
||||
.expect("type-checks should guarantee that from has every field of target");
|
||||
assign(from, target);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use crate::info::DisplayInfo;
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Float(pub f64);
|
||||
|
||||
impl MersData for Float {
|
||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
@@ -33,6 +38,13 @@ impl MersData for Float {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FloatT;
|
||||
impl MersType for FloatT {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
errors::CheckError,
|
||||
info::Local,
|
||||
info::DisplayInfo,
|
||||
program::run::{CheckInfo, Info},
|
||||
};
|
||||
|
||||
@@ -87,13 +87,13 @@ impl Function {
|
||||
(self.run)(arg, &mut self.info.duplicate())
|
||||
}
|
||||
pub fn get_as_type(&self) -> FunctionT {
|
||||
let info = self.info_check.lock().unwrap().clone();
|
||||
match &self.out {
|
||||
Ok(out) => {
|
||||
let out = Arc::clone(out);
|
||||
let info = self.info_check.lock().unwrap().clone();
|
||||
FunctionT(Ok(Arc::new(move |a| out(a, &mut info.clone()))))
|
||||
FunctionT(Ok(Arc::new(move |a, i| out(a, &mut i.clone()))), info)
|
||||
}
|
||||
Err(types) => FunctionT(Err(Arc::clone(types))),
|
||||
Err(types) => FunctionT(Err(Arc::clone(types)), info),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,9 @@ impl Function {
|
||||
}
|
||||
|
||||
impl MersData for Function {
|
||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
Some(self.get_as_type())
|
||||
}
|
||||
@@ -151,18 +154,50 @@ impl MersData for Function {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FunctionT(
|
||||
pub Result<Arc<dyn Fn(&Type) -> Result<Type, CheckError> + Send + Sync>, Arc<Vec<(Type, Type)>>>,
|
||||
pub Result<
|
||||
Arc<dyn Fn(&Type, &CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
|
||||
Arc<Vec<(Type, Type)>>,
|
||||
>,
|
||||
pub CheckInfo,
|
||||
);
|
||||
impl FunctionT {
|
||||
/// get output type
|
||||
pub fn o(&self, i: &Type) -> Result<Type, CheckError> {
|
||||
match &self.0 {
|
||||
Ok(f) => f(i),
|
||||
Err(v) => v.iter().find(|(a, _)| i.is_included_in(a)).map(|(_, o)| o.clone()).ok_or_else(|| format!("This function, which was defined with an explicit type, cannot be called with an argument of type {i}.").into()),
|
||||
Ok(f) => f(i, &self.1),
|
||||
Err(v) => v
|
||||
.iter()
|
||||
.find(|(a, _)| i.is_included_in(a))
|
||||
.map(|(_, o)| o.clone())
|
||||
.ok_or_else(|| format!("This function, which was defined with an explicit type, cannot be called with an argument of type {}.", i.with_info(&self.1)).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl MersType for FunctionT {
|
||||
fn display(
|
||||
&self,
|
||||
info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
match &self.0 {
|
||||
Err(e) => {
|
||||
write!(f, "(")?;
|
||||
for (index, (i, o)) in e.iter().enumerate() {
|
||||
if index > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{} -> {}", i.with_display(info), o.with_display(info))?;
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
Ok(_) => match self.o(&Type::empty_tuple()) {
|
||||
Ok(t) => write!(f, "(() -> {}, ...)", t.with_display(info)),
|
||||
Err(_) => {
|
||||
write!(f, "(... -> ...)",)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
Some(self.clone())
|
||||
}
|
||||
@@ -249,25 +284,3 @@ impl Display for Function {
|
||||
write!(f, "<function>")
|
||||
}
|
||||
}
|
||||
impl Display for FunctionT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match &self.0 {
|
||||
Err(e) => {
|
||||
write!(f, "(")?;
|
||||
for (index, (i, o)) in e.iter().enumerate() {
|
||||
if index > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{i} -> {o}")?;
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
Ok(_) => match self.o(&Type::empty_tuple()) {
|
||||
Ok(t) => write!(f, "(() -> {t}, ...)"),
|
||||
Err(_) => {
|
||||
write!(f, "(... -> ...)",)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use crate::info::DisplayInfo;
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Int(pub isize);
|
||||
|
||||
impl MersData for Int {
|
||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
@@ -33,6 +38,13 @@ impl MersData for Int {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IntT;
|
||||
impl MersType for IntT {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::{
|
||||
sync::{atomic::AtomicUsize, Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
use crate::errors::CheckError;
|
||||
use crate::{errors::CheckError, info::DisplayInfo};
|
||||
|
||||
pub mod bool;
|
||||
pub mod byte;
|
||||
@@ -18,7 +18,12 @@ pub mod tuple;
|
||||
|
||||
pub mod defs;
|
||||
|
||||
pub trait MersData: Any + Debug + Display + Send + Sync {
|
||||
pub trait MersData: Any + Debug + Send + Sync {
|
||||
fn display(
|
||||
&self,
|
||||
info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result;
|
||||
/// must be the same as the `executable` impl on the MersType
|
||||
#[allow(unused_variables)]
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
@@ -46,7 +51,66 @@ pub trait MersData: Any + Debug + Display + Send + Sync {
|
||||
fn to_any(self) -> Box<dyn Any>;
|
||||
}
|
||||
|
||||
pub trait MersType: Any + Debug + Display + Send + Sync {
|
||||
pub trait MersDataWInfo {
|
||||
fn with_display<'a>(&'a self, info: &DisplayInfo<'a>) -> MersDataWithInfo<'a, Self> {
|
||||
MersDataWithInfo(self, *info)
|
||||
}
|
||||
fn with_info<'a>(
|
||||
&'a self,
|
||||
info: &'a crate::info::Info<impl crate::info::Local>,
|
||||
) -> MersDataWithInfo<'a, Self> {
|
||||
MersDataWithInfo(self, info.display_info())
|
||||
}
|
||||
}
|
||||
pub trait MersTypeWInfo {
|
||||
fn with_display<'a>(&'a self, info: &DisplayInfo<'a>) -> MersTypeWithInfo<'a, Self> {
|
||||
MersTypeWithInfo(self, *info)
|
||||
}
|
||||
fn with_info<'a>(
|
||||
&'a self,
|
||||
info: &'a crate::info::Info<impl crate::info::Local>,
|
||||
) -> MersTypeWithInfo<'a, Self> {
|
||||
MersTypeWithInfo(self, info.display_info())
|
||||
}
|
||||
}
|
||||
impl Type {
|
||||
pub fn with_display<'a>(&'a self, info: &DisplayInfo<'a>) -> TypeWithInfo<'a> {
|
||||
TypeWithInfo(self, *info)
|
||||
}
|
||||
pub fn with_info<'a>(
|
||||
&'a self,
|
||||
info: &'a crate::info::Info<impl crate::info::Local>,
|
||||
) -> TypeWithInfo<'a> {
|
||||
TypeWithInfo(self, info.display_info())
|
||||
}
|
||||
}
|
||||
impl<T: MersData + ?Sized> MersDataWInfo for T {}
|
||||
impl<T: MersType + ?Sized> MersTypeWInfo for T {}
|
||||
pub struct MersDataWithInfo<'a, T: ?Sized>(&'a T, crate::info::DisplayInfo<'a>);
|
||||
pub struct MersTypeWithInfo<'a, T: ?Sized>(&'a T, crate::info::DisplayInfo<'a>);
|
||||
pub struct TypeWithInfo<'a>(&'a Type, crate::info::DisplayInfo<'a>);
|
||||
impl<'a, T: ?Sized + MersData> Display for MersDataWithInfo<'a, T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.display(&self.1, f)
|
||||
}
|
||||
}
|
||||
impl<'a, T: ?Sized + MersType> Display for MersTypeWithInfo<'a, T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.display(&self.1, f)
|
||||
}
|
||||
}
|
||||
impl<'a> Display for TypeWithInfo<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.display(&self.1, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MersType: Any + Debug + Send + Sync {
|
||||
fn display(
|
||||
&self,
|
||||
info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result;
|
||||
#[allow(unused_variables)]
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
None
|
||||
@@ -93,13 +157,20 @@ pub trait MersType: Any + Debug + Display + Send + Sync {
|
||||
}
|
||||
fn simplified_as_string(&self, info: &crate::program::run::CheckInfo) -> String {
|
||||
self.simplify_for_display(info)
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or_else(|| self.to_string())
|
||||
.map(|s| s.with_info(info).to_string())
|
||||
.unwrap_or_else(|| self.with_info(info).to_string())
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct TypeWithOnlyName(pub(crate) String);
|
||||
impl MersType for TypeWithOnlyName {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, _other: &dyn MersType) -> bool {
|
||||
false
|
||||
}
|
||||
@@ -447,20 +518,20 @@ impl Type {
|
||||
out
|
||||
}
|
||||
pub fn simplified_as_string(&self, info: &crate::program::run::CheckInfo) -> String {
|
||||
self.simplify_for_display(info).to_string()
|
||||
self.simplify_for_display(info).with_info(info).to_string()
|
||||
}
|
||||
}
|
||||
impl Display for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
impl Type {
|
||||
fn display(&self, info: &DisplayInfo, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.types.is_empty() {
|
||||
write!(f, "<unreachable>")
|
||||
} else {
|
||||
// if self.types.len() > 1 {
|
||||
// write!(f, "{{")?;
|
||||
// }
|
||||
write!(f, "{}", self.types[0])?;
|
||||
write!(f, "{}", self.types[0].with_display(info))?;
|
||||
for t in self.types.iter().skip(1) {
|
||||
write!(f, "/{t}")?;
|
||||
write!(f, "/{}", t.with_display(info))?;
|
||||
}
|
||||
// if self.types.len() > 1 {
|
||||
// write!(f, "}}")?;
|
||||
|
||||
@@ -1,13 +1,61 @@
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
use crate::info::DisplayInfo;
|
||||
|
||||
use super::{Data, MersData, MersDataWInfo, MersType, Type};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Object(pub Vec<(String, Data)>);
|
||||
pub struct Object(Vec<(usize, Data)>);
|
||||
impl Object {
|
||||
pub fn new(v: Vec<(usize, Data)>) -> Self {
|
||||
Self(v)
|
||||
}
|
||||
pub fn get(&self, f: usize) -> Option<&Data> {
|
||||
self.iter().find(|v| v.0 == f).map(|v| &v.1)
|
||||
}
|
||||
pub fn iter(&self) -> std::slice::Iter<(usize, Data)> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ObjectT(pub Vec<(String, Type)>);
|
||||
pub struct ObjectT(Vec<(usize, Type)>);
|
||||
impl ObjectT {
|
||||
pub fn new(v: Vec<(usize, Type)>) -> Self {
|
||||
Self(v)
|
||||
}
|
||||
pub fn get(&self, f: usize) -> Option<&Type> {
|
||||
self.iter().find(|v| v.0 == f).map(|v| &v.1)
|
||||
}
|
||||
pub fn iter(&self) -> std::slice::Iter<(usize, Type)> {
|
||||
self.0.iter()
|
||||
}
|
||||
fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl MersData for Object {
|
||||
fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let mut comma_sep = false;
|
||||
write!(f, "{{")?;
|
||||
for (field, val) in self.iter() {
|
||||
if comma_sep {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
"{}: {}",
|
||||
info.get_object_field_name(*field),
|
||||
val.get().with_display(info)
|
||||
)?;
|
||||
comma_sep = true;
|
||||
}
|
||||
write!(f, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
self == other
|
||||
@@ -20,8 +68,7 @@ impl MersData for Object {
|
||||
}
|
||||
fn as_type(&self) -> Type {
|
||||
Type::new(ObjectT(
|
||||
self.0
|
||||
.iter()
|
||||
self.iter()
|
||||
.map(|(n, v)| (n.clone(), v.get().as_type()))
|
||||
.collect(),
|
||||
))
|
||||
@@ -38,14 +85,35 @@ impl MersData for Object {
|
||||
}
|
||||
|
||||
impl MersType for ObjectT {
|
||||
fn display(
|
||||
&self,
|
||||
info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
let mut comma_sep = false;
|
||||
write!(f, "{{")?;
|
||||
for (field, t) in self.iter() {
|
||||
if comma_sep {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
"{}: {}",
|
||||
info.get_object_field_name(*field),
|
||||
t.with_display(info)
|
||||
)?;
|
||||
comma_sep = true;
|
||||
}
|
||||
write!(f, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
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))
|
||||
self.len() == other.len()
|
||||
&& other.iter().all(|(field, target_type)| {
|
||||
self.get(*field)
|
||||
.is_some_and(|self_type| self_type.is_same_type_as(target_type))
|
||||
})
|
||||
})
|
||||
}
|
||||
fn is_included_in(&self, target: &dyn MersType) -> bool {
|
||||
@@ -53,16 +121,15 @@ impl MersType for ObjectT {
|
||||
.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))
|
||||
self.len() >= target.len()
|
||||
&& target.iter().all(|(field, target_type)| {
|
||||
self.get(*field)
|
||||
.is_some_and(|self_type| self_type.is_included_in(target_type))
|
||||
})
|
||||
})
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.0.len()));
|
||||
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.len()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
@@ -83,44 +150,13 @@ impl MersType for ObjectT {
|
||||
}
|
||||
}
|
||||
|
||||
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>)>,
|
||||
types: &mut Vec<(usize, Arc<dyn MersType>)>,
|
||||
) {
|
||||
if types.len() >= self.0.len() {
|
||||
if types.len() >= self.len() {
|
||||
let nt = Self(
|
||||
types
|
||||
.iter()
|
||||
@@ -137,3 +173,18 @@ impl ObjectT {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ObjectFieldsMap {
|
||||
fn get_or_add_field(&self, field: &str) -> usize;
|
||||
}
|
||||
impl ObjectFieldsMap for Arc<Mutex<HashMap<String, usize>>> {
|
||||
fn get_or_add_field(&self, field: &str) -> usize {
|
||||
let mut s = self.lock().unwrap();
|
||||
if let Some(f) = s.get(field) {
|
||||
return *f;
|
||||
}
|
||||
let o = s.len();
|
||||
s.insert(field.to_owned(), o);
|
||||
o
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use std::{
|
||||
any::Any,
|
||||
fmt::Display,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use crate::errors::CheckError;
|
||||
use crate::{errors::CheckError, info::DisplayInfo};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
@@ -12,6 +11,9 @@ use super::{Data, MersData, MersType, Type};
|
||||
pub struct Reference(pub Arc<RwLock<Data>>);
|
||||
|
||||
impl MersData for Reference {
|
||||
fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
self.0.read().unwrap().get().display(info, f)
|
||||
}
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
let inner = self.0.read().unwrap();
|
||||
let inner = inner.get();
|
||||
@@ -88,6 +90,17 @@ impl MersData for Reference {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReferenceT(pub Type);
|
||||
impl MersType for ReferenceT {
|
||||
fn display(
|
||||
&self,
|
||||
info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
if self.0.types.len() > 1 {
|
||||
write!(f, "&{{{}}}", self.0.with_display(info))
|
||||
} else {
|
||||
write!(f, "&{}", self.0.with_display(info))
|
||||
}
|
||||
}
|
||||
fn executable(&self) -> Option<crate::data::function::FunctionT> {
|
||||
let mut funcs: Vec<crate::data::function::FunctionT> = vec![];
|
||||
for func in self.0.types.iter() {
|
||||
@@ -96,13 +109,16 @@ impl MersType for ReferenceT {
|
||||
.downcast_ref::<crate::data::function::FunctionT>()?,
|
||||
));
|
||||
}
|
||||
Some(super::function::FunctionT(Ok(Arc::new(move |a| {
|
||||
let mut out = Type::empty();
|
||||
for func in funcs.iter() {
|
||||
out.add_all(&func.o(a)?);
|
||||
}
|
||||
Ok(out)
|
||||
}))))
|
||||
Some(super::function::FunctionT(
|
||||
Ok(Arc::new(move |a, _| {
|
||||
let mut out = Type::empty();
|
||||
for func in funcs.iter() {
|
||||
out.add_all(&func.o(a)?);
|
||||
}
|
||||
Ok(out)
|
||||
})),
|
||||
crate::info::Info::neverused(),
|
||||
))
|
||||
}
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
let mut out = Type::empty();
|
||||
@@ -156,18 +172,3 @@ impl MersType for ReferenceT {
|
||||
Some(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Reference {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "&{}", self.0.read().unwrap().get())
|
||||
}
|
||||
}
|
||||
impl Display for ReferenceT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.0.types.len() > 1 {
|
||||
write!(f, "&{{{}}}", self.0)
|
||||
} else {
|
||||
write!(f, "&{}", self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use crate::info::DisplayInfo;
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct String(pub std::string::String);
|
||||
|
||||
impl MersData for String {
|
||||
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
@@ -33,6 +38,13 @@ impl MersData for String {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StringT;
|
||||
impl MersType for StringT {
|
||||
fn display(
|
||||
&self,
|
||||
_info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
use std::{any::Any, sync::Arc};
|
||||
|
||||
use crate::errors::CheckError;
|
||||
use crate::{errors::CheckError, info::DisplayInfo};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
@@ -17,6 +17,17 @@ impl Tuple {
|
||||
}
|
||||
|
||||
impl MersData for Tuple {
|
||||
fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, c) in self.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
c.get().display(info, f)?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
Ok(())
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
@@ -47,6 +58,21 @@ impl MersData for Tuple {
|
||||
#[derive(Debug)]
|
||||
pub struct TupleT(pub Vec<Type>);
|
||||
impl MersType for TupleT {
|
||||
fn display(
|
||||
&self,
|
||||
info: &crate::info::DisplayInfo<'_>,
|
||||
f: &mut std::fmt::Formatter,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, c) in self.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", c.with_display(info))?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
Ok(())
|
||||
}
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
let mut o = Type::empty();
|
||||
for t in self.0.iter() {
|
||||
@@ -100,33 +126,6 @@ impl MersType for TupleT {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Tuple {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, c) in self.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", c.get())?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Display for TupleT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, c) in self.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", c)?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl TupleT {
|
||||
pub fn gen_subtypes_recursively(&self, acc: &mut Type, types: &mut Vec<Arc<dyn MersType>>) {
|
||||
if types.len() >= self.0.len() {
|
||||
|
||||
Reference in New Issue
Block a user