Super Prev Next


A module is a collection of declarations of constants, types, variables, and procedures, together with a sequence of statements for the purpose of assigning initial values to the variables. A module constitutes a text that is compilable as a unit.

  Module     = MODULE ident ";" [ImportList]
               [ BEGIN StatementSequence ]
               END ident ".".
  ImportList = IMPORT Import {"," Import} ";".
  Import     = [ident ":="] ident.

The import list specifies the names of the imported modules. If a module A is imported by a module M and A exports an identifier x, then x is referred to as A.x within M. If A is imported as B := A, the object x is referenced as B.x. This allows short alias names in qualified identifiers. A module must not import itself. Identifiers that are to be exported (i.e. that are to be visible in client modules) must be marked by an export mark in their declaration (see section Declarations and scope rules).

The statement sequence following the symbol BEGIN is executed when the module is added to a system (loaded), which is done after the imported modules have been loaded. It follows that cyclic import of modules is illegal. Individual (parameterless and exported) procedures can be activated from the system, and these procedures serve as commands.

(* exports:
  Tree, Node, Insert, Search, Write, NewTree
(* exports read-only: *)
IMPORT Texts, Oberon;
  Tree* = POINTER TO Node;
  Node* = RECORD
    left, right: Tree

VAR w: Texts.Writer;

PROCEDURE (t: Tree) Insert* (name: ARRAY OF CHAR);
  VAR p, father: Tree;
  p := t;
  REPEAT father := p;
    IF name =^ THEN RETURN END;
    IF name <^ THEN p := p.left
    ELSE p := p.right
  UNTIL p = NIL;
  NEW(p); p.left := NIL; p.right := NIL;
  IF name <^ THEN father.left := p
  ELSE father.right := p
END Insert;

PROCEDURE (t: Tree) Search* (name: ARRAY OF CHAR): Tree;
  VAR p: Tree;
  p := t;
  WHILE (p # NIL) & (name #^) DO
    IF name =^ THEN p := p.left
    ELSE p := p.right
END Search;

PROCEDURE (t: Tree) Write*;
  IF t.left # NIL THEN t.left.Write END;
  Texts.Append(Oberon.Log, w.buf);
  IF t.right # NIL THEN t.right.Write END
END Write;

PROCEDURE NewTree* (): Tree;
  VAR t: Tree;
  NEW(t); NEW(, 1);[0] := 0X;
  t.left := NIL; t.right := NIL;
END NewTree;

END Trees.