Legend:
Library
Module
Module type
Parameter
Class
Class type
The A-normal form (ANF) grammar
The first step in compiling Sail into Jib IR is converting the Sail expression grammar into A-normal form (ANF). Essentially this converts expressions such as f(g(x), h(y)) into something like:
let v0 = g(x) in let v1 = h(x) in f(v0, v1)
Essentially the arguments to every function must be trivial, and complex expressions must be let bound to new variables, or used in a block, assignment, or control flow statement (if, for, and while/until loops). The aexp datatype represents these expressions, while aval represents the trivial values.
The convention is that the type of an aexp is given by last argument to a constructor. It is omitted where it is obvious - for example all for loops have unit as their type. If some constituent part of the aexp has an annotation, the it refers to the previous argument, so in
AE_let (id, typ1, _, body, typ2)
typ1 is the type of the bound identifer, whereas typ2 is the type of the whole let expression (and therefore also the body). The type is represented as a generic parameter 'a, so we can represent both typed and untyped ANF expressions.
See Flanagan et al's The Essence of Compiling with Continuations.
Each ANF expression has an annotation which contains the location of the original Sail expression, it's typing environment, and the uannot type containing any attributes attached to the original expression.
We allow ANF->ANF optimization to insert fragments of Jib IR directly in the ANF grammar via AV_cval. Such fragments must be side-effect free expressions.
This function 'folds' an aexp applying the provided function to all leaf subexpressions, then applying the function to their containing expression, and so on recursively in a bottom-up order.