Step 5a does type inference and various rewriting rules dependent on it. The substeps are

- fill in type information for input and output variables
- type inference
- coerce outputs to the declared type of output variables and wrap the code in a return form if it returns values
- in-line scanner substitution (recursively calls type inference)
- real contagion
- expand guaranteed-divide (recursively calls type inference)
- give distinctive names to 2D and 3D vector operations

Rules that require type information are collected into two parts of the compiler: step 5a, and steps 6b through 8/8'. The intervening steps (5b and 6a) and the earlier and later steps (1-4 and 9/9') do not require type markings. This organization means that these other steps (and also the last step in 5a) need not attempt to preserve type markings. The markings are gradually eroded away by rewrite rules and restored again near the start of 5b.

Forms headed by guaranteed-divide and make-into-integer are produced when step4 expands sheet-ref and sheet-set! forms. They are used to compute integer locations for referencing into storage arrays.

A form (guaranteed-divide expr1 expr2) is expanded as guaranteed-/ or guaranteed-quotient, depending on whether the inputs are real or integer. The forms guaranteed-quotient and guaranteed-/ inform later stages of the compiler (notably C code generation) that the second input can never be zero, so these forms always produce a numerical value. Guaranteed-/ eventually turns into a regular division. Guaranteed-quotient eventually expands into modular arithmetic with an error if the division isn't even.

A form (make-into-integer foo) is translated into foo if foo is integer, but (inexact->exact (round foo)) if foo is real.

Arithmetic operations acting on 2D and 3D vector inputs are given distinct names. This allows them to be expanded in step 6a without having to ensure that all forms have type markings at that point.

First, multiplication (*) is renamed as left-multiply or right-multiply, depending on which input is a scalar.

Then, the 2D and 3D versions of the following operations are given distinct names:

- left-multiply right-multiply dot-product vector-<= exact->inexact inexact->exact unary-minus round = + - / guaranteed-quotient evenly-divides guaranteed-/ vector-magnitude zero?

When applied to 1D inputs, the following functions are renamed:

- vector-magnitude becomes abs
- dot-product becomes *
- left-multiply becomes *
- right-multiply becomes *
- vector-<= becomes <=

The operation vector-<= is introduced in step 4, during the expansion of in-focus-area.

The operator unscaled-sheet-ref is renamed as real-sheet-ref (interpolated reference) if the sheet is a manifold, otherwise as integer-sheet-ref (on-sample reference). When a form is rewritten using real-sheet-ref, its point input is coerced to real, by enclosing it in an exact->inexact form if it is an integer point.

Forms headed by unscaled-sheet-ref come from the expansion of sheet-ref, which is defined as interpolating when its input is a manifold. Expansion of sample-ref (always an on-sample reference) in step 4 uses integer-sheet-ref.

Finally, if the second input to a point-coordinate form is not pure, it is rewritten to incorporate a test for whether the second input is in the correct range. The second input must be non-negative and less than the dimension of the first input. This is done by replacing the second input with a complex form, the details of which depend on the type of the second input.

The expansions are analogous to the tests for missing inputs produced by the step 4 rewriting rules. However, constant inputs are evaluated (they may be complex expressions with constant inputs) and checked at run-time.

If the first input to point-coordinate is a scalar and the second input was a constant point, it must have been zero. In this case, the entire form is simplified to the first input.

Ownership, Maintenance and Disclaimers

Last modified