mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +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};
|
use super::{MersData, MersType, Type};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl MersData for Bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BoolT;
|
pub struct BoolT;
|
||||||
impl MersType for BoolT {
|
impl MersType for BoolT {
|
||||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
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 {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.is_same_type_as(target)
|
self.is_same_type_as(target)
|
||||||
}
|
}
|
||||||
|
fn subtypes(&self, acc: &mut Type) {
|
||||||
|
acc.add(Arc::new(self.clone()));
|
||||||
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, fmt::Display};
|
use std::{any::Any, fmt::Display, sync::Arc};
|
||||||
|
|
||||||
use super::{MersData, MersType, Type};
|
use super::{MersData, MersType, Type};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl MersData for Float {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FloatT;
|
pub struct FloatT;
|
||||||
impl MersType for FloatT {
|
impl MersType for FloatT {
|
||||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
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 {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.is_same_type_as(target)
|
self.is_same_type_as(target)
|
||||||
}
|
}
|
||||||
|
fn subtypes(&self, acc: &mut Type) {
|
||||||
|
acc.add(Arc::new(self.clone()));
|
||||||
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ impl MersData for Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct FunctionT(pub Arc<dyn Fn(&Type) -> Result<Type, CheckError> + Send + Sync>);
|
pub struct FunctionT(pub Arc<dyn Fn(&Type) -> Result<Type, CheckError> + Send + Sync>);
|
||||||
impl MersType for FunctionT {
|
impl MersType for FunctionT {
|
||||||
fn iterable(&self) -> Option<Type> {
|
fn iterable(&self) -> Option<Type> {
|
||||||
@ -100,6 +101,9 @@ impl MersType for FunctionT {
|
|||||||
fn is_included_in_single(&self, _target: &dyn MersType) -> bool {
|
fn is_included_in_single(&self, _target: &dyn MersType) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
fn subtypes(&self, acc: &mut Type) {
|
||||||
|
acc.add(Arc::new(self.clone()));
|
||||||
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, fmt::Display};
|
use std::{any::Any, fmt::Display, sync::Arc};
|
||||||
|
|
||||||
use super::{MersData, MersType, Type};
|
use super::{MersData, MersType, Type};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl MersData for Int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct IntT;
|
pub struct IntT;
|
||||||
impl MersType for IntT {
|
impl MersType for IntT {
|
||||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
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 {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.is_same_type_as(target)
|
self.is_same_type_as(target)
|
||||||
}
|
}
|
||||||
|
fn subtypes(&self, acc: &mut Type) {
|
||||||
|
acc.add(Arc::new(self.clone()));
|
||||||
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,20 @@ pub trait MersType: Any + Debug + Display + Send + Sync {
|
|||||||
self.is_included_in_single(target)
|
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 as_any(&self) -> &dyn Any;
|
||||||
fn mut_any(&mut self) -> &mut dyn Any;
|
fn mut_any(&mut self) -> &mut dyn Any;
|
||||||
fn to_any(self) -> Box<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 {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.types.iter().all(|t| t.is_included_in_single(target))
|
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 {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ impl MersData for Reference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ReferenceT(pub Type);
|
pub struct ReferenceT(pub Type);
|
||||||
impl MersType for ReferenceT {
|
impl MersType for ReferenceT {
|
||||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
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
|
// &int isn't included in &(int/float), otherwise we could assign a float to it
|
||||||
self.is_same_type_as(target)
|
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 {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{any::Any, fmt::Display};
|
use std::{any::Any, fmt::Display, sync::Arc};
|
||||||
|
|
||||||
use super::{MersData, MersType, Type};
|
use super::{MersData, MersType, Type};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl MersData for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct StringT;
|
pub struct StringT;
|
||||||
impl MersType for StringT {
|
impl MersType for StringT {
|
||||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
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 {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.is_same_type_as(target)
|
self.is_same_type_as(target)
|
||||||
}
|
}
|
||||||
|
fn subtypes(&self, acc: &mut Type) {
|
||||||
|
acc.add(Arc::new(self.clone()));
|
||||||
|
}
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,31 @@ impl MersType for TupleT {
|
|||||||
Some(o)
|
Some(o)
|
||||||
}
|
}
|
||||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
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 {
|
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 {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
@ -95,3 +116,23 @@ impl Display for TupleT {
|
|||||||
Ok(())
|
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 arg_type = &t.0[0];
|
||||||
let functions = &t.0[1];
|
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()]);
|
let arg_type = Type::newm(vec![arg_type.clone()]);
|
||||||
// possibilities for the tuple (f1, f2, f3, ..., fn)
|
// possibilities for the tuple (f1, f2, f3, ..., fn)
|
||||||
for ft in functions.types.iter() {
|
for ft in functions.types.iter() {
|
||||||
|
@ -83,7 +83,7 @@ impl Config {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RunCommandError(String);
|
pub struct RunCommandError(String);
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RunCommandErrorT;
|
pub struct RunCommandErrorT;
|
||||||
impl MersData for RunCommandError {
|
impl MersData for RunCommandError {
|
||||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
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 {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.is_same_type_as(target)
|
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 {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,10 @@ impl MersType for IterT {
|
|||||||
false
|
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 {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -201,6 +201,11 @@ impl MersType for ListT {
|
|||||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||||
self.is_same_type_as(target)
|
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 {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,11 @@ impl MersType for ThreadT {
|
|||||||
false
|
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 {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user