スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#で入門 コンパイラ 、インタプリタ編 チューリング・マシン(3)

 今回は前回作成したチューリング・マシンのソフトを使って何かプログラミングしてみたいと思います。 
今回作成してみるプログラムは2進数に1を加えるというプログラムです。 
「最初にテープに位置0から11011と印字されていれば、プログラムの実行の結果11100となり停止」というようにします。計算結果のヘッドの位置は最小位の数字の右隣で止まるようにします。 
 
最初の状態番号は1でこの時、まず数字がない部分までヘッドを右に移動します。 
数字がない部分に行き当たれば状態番号2に遷移せてヘッドを左に移動します。 
この部分のコードが次です。 
(状態番号、ヘッド値、遷移状態番号、書き込み動作、移動) 
1,0,1,_,1 
1,1,1,_,1 
1,_,2,_,-1 
 
状態2(これは繰り上がり1の状態で桁上がりの処理をしなければならない場合です。)になったら、 
(1)読み込んだ数字が0なら1に書き換えて終了準備(単にヘッドを右端にもっていくだけ)の状態3に移行します。 
2,0,3,1,1 
(2)読み込んだ数字が1なら0に書き換えて、繰り上がり1の状態(すなわち状態2)で、左にヘッドを動かします。 
2,1,2,0,-1 
(3)読み込んだものがプランク_なら、1を書き込んで終了準備(単にヘッドを右端にもっていくだけ)の状態3に移行します。 
 
状態3(これは終了準備(単にヘッドを右端にもっていくだけ))になったら 
(1)読み込んだ数字が0か1なら、単にヘッドを右に移動します。 
3,0,3,_,1 
3,1,3,_,1 
(2)ブランク_なら、ヘッドを左に動かして、終了状態を4として4に移行します。 
3,_,4,_,-1 
 
以上でプログラムは出来上がりです。まとめて表記すると 
 
1,0,1,_,1 
1,1,1,_,1 
1,_,2,_,-1 
2,0,3,1,1 
2,_,3,1,1 
2,1,2,0,-1 
3,0,3,_,1 
3,1,3,_,1 
3,_,4,_,-1 
 
終了状態番号は4 
 
例えばテープ初期値を 
として、前回のソフトで実行すると 
実行前が 
 
1045-1.jpg
 
で 
実行後が 
 
1045-2.jpg
 
 
になります。 
 
なお、定期ブログ更新を3ヶ月ほどお休みする予定です。 

続きを読む

スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

F#で入門 コンパイラ 、インタプリタ編 チューリング・マシン(2)

 今回はチューリングマシンのWinソフト版です。 
次のようなソフトを作成します。 
 
1044-1.jpg
  
まずは使い方の説明から 
(1)プログラムを入力 
読み込み時の状態と読み込みの値から次のする動作の対応を入力します。 
前回の例なら次の様に入力します。 
 
1,0,2,_,1 
1,1,3,_,1 
2,0,4,_,1 
2,1,5,_,1 
2,_,7,_,-1 
3,0,5,_,1 
3,1,6,_,1 
3,_,7,_,-1 
4,+,2,0,1 
4,*,2,0,1 
5,+,3,1,1 
5,*,2,0,1 
6,+,2,0,1 
6,*,3,1,1 
 
これで「Set」ボタンを押します。 
 
画面はこうなります。 
 
1044-2.jpg
   
(2)テープ初期値を入力します。 
01+1*を計算させるなら次のような入力となります。 
 
 
これで「Set」ボタンを押します。 
 
画面はこうなります。 
 
1044-3.jpg 
 
(3)終了状態(accept state No.)を入力します。 
 
 
1044-4.jpg
 
 
あとは右の「OneStepExec」ボタンを押すと、一ステップごと進行します。 
 
なおテープは、位置が0以上の部分と、負の部分を分けて表示するようにしてあります。 
 
1044-5.jpg
 
なお、チューリングマシンでエラーの場合は、無限ループに陥って終了しないのが本義なのですが、このプログラムの場合は、エラー表示をして終了するようにしてあります。 
テープ初期値を色々変えて計算させてみてください。(8通りしか計算できませんが。) 
 
今回のソースは次の通りです。 

続きを読む

テーマ : プログラミング
ジャンル : コンピュータ

F#で入門 コンパイラ 、インタプリタ編 チューリング・マシン(1)

