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
1. Optimize if statements (parity with OG compiler):
- discard empty 'alternative' blocks
- optimize to the consequent if the predicate is a nonzero integer
- optimize to the alternative, or an empty block if there is none, if the predicate is a zero integer.
2. In comparison mode, emit module functions in the same order as the OG compiler.
This is because the OG compiler can emit declarations for module functions that it doesn't actually call, and in a different order than calls to actual module functions.
Adds:
- optimizer/BinaryOperatorOptimizer: optimizes expressions with a binary operator
- assignments will be handled by optimizer/AssignmentOptimizer
- optimizer/BinaryOperatorWithFloatOptimizer: optimizes binary operator expressions with a FloatValue left-hand side
- optimizer/BinaryOperatorWithIntegerOptimizer: optimizes binary operator expressions with an IntegerValue left-hand side
- optimizer/BinaryOperatorWithStringOptimizer: optimizes binary operator expressions with a StringValue left-hand side
Adds:
- analyzer/Constants: holds constant name -> value for lookup
- ast/ConstDeclaration: AST node for a const declaration
- optimizer/ConstValidator: validates that an optimized expression is valid to use as a constant.
the Optimizer converts Identifiers that refer to a constant to the optimized constant value.
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:
- 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");