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).
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:
INTEGER -> Kept as is
DECIMAL -> Not supported, fails (could later be added potentially)
any variant of string -> Not supported
VARIABLE if macro variable: The value of the macro variable is used
VARIABLE if system-defined constant OR IDENTIFIER: If the value of the system-defined constant is known to the compiler (new addition, see below) and is an integer it is used, otherwise the compilation fails
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.
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
Using a const-evaluation expression as a parameter. This generates this operation as output:
myOperation(1, 8, 1);
.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 setsXYZ
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
orstring
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
orstring
. 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 anINTEGER
orDECIMAL
compatible output, otherwise the compiler must error.Other than that the expressions may support only a subset of the remaining
integer_like
/string
s. In particular all here proposed expressions only support values which can be converted to integers at compile time as follows:INTEGER
-> Kept as isDECIMAL
-> Not supported, fails (could later be added potentially)string
-> Not supportedVARIABLE
if macro variable: The value of the macro variable is usedVARIABLE
if system-defined constant ORIDENTIFIER
: If the value of the system-defined constant is known to the compiler (new addition, see below) and is an integer it is used, otherwise the compilation failsIn 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 is1
ifX <= 0
and0
ifX > 0
.X
: The return value isX
.Logical comparision
ie.
X == Y
,X > Y
,X <= Y
The return value is1
if the condition is true and0
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.