mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 05:43:53 +01:00
Added the concept of subtypes
...
... which `try` now uses to avoid some problems with inner types
This commit is contained in:
parent
ea95a16c30
commit
5e20f92849
@ -1,4 +1,4 @@
|
||||
use std::{any::Any, fmt::Display};
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
@ -30,7 +30,7 @@ impl MersData for Bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BoolT;
|
||||
impl MersType for BoolT {
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
@ -39,6 +39,9 @@ impl MersType for BoolT {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{any::Any, fmt::Display};
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
@ -30,7 +30,7 @@ impl MersData for Float {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FloatT;
|
||||
impl MersType for FloatT {
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
@ -39,6 +39,9 @@ impl MersType for FloatT {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ impl MersData for Function {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FunctionT(pub Arc<dyn Fn(&Type) -> Result<Type, CheckError> + Send + Sync>);
|
||||
impl MersType for FunctionT {
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
@ -100,6 +101,9 @@ impl MersType for FunctionT {
|
||||
fn is_included_in_single(&self, _target: &dyn MersType) -> bool {
|
||||
false
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{any::Any, fmt::Display};
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
@ -30,7 +30,7 @@ impl MersData for Int {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IntT;
|
||||
impl MersType for IntT {
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
@ -39,6 +39,9 @@ impl MersType for IntT {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -59,6 +59,20 @@ pub trait MersType: Any + Debug + Display + Send + Sync {
|
||||
self.is_included_in_single(target)
|
||||
}
|
||||
}
|
||||
/// Returns all types that can result from the use of this type.
|
||||
/// Usually, this is just `acc.add(Arc::new(self.clone()))`
|
||||
/// but if there exists one or more inner types, this becomes interesting:
|
||||
/// Using `(int/string)` will end up being either `(int)` or `(string)`,
|
||||
/// so this function should add `(int)` and `(string)`.
|
||||
/// Since `(int/string)` can't exist at runtime, we don't need to list `self`.
|
||||
/// note also: `subtypes` has to be called recursively, i.e. you would have to call `.substring` on `int` and `string`.
|
||||
fn subtypes(&self, acc: &mut Type);
|
||||
/// like `subtypes`, but returns the accumulator
|
||||
fn subtypes_type(&self) -> Type {
|
||||
let mut acc = Type::empty();
|
||||
self.subtypes(&mut acc);
|
||||
acc
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn mut_any(&mut self) -> &mut dyn Any;
|
||||
fn to_any(self) -> Box<dyn Any>;
|
||||
@ -293,6 +307,11 @@ impl MersType for Type {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.types.iter().all(|t| t.is_included_in_single(target))
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
for t in &self.types {
|
||||
t.subtypes(acc);
|
||||
}
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ impl MersData for Reference {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReferenceT(pub Type);
|
||||
impl MersType for ReferenceT {
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
@ -48,6 +48,11 @@ impl MersType for ReferenceT {
|
||||
// &int isn't included in &(int/float), otherwise we could assign a float to it
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
// we don't call subtypes because (int/string) must stay that so we can assign either
|
||||
// NOTE: this might not be right...?
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{any::Any, fmt::Display};
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
@ -30,7 +30,7 @@ impl MersData for String {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StringT;
|
||||
impl MersType for StringT {
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
@ -39,6 +39,9 @@ impl MersType for StringT {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
@ -53,10 +53,31 @@ impl MersType for TupleT {
|
||||
Some(o)
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
self.0.len() == other.0.len()
|
||||
&& self
|
||||
.0
|
||||
.iter()
|
||||
.zip(other.0.iter())
|
||||
.all(|(s, o)| s.is_same_type_as(o))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
if let Some(target) = target.as_any().downcast_ref::<Self>() {
|
||||
self.0.len() == target.0.len()
|
||||
&& self
|
||||
.0
|
||||
.iter()
|
||||
.zip(target.0.iter())
|
||||
.all(|(s, t)| s.is_included_in(t))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.0.len()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
@ -95,3 +116,23 @@ impl Display for TupleT {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl TupleT {
|
||||
pub fn gen_subtypes_recursively(&self, acc: &mut Type, types: &mut Vec<Arc<dyn MersType>>) {
|
||||
if types.len() >= self.0.len() {
|
||||
let nt = Self(
|
||||
types
|
||||
.iter()
|
||||
.map(|v| Type::newm(vec![Arc::clone(v)]))
|
||||
.collect(),
|
||||
);
|
||||
acc.add(Arc::new(nt));
|
||||
} else {
|
||||
for t in self.0[types.len()].subtypes_type().types {
|
||||
types.push(t);
|
||||
self.gen_subtypes_recursively(acc, types);
|
||||
types.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ impl Config {
|
||||
}
|
||||
let arg_type = &t.0[0];
|
||||
let functions = &t.0[1];
|
||||
for arg_type in arg_type.types.iter() {
|
||||
for arg_type in arg_type.subtypes_type().types.iter() {
|
||||
let arg_type = Type::newm(vec![arg_type.clone()]);
|
||||
// possibilities for the tuple (f1, f2, f3, ..., fn)
|
||||
for ft in functions.types.iter() {
|
||||
|
@ -83,7 +83,7 @@ impl Config {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RunCommandError(String);
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RunCommandErrorT;
|
||||
impl MersData for RunCommandError {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
@ -116,6 +116,9 @@ impl MersType for RunCommandErrorT {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
@ -247,6 +247,10 @@ impl MersType for IterT {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
// NOTE: This might not be good enough
|
||||
acc.add(Arc::new(self.clone()));
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
@ -201,6 +201,11 @@ impl MersType for ListT {
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
for t in self.0.subtypes_type().types {
|
||||
acc.add(Arc::new(Self(Type::newm(vec![t]))));
|
||||
}
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
@ -127,6 +127,11 @@ impl MersType for ThreadT {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn subtypes(&self, acc: &mut Type) {
|
||||
for t in self.0.subtypes_type().types {
|
||||
acc.add(Arc::new(Self(Type::newm(vec![t]))));
|
||||
}
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user