mirror of
https://github.com/Dummi26/mers.git
synced 2026-03-04 08:36:33 +01:00
mers rewrite is starting to be usable
This commit is contained in:
@@ -1,14 +1,24 @@
|
||||
use std::{any::Any, fmt::Display};
|
||||
|
||||
use super::{MersData, MersType};
|
||||
use super::{MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Bool(pub bool);
|
||||
|
||||
impl MersData for Bool {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> super::Type {
|
||||
Type::new(BoolT)
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -45,3 +55,8 @@ impl Display for Bool {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
impl Display for BoolT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Bool")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use super::Data;
|
||||
use crate::program::run::CheckError;
|
||||
|
||||
use super::{Data, MersType, Type};
|
||||
|
||||
pub fn assign(from: Data, target: &Data) {
|
||||
let mut target = target.get_mut();
|
||||
let target = target.get();
|
||||
if let Some(r) = target
|
||||
.mut_any()
|
||||
.downcast_mut::<crate::data::reference::Reference>()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::reference::Reference>()
|
||||
{
|
||||
*r.0.get_mut() = from.get().clone();
|
||||
*r.0.lock().unwrap().get_mut() = from.get().clone();
|
||||
} else {
|
||||
todo!("assignment to non-reference")
|
||||
}
|
||||
|
||||
@@ -6,9 +6,19 @@ use super::{MersData, MersType, Type};
|
||||
pub struct Float(pub f64);
|
||||
|
||||
impl MersData for Float {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> super::Type {
|
||||
Type::new(FloatT)
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -45,3 +55,8 @@ impl Display for Float {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
impl Display for FloatT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Float")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,57 @@
|
||||
use std::{
|
||||
any::Any,
|
||||
fmt::{Debug, Display},
|
||||
sync::Arc,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::program::{self, run::Info};
|
||||
use crate::program::{
|
||||
self,
|
||||
run::{CheckError, CheckInfo, Info},
|
||||
};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Function {
|
||||
pub info: Info,
|
||||
pub out: Arc<dyn Fn(&Type) -> Option<Type>>,
|
||||
pub run: Arc<dyn Fn(Data, &mut crate::program::run::Info) -> Data>,
|
||||
pub info: Arc<Info>,
|
||||
pub info_check: Arc<Mutex<CheckInfo>>,
|
||||
pub out: Arc<dyn Fn(&Type, &mut CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
|
||||
pub run: Arc<dyn Fn(Data, &mut crate::program::run::Info) -> Data + Send + Sync>,
|
||||
}
|
||||
impl Function {
|
||||
pub fn with_info(&self, info: program::run::Info) -> Self {
|
||||
pub fn with_info_run(&self, info: Arc<Info>) -> Self {
|
||||
Self {
|
||||
info,
|
||||
info_check: Arc::clone(&self.info_check),
|
||||
out: Arc::clone(&self.out),
|
||||
run: Arc::clone(&self.run),
|
||||
}
|
||||
}
|
||||
pub fn with_info_check(&self, check: CheckInfo) {
|
||||
*self.info_check.lock().unwrap() = check;
|
||||
}
|
||||
pub fn check(&self, arg: &Type) -> Result<Type, CheckError> {
|
||||
(self.out)(arg, &mut self.info_check.lock().unwrap().clone())
|
||||
}
|
||||
pub fn run(&self, arg: Data) -> Data {
|
||||
(self.run)(arg, &mut self.info.clone())
|
||||
(self.run)(arg, &mut self.info.as_ref().clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl MersData for Function {
|
||||
fn is_eq(&self, _other: &dyn MersData) -> bool {
|
||||
false
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> Type {
|
||||
let out = Arc::clone(&self.out);
|
||||
let info = Arc::clone(&self.info_check);
|
||||
Type::new(FunctionT(Arc::new(move |a| {
|
||||
out(a, &mut info.lock().unwrap().clone())
|
||||
})))
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -42,7 +63,7 @@ impl MersData for Function {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FunctionT(Arc<dyn Fn(&Type) -> Option<Type>>);
|
||||
pub struct FunctionT(pub Arc<dyn Fn(&Type) -> Result<Type, CheckError> + Send + Sync>);
|
||||
impl MersType for FunctionT {
|
||||
fn is_same_type_as(&self, _other: &dyn MersType) -> bool {
|
||||
false
|
||||
@@ -77,3 +98,8 @@ impl Display for Function {
|
||||
write!(f, "<function>")
|
||||
}
|
||||
}
|
||||
impl Display for FunctionT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Function")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,19 @@ use super::{MersData, MersType, Type};
|
||||
pub struct Int(pub isize);
|
||||
|
||||
impl MersData for Int {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> super::Type {
|
||||
Type::new(IntT)
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -45,3 +55,8 @@ impl Display for Int {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
impl Display for IntT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Int")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{
|
||||
any::Any,
|
||||
fmt::{Debug, Display},
|
||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
sync::{atomic::AtomicUsize, Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
pub mod bool;
|
||||
@@ -14,10 +14,7 @@ pub mod tuple;
|
||||
|
||||
pub mod defs;
|
||||
|
||||
pub trait MersData: Any + Debug + Display {
|
||||
fn matches(&self) -> Option<Data> {
|
||||
None
|
||||
}
|
||||
pub trait MersData: Any + Debug + Display + Send + Sync {
|
||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
|
||||
None
|
||||
}
|
||||
@@ -26,18 +23,17 @@ pub trait MersData: Any + Debug + Display {
|
||||
fn get(&self, i: usize) -> Option<Data> {
|
||||
self.iterable()?.nth(i)
|
||||
}
|
||||
/// If self and other are different types (`other.as_any().downcast_ref::<Self>().is_none()`),
|
||||
/// this *must* return false.
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool;
|
||||
fn clone(&self) -> Box<dyn MersData>;
|
||||
fn as_type(&self) -> Type;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn mut_any(&mut self) -> &mut dyn Any;
|
||||
fn to_any(self) -> Box<dyn Any>;
|
||||
}
|
||||
|
||||
pub trait MersType: Any + Debug {
|
||||
/// If Some((_, false)) is returned, data of this type could match. If it matches, it matches with the type.
|
||||
/// If Some((_, true)) is returned, data of this type will always match with the type.
|
||||
fn matches(&self) -> Option<(Type, bool)> {
|
||||
None
|
||||
}
|
||||
pub trait MersType: Any + Debug + Display + Send + Sync {
|
||||
/// If Some(T), calling `iterable` on the MersData this MersType belongs to
|
||||
/// Should return Some(I), where I is an Iterator which only returns items of type T.
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
@@ -66,18 +62,28 @@ pub trait MersType: Any + Debug {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn mut_any(&mut self) -> &mut dyn Any;
|
||||
fn to_any(self) -> Box<dyn Any>;
|
||||
fn is_reference_to(&self) -> Option<&Type> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Data {
|
||||
is_mut: bool,
|
||||
counts: Arc<(AtomicUsize, AtomicUsize)>,
|
||||
pub data: Arc<RwLock<Box<dyn MersData>>>,
|
||||
}
|
||||
impl Data {
|
||||
pub fn new<T: MersData>(data: T) -> Self {
|
||||
Self::new_boxed(Box::new(data))
|
||||
Self::new_boxed(Box::new(data), true)
|
||||
}
|
||||
pub fn new_boxed(data: Box<dyn MersData>) -> Self {
|
||||
pub fn new_boxed(data: Box<dyn MersData>, is_mut: bool) -> Self {
|
||||
Self {
|
||||
is_mut,
|
||||
counts: Arc::new((
|
||||
AtomicUsize::new(if is_mut { 0 } else { 1 }),
|
||||
AtomicUsize::new(if is_mut { 1 } else { 0 }),
|
||||
)),
|
||||
data: Arc::new(RwLock::new(data)),
|
||||
}
|
||||
}
|
||||
@@ -87,27 +93,116 @@ impl Data {
|
||||
pub fn one_tuple(v: Self) -> Self {
|
||||
Self::new(tuple::Tuple(vec![v]))
|
||||
}
|
||||
/// Returns true if self is `()`.
|
||||
pub fn is_zero_tuple(&self) -> bool {
|
||||
if let Some(tuple) = self
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::tuple::Tuple>()
|
||||
{
|
||||
tuple.0.is_empty()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
/// Returns `Some(d)` if and only if self is `(d)`.
|
||||
pub fn one_tuple_content(&self) -> Option<Data> {
|
||||
if let Some(data) = self
|
||||
.get()
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::tuple::Tuple>()
|
||||
.filter(|v| v.len() == 1)
|
||||
.and_then(|v| v.get(0))
|
||||
{
|
||||
Some(data.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn get(&self) -> RwLockReadGuard<Box<dyn MersData>> {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!("[mers:data:cow] get");
|
||||
self.data.read().unwrap()
|
||||
}
|
||||
pub fn get_mut(&self) -> RwLockWriteGuard<Box<dyn MersData>> {
|
||||
pub fn get_mut_unchecked(&self) -> RwLockWriteGuard<Box<dyn MersData>> {
|
||||
self.data.write().unwrap()
|
||||
}
|
||||
pub fn try_get_mut(&self) -> Option<RwLockWriteGuard<Box<dyn MersData>>> {
|
||||
if self.is_mut && self.counts.0.load(std::sync::atomic::Ordering::Relaxed) == 0 {
|
||||
Some(self.get_mut_unchecked())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
/// like try_get_mut, but instead of returning `None` this function `get()`s the data and clones it.
|
||||
/// When cloning data, this transforms `self` into a `Data` with `is_mut: true`, hence the `&mut self` parameter.
|
||||
pub fn get_mut(&mut self) -> RwLockWriteGuard<Box<dyn MersData>> {
|
||||
if self.try_get_mut().is_none() {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!(
|
||||
"[mers:data:cow] cloning! get_mut called on {}",
|
||||
if !self.is_mut {
|
||||
"non-mut value"
|
||||
} else {
|
||||
"value with immut references"
|
||||
}
|
||||
);
|
||||
let val = self.get().clone();
|
||||
*self = Self::new_boxed(val, true);
|
||||
}
|
||||
self.get_mut_unchecked()
|
||||
}
|
||||
pub fn mkref(&self) -> Self {
|
||||
if self.is_mut {
|
||||
self.counts
|
||||
.1
|
||||
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
Self {
|
||||
is_mut: true,
|
||||
counts: Arc::clone(&self.counts),
|
||||
data: Arc::clone(&self.data),
|
||||
}
|
||||
} else {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!("[mers:data:cow] cloning! mkref called on immutable data");
|
||||
Self::new_boxed(self.data.read().unwrap().clone(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Clone for Data {
|
||||
fn clone(&self) -> Self {
|
||||
// todo!("clone for data - requires CoW");
|
||||
self.counts
|
||||
.0
|
||||
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
Self {
|
||||
is_mut: false,
|
||||
counts: Arc::clone(&self.counts),
|
||||
data: Arc::clone(&self.data),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Drop for Data {
|
||||
fn drop(&mut self) {
|
||||
if self.is_mut {
|
||||
&self.counts.1
|
||||
} else {
|
||||
&self.counts.0
|
||||
}
|
||||
.fetch_sub(1, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Data {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.get().is_eq(other.get().as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Type {
|
||||
// TODO: Maybe make sure this is always sorted by (recursive?!?) TypeId,
|
||||
// that way is_same_type_as can work more efficiently (cuz good code but also branch prediction)
|
||||
types: Vec<Arc<dyn MersType>>,
|
||||
pub types: Vec<Arc<dyn MersType>>,
|
||||
}
|
||||
impl Type {
|
||||
pub fn new<T: MersType>(t: T) -> Self {
|
||||
@@ -118,11 +213,64 @@ impl Type {
|
||||
pub fn newm(types: Vec<Arc<dyn MersType>>) -> Self {
|
||||
Self { types }
|
||||
}
|
||||
pub fn empty() -> Self {
|
||||
Self { types: vec![] }
|
||||
}
|
||||
pub fn empty_tuple() -> Self {
|
||||
Self::new(tuple::TupleT(vec![]))
|
||||
}
|
||||
pub fn add<T: MersType>(&mut self, new: Box<T>) {
|
||||
todo!()
|
||||
/// Returns true if self is `()`.
|
||||
pub fn is_zero_tuple(&self) -> bool {
|
||||
let mut o = false;
|
||||
for t in &self.types {
|
||||
o = true;
|
||||
if let Some(tuple) = t.as_any().downcast_ref::<crate::data::tuple::TupleT>() {
|
||||
if !tuple.0.is_empty() {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
o
|
||||
}
|
||||
/// Returns `Some(d)` if and only if self is `(d)`.
|
||||
pub fn one_tuple_content(&self) -> Option<Type> {
|
||||
let mut o = Self::empty();
|
||||
for t in &self.types {
|
||||
if let Some(t) = t
|
||||
.as_any()
|
||||
.downcast_ref::<crate::data::tuple::TupleT>()
|
||||
.filter(|v| v.0.len() == 1)
|
||||
.and_then(|v| v.0.get(0))
|
||||
{
|
||||
o.add(Arc::new(t.clone()));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(o)
|
||||
}
|
||||
pub fn add(&mut self, new: Arc<dyn MersType>) {
|
||||
let n = new.as_any();
|
||||
if let Some(s) = n.downcast_ref::<Self>() {
|
||||
for t in &s.types {
|
||||
self.add(Arc::clone(t));
|
||||
}
|
||||
} else {
|
||||
self.types.push(new);
|
||||
}
|
||||
}
|
||||
pub fn dereference(&self) -> Option<Self> {
|
||||
let mut o = Self::empty();
|
||||
for t in &self.types {
|
||||
if let Some(t) = t.is_reference_to() {
|
||||
o.add(Arc::new(t.clone()));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(o)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +289,7 @@ impl MersType for Type {
|
||||
todo!()
|
||||
}
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
todo!()
|
||||
self.types.iter().all(|t| t.is_included_in_single(target))
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
@@ -152,4 +300,45 @@ impl MersType for Type {
|
||||
fn to_any(self) -> Box<dyn Any> {
|
||||
Box::new(self)
|
||||
}
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
let mut o = Self::empty();
|
||||
for t in self.types.iter() {
|
||||
if let Some(t) = t.iterable() {
|
||||
o.add(Arc::new(t));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(o)
|
||||
}
|
||||
fn get(&self) -> Option<Type> {
|
||||
let mut o = Self::empty();
|
||||
for t in self.types.iter() {
|
||||
if let Some(t) = t.get() {
|
||||
o.add(Arc::new(t));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(o)
|
||||
}
|
||||
}
|
||||
impl Display for Type {
|
||||
fn fmt(&self, 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])?;
|
||||
for t in self.types.iter().skip(1) {
|
||||
write!(f, "/{t}")?;
|
||||
}
|
||||
if self.types.len() > 1 {
|
||||
write!(f, "}}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
use std::{any::Any, fmt::Display, sync::Mutex};
|
||||
use std::{
|
||||
any::Any,
|
||||
fmt::Display,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Reference(pub Data);
|
||||
pub struct Reference(pub Arc<Mutex<Data>>);
|
||||
|
||||
impl MersData for Reference {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
*other.0.lock().unwrap() == *self.0.lock().unwrap()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> Type {
|
||||
Type::new(ReferenceT(self.0.lock().unwrap().get().as_type()))
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -31,6 +45,7 @@ impl MersType for ReferenceT {
|
||||
}
|
||||
}
|
||||
fn is_included_in_single(&self, target: &dyn MersType) -> bool {
|
||||
// &int isn't included in &(int/float), otherwise we could assign a float to it
|
||||
self.is_same_type_as(target)
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
@@ -42,10 +57,18 @@ impl MersType for ReferenceT {
|
||||
fn to_any(self) -> Box<dyn Any> {
|
||||
Box::new(self)
|
||||
}
|
||||
fn is_reference_to(&self) -> Option<&Type> {
|
||||
Some(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Reference {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "&{}", self.0.get())
|
||||
write!(f, "&{}", self.0.lock().unwrap().get())
|
||||
}
|
||||
}
|
||||
impl Display for ReferenceT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "&{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,22 @@ use super::{MersData, MersType, Type};
|
||||
pub struct String(pub std::string::String);
|
||||
|
||||
impl MersData for String {
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn as_type(&self) -> super::Type {
|
||||
Type::new(StringT)
|
||||
}
|
||||
fn mut_any(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -45,3 +55,8 @@ impl Display for String {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
impl Display for StringT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "String")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::{any::Any, fmt::Display};
|
||||
use std::{any::Any, fmt::Display, sync::Arc};
|
||||
|
||||
use super::{Data, MersData, MersType, Type};
|
||||
|
||||
@@ -15,15 +15,11 @@ impl Tuple {
|
||||
}
|
||||
|
||||
impl MersData for Tuple {
|
||||
fn matches(&self) -> Option<Data> {
|
||||
if let Some(d) = self.0.first() {
|
||||
if self.0.len() == 1 {
|
||||
Some(d.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
fn is_eq(&self, other: &dyn MersData) -> bool {
|
||||
if let Some(other) = other.as_any().downcast_ref::<Self>() {
|
||||
other.0 == self.0
|
||||
} else {
|
||||
None
|
||||
false
|
||||
}
|
||||
}
|
||||
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
|
||||
@@ -32,6 +28,9 @@ impl MersData for Tuple {
|
||||
fn clone(&self) -> Box<dyn MersData> {
|
||||
Box::new(Clone::clone(self))
|
||||
}
|
||||
fn as_type(&self) -> Type {
|
||||
Type::new(TupleT(self.0.iter().map(|v| v.get().as_type()).collect()))
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -46,19 +45,12 @@ impl MersData for Tuple {
|
||||
#[derive(Debug)]
|
||||
pub struct TupleT(pub Vec<Type>);
|
||||
impl MersType for TupleT {
|
||||
fn matches(&self) -> Option<(Type, bool)> {
|
||||
if let Some(d) = self.0.first() {
|
||||
if self.0.len() == 1 {
|
||||
Some((d.clone(), true))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn iterable(&self) -> Option<Type> {
|
||||
Some(todo!("joine types"))
|
||||
let mut o = Type::empty();
|
||||
for t in self.0.iter() {
|
||||
o.add(Arc::new(t.clone()));
|
||||
}
|
||||
Some(o)
|
||||
}
|
||||
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some()
|
||||
@@ -90,3 +82,16 @@ impl Display for Tuple {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user