Compiler Step 5b: Restructuring


Step 5b restructures the form of the code, so as to remove from expressions all control constructs and all forms that might cause side-effects. This restructuring is done for two reasons: to simplify the code that detects and handles missing inputs to expressions (first step in 6a) and to ensure that the compiler's output satisfies the constraint in C that while statements cannot occur inside expressions.

The substeps in 5b are:

Rules in 5b neither require nor reliably preserve type markings.

Rewrite if clauses

Forms headed by binary-if are rewritten so that they never return values to the caller. That is, an expression of the form (binary-if test expr1 expr2) is rewritten as:

This rewriting is only done if the binary-if form returns a value and this value is actually used by some enclosing form.

After the subform is rewritten, it is run through percolation before recursively examining its sub-expressions for value-returning binary-if forms. This call, and the call to percolation at the start of step 5b, are done because percolation tends to reduce the number of value-returning binary-if forms by removing those inside set-type forms, and the rewriting introduces new set! forms.

After this process is finished, all control constructs and side-effect-laden forms inside expressions must be non-final inputs to a begin form. This makes them (relatively speaking) easy to remove.

Remove begin forms from expressions

This step removes from expressions all non-final items in begin forms, placing them immediately before the expression. The trick in doing this is to keep track of which variables have been side-effected by these forms. Final forms must also be removed, and replaced by temporary variables, if they use variables whose value may have been altered by non-final forms later in the expression.

This code walks through the inputs to each expression backwards, keeping an assoc list of which variables have been side-effected. If such a variable is subsequently (i.e. earlier in the code) used by an expression, a temporary variable is allocated and stored in the assoc list entry. This prevents allocation of multiple temporaries to protect the same value. A new entry, without temporary, is pushed onto the assoc list if the variable is subsequently modified.

Forms headed by sample-set! and sample-erase! side-effect values in sheets. It would be difficult to keep track of which locations have been modified. It would be difficult to track down which sheet has been modified, because a given variable may point to more than one sheet during execution. Worse, it is not possible at compile-time to determine what sheet is pointed to by an input sample, and whether this sheet is identical some other sheet used by the program.

Therefore, the compiler treats all sheets as indistinguishable. When any sheet has been modified, an entry for "sheets" is pushed onto the assoc list. If any forms headed integer-sheet-ref real-sheet-ref are subsequently encountered in the code, a temporary variable is allocated and they are removed.


Ownership, Maintenance and Disclaimers

Manual Top Page

Last modified