今回は一息いれて「チューリング・マシン」を実装してみたいと思います。 
 
チューリング・マシンは参考にする文献によって、いろいろ細かい部分が異なるのですが、今回はウィキペディア版のものを取り上げます。 
 
チューリングの仮想機械は、 
(1)マス目で区切られた無限に長いテープ(マス目毎に一文字が記録できるようになっている) 
(2)(1)のテープに格納された情報(文字群)のうち現在位置の一文字を読み書きする可動式ヘッド 
(3)機械の内部状態を記憶するメモリ(何種類かの最初に使用者側で設定した状態の内、「今状態6ですよ」というような情報を記録する) 
で構成され、内部状態とヘッドから読み出した情報の組み合わせに応じて、次の動作を実行する。 
(Ⅰ)ヘッド位置のテープに情報を書き込む 
(Ⅱ)機械の内部状態を変える 
(Ⅲ)ヘッドを右か左に一つ移動する 
上の動作を、機械は内部状態が停止状態になるまで反復して実行し続ける。 
 
というものです。 
 
流れとしては、次の繰り返しです。 
 
読み込みー>書き込み(ない場合あり)->読み込みの値と状態により遷移(状態と位置を変化させる) 
 
ではプログラムを考えます。 
読み込み時の状態と読み込みの値から次のする動作が決定するのでこれをmapにしておきます。 
例えば次のように考えます。 
「状態2で記号0を読み込んだ時に、何も書き込まずに、右に一つ移動する。また状態は4に移行する。」というのを、(2,'0')に対し(4,None, 1)を対応させると考えます。 
(書き込みがある場合はNoneの場所をSome(書き込む文字)とします。) 
これらの対応をmapにして定義します。(何のプログラムかは後で説明します。) 
 
> let changeTB = // _はブランクを表す 
    [((1,'0'),(2,None, 1));((1,'1'),(3,None, 1));((1,'+'),(8,None, 1));     ((1,'*'),(8,None, 1));     ((1,'_'),(8,None, 1)); 
     ((2,'0'),(4,None, 1));((2,'1'),(5,None, 1));((2,'+'),(8,None, 1));     ((2,'*'),(8,None, 1));     ((2,'_'),(7,None,-1)); 
     ((3,'0'),(5,None, 1));((3,'1'),(6,None, 1));((3,'+'),(8,None, 1));     ((3,'*'),(8,None, 1));     ((3,'_'),(7,None,-1)); 
     ((4,'0'),(8,None, 1));((4,'1'),(8,None, 1));((4,'+'),(2,Some('0'), 1));((4,'*'),(2,Some('0'), 1));((4,'_'),(8,None, 1)); 
     ((5,'0'),(8,None, 1));((5,'1'),(8,None, 1));((5,'+'),(3,Some('1'), 1));((5,'*'),(2,Some('0'), 1));((5,'_'),(8,None, 1)); 
     ((6,'0'),(8,None, 1));((6,'1'),(8,None, 1));((6,'+'),(2,Some('0'), 1));((6,'*'),(3,Some('1'), 1));((6,'_'),(8,None, 1)); 
     //7はaccept(正常終了を表します。) 
     //8,9はエラー処理(互いに相手を呼び合い終了しなくします。) 
     ((8,'0'),(9,None,-1));((8,'1'),(9,None,-1));((8,'+'),(9,None,-1));     ((8,'*'),(9,None,-1));     ((8,'_'),(9,None,-1)); 
     ((9,'0'),(8,None, 1));((9,'1'),(8,None, 1));((9,'+'),(8,None, 1));     ((9,'*'),(8,None, 1));     ((9,'_'),(8,None, 1)); 
 
    ] 
    |> Map.ofList;; 
 
val changeTB : Map<(int * char),(int * char option * int)> = 
  map 
    [((1, '*'), (8, null, 1)); ((1, '+'), (8, null, 1)); 
     ((1, '0'), (2, null, 1)); ((1, '1'), (3, null, 1)); 
     ((1, '_'), (8, null, 1)); ((2, '*'), (8, null, 1)); 
     ((2, '+'), (8, null, 1)); ((2, '0'), (4, null, 1)); 
     ((2, '1'), (5, null, 1)); ...] 
      
これはi j + k * (普通の書き方をすると(i+j)*k)の計算をするプログラムです。 
ただしi,j,kは0か1で 1+1=0と定義するものとします。 
テープは最初に11+1*とか10+0*等の形で、印字されているものとし、ヘッド位置は左端にあるものとします。(最後にヘッドが停止した位置の値が計算結果です。) 
 
