modula-2 home

  Home  
  Tutorial  
  Win32 API  
  Reference  
  Projects  
 

 

Compilation units

A text which is accepted by the compiler as a unit is called a compilation unit. There are three kinds of compilation units: main modules, definition modules, and implementation modules. A main module constitutes a main program and consists of a so-called program module. In particular, it has no export list. Imported objects are defined in other (separately compiled) program parts which themselves are subdivided into two units, called definition module and implementation module.

The definition module specifies the names and properties of objects that are relevant to clients, i.e. other modules which import from it. The implementation module contains local objects and statements that need not be known to a client In particular the defInition module contains constant, type, and variable declarations, and specifications of procedure headings. The corresponding implementation module contains the complete procedure declarations, and possibly further declarations of objects not exported. Definition and implementation modules exist in pairs. Both may contain import lists, and all objects declared in the definition module are available in the corresponding implementation module without explicit import.

  DefinitionModule = DEFINITION MODULE ident ";"
      {import} {definition} END ident ".".
  definition = CONST {ConstantDeclaration ";"} |
   	  TYPE {ident["=" type] ";"} |
  	  VAR {VariableDeclaration ";"} |
  	  ProcedureHeading ";".
  ProgramModule = MODULE ident [priority] ";" {import} block ident ".".
  CompilationUnit = DefinitionModule | [IMPLEMENTATION] ProgramModule.

The definition module evidently represents the interface between the implementation module on one side and its clients on the other side. The definition module contains those declarations which are relevant to the client modules, and presumably no other ones. Hence, the definition module acts as the implementation module's (extended) export list, and all its declared objects are exported.

Definition modules imply the use of qualified export. Type definitions may consist of the full specification of the type (in this case its export is said to be transparent), or they may consist of the type identifier only. In this case the full specification must appear in the corresponding implementation module, and its export is said to be opaque. The type is known in the importing client modules by its name only, and all its properties are hidden. Therefore, procedures operating on operands of this type, and in particular operating on its components, must be defined in the same implementation module which hides the type's properties. Opaque export is restricted to pointers. Assignment and test for equality are applicable to all opaque types.

As in local modules, the body of an implementation module acts as an initialization facility for its local objects. Before its execution, the imported modules are initialized in the order in which they are listed. If circular references occur among modules, their order of initialization is not defined.


Source: Wirth N: Programming in Modula-2, 3rd ed. Springer Verlag, 1985