-
Notifications
You must be signed in to change notification settings - Fork 2
Construct Source To Source Compiler
Construct has its own compiler which transpiles Microsoft JScript code in to valid ES2015 code. Any time JScript is evaluated within Construct, CSTSC is called upon to perform transpilation, examples include:
- loading code in to the Construct VM,
- dynamically analysing code blocks during code execution either via
eval
or theFunction()
constructor.
The initial version of CSTSC has been designed specifically to handle a unique feature of the JScript language known as “Conditional Compilation”, or “CC” for short. Conditional Compilation is Microsoft’s own invention, providing a mechanism for script authors to test the current script host environment and evaluate code known to be compatible with the scripting runtime. For example:
/*@cc_on
WScript.Echo("CC enabled.");
/*@if (@_jscript_version >= 5)
WScript.Echo("JScript version is >= 5.");
@else @*/
WScript.Echo("CC is not supported.");
/*@end @*/
Here we see JScript CC code, identified by the use of special
mutli-line comment syntax (/*@ .. @*/
) and other statements
prepended with an @
symbol, such as @if
, @else
, @end
, etc.
When CSTSC scans this JScript code it attempts to convert it to valid
JavaScript, the output of which would look something like:
WScript.Echo("CC enabled.");
if (5 >= 5) {
WScript.Echo("JScript version is >= 5.");
} else {
WScript.Echo("CC is not supported.");
}
The following transforms have been applied:
- All CC comment blocks have been removed.
- All special JScript variables (those beginning
@...
) are converted to a literal value so as to avoid name collisions. - The
@if
statement has been converted to a standards compliant JavaScript (bracketed) if statement.
By default, Construct will always play the role of a CC-aware script host.
When a script host begins parsing a given JScript file, Conditional
Compilation is off by default. The most straightforward way to enable
CC is to use @cc_on
, however this isn’t the only way CC can be
enabled. The table below outlines the different techniques for
enabling CC. Any references to “CC literals” shall mean “CC
statements not enclosed between CC comments”.
Code | CC enabled? | Remarks |
---|---|---|
@cc_on |
YES | Enabled, CC literal. |
@if (true) ... |
YES | Enabled, CC literal (no @cc_on). |
@set @foo = 12 |
YES | Enabled, CC literal (no @cc_on). |
/*@cc_on ... |
YES | Enabled via CC comment. |
/*@if (true) ... |
NO | Not enabled, no preceding @cc_on . |
/*@set @x = ... |
NO | Not enabled, no preceding @cc_on . |
What this table shows is that CC code is evaluated without the need
for @cc_on
only when CC literals are used. Use of CC code between
CC comments requires that CC be enabled. Once a statement is
encountered which enables CC, CC is enabled for the remainder of the
file, best illustrated by the examples:
@if(true) // CC enabled because of @if CC literal.
WScript.Echo("Hello"); // PRINTS => "Hello"
@end
/*@if (true) // Eval'd because line #1 enabled CC
WScript.Echo("World!"); // PRINTS => "World!"
@end @*/
Enabling CC using a CC literal ~@if~
/*@if(true) // CC is not yet enabled.
WScript.Echo("Hello"); // Ignored.
@end @*/
@if (true) // CC enabled because of @if CC literal.
WScript.Echo("World!"); // PRINTS => "World!"
@end @
CC is NOT enabled for the first block.