テープもマップで表すことにして、例えば01+1*を計算させるためには次のようにマップの初期設定を次のようにします。 
 
> let init_tape = 
    [(0,'0');(1,'1');(2,'+');(3,'1');(4,'*')] 
    |> Map.ofList;; 
 
val init_tape : Map<int,char> = 
  map [(0, '0'); (1, '1'); (2, '+'); (3, '1'); (4, '*')] 
 
では上の動作対応Mapと、現在のテープおよび、現在の状態ナンバー、現在のヘッド位置を引数にして、変化したテープ、次の状態ナンバー、次のヘッド位置を返す関数を定義します。 
 
> let TM_OneStepExecResult (in_changeTB: Map<(int * char),(int * char option * int)>) ((curTape:Map<int,char>),curStateNo,curPos) = 
        //mapにindex登録があれば、indexに対応するchar、なければ'_'(blank) 
        let charAtPos = 
                if Map.containsKey curPos curTape then 
                    curTape.[curPos] 
                else '_' 
        let (nextStateNo,doWrite,headMove) = in_changeTB.[(curStateNo,charAtPos)] 
        let nextTape = 
            if doWrite.IsNone then 
                curTape 
            else 
                if doWrite.Value = '_' then 
                    Map.remove curPos curTape 
                else 
                    Map.add curPos doWrite.Value curTape 
        let nextPos = curPos + headMove 
        (nextTape,nextStateNo,nextPos);; 
 
val TM_OneStepExecResult : 
  Map<(int * char),(int * char option * int)> -> 
    Map<int,char> * int * int -> Map<int,char> * int * int 
 
先ほどのinit_tape と動作対応Mapを用いて、一ステップだけ動かしてみます。 
 
> TM_OneStepExecResult changeTB (init_tape,1,0)//1は最初の状態、0は最初の位置;; 
val it : Map<int,char> * int * int = 
  (map [(0, '0'); (1, '1'); (2, '+'); (3, '1'); (4, '*')], 2, 1) 
 
これで、状態2に移り、位置が1になったことがわかります。 
 
では、動作対応Map、初期テープ、最初の状態No.、最初のヘッド位置、終了状態No.を与えると、最後まで連続して実行する関数を定義します。 
 
> let TM_Exec in_changeTB in_initTape in_initStateNo in_startPos in_finStateNo  = 
        let oneStepExec = TM_OneStepExecResult in_changeTB 
        let rec execAll ((curTape:Map<int,char>),curStateNo,curPos) = 
            printfn "%A" (curTape,curStateNo,curPos) //表示用関数で表示 
            if curStateNo = in_finStateNo then 
                                (curTape,curStateNo,curPos) 
            else 
                let nextArg = oneStepExec (curTape,curStateNo,curPos) 
                execAll nextArg 
        execAll (in_initTape,in_initStateNo,in_startPos);; 
 
val TM_Exec : 
  Map<(int * char),(int * char option * int)> -> 
    Map<int,char> -> int -> int -> int -> Map<int,char> * int * int 
 
>  
 
では先ほど定義した、init_tape(01+1*の計算用)を試しに使って実行してみます。 
 
> TM_Exec changeTB init_tape 1 0 7 ;; 
(map [(0, '0'); (1, '1'); (2, '+'); (3, '1'); (4, '*')], 1, 0) 
(map [(0, '0'); (1, '1'); (2, '+'); (3, '1'); (4, '*')], 2, 1) 
(map [(0, '0'); (1, '1'); (2, '+'); (3, '1'); (4, '*')], 5, 2) 
(map [(0, '0'); (1, '1'); (2, '1'); (3, '1'); (4, '*')], 3, 3) 
(map [(0, '0'); (1, '1'); (2, '1'); (3, '1'); (4, '*')], 6, 4) 
(map [(0, '0'); (1, '1'); (2, '1'); (3, '1'); (4, '1')], 3, 5) 
(map [(0, '0'); (1, '1'); (2, '1'); (3, '1'); (4, '1')], 7, 4) 
val it : Map<int,char> * int * int = 
  (map [(0, '0'); (1, '1'); (2, '1'); (3, '1'); (4, '1')], 7, 4) 
   
最後のテープの状態から、ヘッド位置は4であることがわかり、4の位置には1が書き込まれているので、1が計算結果となります。 
 
