The bootstrap intermediate representation uses a tree-structured control flow representation, with instructions at the leaves accepting constants or variables as inputs and producing some number of variables as outputs. * Control flow nodes Node contains at least a link to its parent node, if any, and a link to its closure/method node. Basic block node - Contains a group of contiguous instructions. Also contains successor/predecessor edges or any other basic block info needed for compilation. Doesn't contain any child control flow nodes, just instructions. Sequence node - Executes child control flow nodes in sequence. Represent as either cons-cellish (current node, next node) structure or simply have it contain a list of nodes. This node might otherwise be replaced by including the "next node" link directly in all nodes themselves. Loop node - Repeatedly executes its child node endlessly. Needs to be combined with continuation and match nodes to terminate. Continuation node - Represents a continuation point in control flow. Executes its child node, and within that child node, a return-to-label node may be used to exit the particular label node and resume execution after it. Should note all returns targetting it. Return-to-label node - Return to an enclosing continuation node. Doesn't contain any child control flow nodes. This could also represented as an instruction, but for analysis purposes it might be more convenient to leave it as a control flow node. Only used within the same closure as the continuation is defined. Match node - Contains two alternative child control flow nodes. Compares a variable against a constant by identity. If the variable's value matches the constant, the first child node (success node) is executed, or otherwise the second child node (failure node) is executed. Closure node - Contains a list of all variables declared in this particular block of code. Contains a list of any relevant constants (either complex literal constants). Contains a list of all instructions instantiating the closure. Contains a list of all closures embedded within the closure. Contains a child node that is the body of the closure. Specific instructions are used to instantiate the closure and treat it as a value. ... * Operands Variable operand - Contains name of variable and closure it's declared in. Contains type of variable. Contains instruction defining the variable and the variable it is representative of (SSA). Notes whether its an input variable, output variable, or local variable. May also classify temporary variables generated by the compiler as different from local variables. Notes whether the variable is captured by a child closure (and thus a free variable). Possibly also contains any relevant type information. Constant operand - Contains value and type. Possibly allow for the value to be an operand by itself interpreted as the normal object type. Memory operand - Contains the address of the memory as a base/offset pair. Contains a collection of other memory locations this aliases with. Contains the type of the memory. ... * Instructions Instructions contain a link to their basic block. Should probably also contain their position within the basic block; the simplest methods are to use a doubly-linked list of instructions (previous/next links on the instructions themselves), or use an ordered collection of instructions in the basic block and note the current index on the instruction. Unless otherwise specified no instructions should operate upon free variables. Method invocation instruction - First input is a symbol naming the method to be invoked. The rest of the inputs are arguments to the method invocation. The outputs are variables that are set to the result values of the invocation. Closure instantiation instruction - The input is a closure to be instantiate. The output is a variable to be set to the resultant instantiated closure. Set variable instruction - The output is a variable to be set. The input is the value to store to the variable. This represents a simple register or stack variable movement. Load free variable instruction - The output is a non-free variable to to be set. The input is a free variable to load the value from. This represents a load from an environment record. Store free variable instruction - The output is a free variable in which to store a value. The input is a non-free variable or constant. This represents a store to an environment record. Merge variable instruction - The output is the variable to merge into. The inputs are variables to merge into a single definition. ... As a simple example, the block [| :x | ^ x] would be translated into the following: (closure (outputs o1) (inputs x) (label l1 (sequence (basic-block (set o1 x) ) (return-to-label l1) ) ) )