mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
fixed bug where all but the first loop iterations would write data to the mutable variables from the last iteration(s) even though the variables are supposed to be completely local: is_init can be set on steatements that have an output_to to force them to always redeclare and never reassign the new value.
This commit is contained in:
parent
9ec4acaf70
commit
79b169d951
@ -81,27 +81,33 @@ impl RFunction {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RStatement {
|
pub struct RStatement {
|
||||||
pub output_to: Option<(usize, usize)>,
|
// (_, _, is_init)
|
||||||
|
pub output_to: Option<(usize, usize, bool)>,
|
||||||
statement: Box<RStatementEnum>,
|
statement: Box<RStatementEnum>,
|
||||||
pub force_output_type: Option<VType>,
|
pub force_output_type: Option<VType>,
|
||||||
}
|
}
|
||||||
impl RStatement {
|
impl RStatement {
|
||||||
pub fn run(&self, vars: &mut Vec<VData>, info: &GSInfo) -> VData {
|
pub fn run(&self, vars: &mut Vec<VData>, info: &GSInfo) -> VData {
|
||||||
let out = self.statement.run(vars, info);
|
let out = self.statement.run(vars, info);
|
||||||
if let Some((v, derefs)) = self.output_to {
|
if let Some((v, derefs, is_init)) = self.output_to {
|
||||||
let mut val = dereference_n(&mut vars[v], derefs);
|
// let mut parent = None;
|
||||||
fn dereference_n(d: &mut VData, n: usize) -> VData {
|
let mut val = &mut vars[v];
|
||||||
if n > 0 {
|
fn deref(n: usize, val: &mut VData, is_init: bool, out: VData) {
|
||||||
if let VDataEnum::Reference(v) = &mut d.data.lock().unwrap().0 {
|
if n == 0 {
|
||||||
dereference_n(v, n - 1)
|
if is_init {
|
||||||
|
*val = out.inner().to();
|
||||||
} else {
|
} else {
|
||||||
unreachable!("dereferencing something that isn't a reference in assignment")
|
val.assign(out.inner());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
d.clone_mut()
|
if let VDataEnum::Reference(r) = &mut val.data().0 {
|
||||||
|
deref(n - 1, r, is_init, out)
|
||||||
|
} else {
|
||||||
|
unreachable!("cannot derefence: not a reference.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val.assign(out.inner());
|
deref(derefs, val, is_init, out);
|
||||||
VDataEnum::Tuple(vec![]).to()
|
VDataEnum::Tuple(vec![]).to()
|
||||||
} else {
|
} else {
|
||||||
out
|
out
|
||||||
|
@ -652,11 +652,11 @@ fn statement(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
linfo.vars.insert(opt.clone(), (ginfo.vars, out));
|
linfo.vars.insert(opt.clone(), (ginfo.vars, out));
|
||||||
statement.output_to = Some((ginfo.vars, 0));
|
statement.output_to = Some((ginfo.vars, 0, true));
|
||||||
ginfo.vars += 1;
|
ginfo.vars += 1;
|
||||||
} else {
|
} else {
|
||||||
// mutate existing variable
|
// mutate existing variable
|
||||||
statement.output_to = Some((*var_id, *derefs));
|
statement.output_to = Some((*var_id, *derefs, false));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut out = statement.out(ginfo);
|
let mut out = statement.out(ginfo);
|
||||||
@ -672,7 +672,7 @@ fn statement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
linfo.vars.insert(opt.clone(), (ginfo.vars, out));
|
linfo.vars.insert(opt.clone(), (ginfo.vars, out));
|
||||||
statement.output_to = Some((ginfo.vars, *derefs));
|
statement.output_to = Some((ginfo.vars, *derefs, true));
|
||||||
ginfo.vars += 1;
|
ginfo.vars += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user