最後に、状態番号はどのような意味になっているのかを少し説明しておきます。 
これはスタックマシンを模していて 
状態1はスタックが空で、今から「2項演算対象の一つ目の数値」をスタックに押し込む状態を表しています。 
0なら状態2へ、1なら状態3へ移行します。 
状態2は0がスタックに積まれた状態で、読み取った数字が0なら状態5へ、1なら状態6へ移行します。 
状態5は0が2個スタックに積まれた場合なので、+を読み込んだ時は計算結果の0が1個だけスタックに積まれた状態、すなわち状態2へ移行します...という意味合いでこのチューリングマシンのプログラムは書かれています。 
 
次回はWinソフト化します。今回のコードは以下の通りです。 
 
let init_tape = 
    [(0,'0');(1,'1');(2,'+');(3,'1');(4,'*')] 
    |> Map.ofList 
 
let changeTB = // _はブランクを表す 
    [((1,'0'),(2,None, 1));((1,'1'),(3,None, 1));((1,'+'),(8,None, 1));     ((1,'*'),(8,None, 1));     ((1,'_'),(8,None, 1)); 
     ((2,'0'),(4,None, 1));((2,'1'),(5,None, 1));((2,'+'),(8,None, 1));     ((2,'*'),(8,None, 1));     ((2,'_'),(7,None,-1)); 
     ((3,'0'),(5,None, 1));((3,'1'),(6,None, 1));((3,'+'),(8,None, 1));     ((3,'*'),(8,None, 1));     ((3,'_'),(7,None,-1)); 
     ((4,'0'),(8,None, 1));((4,'1'),(8,None, 1));((4,'+'),(2,Some('0'), 1));((4,'*'),(2,Some('0'), 1));((4,'_'),(8,None, 1)); 
     ((5,'0'),(8,None, 1));((5,'1'),(8,None, 1));((5,'+'),(3,Some('1'), 1));((5,'*'),(2,Some('0'), 1));((5,'_'),(8,None, 1)); 
     ((6,'0'),(8,None, 1));((6,'1'),(8,None, 1));((6,'+'),(2,Some('0'), 1));((6,'*'),(3,Some('1'), 1));((6,'_'),(8,None, 1)); 
     //7はaccept 
     //8,9はエラー処理(交互に呼び出し、エンドレスループに入る) 
     ((8,'0'),(9,None,-1));((8,'1'),(9,None,-1));((8,'+'),(9,None,-1));     ((8,'*'),(9,None,-1));     ((8,'_'),(9,None,-1)); 
     ((9,'0'),(8,None, 1));((9,'1'),(8,None, 1));((9,'+'),(8,None, 1));     ((9,'*'),(8,None, 1));     ((9,'_'),(8,None, 1)); 
 
    ] 
    |> Map.ofList 
 
let TM_OneStepExecResult (in_changeTB: Map<(int * char),(int * char option * int)>) ((curTape:Map<int,char>),curStateNo,curPos) = 
        //mapにindex登録があれば、indexに対応するchar、なければ'_'(blank) 
        let charAtPos = 
                if Map.containsKey curPos curTape then 
                    curTape.[curPos] 
                else '_' 
        let (nextStateNo,doWrite,headMove) = in_changeTB.[(curStateNo,charAtPos)] 
        let nextTape = 
            if doWrite.IsNone then 
                curTape 
            else 
                if doWrite.Value = '_' then 
                    Map.remove curPos curTape 
                else 
                    Map.add curPos doWrite.Value curTape 
        let nextPos = curPos + headMove 
        (nextTape,nextStateNo,nextPos) 
  
let TM_Exec in_changeTB in_initTape in_initStateNo in_startPos in_finStateNo  = 
        let oneStepExec = TM_OneStepExecResult in_changeTB 
        let rec execAll ((curTape:Map<int,char>),curStateNo,curPos) = 
            printfn "%A" (curTape,curStateNo,curPos) //表示用関数で表示 
            if curStateNo = in_finStateNo then 
                                (curTape,curStateNo,curPos) 
            else 
                let nextArg = oneStepExec (curTape,curStateNo,curPos) 
                execAll nextArg 
        execAll (in_initTape,in_initStateNo,in_startPos) 
 
 
 
TM_Exec changeTB init_tape 1 0 7  |> ignore 

続きを読む

