From 19443eae003a5a80ade596922f51b0d1cb2c545e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 8 Apr 2023 17:03:04 -0700 Subject: compiler: bugfix: eval order of variables. We have the following problem: when function call argument expressions mutate some of the variables that are being passed as arguments, the left-to-right semantics isn't obeyed. The problem is that the funcction call simply refers to the registers that hold the variables, rather than to the evaluated values. For instance (fun a (inc a)) will translate to something like (gcall (v 3) (v 3)) which is incorrect: both argument positions refer to the current value of a, whereas we need the left argument to refer to the value before the increment. * stdlib/compiler.tl (compiler comp-var): Do not assert the variable as the output register, with null code. Indicate that the value is in the caller's output register, and if necessary generate the move. (compiler comp-setq): When compiling the right-hand-side, use the original output register, so that we don't end up reporting the variable as the result location. --- stdlib/compiler.tl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl index bb896344..9e99c9c1 100644 --- a/stdlib/compiler.tl +++ b/stdlib/compiler.tl @@ -570,7 +570,7 @@ (vbin (each ((spy me.access-spies)) spy.(accessed vbin sym)) - (new (frag vbin.loc nil (list sym)))) + (new (frag oreg (maybe-mov oreg vbin.loc) (list sym)))) ((special-var-p sym) (let ((dreg me.(get-dreg sym))) (new (frag oreg ^((getv ,oreg ,dreg)) (list sym))))) @@ -584,7 +584,7 @@ (bind bind.loc) (spec me.(get-dreg sym)) (t me.(get-sidx sym)))) - (vfrag me.(compile (if bind vloc oreg) env value))) + (vfrag me.(compile oreg env value))) (when bind (each ((spy me.access-spies)) spy.(assigned bind sym))) -- cgit v1.2.3