Reply to topic  [ 3 posts ] 
ternary operator drops not operator 
Author Message
Yorick Guru

Joined: Wed Nov 24, 2004 12:51 pm
Posts: 97
Location: Observatoire de Lyon (France)
Post ternary operator drops not operator
Consider the two functions below and their "assembler" code:
Code:
func f1(a,b,c) { return (a ? !b : c); }
func f2(a,b,c) { return (a ? b : !c); }
disassemble,f1;
// func f1(a,b,c)
//    4 sp+>1    PushVariable(a)
//    6 sp->0    BranchFalse to pc= 12
//    8 sp+>1    PushVariable(b)
//   10 sp0>1    Branch to pc= 14
//   12 sp+>1    PushVariable(c)
//   14 sp->0    Return
//   15 sp==0    Halt-Virtual-Machine
disassemble,f2;
// func f2(a,b,c)
//    4 sp+>1    PushVariable(a)
//    6 sp->0    BranchFalse to pc= 12
//    8 sp+>1    PushVariable(b)
//   10 sp0>1    Branch to pc= 15
//   12 sp+>1    PushVariable(c)
//   14 sp0>1    Not
//   15 sp->0    Return
//   16 sp==0    Halt-Virtual-Machine
you can see that, in the first case, the not operator has been suppressed in the second operand by Yorick parser/compiler. To achieve the intended behavior, you must add an extra ! (with parenthesis because Yorick parser trigger a syntax error with !!):
Code:
func f3(a,b,c) { return (a ? !(!b) : c); }
disassemble,f3;
// func f3(a,b,c)
//    4 sp+>1    PushVariable(a)
//    6 sp->0    BranchFalse to pc= 13
//    8 sp+>1    PushVariable(b)
//   10 sp0>1    Not
//   11 sp0>1    Branch to pc= 15
//   13 sp+>1    PushVariable(c)
//   15 sp->0    Return
//   16 sp==0    Halt-Virtual-Machine

I think that the problem is due to some "optimlization" done by the parser. Indeed (a?...) yields a BranchFalse jump while (!a?...) drops the Not for operand a and yields a BranchTrue jump (see code for f4 below).
Until the bug is fixed, avoiding the bug is easy (but you have to be aware of it): replace any construct like
Code:
(a ? !b : c)
by
Code:
(!a ? c : !b)
For instance:
Code:
func f4(a,b,c) { return (!a ? c : !b); }
disassemble,f4;
//func f4(a,b,c)
//   4 sp+>1    PushVariable(a)
//   6 sp->0    BranchTrue to pc= 12
//   8 sp+>1    PushVariable(c)
//  10 sp0>1    Branch to pc= 15
//  12 sp+>1    PushVariable(b)
//  14 sp0>1    Not
//  15 sp->0    Return
//  16 sp==0    Halt-Virtual-Machine
is equivalent to what f1 was intended to do except that it compiles correctly in Yorick.


Mon Mar 05, 2012 12:40 am
Profile WWW
Yorick Master

Joined: Mon Nov 22, 2004 9:43 am
Posts: 354
Location: Livermore, CA, USA
Post Re: ternary operator drops not operator
Thanks, Eric.

This will be hard to fix, because I have to debug the byacc input, and merge its output parser tables back by hand. So you will need to rely on your workaround for quite some time.

Did you check if other unary operators are also broken (- or ~)? It's strange that only that one is wrong...


Tue Mar 13, 2012 6:47 pm
Profile
Yorick Guru

Joined: Wed Nov 24, 2004 12:51 pm
Posts: 97
Location: Observatoire de Lyon (France)
Post Re: ternary operator drops not operator
Hi Dave,

I've checked with ~ and -, they are corretly parsed.


Wed Mar 14, 2012 11:05 pm
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 3 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.