プログラムインターフェース

第0.43版 2016年10月23日
第0.03版 1996年 5月 3日

ここでは、プログラム中からプログラムを生成して実行させるインターフェースの
説明をします。

al_gp("runtime_class", class_name, null, null, null);

クラス名からクラスを表わす内部構造体を返します。
見つからない場合はnullを返します。
.headにクラス名が入っています。
-/"$subclass"/->でサブクラスをたどることができます。
al_gp("runtime_class", "A", null, nill, null)は runtime A と同じ意味です。

al_gp("regist_class", base_class_name, class_name, null, null);

base_class_nameをベースクラスとしてclass_nameのクラスを追加します。
追加に成功するとnullが、それ以外は1が返ります。

al_gp("unregist_class", class_name, opt, null, null);

class_nameのクラスを削除します。
戻り値(optがnullのとき)
 null 削除に成功
 1    class_nameが文字列でない
 2    class_nameがクラスを表わしていない
 3    クラスが参照されている
 4    派生クラスを持っている
 5    ルートクラスである

 optが非nullのときは「参照されている/派生クラスを持っている」にかかわらず、
 クラスが強制的に削除されます。

al_gp("regist_var", class_name, type_name, var_name, null);

クラスにメンバー変数を追加します。
追加に成功するとnullが、それ以外は1が返ります。
クラスに関数void public_var()がなければ追加し、その中に
メンバー変数の参照を追加します。

al_gp("unregist_var", class_name, var_name, null, null);

クラスからメンバー変数を削除します。
削除に成功するとnullが、それ以外は1が返ります。

al_gp("add_to_arg_dcl", arg_dcl, type_name, arg_name, null);

関数引数のプロトタイプを作成します。
関数func(integer i, string s)の場合なら以下のようにします。
    var list arg_dcl;
    arg_dcl = al_gp("add_to_arg_dcl", null, "integer", "i", null);
    arg_dcl = al_gp("add_to_arg_dcl", arg_dcl, "string", "s", null);

al_gp("regist_sfunc", class_name, type_name, func_name, arg_dcl);

クラスにstatic関数を追加します。
追加に成功するとnullが、それ以外は1が返ります。
クラスに関数void public_func()がなければ追加し、その中に
static関数の参照を追加します。

al_gp("unregist_sfunc", class_name, null, func_name, arg_dcl);

クラスからstatic関数を削除します。
戻り値
 null 削除に成功
 1    引数が文字列でない
 2    class_nameがクラスを表わしていない
 3    関数が見つからない
 4    関数が参照されている

al_gp("regist_vfunc", class_name, type_name, func_name, arg_dcl);

クラスにvirtual関数を追加します。
追加に成功するとnullが、それ以外は1が返ります。
クラスに関数void public_func()がなければ追加し、その中に
virtual関数の参照を追加します。

al_gp("unregist_vfunc", class_name, null, func_name, arg_dcl);

クラスからvirtual関数を削除します。
戻り値
 null 削除に成功
 1    引数が文字列でない
 2    class_nameがクラスを表わしていない
 3    関数が見つからない
 4    関数が参照されている

al_gp("var_list", class_name, null, null, null);

クラスのメンバー関数public_var()から参照されているメンバー変数名の
コレクションを返します。
戻り値は、()-/-/=>メンバー変数名-/-/->var_dcl
var_dclはメンバー変数を表わす内部構造体。

al_gp("sfunc_list", class_name, null, null, null);

クラスのメンバー関数public_func()から参照されているstatic関数の
プロトタイプのコレクションを返します。
戻り値は、()-/-/=>関数のプロトタイプ-/-/->func_dcl
func_dclはメンバー関数を表わす内部構造体。

al_gp("vfunc_list", class_name, null, null, null);

クラスのメンバー関数public_func()から参照されているvirtual関数の
プロトタイプのコレクションを返します。
戻り値は、()-/-/=>関数のプロトタイプ-/-/->func_dcl
func_dclはメンバー関数を表わす内部構造体。

al_gp("type_to_name", type, null, null, null);

型を表わす内部構造体を文字列に変換します。

al_gp("class_name_of", obj, null, null, null);

オブジェクトからそのオブジェクトのクラス名を得ます

al_gp("pif_create", class_name, null, func_name, arg_dcl);

プログラム中でプログラムを行うためのオブジェクトを作成します。
以後これをプログラミングイテレータと呼ぶことにします。
単位はメンバー関数単位です。

al_gp("pif_destroy", pif, null, null, null);

プログラミングイテレータを破壊します。
プログラミングイテレータが不要になった場合は必ずこれを行ってください。
これを行わないとメモリリークします。

al_gp("pif_clear", pif, null, null, null);

プログラミングイテレータが指している関数の中身を空にします。

al_gp("pif_insert", pif, str, null, null);

