make list.get_mut return a 1-tuple on success, and fix reference type being incomplete

This commit is contained in:
Mark 2024-02-22 19:41:03 +01:00
parent 05c88b7826
commit dc2db1d0e8
3 changed files with 32 additions and 23 deletions

View File

@ -7,7 +7,7 @@ use std::{
use super::{Data, MersData, MersType, Type};
#[derive(Debug, Clone)]
pub struct Reference(pub Arc<RwLock<Data>>);
pub struct Reference(pub Arc<RwLock<Data>>, pub Type);
impl MersData for Reference {
fn is_eq(&self, other: &dyn MersData) -> bool {
@ -21,7 +21,7 @@ impl MersData for Reference {
Box::new(Clone::clone(self))
}
fn as_type(&self) -> Type {
Type::new(ReferenceT(self.0.write().unwrap().get().as_type()))
Type::new(ReferenceT(self.1.clone()))
}
fn as_any(&self) -> &dyn Any {
self

View File

@ -46,7 +46,7 @@ impl Config {
if let Some(t) = t.0[0].dereference() {
for t in t.types.iter() {
if let Some(t) = t.as_any().downcast_ref::<ListT>() {
out.add(Arc::new(data::reference::ReferenceT(t.0.clone())));
out.add(Arc::new(data::tuple::TupleT(vec![Type::new(data::reference::ReferenceT(t.0.clone()))])));
} else {
return Err(format!(
"get_mut: first argument in tuple {t} isn't `&List<_>`."
@ -75,20 +75,21 @@ impl Config {
let t = a.get();
let t = t.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
let i = t.0[1].get().as_any().downcast_ref::<data::int::Int>().unwrap().0.max(0) as usize;
let o = match t.0[0].get()
let list = t.0[0].get();
let list = &list
.as_any()
.downcast_ref::<data::reference::Reference>()
.unwrap()
.0
.unwrap().0;
let list = list
.read()
.unwrap()
.get()
.as_any()
.unwrap();
let list = list.get();
let list = list.as_any()
.downcast_ref::<List>()
.unwrap().0.get(i)
{
.unwrap();
let o = match list.0.get(i) {
Some(data) => {
Data::new(data::reference::Reference(Arc::clone(data)))
Data::one_tuple(Data::new(data::reference::Reference(Arc::clone(data), list.inner_type())))
}
None => Data::empty_tuple(),
};
@ -263,11 +264,7 @@ impl MersData for List {
Box::new(Clone::clone(self))
}
fn as_type(&self) -> Type {
let mut t = Type::empty();
for el in &self.0 {
t.add(Arc::new(el.read().unwrap().get().as_type()));
}
Type::new(ListT(t))
Type::new(ListT(self.inner_type()))
}
fn as_any(&self) -> &dyn std::any::Any {
self
@ -332,3 +329,12 @@ impl Display for ListT {
Ok(())
}
}
impl List {
pub fn inner_type(&self) -> Type {
let mut t = Type::empty();
for el in &self.0 {
t.add(Arc::new(el.read().unwrap().get().as_type()));
}
t
}
}

View File

@ -60,15 +60,18 @@ impl MersStatement for Variable {
info.scopes[self.var.0].vars[self.var.1] = nothing;
} else {
// (reference to) data which will never be referenced again
return Data::new(data::reference::Reference(Arc::new(RwLock::new(
Data::empty_tuple(),
))));
return Data::new(data::reference::Reference(
Arc::new(RwLock::new(Data::empty_tuple())),
Type::empty(),
));
}
}
if self.is_ref_not_ignore {
Data::new(data::reference::Reference(Arc::clone(
&info.scopes[self.var.0].vars[self.var.1],
)))
let v = &info.scopes[self.var.0].vars[self.var.1];
Data::new(data::reference::Reference(
Arc::clone(v),
v.read().unwrap().get().as_type(),
))
} else {
info.scopes[self.var.0].vars[self.var.1]
.write()