ENIGMA's compiler takes EDL and compiles it to
C++.
Before the process begins, the compiler is already aware of the target
platform, the necessary make calls, and the variables, functions, and
other important definitions from the C++ engine. The process begins with
this information tucked away in global memory.
First and foremost, the compiler tosses around resource names and makes
declarations for them, adding them to a new virtual namespace allocated
for this compile. This includes minor code
generation for instances. From there, it
begins lexing all the code and does some parse operations such as adding
semicolons (see page on Parser for details on lexer
and preliminary parsing), and then takes note of all the types that are
declared locally in each object and script. At this point, the compiler
has a structure for each event in each object and for each script,
containing the code, the lex string, and a list of the variables it
declares for each scope: globally, instance-locally, and via
dot-access.
From there, it looks at which objects make what calls to what scripts,
and which scripts call what scripts, in a complex resolution pass that
results in a list of every script that could possibly be invoked by an
object. Using that resolved list, the compiler scopes the scripts into
the appropriate objects and then starts at the bottom and works its way
up, gathering variables used by any script or event. The results of this
pass are a comprehensive list of both scripts invoked by and variables
used in each object.
Using the list of used variables and scripts for each object, the
compiler can make choices on where to scope scripts and objects, be it
solely at the global scope (using with() where
necessary), at the parent-object scope (where all objects will inherit
it), or at the individual object scope.
From there, the compiler conducts a second pass, using its newly
gathered information to resolve access routines
and other heavily context-dependent mechanisms of EDL, many of which
involve heavy code generation. Dot-based
access of form a.b, where '' 'a' '' is an integer, resolves to
either enigma::glaccess(a)->b in the case of shared or "global"
locals, or enigma::varaccess_b(a) for strict locals. It is up to the
compiler to generate these functions.
static`` ``someTypedummy_someType;After that, the hard work is basically done on ENIGMA's part; it uses
the lex buffer to dump the code buffer into the specific files under
ENIGMAsystem/SHELL/Preprocessor_Environment_Editable/
so it looks nice, meanwhile adding the strings and other collapsed
sections back in. At this point, it is compiled to C++, and it is just a
matter of invoking the GCC on the produced code. Native compiler
invocation is done through Make; when that process
finishes, the game is officially natively compiled.
From there, the compiler simply tacs resource data onto the end of the
executable, or where requested by
Compilers/*/compiler.ey.
If requested, the compiler will then invoke the game.
Getting GML to bode well with a C++ compiler is obviously impossible
without generating some additional code to be compiled with the game.
The code often fills large gaps in the ENIGMA
engine. Among the various code pieces
generated to get a variety of games to compile are the following:
new statement.object.local_variable.const if and only if all of the case label types are constant.switch() must be replaced withif()s.To allow compilation of games for all platforms, and to allow
cross-compilation, a system needed
incorporated for compiler management. Though the
About.ey files allow for some specification of
system dependencies, compilers need to be delimited in a manner in which
they can be looked up by the name of one of the three operating systems
on which the IDE can run. In other words, a directory called
Compilers/ must be kept containing a folder for
each of Windows, Linux, and MacOSX. In each of those child folders, an
eYAML file must be kept specifying fundamental
information needed to call the toolchain
executables.
Wiki: About.ey
Wiki: Accessor
Wiki: C++
Wiki: Code::Blocks
Wiki: Collision_Systems
Wiki: Compile
Wiki: Dot_access
Wiki: EDL
Wiki: ENIGMA_Compiler
Wiki: ENIGMA_engine
Wiki: Events.res
Wiki: Make
Wiki: MinGW
Wiki: Parser