Module Generator

Generates intermediate codes from the given semantic graph

include Generator__.Instruction
type reg_i = int

レジスタ番号

type functor_ = string * int

ファンクタ := (アトム名, リンクの数)

type lhs_inst =
| PeakAtom of reg_i * functor_

アトムリストの先頭から随時,ファンクタが functor_ であるアトムへの参照を, レジスタ reg_i に格納してゆく

  • failable and possibly rewind
| CheckFunctor of reg_i * functor_

reg_i に格納したアトムのファンクタが functor_ であることを確認する

  • failable and does not rewind
| DerefAtom of reg_i * reg_i * int * int

DerefAtom dst_reg_i src_reg_i src_port_i dst_port_i は, レジスタ src_reg_i が参照するアトムの src_port_i 番目の引数の持つアトムへの参照を このリンクが相手先で dst_port_i 番目の引数に接続されていることを確認して レジスタ dst_reg_i に格納する

  • failable and does not rewind
  • (通常のリンクではなかったときも失敗するようにしようと思っていたけど,そうしないことにする?)
  • 基本的に局所リンクのマッチングに用いる
| CheckRefEq of reg_i * reg_i

CheckRefEq reg_i reg_j は レジスタ reg_i に格納されているアドレスと レジスタ reg_j に格納されているアドレスが等しいことを確認する

  • failable and does not rewind
| CheckRefNeq of reg_i * reg_i

CheckRefEq reg_i reg_j は レジスタ reg_i に格納されているアドレスと レジスタ reg_j に格納されているアドレスが異なることを確認する

  • failable and does not rewind
| BindData of string * reg_i * int

BindData var src_reg_i src_port_i は レジスタ src_reg_i が参照するアトムのポート src_port_i 番目のデータアトムを 変数 var に束縛する

  • 今は完全にインタプリタ方式だが,より低レベルな命令列に変更する必要がある.
| FailMatching of string

仮想マシンを(途中で)強制終了する.デバッグのための命令

ルール左辺におけるマッチングのための中間命令

  • failable は失敗する可能性があるということ
  • rewind は後続の命令が失敗したときに巻き戻しの起点になるということ
  • レジスタに格納するデータはアトムへの参照のみ
  • type register = atom ref
type lhs_insts = lhs_inst list
type rhs_inst =
| PushAtom of reg_i * functor_

PushAtom reg_i functor_ は, ルール右辺で生成する,ファンクタ functor_ の(シンボル)アトムを生成し,レジスタ reg_i に代入する

  • アトムリストへの追加も行う
  • ただし,リンクの値は正しい値にセットされない
| FreeAtom of reg_i

FreeAtom reg_i は, レジスタ reg_i が参照する先のアトムをアトムリストから除去し,メモリを解放する

| Connect of reg_i * int * reg_i * int

Connect reg_i reg_j は, レジスタ reg_i が参照するルール左辺でマッチしたアトムの port_i 番目のリンクと レジスタ reg_j が参照するルール左辺でマッチしたアトムの port_j 番目のリンクとを結ぶ

  • リンクオブジェクトは,基本的には,参照先のアトムと,参照先でのポート番号の組になっている
  • 自由リンク同士を接続するために用いる
| SetData of reg_i * int * string

PushData reg_i port_i var は, ルール右辺で生成する,変数 var に束縛されたデータアトムを生成し, レジスタ reg_i 番目のアトムの,ポート port_i にセットする

  • アトムリストへの追加は行わない
  • 今は完全にインタプリタ方式だが,より低レベルな命令列に変更する必要がある.
| FailPushout of string

仮想マシンを(途中で)強制終了する.デバッグのための命令

ルール右辺におけるマッチングのための中間命令. どれも失敗することはない.

type rhs_insts = rhs_inst list
val string_of_functor : (string * int) -> string
val string_of_lhs_inst : lhs_inst -> string
val string_of_rhs_inst : rhs_inst -> string
val string_of_lhs_insts : lhs_inst list -> string
val string_of_rhs_insts : rhs_inst list -> string
val string_of_rule : (string * (int * (lhs_inst list * Parse__.Syntax.arg list * rhs_inst list))) -> string
val break_line : string -> string
val string_of_prog : ((int * rhs_inst list) * (string * (int * (lhs_inst list * Parse__.Syntax.arg list * rhs_inst list))) list) -> string
val gen_ic_of_rule : Analyze.a_rule -> string * (int * (Generator__.Instruction.lhs_inst list * Parse.arg list * Generator__.Instruction.rhs_inst list))

ルールから中間命令列を生成する

  • 戻り値は,生成した中間命令列と必要になるレジスタの数
val gen_ic_of_rules : Analyze.a_rule list -> (string * (int * (Generator__.Instruction.lhs_inst list * Parse.arg list * Generator__.Instruction.rhs_inst list))) list

ルールセットから中間命令列とレジスタの数のタプルのリストを生成する

val gen_ic_of_init : (Analyze.local_port_map * (int * (string * Corelang.c_link list)) list) -> int * Generator__.Instruction.rhs_inst list

初期状態を生成するための中間命令と必要なレジスタの数を返す

val gen_ic : ((Analyze.local_port_map * (int * (string * Corelang.c_link list)) list) * Analyze.a_rule list) -> (int * Generator__.Instruction.rhs_inst list) * (string * (int * (Generator__.Instruction.lhs_inst list * Parse.arg list * Generator__.Instruction.rhs_inst list))) list

初期状態とルールを受け取って,中間命令やレジスタの本数を返す