code generation bug

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

code generation bug

Kelley, Brian
I was surprised to notice the following:

   Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
   > =((1 or false) and true) or false
   1

Same results on 5.1.2 and 5.1.3, MacOS and Windows.

For what it's worth, I observed in lcode.c that the OPR_AND expression inherited the 'k' (kind) of VTRUE from its rhs subexpression, which seems wrong and seems to throw off the subsequent call to luaK_goiffalse().

-bhk

Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Eike Decker
This is looking weird in deed:

Lua 5.1.3  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> =((1 or false) and 2) or false
2
> =((1 or false) and true) or false
1
> =((1 or false or 3) and 2 and true) or false
1

I always thought that the last evaluated value would be returned that
would make the whole condition becoming true, instead... I have no
idea which value is going to be returned in a more complex logical
operation.

>From the manual:

"The negation operator not always returns false or true. The
conjunction operator and returns its first argument if this value is
false or nil; otherwise, and returns its second argument. The
disjunction operator or returns its first argument if this value is
different from nil and false; otherwise, or returns its second
argument. Both and and or use short-cut evaluation; that is, the
second operand is evaluated only if necessary. Here are some examples:
"

The examples in the manual are much simpler and don't cover the given situation.

I am not sure, but I can't find there a clue about the value to be
returned that would match the examples above. Maybe it needs to be
extended there?

Eike


2009/4/16 Kelley, Brian <[hidden email]>:

> I was surprised to notice the following:
>
>   Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>   > =((1 or false) and true) or false
>   1
>
> Same results on 5.1.2 and 5.1.3, MacOS and Windows.
>
> For what it's worth, I observed in lcode.c that the OPR_AND expression inherited the 'k' (kind) of VTRUE from its rhs subexpression, which seems wrong and seems to throw off the subsequent call to luaK_goiffalse().
>
> -bhk
>
>
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Linker
In reply to this post by Kelley, Brian
I had try it in Lua 5.1.4 win xp:

> =1 or false
1 -- right
> =1 and true or false
true -- right
> =1 or false and true or false
1 -- wrong
> =((1 or false) and true)or false
1 -- wrong
>



On Thu, Apr 16, 2009 at 12:37, Kelley, Brian <[hidden email]> wrote:
I was surprised to notice the following:

  Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
  > =((1 or false) and true) or false
  1

Same results on 5.1.2 and 5.1.3, MacOS and Windows.

For what it's worth, I observed in lcode.c that the OPR_AND expression inherited the 'k' (kind) of VTRUE from its rhs subexpression, which seems wrong and seems to throw off the subsequent call to luaK_goiffalse().

-bhk




--
Regards,
Linker Lin
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Vaughan McAlley
Maybe it's a parsing issue. This from the Lua Demo site:

print( ((1 or false) and true) or false)
local x, y, z = 1, true, false
print( ((x or z) and y) or z )

-->1
-->true

The strange behaviour doesn't happen if the inner parenthesis is
(false or 1) for example.

Vaughan

2009/4/16 Linker <[hidden email]>:

> I had try it in Lua 5.1.4 win xp:
>> =1 or false
> 1 -- right
>> =1 and true or false
> true -- right
>> =1 or false and true or false
> 1 -- wrong
>> =((1 or false) and true)or false
> 1 -- wrong
>>
>
>
> On Thu, Apr 16, 2009 at 12:37, Kelley, Brian <[hidden email]> wrote:
>>
>> I was surprised to notice the following:
>>
>>   Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>>   > =((1 or false) and true) or false
>>   1
>>
>> Same results on 5.1.2 and 5.1.3, MacOS and Windows.
>>
>> For what it's worth, I observed in lcode.c that the OPR_AND expression
>> inherited the 'k' (kind) of VTRUE from its rhs subexpression, which seems
>> wrong and seems to throw off the subsequent call to luaK_goiffalse().
>>
>> -bhk
>>
>
>
>
> --
> Regards,
> Linker Lin
> [hidden email]
>
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Asko Kauppi
In reply to this post by Kelley, Brian

On OS X PowerPC:
<<
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> =1 or false
1
> =1 and true
true
> =true or false
true
> =((1 or false) and true) or false
1
<<

Indeed seems funny that combining expressions with
paranthesis has different result than having them as
separate expressions.

-asko


On Wed, 15 Apr 2009 21:37:25 -0700
  "Kelley, Brian" <[hidden email]> wrote:

