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}; use super::{Data, MersData, MersType, Type};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Reference(pub Arc<RwLock<Data>>); pub struct Reference(pub Arc<RwLock<Data>>, pub Type);
impl MersData for Reference { impl MersData for Reference {
fn is_eq(&self, other: &dyn MersData) -> bool { fn is_eq(&self, other: &dyn MersData) -> bool {
@ -21,7 +21,7 @@ impl MersData for Reference {
Box::new(Clone::clone(self)) Box::new(Clone::clone(self))
} }
fn as_type(&self) -> Type { 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 { fn as_any(&self) -> &dyn Any {
self self

View File

@ -46,7 +46,7 @@ impl Config {
if let Some(t) = t.0[0].dereference() { if let Some(t) = t.0[0].dereference() {
for t in t.types.iter() { for t in t.types.iter() {
if let Some(t) = t.as_any().downcast_ref::<ListT>() { 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 { } else {
return Err(format!( return Err(format!(
"get_mut: first argument in tuple {t} isn't `&List<_>`." "get_mut: first argument in tuple {t} isn't `&List<_>`."
@ -75,20 +75,21 @@ impl Config {
let t = a.get(); let t = a.get();
let t = t.as_any().downcast_ref::<data::tuple::Tuple>().unwrap(); 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 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() .as_any()
.downcast_ref::<data::reference::Reference>() .downcast_ref::<data::reference::Reference>()
.unwrap() .unwrap().0;
.0 let list = list
.read() .read()
.unwrap() .unwrap();
.get() let list = list.get();
.as_any() let list = list.as_any()
.downcast_ref::<List>() .downcast_ref::<List>()
.unwrap().0.get(i) .unwrap();
{ let o = match list.0.get(i) {
Some(data) => { 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(), None => Data::empty_tuple(),
}; };
@ -263,11 +264,7 @@ impl MersData for List {
Box::new(Clone::clone(self)) Box::new(Clone::clone(self))
} }
fn as_type(&self) -> Type { fn as_type(&self) -> Type {
let mut t = Type::empty(); Type::new(ListT(self.inner_type()))
for el in &self.0 {
t.add(Arc::new(el.read().unwrap().get().as_type()));
}
Type::new(ListT(t))
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self
@ -332,3 +329,12 @@ impl Display for ListT {
Ok(()) 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; info.scopes[self.var.0].vars[self.var.1] = nothing;
} else { } else {
// (reference to) data which will never be referenced again // (reference to) data which will never be referenced again
return Data::new(data::reference::Reference(Arc::new(RwLock::new( return Data::new(data::reference::Reference(
Data::empty_tuple(), Arc::new(RwLock::new(Data::empty_tuple())),
)))); Type::empty(),
));
} }
} }
if self.is_ref_not_ignore { if self.is_ref_not_ignore {
Data::new(data::reference::Reference(Arc::clone( let v = &info.scopes[self.var.0].vars[self.var.1];
&info.scopes[self.var.0].vars[self.var.1], Data::new(data::reference::Reference(
))) Arc::clone(v),
v.read().unwrap().get().as_type(),
))
} else { } else {
info.scopes[self.var.0].vars[self.var.1] info.scopes[self.var.0].vars[self.var.1]
.write() .write()