mirror of
https://github.com/Dummi26/mers.git
synced 2025-12-13 19:06:16 +01:00
fix list cloning not cloning inner values
this would allow mutating values through a list passed by value, but now it doesn't, which is how it always should have been.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
sync::{Arc, Mutex, RwLock},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ use super::Config;
|
||||
|
||||
impl Config {
|
||||
/// `deref: fn` clones the value from a reference
|
||||
/// `mkref: fn` returns a reference to a copy of the value
|
||||
/// `eq: fn` returns true if all the values are equal, otherwise false.
|
||||
/// `loop: fn` runs a function until it returns (T) instead of (), then returns T. Also works with ((), f) instead of f for ().loop(() -> { ... }) syntax, which may be more readable
|
||||
/// `try: fn` runs the first valid function with the argument. usage: (arg, (f1, f2, f3)).try
|
||||
@@ -173,6 +174,18 @@ impl Config {
|
||||
inner_statements: None,
|
||||
}),
|
||||
)
|
||||
.add_var(
|
||||
"mkref".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
info: Arc::new(Info::neverused()),
|
||||
info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
|
||||
out: Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone())))),
|
||||
run: Arc::new(|a, _i| {
|
||||
Data::new(data::reference::Reference(Arc::new(RwLock::new(a.clone()))))
|
||||
}),
|
||||
inner_statements: None,
|
||||
}),
|
||||
)
|
||||
.add_var(
|
||||
"deref".to_string(),
|
||||
Data::new(data::function::Function {
|
||||
|
||||
@@ -80,16 +80,16 @@ impl Config {
|
||||
.as_any()
|
||||
.downcast_ref::<data::reference::Reference>()
|
||||
.unwrap().0;
|
||||
let list = list
|
||||
.read()
|
||||
let mut list = list
|
||||
.write()
|
||||
.unwrap();
|
||||
let list = list.get();
|
||||
let list = list.get_mut();
|
||||
let list = list.as_any()
|
||||
.downcast_ref::<List>()
|
||||
.unwrap();
|
||||
let o = match list.0.get(i) {
|
||||
Some(data) => {
|
||||
Data::one_tuple(Data::new(data::reference::Reference(Arc::clone(data), list.inner_type())))
|
||||
Data::one_tuple(Data::new(data::reference::Reference(Arc::clone(data))))
|
||||
}
|
||||
None => Data::empty_tuple(),
|
||||
};
|
||||
@@ -235,8 +235,18 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct List(pub Vec<Arc<RwLock<Data>>>);
|
||||
impl Clone for List {
|
||||
fn clone(&self) -> Self {
|
||||
Self(
|
||||
self.0
|
||||
.iter()
|
||||
.map(|v| Arc::new(RwLock::new(v.read().unwrap().clone())))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ListT(pub Type);
|
||||
impl MersData for List {
|
||||
|
||||
@@ -60,18 +60,14 @@ 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())),
|
||||
Type::empty(),
|
||||
));
|
||||
return Data::new(data::reference::Reference(Arc::new(RwLock::new(
|
||||
Data::empty_tuple(),
|
||||
))));
|
||||
}
|
||||
}
|
||||
if self.is_ref_not_ignore {
|
||||
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(),
|
||||
))
|
||||
Data::new(data::reference::Reference(Arc::clone(v)))
|
||||
} else {
|
||||
info.scopes[self.var.0].vars[self.var.1]
|
||||
.write()
|
||||
|
||||
Reference in New Issue
Block a user