テーマ : プログラミング
ジャンル : コンピュータ

F#で入門 コンパイラ 、インタプリタ編 記号表(9)

 今回は前回までの内容を、Winソフト化します。   
実行画面は次の通りです。 
 
1042.jpg
 
使用方法等は前回のソフトとまったく同様なので略します。 
 
コードは以下の通りです。

続きを読む

テーマ : プログラミング
ジャンル : コンピュータ

F#で入門 コンパイラ 、インタプリタ編 記号表(8)

 前回はソースコード 
struct A {  
  int x;  
  struct B {int y;};  
  B z;  
  };  
  
A k;  
int u = k.z.y;  
 
に対応する、ASTが 
 
[StructDecAST0  
   ("A",(1, 10),  
    [VarDecAST0 ("int", (1, 17), "x", (1, 21), null);  
     StructDecAST0  
       ("B",(1, 34),[VarDecAST0 ("int", (1, 37), "y", (1, 41), null)]);  
     VarDecAST0 ("B", (1, 49), "z", (1, 51), null)]);  
 VarDecAST0 ("A", (1, 63), "k", (1, 65), null);  
 VarDecAST0  
   ("int", (1, 69), "u", (1, 73),  
    Some (DotExpAST0 ("k",(1, 77),[("z", (1, 79)); ("y", (1, 81))])))]  
 
となるようにDiscrimitive Unionと変換関数を定義しましたが、今回は記号表を定義していきます。 
 
以前取り上げた入れ子に対応した記号表とほぼ同じですが、追加としてScopedSymbolクラスの子クラスとして,StructSymbolクラスを定義します。 
 
なお、ScopedSymbolクラスで、名前の解決をする場合、辞書で見つからなければ、それを包含する部分で更に探すように再帰処理をしていましたが、Struct内で、名前を探す場合、見つからなければそれで終わりです。 
例えば 
int y; 
struct A {  
  int x;  
 }; 
で 
A k; 
A.y 
としたとき、Struct内でyを検索しますが、(上の場合は、、Struct内にyはないのでエラー)このときその上のスコープまで捜しにいってはいけないということです。 
このため、resolveMemberというメソッドを定義して、そのStructの辞書内だけで、記号を探すようにします。 
 
また、今回はA.xというようなドット表記された表現を処理を考える必要があります。 
 
struct A {  
  int x;  
  struct B {int y;};  
  B z;  
  };  
  
A k;  
int u = k.z.y;  
 
という例でk.z.yという部分を処理するには、まずkの型を調べて、struct A型ということをおさえ、次に 
Aに対応する記号表の部分で、zの型を調べ、zがB型という情報を得てからBに対応する記号法の部分でyの型をしらべint型だということを得ます。 
この処理のに対応するコードの抜粋は下の様になります。 
 
        |DotExpAST0(dotExpName,dotExpPos,fieldListExp)  //////////この部分全部追加///////////////////////////////////////////// 
            ->  //一つ目の参照演算 現スコープでdotExpNameの型を求める a.x.yならaの、b.xならbの処理 
                let varRef = (!cur_scope).resolve(dotExpName) 
                if varRef.IsNone then 
                    printfn "%A %A この変数名が登録されていないため参照を解決できません。" dotExpName dotExpPos 
                else 
                    let varrv = varRef.Value //型を得る 
                    match varrv with 
                    | :? VariableSymbol -> 
                        printfn "%A %A は 型名 %Aへの参照として解決しました。" dotExpName dotExpPos varrv.SType.Value  
                        //fieldList部分の処理 
                        let mutable parentType = varrv.SType.Value //a.x.yならxのparentType は aのtype,yのparentType は xのtype 
                        for (fldName,fldPos) in fieldListExp do 
                            let strctSymScope = parentType :?> StructSymbol  
                            let sym = strctSymScope.resolveMember(fldName) 
                            if sym.IsNone then      
                                printfn "%A %A このfield名が登録されていないため参照を解決できません。" fldName fldPos 
                            else 
                                printfn "field %A %A は 型名 %Aへの参照として解決しました。" fldName fldPos (sym.Value.SType.Value) 
                            parentType<- sym.Value.SType.Value 
  
                    | _ ->  
                        printfn "%A %A は %Aが変数名でないため解決できません。" dotExpName dotExpPos dotExpName 
                         
                         
 
 
以上のことをふまえ、 
 
