Go to the first, previous, next, last section, table of contents.

### モジュール

ライブラリで定義されている関数, 変数をカプセル化する仕組みが モジュール (module) である. はじめにモジュールを用いたプログラムの例をあげよう.

    module stack;

    static Sp $
    Sp = 0$
    static Ssize$
    Ssize = 100$
    static Stack $
    Stack = newvect(Ssize)$
    localf push $
    localf pop $

    def push(A) {
      if (Sp >= Ssize) {print("Warning: Stack overflow\nDiscard the top"); pop();}
      Stack[Sp] = A;
      Sp++;
    }
    def pop() {
      local A;
      if (Sp <= 0) {print("Stack underflow"); return 0;}
      Sp--;
      A = Stack[Sp];
      return A;
    }
    endmodule;

    def demo() {
      stack.push(1);
      stack.push(2);
      print(stack.pop());
      print(stack.pop());
    }

モジュールは `module` モジュール名 〜 `endmodule`で囲む. モジュールは入れ子にはできない. モジュールの中だけで使う大域変数は `static` で宣言する. この変数はモジュールの外からは参照もできないし変更もできない. モジュールの外の大域変数は `extern` で宣言する.

モジュール内部で定義する関数は `localf` を用いて宣言しないといけない. 上の例では `push` と `pop` を宣言している. この宣言は必須である.

モジュール `moduleName` で定義された関数 `functionName` を モジュールの外から呼ぶには `moduleName.functionName(引数1, 引数2, ... )` なる形式でよぶ. モジュールの中からは, 関数名のみでよい. 次の例では, モジュールの外からモジュール `stack` で定義された関数 `push`, `pop` を呼んでいる.

     stack.push(2);
     print( stack.pop() );
     2

モジュールで用いる関数名は局所的である. つまりモジュールの外や別のモジュールで定義されている関数名と同じ名前が 利用できる.

モジュール機能は大規模ライブラリの開発を想定している. ライブラリを必要に応じて分割ロードするには, 関数 `module_definedp` を用いるのが 便利である. デマンドロードはたとえば次のように行なえば良い.

    if (!module_definedp("stack")) load("stack.rr") $

asir では局所変数の宣言は不要であった. しかしモジュール stack の例を見れば分かるように, `local A;` なる形式で 局所変数を宣言できる. キーワード `local` を用いると, 宣言機能が有効となる. 宣言機能を有効にすると, 宣言されてない変数はロードの段階で エラーを起こす. 変数名のタイプミスによる予期しないトラブルを防ぐには, 宣言機能を有効にしてプログラムするのがよい.

モジュール内の関数をそのモジュールが定義される前に 呼び出すような関数を書くときには, その関数の前でモジュールを次のように プロトタイプ宣言しておく必要がある.

    /* Prototype declaration of the module stack */
    module stack;
    localf push $
    localf pop $
    endmodule;

    def demo() {
      print("----------------");
      stack.push(1);
      print(stack.pop());
      print("---------------");
    }

    module stack;
      /* The body of the module stack */
    endmodule;

モジュールの中からトップレベルで定義されている関数を呼ぶには, 下の例のように `::` を用いる.

    def afo() {
      S = "afo, afo";
      return S;
    }
    module abc;
    localf foo,afo $

    def foo() {
      G = ::afo();
      return G;
    }
    def afo() {
      return "afo, afo in abc";
    }
    endmodule;
    end$

    [1200] abc.foo();
    afo, afo
    [1201] abc.afo();
    afo, afo in abc

`参照`
  section `module_list`, section `module_definedp`, section `remove_module`.

Go to the first, previous, next, last section, table of contents.