mojo icon indicating copy to clipboard operation
mojo copied to clipboard

[BUG] Nested Ternary logic does not behave as expected

Open martinvuyk opened this issue 10 months ago • 1 comments

Bug description

I was trying to do some manual UTF-8 parsing and didn't like the amount of lines that all the if elifs took, and when executing couldn't understand why it didn't parse anything.

alias num0: Int8 = String("0").as_bytes()[0]
alias num1: Int8 = String("1").as_bytes()[0]
alias num2: Int8 = String("2").as_bytes()[0]
alias num3: Int8 = String("3").as_bytes()[0]
alias num4: Int8 = String("4").as_bytes()[0]
alias num5: Int8 = String("5").as_bytes()[0]
alias num6: Int8 = String("6").as_bytes()[0]
alias num7: Int8 = String("7").as_bytes()[0]
alias num8: Int8 = String("8").as_bytes()[0]
alias num9: Int8 = String("9").as_bytes()[0]
alias nan8: Int8 = 99
alias nan16: Int16 = 999


fn match_num(number: Int8) -> Int16:
    var found = nan16
    if number == num1:
        found = 1
    elif number == num2:
        found = 2
    elif number == num3:
        found = 3
    elif number == num4:
        found = 4
    elif number == num5:
        found = 5
    elif number == num6:
        found = 6
    elif number == num7:
        found = 7
    elif number == num8:
        found = 8
    elif number == num9:
        found = 9
    elif number == num0:
        found = 0
    var found_method_2 = (
        1 if number
        == num1 else 2 if number
        == num2 else 3 if number
        == num3 else 4 if number
        == num4 else 5 if number
        == num5 else 6 if number
        == num6 else 7 if number
        == num7 else 8 if number
        == num8 else 9 if number
        == num9 else 0 if number
        == num0 else nan16
    )
    print("compared: " + String(number.to_int()) + " and found: ")
    print("normal if elif: " + String(found.to_int()))
    print("nested ternary if else if: " + String(found_method_2.to_int()))
    return found


fn main():
    _ = match_num(47)
    _ = match_num(48)
    _ = match_num(49)
    _ = match_num(50)

Output:

compared: 47 and found: normal if elif: 99 nested ternary if else if: 99 compared: 48 and found: normal if elif: 0 nested ternary if else if: 0 compared: 49 and found: normal if elif: 1 nested ternary if else if: 99 compared: 50 and found: normal if elif: 2 nested ternary if else if: 99

Steps to reproduce

  • drop code into mojo and run it

System information

- What OS did you do install Mojo on ?

Ubuntu 22.04.4 LTS

- Provide version information for Mojo by pasting the output of `mojo -v`

mojo 24.2.1 (2f0dcf11)

- Provide Modular CLI version by pasting the output of `modular -v`

modular 0.7.1 (28ddab26)

martinvuyk avatar Apr 20 '24 20:04 martinvuyk

It's a problem with operator precedence, smaller repro:

fn main():
    alias n = 0

    var ref = 0 if n == 0 else 1 if n == 1 else 2

    var a = 0 if n == 0 else (1 if n == 1 else 2)  # should be this
    var b = (0 if n == 0 else 1) if n == 1 else 2  # current behaviour

    print(ref, a, b)  # 2 0 2

soraros avatar Apr 20 '24 21:04 soraros

You are correct. We're getting operator precedence wrong here. Thanks for narrowing this down!!

Mogball avatar Jun 27 '24 19:06 Mogball