adapap / OWScript

Python-like scripting language which transpiles into Overwatch Workshop script rulesets.
MIT License
37 stars 2 forks source link

Wrong evaluation of binary operators #29

Closed netux closed 4 years ago

netux commented 5 years ago

Binary operators are evaluated in the order they are found, and not following the usual order (logical first, then arithmetic). This makes chaining conditions impossible without using parentheses.

Example

const y = 5
const z = 7

Rule "Order of operators is important"
    Event
        On Global

    Conditions
        y == 5 or z > 7

outputs

rule("Order of operators is important") {
    Event {
        Ongoing - Global;
    }
    Conditions {
        Compare(5, ==, Or(5, Compare(7, >, 7))) == True;
    }
}

Side note

I couldn't use a variable called solely x because it was giving me a syntax error. Seems like "x" is marked as a reserved word, and even the VSCode extension marks it that way. Is that intentional?

adapap commented 5 years ago

Regarding X, it is the game's reserved name for the icon that looks like a cross. I will probably keep it this way for consistency.

adapap commented 5 years ago

Looking into this made me remember why this occurs. If you take your example and replace the expression with y + 5 or z - 7, you'll see that it is correctly parsed, with the addition and subtraction taking their respective precedence around the logical or. The reason why it fails with comparisons (==, <, !=) is because of the hack I did to support them over multiple lines.

I want to be able to support some form of the following:

Distance Between
    Event Player
    <1, 2, 3>
<= 1.5

The issue in the past was that either:

So in order to support writing that expression as above, I had to use a hack for comparison expressions which is why your example fails. In order to fix this, there would have to be an alternative way to represent the above in an intuitive way.

Source for comparison expressions

MatthewSH commented 5 years ago

Why not just wrap the entire thing in some form of character to inform the compiler to parse it together? Like wrapping the entire thing in parenthesis (before distance and after 1.5) to tell it to basically minify that section of code and parse it as one.