> I was surprised to notice the following:
>
>   Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>   > =((1 or false) and true) or false
>   1
>
> Same results on 5.1.2 and 5.1.3, MacOS and Windows.
>
>For what it's worth, I observed in lcode.c that the
>OPR_AND expression inherited the 'k' (kind) of VTRUE from
>its rhs subexpression, which seems wrong and seems to
>throw off the subsequent call to luaK_goiffalse().
>
> -bhk
>

Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Enrico Colombini
[hidden email] wrote:
> Indeed seems funny that combining expressions with paranthesis has
> different result than having them as separate expressions.

More puzzling (5.1.2 on XP), using the interpreter:

 > =((1 or false) and true)
true

 > =((1 or false) and true) or false
1

   Enrico
Reply | Threaded
Open this post in threaded view
|

RE: code generation bug

Kelley, Brian
In reply to this post by Linker
Linker: Your third case "1 or false and true or false" is not a bug.  Due to operator precedence it is equivalent to "1 or (false and true) or false".

I can generalize the problem a bit, though.  For any X, Y, Z, where X ~=nil and X~=false:

    ((X or Y) and true) or Z  -->  X   (should always be true)
    (X or Y) and (true or Z)  -->  X   (should always be true)

Extra parentheses are for clarity and do not affect the results.

-bhk

________________________________________
From: [hidden email] [mailto:[hidden email]] On Behalf Of Linker
Sent: Wednesday, April 15, 2009 11:47 PM
To: Lua list
Subject: Re: code generation bug

I had try it in Lua 5.1.4 win xp:

> =1 or false
1 -- right
> =1 and true or false
true -- right
> =1 or false and true or false
1 -- wrong
> =((1 or false) and true)or false
1 -- wrong
>


On Thu, Apr 16, 2009 at 12:37, Kelley, Brian <[hidden email]> wrote:
I was surprised to notice the following:

  Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
  > =((1 or false) and true) or false
  1

Same results on 5.1.2 and 5.1.3, MacOS and Windows.

For what it's worth, I observed in lcode.c that the OPR_AND expression inherited the 'k' (kind) of VTRUE from its rhs subexpression, which seems wrong and seems to throw off the subsequent call to luaK_goiffalse().

-bhk



--
Regards,
Linker Lin
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Marco Antonio Abreu-3
In reply to this post by Linker
Hi Linker.
You have to attend that the AND operator has a higher priority than the OR one. So, "1 or false and true or false" is correct when resulting 1. But, in the last line, I agree with you, it's wrong.

On Thu, Apr 16, 2009 at 3:46 AM, Linker <[hidden email]> wrote:
I had try it in Lua 5.1.4 win xp:

> =1 or false
1 -- right
> =1 and true or false
true -- right
> =1 or false and true or false
1 -- wrong
> =((1 or false) and true)or false
1 -- wrong
>



On Thu, Apr 16, 2009 at 12:37, Kelley, Brian <[hidden email]> wrote:
I was surprised to notice the following:

  Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
  > =((1 or false) and true) or false
  1

Same results on 5.1.2 and 5.1.3, MacOS and Windows.

For what it's worth, I observed in lcode.c that the OPR_AND expression inherited the 'k' (kind) of VTRUE from its rhs subexpression, which seems wrong and seems to throw off the subsequent call to luaK_goiffalse().

-bhk




--
Regards,
Linker Lin
[hidden email]



--
Marco Antonio Abreu
Analista de Sistemas
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Peter Cawley
On Fri, Apr 17, 2009 at 5:07 PM, Marco Antonio Abreu
<[hidden email]> wrote:
> Hi Linker.
> You have to attend that the AND operator has a higher priority than the OR
> one. So, "1 or false and true or false" is correct when resulting 1.

