ID:2070108
 
BYOND Version:510.1338
Operating System:Linux
Web Browser:Chrome 49.0.2623.87
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary: When using switch statements containing variable ranges, they mostly work, but are inconsistent and don't even always make sense!

Numbered Steps to Reproduce Problem:
1. Compile code below.
2. Run code below.
3. Observe output.

Code Snippet (if applicable) to Reproduce Problem:
/*
Where the expected result is the actual result, the statement which is (correctly) executed is marked with '<-'
Where the expected result is *not* the actual result, both expected and actual are labelled
*/

/world/New()
var/x = 75

var/low = 0
var/mid = 50
var/high = 100

// Statements in the form (CONST to VAR) do not match alone

world.log << "Separate:"
switch(x)
if(0 to high) world.log << "CV" // Expected
else world.log << "CV NO" // Actual
switch(x)
if(low to 100) world.log << "VC" // <-
else world.log << "VC NO"
switch(x)
if(low to high) world.log << "VV" // <-
else world.log << "VV NO"
switch(x)
if(0 to 100) world.log << "CC" // <-
else world.log << "CC NO"

// ...but they *do* if something else is with them. Any case in this switch, moved to the top, will correctly match.

world.log << "Mixed:"
switch(x)
if(0 to high) world.log << "CV" // <-
if(low to 100) world.log << "VC"
if(low to high) world.log << "VV"
if(0 to 100) world.log << "CC"
else world.log << "Else"

// Sometimes it's just clearly incorrect.

world.log << "Three-case:"
switch(x)
if(low to mid) world.log << "Low-mid" // Actual - this switch says x is between 0 and 50; since x=75, it is clearly not.
if(mid to high) world.log << "Mid-hi" // Expected
else world.log << "Else"

del(src)


Expected Results:

Separate:
CV
VC
VV
CC
Mixed:
CV
Three-case:
Mid-hi


Actual Results:

Separate:
CV NO
VC
VV
CC
Mixed:
CV
Three-case:
Low-mid


Does the problem occur:
Every time? Or how often? Every time.
In other games? Yes.
In other user accounts? Unknown.
On other computers? Yes.

When does the problem NOT occur? Unknown.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? Unknown. Occurs as described in 510.1338 and 509.1318.
Workarounds: None.

Since when do switch statements even allow non-constant expressions? I always remember that throwing an error before?

As an aside, somebody is working on something involving syllable structure.
Okay this just stopped making sense. Those four "Separate:" switches?

In the order they're in up there, CV VC VV CC, CV does not match and the others do.
In VV CV VC CC, neither VV or CV match.
In CC VV CV VC or VC VV CV CC, all four match.

Essentially, it seems VV and CV only match if they are preceded by a switch statement which matched???
In response to Popisfizzy
Popisfizzy wrote:
Since when do switch statements even allow non-constant expressions? I always remember that throwing an error before?

Perhaps it did, perhaps it didn't; I'd prefer it if this did work, but if that's not feasible for Lummox to implement, an obvious error message and a compile failure if you attempt to use non-constant expressions would be better than the current behaviour.
It seems to me this is just another branch of the bug in which values can be reused.
In response to Lummox JR
the bug in which values can be reused.

Do you mean my 'global' bug report, or am I thinking of the wrong bug?
Descriptive Problem Summary:
When using non-constant values as cases in ranges (e.g. `if (x to y)`), the compiler screws up. This sort of code would error with non-range cases, so I guess that is the expected behaviour?

Numbered Steps to Reproduce Problem:
Just run the code

Code Snippet (if applicable) to Reproduce Problem:
/proc/broken(target)
var/min = 11
var/max = 13
switch (target)
if(min to max)
return "in range"
return "out of range"

/proc/working(target)
switch (target)
if(11 to 13)
return "in range"
return "out of range"

/proc/test()
world.log << "broken()"
world.log << " 0) [broken(5)]"
world.log << " 1) [broken(11)]"
world.log << " 2) [broken(12)]"
world.log << " 3) [broken(13)]"
world.log << " 4) [broken(14)]"

world.log << "working()"
world.log << " 0) [working(5)]"
world.log << " 1) [working(11)]"
world.log << " 2) [working(12)]"
world.log << " 3) [working(13)]"
world.log << " 4) [working(14)]"


Expected Results:
error: min: expected a constant expression
error: max: expected a constant expression

OR

broken()
0) out of range
1) in range
2) in range
3) in range
4) out of range
working()
0) out of range
1) in range
2) in range
3) in range
4) out of range

Actual Results:
broken()
0) out of range
1) out of range
2) out of range
3) out of range
4) out of range
working()
0) out of range
1) in range
2) in range
3) in range
4) out of range

Does the problem occur:
Every time? Or how often?
Every time but by the nature of the bug the compiled output changes with every build (and sometimes manages to refer to valid values, such as typepaths.)

I tested with 513.1539, 513.1540, and 513.1541.

In response to Willox
I would call this a bug, but basically only that the compiler isn't throwing an error about the non-constant value in the switch.
In response to Willox
In response to GinjaNinja32
Thanks.