The type checking rules of Tiger, or rather its binding rules, justify the contrived parsing of declarations. This is why this section uses -b/--bindings-compute, implemented later (see TC-3).
In Tiger, to support recursive types and functions, continuous
declarations of functions and continuous declarations of types are
considered “simultaneously”. For instance in the following program,
bar are visible in each other’s scope, and
therefore the following program is correct wrt type checking.
let function foo() : int = bar() function bar() : int = foo() in 0 end
$ tc -b foo-bar.tig
In the following sample, because
bar is not declared in the same
bunch of declarations, it is not visible during the declaration of
foo. The program is invalid.
let function foo() : int = bar() var stop := 0 function bar() : int = foo() in 0 end
$ tc -b foo-stop-bar.tig error→foo-stop-bar.tig:1.28-32: undeclared function: bar ⇒4
The same applies to types.
We shall name chunk a continuous series of type (or function) declaration.
A single name cannot be defined more than once in a chunk.
let function foo() : int = 0 function bar() : int = 1 function foo() : int = 2 var stop := 0 function bar() : int = 3 in 0 end
$ tc -b fbfsb.tig error→fbfsb.tig:3.5-28: redefinition: foo error→fbfsb.tig:1.5-28: first definition ⇒4
It behaves exactly as if chunks were part of embedded
let in end,
i.e., as if the previous program was syntactic sugar for the following
one (in fact, in 2006-tc used to desugar it that way).
let function foo() : int = 0 function bar() : int = 1 in let function foo() : int = 2 in let var stop := 0 in let function bar() : int = 3 in 0 end end end end
Given the type checking rules for variables, whose definitions cannot be recursive, chunks of variable declarations are reduced to a single variable.