struct A {int x; struct B {int y;};B b;struct C {int z;};C c;};void f (){A a;int d = a.b.y;}; 
 
を処理させると次のような表示がなされるようにしました。 
(int,float,voidは先に定義しておきます。) 
 
[StructDecAST0 
   ("A",(1, 8), 
    [VarDecAST0 ("int", (1, 11), "x", (1, 15), null); 
     StructDecAST0 
       ("B",(1, 25),[VarDecAST0 ("int", (1, 28), "y", (1, 32), null)]); 
     VarDecAST0 ("B", (1, 36), "b", (1, 38), null); 
     StructDecAST0 
       ("C",(1, 47),[VarDecAST0 ("int", (1, 50), "z", (1, 54), null)]); 
     VarDecAST0 ("C", (1, 58), "c", (1, 60), null)]); 
 FuncDecAST0 
   ("void",(1, 64),"f",(1, 69),[], 
    BlockStmtAST0 
      [VarDecStmtAST0 ("A", (1, 74), "a", (1, 76), null); 
       VarDecStmtAST0 
         ("int", (1, 78), "d", (1, 82), 
          Some (DotExpAST0 ("a",(1, 86),[("b", (1, 88)); ("y", (1, 90))])))])] 
struct "A" (1, 8)を定義しました 
structスコープに移動します 
"int" (1, 11) は 参照 ref:"int" として解決しました。 
変数 "x" (1, 15)を定義しました 
struct "B" (1, 25)を定義しました 
structスコープに移動します 
"int" (1, 28) は 参照 ref:"int" として解決しました。 
変数 "y" (1, 32)を定義しました 
structスコープを上にもどります。できたscope内の登録は次の通りです 
"struct:B: field and struc Symbol ("y" <y:int> )" 
"B" (1, 36) は 参照 ref:"B" として解決しました。 
変数 "b" (1, 38)を定義しました 
struct "C" (1, 47)を定義しました 
structスコープに移動します 
"int" (1, 50) は 参照 ref:"int" として解決しました。 
変数 "z" (1, 54)を定義しました 
structスコープを上にもどります。できたscope内の登録は次の通りです 
"struct:C: field and struc Symbol ("z" <z:int> )" 
"C" (1, 58) は 参照 ref:"C" として解決しました。 
変数 "c" (1, 60)を定義しました 
structスコープを上にもどります。できたscope内の登録は次の通りです 
"struct:A: field and struc Symbol ("x" <x:int> )("B" struct:B: field and struc S 
ymbol ("y" <y:int> ) )("b" <b:B> )("C" struct:C: field and struc Symbol ("z" <z: 
int> ) )("c" <c:C> )" 
"void" (1, 64) は 参照 ref:"void" として解決しました。 
関数 "f" (1, 69)を定義しました 
メソッドスコープに移動します 
ローカルスコープに移動します 
"A" (1, 74) は 参照 ref:"A" として解決しました。 
変数 "a" (1, 76)を定義しました 
"a" (1, 86) は 型名 struct:A: field and struc Symbol ("x" <x:int> )("B" struct: 
B: field and struc Symbol ("y" <y:int> ) )("b" <b:B> )("C" struct:C: field and s 
truc Symbol ("z" <z:int> ) )("c" <c:C> )への参照として解決しました。 
field "b" (1, 88) は 型名 struct:B: field and struc Symbol ("y" <y:int> )への参 
照として解決しました。 
field "y" (1, 90) は 型名 intへの参照として解決しました。 
"int" (1, 78) は 参照 ref:"int" として解決しました。 
変数 "d" (1, 82)を定義しました 
スコープを上に戻ります。できたscope内の登録は次の通りです 
" "a" <a:A> 
 "d" <d:int> 
メソッドスコープを上にもどります。できたscope内の登録は次の通りです 
"method:f: args " 
グローバルスコープ内の登録は次の通りです。 
" "int" int 
 "float" float 
 "void" void 
 "A" struct:A: field and struc Symbol ("x" <x:int> )("B" struct:B: field and str 
uc Symbol ("y" <y:int> ) )("b" <b:B> )("C" struct:C: field and struc Symbol ("z" 
 <z:int> ) )("c" <c:C> ) 
 "f" method:f: args 
 
次回はいつもの通りこれをWinソフト化します。 
 
今回のコードは以下の通りです。 

続きを読む

テーマ : プログラミング
ジャンル : コンピュータ

プロフィール

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。