Euphoria
Ticket #694:
if statement / namespace / sequence weird bug
-
Reported by
AndySerpa
Jul 21, 2011
Don't know what to call this one, but it is a bit strange.
Ok, so the following program will crash with an "true/false condition needs to be an atom" error, which it shouldn't because the "sum()" expression is an atom.
include std/math.e
object x
x = {0,1,2,3,4}
if sum(x < 1 or x > 3) then
? 1
else
? 0
end if
The weird thing about it is that it will work if you add a namespace qualifier to the sum function, i.e. math:sum
It also works if you define the sum function locally, or assign the sum to a variable and use that in the if statement instead, or simplify the expression being summed "(x < 1)" by itself works ok, it is only with and or'd or and'd expression that it fails.
Details
1. Comment by Insolor
Jul 21, 2011
Interesting, the following code works as expected:
function sum(sequence s)
atom sum
sum = 0
for i = 1 to length(s) do
sum += s[i]
end for
return sum
end function
object x
x = {0,1,2,3,4}
if sum(x < 1 or x > 3) then ? 1 else ? 0 end if
Output:
1
2. Comment by mattlewis
Jul 21, 2011
When you don't use a namespace, the parser defers fully resolving the symbol from another file until it can prove which symbol you're really asking for. You could be referring to a function later in the same file, or there could be multiple sum functions defined in various include files. That appears to be the source of this.
It appears that the short circuit operation is kicking in on the or operator, which is obviously incorrect. Here is the output of eudis for the code above:
13: 109 1000 # GLOBAL_INIT_CHECK: [x:1000]
15: 001 1000 1006 1007 # LESS: [x:1000], [LIT 1:1006] => [_temp_:1007]
19: 143 1007 1008 32 # SC1_OR: [_temp_:1007], [_temp_:1008], 0032
23: 109 1000 # GLOBAL_INIT_CHECK: [x:1000]
25: 006 1000 1001 1009 # GREATER: [x:1000], [LIT 3:1001] => [_temp_:1009]
29: 144 1009 1008 # SC2_OR: [_temp_:1009], [_temp_:1008]
32: 027 775 1008 1010 # FUNC: [sum:775][_temp_:1008] => [_temp_:1010]
36: 208 1007 # DEREF_TEMP: [_temp_:1007]
38: 208 1009 # DEREF_TEMP: [_temp_:1009]
40: 020 1010 48 # IF: [_temp_:1010] = 0 goto 0048
When using a namespace (or a function already defined in the same file):
54: 109 1000 # GLOBAL_INIT_CHECK: [x:1000]
56: 001 1000 1006 1012 # LESS: [x:1000], [LIT 1:1006] => [_temp_:1012]
60: 109 1000 # GLOBAL_INIT_CHECK: [x:1000]
62: 006 1000 1001 1013 # GREATER: [x:1000], [LIT 3:1001] => [_temp_:1013]
66: 009 1012 1013 1014 # OR: [_temp_:1012], [_temp_:1013] => [_temp_:1014]
70: 027 775 1014 1015 # FUNC: [sum:775][_temp_:1014] => [_temp_:1015]
74: 208 1012 # DEREF_TEMP: [_temp_:1012]
76: 208 1013 # DEREF_TEMP: [_temp_:1013]
78: 208 1014 # DEREF_TEMP: [_temp_:1014]
80: 020 1015 88 # IF: [_temp_:1015] = 0 goto 0088
3. Comment by AndySerpa
Jul 21, 2011
Hmmm...this may be related to another problem I've been tracking but haven't nailed down. (Memory leak with certain convoluted function calls via routine_id.) More tests...
4. Comment by mattlewis
Jul 21, 2011
I don't think this would cause a memory leak.
5. Comment by AndySerpa
Jul 21, 2011
Probably not, but this short-circuiting when it is not supposed to may be causing another weird problem I've been trying to figure out the leak I've been trying to find may be caused by code not being executed the way it is supposed to be. In any case, I'm on the trail of another bug that may or may not be connected. I will make a ticket for it when I can isolate it.
6. Comment by DerekParnell
Jul 21, 2011
What happens when you put parenthesis around the expressions? ...
include std/math.e
object x
x = {0,1,2,3,4}
if sum( (x < 1) or (x > 3)) then
? 1
else
? 0
end if
7. Comment by mattlewis
Jul 22, 2011
Parentheses result in the same incorrect behavior, whether around the individual comparisons or the or'ed combination of them. Either way, the short circuiting is kicking in.
8. Comment by mattlewis
Jul 24, 2011
See: hg:euphoria/rev/bc676d688d48
changeset: 5074:bc676d688d48 branch: 4.0 parent: 5071:736263b340b0 user: Matt Lewis date: Sun Jul 24 11:20:15 2011 -0400 files: tests/t_fwd.e description:
9. Comment by mattlewis
Jul 24, 2011
See: hg:euphoria/rev/2bdff9a70e17
changeset: 5075:2bdff9a70e17 branch: 4.0 user: Matt Lewis date: Sun Jul 24 11:28:34 2011 -0400 files: source/parser.e description:
- prevent short circuiting in forward calls
- fixes ticket 694
10. Comment by mattlewis
Jul 24, 2011
See: hg:euphoria/rev/856f9971b80b
changeset: 5076:856f9971b80b branch: 4.0 user: Matt Lewis date: Sun Jul 24 11:29:56 2011 -0400 files: docs/release/4.0.4.txt description:
- release notes for ticket 694
11. Comment by mattlewis
Jul 24, 2011
See: hg:euphoria/rev/79567d7709b9
changeset: 5077:79567d7709b9 parent: 5072:ae9647052d94 parent: 5076:856f9971b80b user: Matt Lewis date: Sun Jul 24 11:35:09 2011 -0400 files: source/parser.e tests/t_fwd.e description:
- merge fix for ticket 694 into the trunk
12. Comment by mattlewis
Jul 24, 2011
See: hg:euphoria/rev/5f4bb227afb5
changeset: 5078:5f4bb227afb5 branch: struct tag: tip parent: 5073:182e436a55cd parent: 5077:79567d7709b9 user: Matt Lewis date: Sun Jul 24 11:46:31 2011 -0400 files: source/parser.e description:
- merge ticket 694 into struct branch