ライブラリで定義されている関数, 変数をカプセル化する仕組みが モジュール (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
module_list, section module_definedp, section remove_module.
Go to the first, previous, next, last section, table of contents.