プログラミングイテレータの現在さしている行に
文字列strをプログラムのソースとして挿入します。
挿入に成功するとnullが、それ以外は1が返ります。

al_gp("pif_reset", pif, lno, null, null);

プログラミングイテレータとして使うときの関数です。
イテレータの指す場所を行番号lnoで指定される場所に持っていきます。
行番号は0から始まります。

al_gp("pif_more", pif, null, null, null);

プログラミングイテレータとして使うときの関数です。
まだソースがある場合は1が、ない場合はnullが返ります。

al_gp("pif_last", pif, null, null, null);

プログラミングイテレータとして使うときの関数です。
ソースの最後になったら非nullを返します。

al_gp("pif_next", pif, null, null, null);

プログラミングイテレータとして使うときの関数です。
イテレータの指す場所を1行前へ進めます。

integer al_gp("pif_lno", pif, null, null, null);

プログラミングイテレータとして使うときの関数です。
現在のイテレータの指している場所の行番号を返します。
行番号は0から始まります。
lnoが負のときや最大行番号より大きい場合は
この関数の実行後イテレータはプログラムの最後を指します。

string al_gp("pif_string", pif, null, null, null);

プログラミングイテレータとして使うときの関数です。
イテレータの現在指している行のソーステキストを返します。

list al_gp("run", class_name, null, func_name, null);

引数なしのstatic関数を実行します。この実行は並列処理されます。
プロセスの生成に成功するとnullが返ります。

string al_gp("unique_str", string_value, null, null, null);

Altairでは、文字列の比較処理を高速化するため、内部で用いる文字列の値は
クイックソートしてあって、文字列の比較はアドレスを比較すればよいという
実装になっています。この関数は、文字列をクイックソートし、比較処理はアドレスを
比較すればよい文字列に文字列を変換します。

any al_gp("run2", target, opt, func_name, args);

targetがクラスを表す文字列の場合、引数ありのstatic関数を実行します。
optは無視されます。
targetがAlObjectの派生クラスのオブジェクトの場合、targetを対象オブジェクトとして
引数ありの仮想関数を実行します。
実行に成功した場合は関数の戻り値が返ります。
実行に失敗した場合は、0x80000000が返ります。
optには仮引数宣言を入れます。
この関数は実行が終了するまで制御を放しません。
戻り値には関数の戻り値が返されます。
argsには以下のような形式で引数を与えます。
((arg_name, arg_value, null), ...)
arg_nameはal_gp("unique_str", ...);でアドレスを比較すればよいだけの文字列に
変換しておく必要があります。

any al_gp("new", class_name, null, null, null);

クラスがclass_nameのオブジェクトを作成して返します。
al_gp("new", "AAA", null, null, null); は、new AAA; と同じ意味です。

al_gp("vtbl", null, null, null, null);

バーチャル関数テーブルをアップデートします。

注: regist_class,regist_vfuncをしてもバーチャル関数テーブルは
アップデートされません。
regist_class,regist_vfuncで関数を加えた場合、
その関数を実行する前にこの関数を呼ぶ必要があります。

al_gp("stack_frame", null, null, null, null);

現在実行中のスタックフレームを返します。スタックフレームの形式は
((this_ptr, prog, arg_base, loc_base, ctrl_stack, func), chain)
となっています。
this_ptrは、virtual関数の対象オブジェクトです。static関数の場合はnullです。
progは、現在実行中のプログラムカウンタです。
arg_baseは、実引数リストのリンクトチェーンです。
loc_baseは、ローカル変数リストのリンクトチェーンです。
ctrl_stackは、現在実行中の関数の制御構造のリンクトチェーンです。
funcは、現在実行中の関数の関数宣言(arg_dcl)です。
chainは、ひとつ前のスタックフレームです。

al_gp("method_name", null, null, null, null);

現在実行中の関数名を返します。

al_gp("arg_dcl", null, null, null, null);

現在実行中の関数の仮引数リストを返します。
形式は、al_gp("run2", ...)にそのまま渡せる形式です。
これで得られる値は、以下で得られるarg_dclと等価です。
    var list func_stack, func_dcl, arg_dcl;
    func_stack = al_gp("stack_frame", null, null, null, null);
    func_dcl = func_stack.head.tail.tail.tail.tail.tail.head;
    arg_dcl = func_dcl.tail.tail.tail.head;

al_gp("arg_list", null, null, null, null);

現在実行中の関数の実引数リストを返します。
形式は、al_gp("run2", ...)にそのまま渡せる形式です。

al_gp("encode", arg_dcl, arg_list, null, null);

仮引数リスト、実引数リストをシリアライズ可能な形に変え、
そのリストを返します。

al_gp("decode", arg_dcl, null, null, null);

シリアライズ可能な形から仮引数リストを復元しそれを返します。