Compiler analysis techniques

The CoolBasic Classic compiler has progressed again, and this time I’d like to share some interesting new features about its internal architecture. Using C# enables me to do certain things much more easily than the old procedural approach and the Object Oriented design really starts to kick in. The new compiler is highly structural, and it now records much more data about declared symbols, scopes, and execution paths. This also serves as a good foundation for some code analysis techniques. For example, the compiler will emit warnings for variables, types, and functions that are declared but never used, as well as if a variable is used before it has been initialized. Warnings like these will encourage the users to write better and cleaner code.

The original CoolBasic has almost no optimizations regarding the generated byte code. This is now different: Constant value analysis can ignore code branches (such as If/Else) if the condition can be evaluated to True or False at compile time. Thus, redundant code will not even make it to the final compiled program. Also, since we have constant value pre-evaluation, some expressions will be simplified before conversion to byte code. This ought to improve the runtime performance. In addition, thanks to internal scope-specific dictionaries, resolving branch targets does not produce linear search to all recorded labels (user-defined or generated). This should improve compile time performance greatly for large programs.

We’ll see how far we end up going with code analysis in the future… I’d love to collect data such as Cyclomatic Complexity or Number of Executable Statements in order to derive a general Maintainability Index out of the given source code.

Local scoping
All scopes now have their own list of local variables. This means that the user can declare variables in a code block such as If, For, or Case. These variables are allocated when the execution begins in that block and they will cease to exist after the execution exits the scope. Therefore, it is possible to declare several variables that have the same name as long as they aren’t conflicting in an enclosing block. Consider the following example:

Dim a As Integer

If a = 1 Then
    Dim b As Integer = 2
    // Variable 'b' is only visible within this If block.
	
    // You cannot declare variable 'a' here because it is already declared 
    // outside.
EndIf

If a = 1 Then
    Dim b As Integer = 3
    // Variable 'b' is visible within this If block and any child blocks.
    // Variable 'b' is different than the one declared in the previous 
    // If block.
	
    For i As Integer = 1 To 10
        // Variable 'i' is only visible within this For block.
		
        // Varible 'b' is also visible here since it was declared 
        // in an enclosing block.
        b = b + 1
    Next
EndIf

It is also possible to declare scope specific constants in the same way. Upon entering a scope the Runtime will ensure that all of its local variables are initialized with zero. Similarly, local arrays and strings can now be freed upon leaving the scope.

Short-circuit And/Or
We’ll also change the way how the Boolean And and Or operators work. They have become ‘short-circuit’, meaning that if the end result of the Boolean operation can be determined by just evaluating the first (left) operand, then the program will not evaluate the right half at all. Again this will improve runtime performance, but users need to pay close attention to their code if the right side has any function calls that need to be executed regardless of the end result of the Boolean operation. This is easily fixed, though, by storing the right side expression into a temporary variable first.

Comments are closed.

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress