diff --git a/inputs/failing/doublePreInc.ts b/inputs/passing/doublePreInc.ts similarity index 64% rename from inputs/failing/doublePreInc.ts rename to inputs/passing/doublePreInc.ts index 8187304..c8d66d0 100644 --- a/inputs/failing/doublePreInc.ts +++ b/inputs/passing/doublePreInc.ts @@ -1,5 +1,4 @@ -// test_output! 4 -// (This is wrong.) +// test_output! 3 export default function main() { let x = 0; diff --git a/valuescript_compiler/src/expression_compiler.rs b/valuescript_compiler/src/expression_compiler.rs index 16e197b..d0990c1 100644 --- a/valuescript_compiler/src/expression_compiler.rs +++ b/valuescript_compiler/src/expression_compiler.rs @@ -741,7 +741,19 @@ impl<'a> ExpressionCompiler<'a> { } } - reg.clone() + let res = self.fnc.allocate_tmp(); + nested_registers.push(res.clone()); + + // Always copy pre-increment value into a new register. + // This is a bit heavy-handed (FIXME), but it's consistent with the current policy of + // doing this whenever the variable is mutated, which it clearly is. Really though, the + // issue is when *other* mutations to this variable occur between now and when it's + // inserted. + self + .fnc + .push(Instruction::Mov(Value::Register(reg.clone()), res.clone())); + + res } TargetAccessor::Nested(nta) => match target_register { Some(tr) => { diff --git a/valuescript_compiler/src/function_compiler.rs b/valuescript_compiler/src/function_compiler.rs index 88dea08..076e2e6 100644 --- a/valuescript_compiler/src/function_compiler.rs +++ b/valuescript_compiler/src/function_compiler.rs @@ -447,7 +447,8 @@ impl FunctionCompiler { Some(expr) => { let mut expression_compiler = ExpressionCompiler { fnc: self }; - expression_compiler.compile(expr, Some(Register::Return)); + let compiled = expression_compiler.compile(expr, Some(Register::Return)); + self.use_(compiled); } }