"1 or false and true or false" should be interpreted as "(1 or false)
and (true or false)", which should evaluate to "(1) and (true)", which
should evaluate to "true", not "1" ("The conjunction operator *and*
returns its first argument if this value is *false* or *nil*;
otherwise, *and* returns its second argument" - Lua manual).
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Duncan Cross


On Fri, Apr 17, 2009 at 5:16 PM, Peter Cawley <[hidden email]> wrote:
On Fri, Apr 17, 2009 at 5:07 PM, Marco Antonio Abreu
<[hidden email]> wrote:
> Hi Linker.
> You have to attend that the AND operator has a higher priority than the OR
> one. So, "1 or false and true or false" is correct when resulting 1.

"1 or false and true or false" should be interpreted as "(1 or false)
and (true or false)", which should evaluate to "(1) and (true)", which
should evaluate to "true", not "1" ("The conjunction operator *and*
returns its first argument if this value is *false* or *nil*;
otherwise, *and* returns its second argument" - Lua manual).

The Lua manual also details operator precedences in section 2.5.6 - "or" has the lowest precedence, just lower than "and". So "1 or false and true or false" in fact gets interpreted as "1 or (false and true) or false".
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

David Manura
In reply to this post by Asko Kauppi
On Thu, Apr 16, 2009 at 3:08 AM, wrote:
>> =((1 or false) and true) or false
> 1

Consider this variant:

$ lua
> return (1 or 2) and 3 or 4
3   -- correct
> return (1 or 2) and true or 4
1   -- wrong
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Roberto Ierusalimschy
> On Thu, Apr 16, 2009 at 3:08 AM, wrote:
> >> =((1 or false) and true) or false
> > 1
>
> Consider this variant:
>
> $ lua
> > return (1 or 2) and 3 or 4
> 3   -- correct
> > return (1 or 2) and true or 4
> 1   -- wrong

Quite telling...

-- Roberto
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

David Manura
In reply to this post by David Manura
On Fri, Apr 24, 2009 at 9:02 PM, David Manura wrote:
> Consider this variant: ...

Nevermind, it was basically already stated, but here's another:

> local x =true; return (1 or 2) and x or 4
true  -- correct

There is something wrong with the bytecodes:

$ echo 'return (1 or 2) and true or 4' | luac -p -l -

main <stdin:0,0> (10 instructions, 40 bytes at 0x680e00)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 functions
        1       [1]     LOADK           0 -1    ; 1
        2       [1]     TEST            0 0 1
        3       [1]     JMP             5       ; to 9
        4       [1]     JMP             3       ; to 8
        5       [1]     LOADK           0 -2    ; 4
        6       [1]     JMP             2       ; to 9
        7       [1]     LOADBOOL        0 0 1
        8       [1]     LOADBOOL        0 1 0
        9       [1]     RETURN          0 2
        10      [1]     RETURN          0 1
Reply | Threaded
Open this post in threaded view
|

Re: code generation bug

Roberto Ierusalimschy
In reply to this post by Kelley, Brian
> I was surprised to notice the following:
>
>    Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>    > =((1 or false) and true) or false
>    1
>
> [...]

Not surprisingly, the dual case has the same bug:

  > = ((nil and true) or false) and true
  nil
  > f=false
  > = ((nil and true) or f) and true
  false


> For what it's worth, I observed in lcode.c that the OPR_AND expression
> inherited the 'k' (kind) of VTRUE from its rhs subexpression,
> which seems wrong and seems to throw off the subsequent call to
> luaK_goiffalse().

Well, the result of "((1 or false) and true)" is true, so the inherited
attribute VTRUE is not completely wrong. The problem seems to be the
interaction between this attribute and the patch lists. (But I still need
some time to check this bug...)

-- Roberto
Reply | Threaded
Open this post in threaded view
|

RE: code generation bug

Kelley, Brian
> Not surprisingly, the dual case has the same bug:
>
>   > = ((nil and true) or false) and true
>   nil
>   > f=false
>   > = ((nil and true) or f) and true
>   false


Or more generally, for any Y, Z:

    ((nil and Y) or false) and Z  -->  nil
    (nil and Y) or (false and Z)  -->  nil

Which is symmetrical with my earlier generalization:  For any X, Y, Z, where X ~=nil and X~=false:

    ((X or Y) and true) or Z  -->  X
    (X or Y) and (true or Z)  -->  X


> > For what it's worth, I observed in lcode.c that the OPR_AND
> expression
> > inherited the 'k' (kind) of VTRUE from its rhs subexpression,
> > which seems wrong and seems to throw off the subsequent call to
> > luaK_goiffalse().
>
> Well, the result of "((1 or false) and true)" is true, so the
> inherited
> attribute VTRUE is not completely wrong. The problem seems to be the
> interaction between this attribute and the patch lists. (But I still
> need some time to check this bug...)

Got it.  I didn't have time to grok the code generation, but offered this info in case it might help a bit.

-bhk