SkyTemple / ExplorerScript

ExplorerScript and SSBScript: Script languages for decompiled SSB (Pokémon Mystery Dungeon Explorers of Sky)
MIT License
16 stars 6 forks source link

Const-evaluation expressions (%{}) #54

Open theCapypara opened 2 months ago

theCapypara commented 2 months ago

Summary

Add new syntax that can be used wherever a primitive (integer_like, string) is expected. This syntax allows evaluating a single compile-time expressions. In this proposal these statements can for now be logical or bitwise comparisons or arithmetic operations.

Motivation

This lays the foundation for compile time evaluation of code, opening many potential avenues when combined with macros and user-defined constants, as well as the possibility for compile-time if/switch/while statements (all explored in follow-up issues). Even just this proposal already allows for better readable code by replacing hardcoded values by logical building blocks (eg. when using parameters which require bitmasks, these bitmasks could now be set in these const-evaluation expressions).

Examples

def 0 {
   myOperation(1, %{ 4 * 2 }, %{ 100 > 0});
}

Using a const-evaluation expression as a parameter. This generates this operation as output: myOperation(1, 8, 1);.

const XYZ = %{100*ACTOR_ONE};

Using a const-evaluation expression to define a user-defined constant (#51). Assuming ACTOR_ONE is a system-defined constant (as described by #51), this sets XYZ to whatever 100 times the value of the system-defined constant is. Note that this requires the compiler to know the value of this system-defined constant, otherwise it would fail (see below).

Language Changes

Parser and Lexer Changes

These new expressions must be allowed whereever a integer_like or string is expected. The inner statement requires a new parser block which implements the operations described by this issue.

Behaviour

Const-evaluation expressions are evaluated whenever encountered. They are made up of expressions defined below ("Proposed expressions"). The parts of these expressions are themselves integer_like or string. This allows for nested const-evaluation blocks; the deepest expression is evaluated first. All expressions support this.

Const-evaluation expressions are also allowed for position_marker_arg. There they must produce an INTEGER or DECIMAL compatible output, otherwise the compiler must error.

Other than that the expressions may support only a subset of the remaining integer_like/strings. In particular all here proposed expressions only support values which can be converted to integers at compile time as follows:

In the future different expressions may support other types (eg. string concatenation).

With this change the compiler may optionally get a list of known system-defined constants and their values. This is ONLY used for evaluation in const-evaluation expressions to convert the constant into a primitive value. Anywhere else in the code, system-defined constants are not evaluated, as before.

Proposed expressions

All of these expressions and be combined (may require parenthesis). This must work as in all/most common programming languages in regards to which order are evaluated.

For all of these: Must execute the operation at compile time, where X or Y are any allowed value converted to an integer as described above or another expression.

Unary operations

not X: The return value is 1 if X <= 0 and 0 if X > 0. X: The return value is X.

Logical comparision

ie. X == Y, X > Y, X <= Y The return value is 1 if the condition is true and 0 if the condition is false.

Bitwise comparision and arithmetic

ie. X ^ Y, X << Y, etc.

Arithmetic operations

ie. X + Y, X - Y, etc.

Compiler Implementation

Compiler Interface Changes

The compiler interface will now allow to supply a dict of known system-defined constants and their values. These are only used when referenced in const-evaluation blocks. This means a system-defined constant does not have to be included in this dict to be used anywhere else in the code, system-defined constants are not evaluated, as before (see above).

Decompiler Changes

No changes.

How to teach

A new section in the manual is created. This section should contain all info about meta-programming in ExplorerScript. Documentation on macros should therefor also be moved there.

Alternatives

Other syntax is possible. There are a bunch of other possible approaches.

Backwards compatibility

This is fully backwards compatible.