Язык программирования Оберон-2

         

Модули



11. Модули

Модуль - совокупность объявлений констант, типов, переменных и процедур вместе с последовательностью операторов, предназначенных для присваивания начальных значений переменным. Модуль представляет собой текст, который является единицей компиляции.

Модуль = MODULE идент ";" [СписокИмпорта] ПоследовательностьОбъявлений
[BEGIN ПоследовательностьОператоров] END идент ".".
СписокИмпорта  = IMPORT Импорт {"," Импорт} ";".
Импорт  = [идент ":="] идент.

Список импорта определяет имена импортируемых модулей. Если модуль A импортируется модулем M, и A экспортирует идентификатор x, то x упоминается внутри M как A.x. Если A импортируется как B:=A, объект x должен вызываться как B.x. Это позволяет использовать короткие имена-псевдонимы в уточненных идентификаторах. Модуль не должен импортировать себя. Идентификаторы, которые экспортируются (то есть должны быть видимы в модулях-импортерах) нужно отметить экспортной меткой в их объявлении (см. Главу 4).
     Последовательность операторов после символа BEGIN выполняется, когда модуль добавляется к системе (загружается). Это происходит после загрузки импортируемых модулей. Отсюда следует, тот циклический импорт модулей запрещен. Отдельные (не имеющие параметров и экспортированные) процедуры могут быть активированы из системы. Эти процедуры служат командами (см. Приложение D1).

MODULE Trees; (* экспорт: Tree, Node, Insert, Search, Write, Init *)
     IMPORT Texts, Oberon; (* экспорт только для чтения: Node.name *)

     TYPE
          Tree* = POINTER TO Node;
          Node* = RECORD
               name-: POINTER TO ARRAY OF CHAR;
               left, right: Tree


          END;

     VAR w: Texts.Writer;

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

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

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

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

BEGIN Texts.OpenWriter(w)
END Trees.


Содержание раздела