[BACK]Return to prog1.txt CVS log [TXT][DIR] Up to [local] / OpenXM / src / k097 / Doc

Annotation of OpenXM/src/k097/Doc/prog1.txt, Revision 1.2

1.1       maekawa     1:
                      2:
                      3: yacc/Doc/prog1.txt  (1997, 4/11, 4/17)
                      4: kan/k0 の内部構造とプログラミングに関する注意.
                      5:
                      6: kan/k0 におけるクラスの取扱は C++ や Java に一見して似ているが,
                      7: 実は全く違う.  むしろ, SmallTalk の方が近い.
                      8:
                      9: ☆ クラスのインスタンス変数は class 宣言のすぐ後, 次のように宣言する.
                     10:
                     11:    class  クラス名 extends スーパークラス名 {
                     12:       local インスタンス変数名1,
                     13:             インスタンス変数名2,
                     14:                 ...
                     15:             インスタンス変数名n;
                     16:
                     17:       メンバー関数定義
                     18:    }
                     19:
                     20:    上の local 宣言を二つ以上書くとエラーになる.
1.2     ! takayama   21:    インスタンス変数名がないときは,
        !            22:       local ;
        !            23:    と宣言すること.
1.1       maekawa    24:
                     25: ☆ インスタンス変数名は, そのクラス内での 局所変数名, メンバー関数引数名と
                     26:    して使えない.
                     27:
                     28:    たとえば,
                     29:    class abc extends Object {
                     30:      local a,b;
                     31:      def foo(a) {
                     32:
                     33:    は インスタンス変数名 a を引数として用いているのでエラーである.
                     34:    現在のところ エラーメッセージを表示しないのでもっとたちがわるい.
                     35:
                     36: ☆ インスタンス変数名にたいする ピリオド . を用いた参照, 代入はできない.
                     37:     たとえば,
                     38:           this.a
                     39:     といった参照はできない.  (将来的には, できるようにしたい. )
                     40:     参照, 代入はかならず, メンバー関数を用いて行なう.
                     41:
                     42: ☆  生成子の書き方は, 次の形式に従うこと. (yacc/debug/graph.kk より)
                     43:
                     44:     def new0(引数) {                   生成子名はなんでもいい.
                     45:       this = new();                    かならず, this = new(....) を書く.
                     46:                                        クラスの実体が PrimitiveObject の
                     47:                                        array として生成される.
                     48:       インスタンス変数の初期化
                     49:       return(this);                    かならず、this を戻す.
                     50:     }
                     51:
                     52:
                     53:     new() は, 上のように, new() とよんでもいいし,
                     54:         this = new(super.スーパークラスの生成子)
                     55:     と書いてもいい.
1.2     ! takayama   56:   ==> 現在この書き方は正しく機能しない. 2001, 1/13
        !            57:       BUG: super は正しく動かないので使用しない方がよい.
        !            58:       現在のクラスが class  Hoge extends Foo なら
        !            59:         this = new( Foo.スーパークラスの生成子 )
        !            60:       と生成すべし.
        !            61:       d0 で生成された sm1 のコードを参照.
        !            62:       生成法:  cat object.kk ファイル | d0
1.1       maekawa    63:
                     64: ☆  class インスタンスの内部形式.
                     65:
                     66:     class インスタンス は PrimitiveObject としては, array であり,
                     67:     その最初の要素は class タグである.
                     68:     インスタンス変数は, その array の要素である.
                     69:
                     70: 例えば,
                     71:    class Circle extends Object {
                     72:      local x,  /* 中心 */
                     73:            y,
                     74:            r;  /* 半径 */
                     75:      ;
                     76:    }
                     77:
                     78:    class GraphicCircle extends Circle {
                     79:      local outline, fill;
                     80:      ;
                     81:    }
                     82:
                     83: なる宣言をすると, Circle インスタンスは,
                     84:    [Circle, xの値, yの値, rの値]
                     85: なる array,   GraphicCircle インスタンスは,
                     86:    [GraphicCircle, xの値, yの値, rの値, outlineの値, fillの値]
                     87: なる array となる.
                     88: kan/k0 インタプリタは, たとえば,  x という変数があらわれると,
                     89: kan/sm1 の,
                     90:        this 1 get
                     91: なるコマンドを生成している.   インスタンス変数名と, その位置インデックス
                     92: の対応は, yacc/dic.c の関数で管理されている.
                     93:
                     94: ☆  extends により, 名前空間が, PrimitiveObject --- Object を頂点とする木構造に
                     95: なっている.  メソッドの検索は次のようにおこなわれる.
                     96:
                     97: 関数呼び出しは, 次のように翻訳される.
                     98:      aaa.foo(b,c)             aaa [b c] {foo} sendmsg2
                     99:      foo(b,c)                 this [b c] {foo} sendmsg2
                    100:
                    101: すべての関数は二つの引数がスタックにあることを仮定している.
                    102: sendmsg2 は, 第一引数が, クラスのインスタンス であるばあい,
                    103: 名前空間 (コンテキスト)
                    104: をその クラス のものに変更して, 関数呼び出しをおこなう.
                    105: 例えば, 上の例で, aaa が Graphic の インスタンスであると,
                    106: foo の実行は, Graphic の名前空間で実行される.
                    107:
                    108:
                    109: operator +,-,*,/ については次のように翻訳される.
                    110:     a + b                   a  b  {add} sendmsg2
                    111: sendmsg2 は, 第一引数または第2引数が, クラスのインスタンス であるばあい,
                    112: 名前空間 (コンテキスト)
                    113: をその クラス のものに変更して, 関数呼び出しをおこなう.
                    114: 例:
                    115:    class Integer extends Object {
                    116:      local ival;
                    117:      def new0(i) {
                    118:         this = new();
                    119:         if (IsInteger(i)) ival = i;
                    120:         else {
                    121:            k00_error("new0","Argument must be integer."); sm1(" error ");
                    122:         }
                    123:         return(this);
                    124:      }
                    125:      def value() { return( ival ); }
                    126:      def operator add(b) {
                    127:        local r;
                    128:        r = Integer.new0(ival+b.value());
                    129:        return(r);
                    130:      }
                    131:    }
                    132:
                    133:    a = Integer.new0(3);
                    134:    a + a :
                    135:
                    136:
                    137:
                    138:
                    139:
                    140: なお, 上の4つ以外の,
                    141: <,>, = , == などの operator に関しては, override はできないことに注意.
                    142:
                    143:
                    144:
                    145: ☆  kan/k0 のエンジン部分は初期状態で, 4本のスタックと 一つのコンテキスト
                    146:    をもっている.
                    147:
                    148:    Operand Stack  (標準のスタック, Kan/stackmachine.c では StandardStack)
                    149:    db.VariableStack
                    150:    db.ErrorStack
                    151:    db.DebugStack
                    152:    これらは var.sm1 で定義され,  debug/db.k で活用される.
                    153:
                    154:    db.VariableStack は, 関数呼び出しのときの, 引数や 関数の局所変数を
                    155:    一次的に格納する stack である.
                    156:
                    157:    db.DebugStack は, 関数呼び出しのとき, 現在実行中の関数を格納する
                    158:    stack である. --- engine error or interrupt :  in function xxxxx
                    159:    という表示は, このスタックの情報をもとにしている.
                    160:
                    161:    db.ErrorStack は, engine エラーが積まれるスタックである.
                    162:
                    163:
                    164:    コンテキストは,
                    165:    PrimitiveContextp  (StandardContextp)
                    166:    が初期状態である.  incmac.sm1 を参照せよ.
                    167:    なお PrimitiveObject = [PrimitiveContextp]  である.
                    168:
                    169:
                    170:    SmallTalk のバイトコードマシンでは, コンテキストは, 名前辞書とスタック
                    171:    を合わせたものであるが, kan/k0 の場合, コンテキストとは, 名前辞書のことを
                    172:    さす.  名前辞書は名前とその値よりなる対応表である. 辞書はハッシュ法で
                    173:    検索され, その辞書で値が見つからないと, その super 辞書へ検索が移行する.
                    174:    このような木構造での名前空間の実現については, Kan/stackmachine.c
                    175:    の  *userDictionary*  なる名前の関数を参照されたい.
                    176:
                    177: ☆ コンテキストスイッチについての注意.
                    178:
                    179:    上で説明したような, 名前空間の動的な変更はエラー処理に関して混乱をひきお
                    180:    こす.  したがって, kan/k0 では, 次のような単純な, 解決法をとった.
                    181:
                    182:    エンジンエラー,  ctrl-C の入力があった場合, 必ず CurrentContext を,
                    183:    PrimitiveContext へ戻す.
                    184:
                    185:    この方針は別の問題を引き起こす.  たとえば, エラーが起きた時点の変数の
                    186:    値の検査が一般にできない.  いまのところ, kan/sm1 のコマンドをつかうしか
                    187:    ない.
                    188:    たとえば, class Abc でエラーが起きたとすると,
                    189:        sm1("Abc  0 get setcontext ");
                    190:    で, class Abc の名前空間に移行できる.
                    191:        sm1(" show_user_dictionary ") で現在の辞書に登録されている名前を
                    192:    みることができる.  また,
                    193:         Println(変数名);
                    194:    でその変数の値を検査できる.
                    195:
                    196:    以上のような仕組みの問題点としては,
                    197:    Cleards();  による, 変数の値の回復ができないことをあげておく.
                    198:    (つまり現在の変数スタックは, どの名前空間かの情報をもっていないので、
                    199:     変数の値の正しい回復ができない, また, context ごとに別のスタックを
                    200:     用意している訳でない.)
                    201:    したがって, class  を用いたプログラムは, エラーが起きたら, 再スタートするの
                    202:    が賢明である.
                    203:
                    204:
                    205: ☆ Object については, 必ず概要, および, 実例を記述しておくこと.
                    206:
                    207:    class を用いて書かれたプログラムは一般に読みにくい場合が多々ある.
                    208:    Object が中心にありプログラムをしているにもかかわらず, その Obeject の
                    209:    概要を理解するのがソースからはむづかしいことが多いのが,
                    210:    その理由であると思われる.
                    211:    例えば, ??????????????   (考えること)
                    212:
                    213:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>