|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Tue Mar 25, 2008 9:46 am
[2.20] Order dependent conditional evaluation error |
Code: |
#say Flag = '@flag( {writhe_try|writhing})' and Auto = '@auto( writhe)'
#if (@auto( writhe) and !@flag( {writhe_try|writhing})) {#say success1} {#say fail1}
#if (!@flag( {writhe_try|writhing}) and @auto( writhe)) {#say success2} {#say fail2}
#if ("1" and !0) {#say success3} {#say fail3}
#if (!0 and "1") {#say success4} {#say fail4}
#if (@auto( writhe)) {#say success5} {#say fail5}
#if (!@flag( {writhe_try|writhing})) {#say success6} {#say fail6}
|
Flag = '0' and Auto = '1'
fail1
success2
success3
success4
success5
success6
The first #if statement was failing and I couldn't figure out why, so I ended up reversing the order and it started working (see line 2). I couldn't figure that out either so I thought it must be because the auto function was returning a string and I plugged in what I thought it must be getting from the functions, again it evaluated successfully (lines 3 and 4). Lastly I tried them one at a time and they both pass one at a time. So I'm a little confused about what's going on here that causes it to fail only if I have both and in a particular order.
Code: |
Function auto:
#return %if( %iskey( @auto, %1), 1, 0)
Function flag:
#if (%numitems( %1) > 1) {
$present = 0
#forall %1 {#if (%iskey( @flags, %i)) {$present = 1}}
#return $present
} {#return %if( %iskey( @flags, %1), %db( @flags, %1), 0)}
|
|
|
|
|
Larkin Wizard
Joined: 25 Mar 2003 Posts: 1113 Location: USA
|
Posted: Tue Mar 25, 2008 11:39 am |
When you use %if and you have a space in front of the second or third argument, you will return a string. Remember? So, @flag("blah") would return an integer, but @flag({blah|bleh}) would return a string that looked like an integer with a leading space.
This bug looks like one that I reported and Zugg already added to the bug list, where #IF evaluates incorrectly with mixed types. |
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Tue Mar 25, 2008 1:37 pm |
The bug with mixed types was supposed to have been fixed:
Code: |
Fixed serious bug when using AND and OR operators to test different data types (mixed strings and numbers in IF statement) |
I'm aware of the typing issues which is why I created the subsequent lines to test what was happening. Subsequent lines substitute in what's being returned from the functions. One of them is returning an integer 0 which is negated, the other is returning a string "1" which should evaluate as true. So a true and true should evaluate to true. |
|
|
|
Larkin Wizard
Joined: 25 Mar 2003 Posts: 1113 Location: USA
|
Posted: Tue Mar 25, 2008 5:31 pm |
You are correct on the typing issue. I had read that on the version history but since forgotten.
I just tested this in my 2.20 and it worked for me. I got all successes. There must be something else to this that isn't evident just from what you've posted. Try it in a blank session, and see if it still happens? |
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Wed Mar 26, 2008 4:41 am |
I've done a lot more testing on this and have been able to reproduce it in a clean package. I've also ruled out the mixed types issue which we thought it was before. There is now just one function and it returns a 1. It should have nothing to do with integer vs string compares.
Here's a simplified version of the testing:
#if (@test1( ) and @test1({s})) {#say true1} {#say false1}
#if (@test1( ) and @test1({})) {#say true2} {#say false2}
#if (@test1( ) and @test1( )) {#say true3} {#say false3}
#if (@test1({s})) {#say true4} {#say false4}
#if (@test1( )) {#say true5} {#say false5}
<func name="test1" id="4226">
<value>#return 1</value>
</func>
Results:
false1 <= The case in error
true2 <= Suddenly is correct without the s in the brackets.
true3 <= Is correct without the {s} in the brackets.
true4 <= Second term evaluates to true on its own.
true5 <= First term evaluates to true on its own.
I have no idea why alone both of the items correctly evaluate to true but together they return a false. Also the passing of {s} to the function has something to do with it, because when it has been removed or changed slightly it is correct.
Cut and paste this:
Code: |
<class name="zTest" id="93">
<func name="fun1" id="94">
<value>#return 1</value>
</func>
<alias name="test" id="95">
<value>#if (@fun1( ) and @fun1( {a})) {#say true} {#say false}</value>
</alias>
</class>
|
|
|
|
|
Larkin Wizard
Joined: 25 Mar 2003 Posts: 1113 Location: USA
|
Posted: Wed Mar 26, 2008 11:36 am |
Hmm. I just tried your latest example, and it still returns all true for me. The fact that your ID values are 4226, 93, and 94 makes me wonder what else you did in your test session before this.
|
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Wed Mar 26, 2008 12:52 pm |
The id numbers came from the old session numbering. I copied the xml I posted in the code box above into a brand new session and it gave me the error.
Procedure:
- Load Cmud
- Press escape to dismiss the window and enter a blank session.
- Select this code and do a copy (ctrl-c)
Code: |
<class name="zTest" id="93">
<func name="fun1" id="94">
<value>#return 1</value>
</func>
<alias name="test" id="95">
<value>#if (@fun1( ) and @fun1( {a})) {#say true} {#say false}</value>
</alias>
</class> |
- Open the settings editor
- Right click on the top level item in the settings editor and choose paste
- Right click on the alias "test" and choose "execute".
- Verify that "false" has been printed out to your screen, indicating that the expression evaluated false incorrectly. It should have been true. |
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Thu Mar 27, 2008 1:42 am |
I have tried this again and again in a blank session and I it reproduces the false result every single time.
Larkin, did you deviate at all from the method I described in the previous post? Can anyone else try and verify this as well? |
|
|
|
Larkin Wizard
Joined: 25 Mar 2003 Posts: 1113 Location: USA
|
Posted: Thu Mar 27, 2008 2:25 am |
I'm sorry. I did deviate because I like to create new settings on the command line more than in the Package Editor, especially in trying to recreate faulty scenarios.
I tried it your way and I also see "false" outputted. It seems to only happen when the #IF is inside an alias that's inside of a class, from what I'm seeing. I made a second alias outside of the zTest class folder (under the untitled window) and that evaluates to true. Something strange is definitely happening, anyway, I agree now. |
|
|
|
JQuilici Adept
Joined: 21 Sep 2005 Posts: 250 Location: Austin, TX
|
Posted: Thu Mar 27, 2008 3:13 am |
I can also confirm that I see 'false' from your latest procedure.
|
|
_________________ Come visit Mozart Mud...and tell an imm that Aerith sent you! |
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Sat Mar 29, 2008 1:23 pm |
Tested and still present in version 2.21.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Sat Mar 29, 2008 5:43 pm |
Unless you see that the bug was specifically mentioned in the Version History, there is no need to bump a thread to say that the bug is still present. As I mentioned in the release notes, there are plenty of bugs that I did not fix in this version. Please only bump a post if the Version History claims that something is fixed and it is still broken.
|
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Tue Apr 01, 2008 3:58 am |
Was this able to be confirmed by you Zugg?
I seem to be particularly afflicted by this because of my widespread use of functions. I'm getting random misfires in my scripts every so often as seemingly random #if statements misfire. I'll debug the problems thinking I had my logic wrong and I'll find its this same obscure bug.
If it's already on your list then sorry for being a bother about this. I just want to avoid having this bug slip through the cracks. I realize you don't comment on all bug threads, but the fact that you do comment on various threads about them being added to your bug list, makes me wonder when I don't see that, whether it was overlooked. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Apr 01, 2008 5:05 pm |
Yep, this is on the bug list. It's a parser problem caused by the {a} for some reason.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Apr 01, 2008 8:25 pm |
Well, that was a very interesting bug. Very nasty. When you enter your original script, click the Compiled Code tab and you will see that instead of the "@fun1" function reference for the first function call, it shows "$1" for the name of the function.
If you remove the {} around "a" (so that you just have @fun1(a) in the second function) then click on Compiled Code, then you will see both @fun1 references correctly.
So, something about the {a} was causing the code to be corrupted. When I took a look at this, I found that when using {} the compiled wants to add a #VARTYPE String command to the code. This ensures that "a" is treated as an expandable string and not a literal. One of the steps in adding the #VARTYPE is to see if we are within something called a "PUSHLOC" block. A PUSHLOC is used to create a reference in the code that can be normally skipped (like an argument to a function) until it is needed. But there is another code block called the "PUSHSTRLOC" block, which is used for expandable string arguments.
So, the code for #VARTYPE tries to "backpatch" the code to change the PUSHLOC to a PUSHSTRLOC. However, in this case we are not within any PUSHLOC block. We are just within an expression. So the backpatch overwrites part of the code with a PUSHSTRLOC instruction, which ends up overwriting the name of the user function in the code.
All I needed to do was to check the code being back-patched and make sure it is a PUSHLOC before changing it to a PUSHSTRLOC. And that fixed the problem.
Yeah, I know, it's a very obscure bug that requires a lot of specific knowledge about exactly how the code generator works. But thanks for reporting it since having a backpatch corrupt the compiled code is very bad and might be causing other really obscure bugs in other scripts.
Fixed for 2.22. |
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Tue Apr 01, 2008 11:30 pm |
Zugg wrote: |
Yeah, I know, it's a very obscure bug that requires a lot of specific knowledge about exactly how the code generator works. But thanks for reporting it since having a backpatch corrupt the compiled code is very bad and might be causing other really obscure bugs in other scripts.
|
My pleasure, thanks for fixing it. |
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Sun Apr 06, 2008 7:59 am |
Confirmed fixed in 2.22. Thanks!
|
|
|
|
|
|