Declarations

import

An import clause denote the same expression where it was (recursively) replaced by the set of declarations its corresponding import-file contains. An import-file has the following syntax (see Syntactic Specifications for the definition of the symbols):

import-file = decs

Because the syntax is different, it is convenient to use another extension. We use *.tih for files to import, for instance:

/* fortytwo-fn.tih. */
function fortytwo() : int = 42


/* fortytwo-var.tih. */
import "fortytwo-fn.tih"
var fortytwo := fortytwo()


/* fortytwo-main.tig. */
let
  import "fortytwo-var.tih"
in
  print_int(fortytwo); print("\n")
end

is rigorously equivalent to:

let
  function fortytwo() : int = 42
  var fortytwo := fortytwo()
in
  print_int(fortytwo); print("\n")
end

There can never be a duplicate-name conflict between declarations from different files. For instance:

/* 1.tih */
function one() : int = 1


let
  import "1.tih"
  import "1.tih"
in
  one() = one()
end

is valid although

let
  function one() : int = 1
  function one() : int = 1
in
  one() = one()
end

is not: the function one is defined twice in a row of function declarations.

Importing a nonexistent file is an error. A imported file may not include itself, directly or indirectly. Both these errors must be diagnosed, with status set to 1 (see Errors).

When processing an import directive, the compiler starts looking for files in the current directory, then in all the directories of the include path, in order.

Name spaces

There are three name spaces: types, variables and functions. The original language definition features two: variables and functions share the same name space. The motivation, as noted by Sébastien Carlier, is that in FunTiger, in the second part of the book, functions can be assigned to variables:

let
  type a = {a : int}
  var  a := 0
  function a(a : a) : a = a{a = a.a}
in
  a(a{a = a})
end

Three name spaces support is easier to implement.