* POLLOG* macros use the new formatting
removed all old logging functions
* removed old fmt lib from everything except StreamWriter
removed unneeded functions
* fixed review comments
Also: OG compiler debug info for foreach iterator changed to match actual variable name
Adds:
- ast/DebugStatementMarker: for "intrusive debug" (ecompile -i) instructions
- codegen/DebugBlockGuard: pushes and pops debug block #
- format/DebugStoreSerializer: writes .dbg and .dbg.txt files
- representation/DebugBlock: holds parent block # and local variable names for each block
- representation/DebugStore: holds all debug information
Adds:
- ast/ElementAccess: AST node for x[a] or x[a,b,...] (may be get or set)
- ast/ElementAssignment: AST node for x[a] := b;
- ast/ElementIndexes: AST node to hold all indexes for element lookup
- optimizer/AssignmentOptimizer: optimizes := in different circumstances
Adds:
- ast/DictionaryEntry: AST node for a key -> value pair in a dictionary initializdr
- ast/DictionaryInitializer: AST node for creating a new dictionary
- ast/UninitializedValue: AST node for an uninit object
Adds:
- ast/CaseDispatchDefaultSelector: AST node for a "default:" selector
- ast/CaseDispatchGroup: AST node for a collection of selectors and the code to execute
- ast/CaseDispatchGroups: AST node holding all groups in a case statement
- ast/CaseDispatchSelectors: AST node holding all selectors for one group
- ast/CaseStatement: AST node for a whole case statement
- codegen/CaseDispatchGroupVisitor: knows what to put in a case jump dispatch table
- codegen/CaseJumpDataBlock: knows how to build the entries in the data block
Also, detect multiple case selectors with the same value (or default). This is different from the OG compiler, which only detected duplicate `default:` selectors.
Adds:
- ast/AssignVariableConsume: AST node for assignment to a variable, while consuming the result
- optimizer/ValueConsumerOptimizer: Optimizes expressions where the resulting value will be consumed
Adds:
- ast/UserFunction AST node for user-defined functions.
- astbuilder/AvailableUserFunction: reference to a parse tree for a user function.
- The AST builder only generates ASTs for user functions that are actually referenced.
- astbuilder/UserFunctionVisitor: visits (builds an AST for) a parse tree for a user function.
- This happens after the .src or .inc file has been otherwise processed, so this class serves to hook up the correct SourceFileIdentifier to the AST.
Add:
- ast/ExitStatement: AST node for the exit statement.
- ast/ReturnStatement: AST node for the return statement.
- only handles top-level returns and returns inside program declarations, which do the same thing: progend.
Adds:
- ast/Block: a block scope that allows declaring local variables
- ast/IfThenElseStatement: AST node for if..elseif..else..endif statements
- model/FlowControlLabel: provides an anchor for jumps or calls.
- Function calls, break statements, continue statements, and loops will all use these.
Adds:
- analyzer/LocalVariableScope: tracks local variables created within a given scope.
- Instantiated on the stack during semantic analysis, this registers itself with LocalVariableScopes during construction and deregisters itself during destruction.
- Detects unused variables during deregistration
- analyzer/LocalVariableScopes: this is what LocalVariableScope registers with.
- keeps track of the stack of local scopes.
- can provide the current local scope, for var statements.
Other notes:
"Shadowed" variables: this is when a variable in one scope hides a variable in another, like so:
var a := 2;
if (a)
var a := 3;
a := 4;
endif
print(a); // still 2
"debug_variables": We'll use these later when writing debug files.
Adds:
- UnaryOperator: AST node for unary operators -, ++, --, and so forth
- UnaryOperatorOptimizer: optimizes a unary operator with its operand
- now integer and float negation, and integer inversion
- later x[y]++ to a single instruction
Also:
- automatically include basic.em, which includes some parameter defaults like -1.
This allows the compiler to generate output for a hello, world script with the exact same .ecl output as the legacy compiler.
Adds support for var statements at the global level.
Adds:
- analyzer/Variables: keeps track of the variables in scope (either local or global).
- ast/Identifier: AST node for an identifier.
- The optimizer will replace constant identifiers with their constant value (in a later commit).
- The semantic analyzer will set the variable field for local or global variable identifiers.
- ast/VarStatement: AST node for a var statement.
- A single var statement will generate one VarStatement per variable declared.
- model/Variable: Describes a variable, including its index within its scope.
Adds:
- ast/Argument: AST node for an argument passed to a function.
- ast/FunctionCall: AST node for a function call.
- codegen/ModuleDeclarationRegistrar: The code generator registers module function declarations with this in order to determine module indexes and function indexes for instructions.
- model/FunctionLink: this is a reference either:
- from: a FunctionCall or a FunctionReference
- to: a ModuleFunctionDeclaration or a UserFunction
- optimizer/ReferencedFunctionGatherer: a visitor that determines which module functions and user functions are referenced, by looking at function calls and function references.
Also:
- CodeGenerator registers module functions
- InstructionGenerator generates code for function calls
- InstructionEmitter generates TOK_FUNC instructions
- StoredTokenDecoder decodes TOK_FUNC instructions
After all of this, the compiler can compile print("hello, world");
* Add codegen/InstructionEmitter
* Add codegen/InstructionGenerator
* CodeGenerator: emit progend
Checkpoint: compiler can compile an empty file
* Comment reason for having both emit and emitter.