In this case only the else-branch is evaluated at compile time, only its operations are generated. No Branch opcodes or jumps are actually generated. This means this will be roughly equivalent to this SsbScript:
def 0 {
thisWillHappen();
}
def 0 {
switch (${3}) {
case 1:
foobar();
break;
case 3:
// OPERATIONS STARTING HERE ARE ACTUALLY GENERATED
baz();
case 5:
foo();
// END
case ${4}:
break;
case ${41 * 5}:
break;
}
}
A const-evaluated switch. Only the code for the second case is generated and for the third via fall-through (no break in the second case). Note that it does not matter if const-evaluation expressions is used in case blocks, this is not affected by this change at all and as is processed as normal in #54. However only simple case blocks are allowed, which means more complicated expressions do require const-evaluation expressions. This means this will be roughly equivalent to this SsbScript:
def 0 {
baz();
foo();
}
Language Changes
Parser and Lexer Changes
No expected changes required.
Behaviour
When an if/switch header consists of a single const-evaluation expression these constructs must be evaluated completely different to their usual behaviour.
If / Elseif / Else
The expression in the header of the if's and elseif's are evaluated as would be the runtime-if blocks, however they values are evaluated at runtime. If the value in the header is an integer and >= 0 the condition passes. If it is not an integer this is a compile time error. Once a condition has passed, it's branch block is emitted, the other branch blocks are not emitted.
Switch
The value of the switch header is evaluated at compile-time. This switch only allows simple cases. The exact value of each case is checked against the value in the switch header. The first matching value causes the operations in the case to be taken until a break; or the end of the switch block is hit. No other cases are evaluated or operations are emitted (note however that fall-through is possible if no break; exists before another case is encountered. The cases are ignored in this case, as would be for the runtime-switches.
Loops (while/for)
Note that loops are omitted from this. They continue to function as before. There is no sense in allowing this sort of expression for loops, as it is not possible to assign macro variables at compile time. However compile time loops can be achieved using recursive macro calls.
Compiler Implementation
Compiler Interface Changes
No changes.
Decompiler Changes
No changes.
How to teach
Add this to the section on meta-programming introduced in #54.
Alternatives
Don't allow this
Use special syntax instead of "hijacking" existing if/switch.
Use a different scope for const if/switch.
Backwards compatibility
This is backwards incompatible as it changes the semantics of how the const-evaluation expression is interpreted inside of a if/switch. This feature should be shipped at the same time as #54. However this is fine, even if this feature is shipped later, as such a syntax would be unusual anyway (since it can just be replaced by omitting the const-evaluation block and directly using the value in most cases. In other cases it can be replaced via indirection with a macro call).
Summary
Add special support for const-evaluation in the headers of if/switch.
Dependencies
This needs the following features to be implemented first:
54
Motivation
This allows compile time logical evaluation, adding powerful meta-programming functionality to ExplorerScript.
Examples
In this case only the else-branch is evaluated at compile time, only its operations are generated. No
Branch
opcodes or jumps are actually generated. This means this will be roughly equivalent to this SsbScript:A const-evaluated switch. Only the code for the second case is generated and for the third via fall-through (no break in the second case). Note that it does not matter if const-evaluation expressions is used in case blocks, this is not affected by this change at all and as is processed as normal in #54. However only simple case blocks are allowed, which means more complicated expressions do require const-evaluation expressions. This means this will be roughly equivalent to this SsbScript:
Language Changes
Parser and Lexer Changes
No expected changes required.
Behaviour
When an if/switch header consists of a single const-evaluation expression these constructs must be evaluated completely different to their usual behaviour.
If / Elseif / Else
The expression in the header of the if's and elseif's are evaluated as would be the runtime-if blocks, however they values are evaluated at runtime. If the value in the header is an integer and
>= 0
the condition passes. If it is not an integer this is a compile time error. Once a condition has passed, it's branch block is emitted, the other branch blocks are not emitted.Switch
The value of the switch header is evaluated at compile-time. This switch only allows simple cases. The exact value of each case is checked against the value in the switch header. The first matching value causes the operations in the case to be taken until a
break;
or the end of the switch block is hit. No other cases are evaluated or operations are emitted (note however that fall-through is possible if nobreak;
exists before anothercase
is encountered. Thecase
s are ignored in this case, as would be for the runtime-switches.Loops (while/for)
Note that loops are omitted from this. They continue to function as before. There is no sense in allowing this sort of expression for loops, as it is not possible to assign macro variables at compile time. However compile time loops can be achieved using recursive macro calls.
Compiler Implementation
Compiler Interface Changes
No changes.
Decompiler Changes
No changes.
How to teach
Add this to the section on meta-programming introduced in #54.
Alternatives
Backwards compatibility
This is backwards incompatible as it changes the semantics of how the const-evaluation expression is interpreted inside of a if/switch. This feature should be shipped at the same time as #54. However this is fine, even if this feature is shipped later, as such a syntax would be unusual anyway (since it can just be replaced by omitting the const-evaluation block and directly using the value in most cases. In other cases it can be replaced via indirection with a macro call).