How the Compiler Works

Parent Previous Next

How the Compiler Works.

The compiler is responsible for:


SCRAMBLECODE is a type-strict programming language, and the compiler is very rigid about this. While the source code is being compiled, errors are registered in the Error Log with the file name and a line location. The most common errors are caught while syntax checking the source and are usually easily fixed by the programmer.


Once the source can complete a syntax check without any errors, the compiler can generate the bytecode. During compilation the meta data is eliminated - e.g. names for variables, classes, functions etc. do not exist in the bytecode.


The strictness of the SCRAMBLECODE language allows the VM DLL to execute the bytecode in a very secure manner, because the VM memory storage can be based on encrypted byte-arrays to store any kind of data variables in the exact same way - thus protecting the VM against run time information cracks.



Best Practice.

Beside the primary purpose of syntax checking and/or compiling your source into bytecode, the compiler is also involved in the presentation of symbols to be inserted into your source code while being edited, in which case it does a quick syntax check of the source to identify the relevant symbols to present.


This means that you will probably be using the compiler (at least the syntax checking) significantly more than you might expect, and in order to get the best user experience with the compiler, there are a few things to be aware of.


1. Use Matching Brackets.

Always be careful with the brackets and parentheses - having matching left and right brackets correct at all times. Especially the curly brackets must be correct, or you risk the compiler may report unexpected errors.


The explanation for this is, that the compiler process the source code in multiple steps, and one of these steps involve looking ahead for a matching bracket and then doing a kind of outside-in processing.


The upside of this approach is a quite fast handling of the code and the ability to report errors from multiple blocks of code - being able to exit from an erroneous code block and continue processing on the next.


The downside is that if the brackets are not correctly positioned (especially the curly brackets), the compiler might be trying to digest to much code and it may report an otherwise innocent text symbol as erroneous and unexpected.


Conclusion: If the compiler reports an error that seems strange, ALWAYS check your brackets first.


The IDE lets you check your brackets and parentheses quite easy. If you select one of these { [ ( left brackets as the only character selected, the IDE will look ahead and select the matching right bracket (if it is visible on screen), presenting both with a black background. The opposite is also possible when selecting a right bracket. It could look like this:


 Function Foo(Integer param1, param2)

 {

 }


TIP: It is advisable to use Code Snippets as much as possible, because these contain correctly "balanced" brackets and demonstrate how to structure the code and use the language.


2. Working inwards.

As previously mentioned the compiler processes each code block in an outside-in manner, which makes it possible to report the first error of a code block and then move out of this block and continue syntax checking on the next block at the same level. This procedure allows for reporting multiple errors.


However it also means that some errors further down at the same level or at an inner level may not be detected, as demonstrated here in this example:


 Function Foo()

 {

     Integer i, j, k, p;


     If i == 0 Then

     {

         i := 2.00;    //Error: i is not a real.   Error detected.

         j := "Hello"; //Error: j is not a string. Error not detected.

     }


     k := 0xFF;  //Error: k is not a byte.    Error detected.

     p := True;  //Error: p is not a boolean. Error not detected.

 }


This example contains two code blocks (the Foo-block and If-block). There are 4 errors, but only 2 errors (for i and k) are detected and reported by the compiler. The error for j is at the same level as i but is never detected, because the compiler moves out of the If-block once the first error in this block is detected. Similarly the error for p also goes undetected.


Conclusion: When an error is fixed, always be prepared for another error to appear within the same code block.


3. Finalize Statements Early.

When looking for a particular symbol - using the Select Symbol function of the Edit Menu - it can sometimes be advantageous to finalize a statement (writing the semicolon on the line even if you haven't finished it) before opening the list of symbols.


The reason being that in order to present the list of symbols, the compiler does a quick syntax check to search for symbols which include the current statement. If a semicolon is missing from the current statement, the compiler may report this as an error or erroneously include the next statement considering them as one. Such an error could leave the list of symbols incomplete.


Conclusion: If the list of symbols is incomplete, always consider ending your current statement with a semicolon before starting to investigate any reported errors.


TIP: Even if errors are reported by the compiler when presenting the symbols, the symbol you need may be present in the list and can be selected and used at once - not paying attention to errors which may eventually disappear in the editorial process.