UnderminersTeam / UndertaleModTool

The most complete tool for modding, decompiling and unpacking Undertale (and other GameMaker games!)
GNU General Public License v3.0
1.19k stars 233 forks source link

Decompiler removes parentheses from math equations when adjacent operations are from the same "level" of order #1833

Closed Jesright73 closed 4 months ago

Jesright73 commented 4 months ago

Describe the bug

When writing math equations, parentheses are used to "override" the order of operations. This is very important when subtracting and dividing, as changing the order (by removal of parentheses) will result in a difference value. The decompiler removes some of these parentheses when variables are present, resulting in undesired values during runtime.

Unsure of how GML handles Order of Operations (Is addition is prioritized before subtraction, or calculated in sequential order?), i ran the following test:

    a = 5
    b = 3
    c = 2
    d = b + c
    debug_draw_var("a - (b + c) = ", (a - d))
    debug_draw_var("a - b + c = ", (a - b + c)) 

Here is the result of these equations drawn in-game: image As shown here, addition and subtraction are performed in sequential order (as it should be).

Here are some examples of how the Bleeding Edge decompiler currently handles parentheses in math equations. Before decompiler:

z = (a - b) + c
z = a - (b + c)
z = a * (b / c)
z = (a * b) / c
z = a + (b - c) * (d / e)
z = (a + b) - (c * d) / e
z = (a + b - c) * (d / e)
z = (a + b) - (c * d / e)
debug_draw_var("5 - 3 + 2 = ", (5 - 3 + 2))
debug_draw_var("5 - (3 + 2) = ", (5 - (3 + 2)))

After decompiler:

z = a - b + c
z = a - b + c
z = a * b / c
z = a * b / c
z = a + (b - c) * d / e
z = a + b - c * d / e
z = (a + b - c) * d / e
z = a + b - c * d / e
debug_draw_var("5 - 3 + 2 = ", 4)
debug_draw_var("5 - (3 + 2) = ", 0)

As can be seen in the debug_draw_var functions, the decompiler respects the parentheses when only real numbers are used, during simplification of the code. It is only when variables are introduced that the parentheses are removed.

Reproducing steps

  1. In the Decompiled code editor, write an equation containing math operators of the same "tier", at least one variable, and parentheses encapsulating a latter section of the equation. e.g. x = a - (b + c)
  2. Apply the change. Notice the resulting code now lacks parentheses.
  3. Run the game, and see that the desired outcome is not achieved when the equation is calculated.

Setup Details

UndertaleModTool version: Bleeding Edge (most recent commit as of this posting: https://github.com/UnderminersTeam/UndertaleModTool/commit/c8e1b9babec8c3130e8211f0190b8e2a9c04de4a) OS: Windows 10 22H2 Game: AM2R, but occurs with any, including new projects

Jacky720 commented 4 months ago

It seems like we've fumbled the detection for non-commutative operators from the last time we did this (Decompiler.ExpressionTwo.cs#L81). I should point out that in your overall examples, only line 2 is mathematically incorrect, although the decompiler should still be picking up on the right-hand side parentheses as compiled in several of the other cases. I'll get on a fix.