berry-lang/berry

Side-effect reassignment of boolean variable

Closed this issue · 4 comments

On release 1.1.0, a boolean variable may change its value after being used on the right hand side of an assignment, as in the below code:

def f()
 a=false
 print(a)
 b=true||a
 print(a)
end

f()

The def block may be swapped with an if or for block, but the issue goes away if the code happens outside of a block. The issue also goes away if b=true||a is replaced with b=a||true.

Thanks. I will investigate

Confirmed:
`def f() var a=false var b=true||a end``

Disassembly:

  0000  LDBOOL	R0	0	0        # R0 is a

  0001  LDBOOL	R1	1	0        # R1 is used as a temp variable
  0002  JMPT	R1	#0005
  0003  JMPT	R0	#0005
  0004  LDBOOL	R0	0	1        # wrongly using R0
  0005  LDBOOL	R0	1	0        # wrongly using R0
  0006  MOVE	R1	R0               # R1 is b

  0007  RET	0

Using more local variables shows that the assignment is alway done on R0:
def f() var a=false var c=false var d=false var b=true||a end

  0000  LDBOOL	R0	0	0
  0001  LDBOOL	R1	0	0
  0002  LDBOOL	R2	0	0
  0003  LDBOOL	R3	1	0
  0004  JMPT	R3	#0007
  0005  JMPT	R0	#0007
  0006  LDBOOL	R0	0	1
  0007  LDBOOL	R0	1	0
  0008  MOVE	R3	R0
  0009  RET	0

But when using globals, the assignment is correct:
ga = nil gb = nil def f() var a=false ga=false gb=true||ga end

  0000  LDBOOL	R0	0	0
  0001  LDBOOL	R1	0	0
  0002  SETNGBL	R1	K0
  0003  LDBOOL	R1	1	0
  0004  JMPT	R1	#0008
  0005  GETNGBL	R1	K0
  0006  JMPT	R1	#0008
  0007  LDBOOL	R1	0	1
  0008  LDBOOL	R1	1	0
  0009  SETNGBL	R1	K1
  000A  RET	0

This is fixed in #374. Thanks for reporting.