DavidKinder / Inform6

The latest version of the Inform 6 compiler, used for generating interactive fiction games.
http://inform-fiction.org/
Other
199 stars 32 forks source link

Fix internal compiler errors on certain invalid expressions #252

Closed erkyrath closed 9 months ago

erkyrath commented 9 months ago

Fixes https://github.com/DavidKinder/Inform6/issues/248 .

Expressions like (a++ b), (a ~b), (a++ ~b), (a++ --b) were accepted by the expression parser but caused errors in the code generator. These manifested as compiler errors, such as:

*** Compiler error: SR error: emitter stack overfull

*** Compiler error: SR error: Attempt to remove a nonexistent bracket layer from the emitter stack

All these expressions are invalid. (With the possible exception of (a++ -b), which could be valid if the - were a binary operator, but Inform treats it as unary.)

To handle this, I expanded the prec_table[] in expressp.c to have separate rows and columns for prefix, binary, and postfix operators. (Previously it had just one row and column for all operators.) The bad cases now have the entry NOOP_E, which indicates an expression parsing error.

(NOOP_E is glossed as "missing operator" because the most likely cause is a missing binary operator. That is, you could make the above examples valid by adding a + sign: (a++ + b), (a + ~b), (a++ + ~b), (a++ + --b).)


Test cases: https://github.com/erkyrath/Inform6-Testing/blob/unaryop-err/src/unaryop_err_test.inf


Incidental changes:

I renamed the error constants e1, e2, etc to have more meaningful names. Same goes for the -1 table entry.

The prec_table[] is now 7x7, which makes it a bit too wide for the source's normal 80-character formatting. Sorry!

The compiler error "Missing operator: inserting '+'" now reads "Missing operator after ..."

The trace message "Adding bracket layer" now shows the depth argument.