annotate paper/chapter/05-perl.tex @ 69:9950430ccc47

...
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Wed, 03 Feb 2021 21:29:14 +0900
parents bb057c720016
children d50a39e6e6a7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
50
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 40
diff changeset
1 \chapter{トランスコンパイラによるメタ計算}
4
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
2
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
3 GearsOSはCbCで実装を行う。
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
4 CbCはC言語よりアセンブラに近い言語である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
5 すべてを純粋なCbCで記述すると記述量が膨大になる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
6 またノーマルレベルの計算とメタレベルの計算を、全てプログラマが記述する必要がでる。
4
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
7 メタ計算では値の取り出しなどを行うが、 これはノーマルレベルのCodeGearのAPIが決まれば一意に決定される。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
8 したがってノーマルレベルのみ記述すれば、 機械的にメタ部分の処理は概ね生成可能となる。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
9 また、メタレベルのみ切り替えたいなどの状況が存在する。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
10 ノーマルレベル、メタレベル共に同じコードの場合は記述の変更量が膨大であるが、 メタレベルの作成を分離するとこの問題は解消される。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
11
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
12 GearsOSではメタレベルの処理の作成にPerlスクリプトを用いており、 ノーマルレベルで記述されたCbCから、 メタ部分を含むCbCへと変換する。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
13 変換前のCbCをGearsCbCと呼ぶ。
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14
8
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
15 \section{トランスコンパイラ}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
16 プログラミング言語から実行可能ファイルやアセンブラを生成する処理系のことを、一般的にコンパイラと呼ぶ。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
17 特定のプログラミング言語から別のプログラミング言語に変換するコンパイラのことを、 トランスコンパイラと呼ぶ。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
18 トランスコンパイラとしてはJavaScriptを古い規格のJavaScriptに変換するBabel\cite{babel}がある。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
19
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
20 またトランスコンパイラは、変換先の言語を拡張した言語の実装としても使われる。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
21 JavaScriptに強い型制約をつけた拡張言語であるTypeScriptは、 TypeScriptから純粋なJavaScriptに変換を行うトランスコンパイラである。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
22 すべてのTypeScriptのコードはJavaScriptにコンパイル可能である。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
23 JavaScriptに静的型の機能を取り込みたい場合に使われる言語であり、 JavaScriptの上位の言語と言える。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
24
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 7
diff changeset
25
60
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
26 GearsOSはCbCにノーマルレベル、メタレベルの書き別けの機能などを追加した拡張言語であると言える。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
27 コンパイル時にCMakeによって呼び出される2種類のPerlスクリプトで等価な純粋なCbCに変換される。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
28 これらのPerlスクリプトはGearsOSのCbCから純粋なCbCへと変換している為に一種のトランスコンパイラと言える。
17
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 16
diff changeset
29
60
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
30 \section{トランスコンパイラによるメタレベルのコード生成}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
31 トランスコンパイラはノーマルレベルで記述されたGearsOSを、メタレベルを含むCbCへと変換する役割である。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
32 変換時に様々なメタ情報をCbCのファイルに書き出すことが可能である。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
33 従来はStubの生成や、 引数の変更などを行っていたが、 さらにメタレベルのコードをトランスコンパイラで作製したい。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
34 トランスコンパイラ上でメタレベルのコードを作製することによって、 GearsOS上でのアプリケーションの記述が容易になり、かつメタレベルのコードを柔軟に扱うことができる。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
35 本研究では様々なメタレベルのコードを、トランスコンパイラで生成することを検討した。
16
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 14
diff changeset
36
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 14
diff changeset
37
69
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 68
diff changeset
38 \section{トランスコンパイラ用のPerlライブラリ作製}
68
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
39 従来のPerlトランスコンパイラはgenerate\_stub.plとgenerate\_context.plの2種類のスクリプトで構築されていた。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
40 これらのスクリプトはそれぞれ独立した処理を行っていた。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
41
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
42 しかし本研究を進めるにつれて、 Interfaceのパーサーやメタ計算部分の操作を行うAPIなど、 Perlスクリプトで共通した実装が見られた。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
43 さらにgenerate\_stub.plらPerlスクリプトの行数や処理の複雑度が上がり、 適切に処理をモジュール化する必要が生じた。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
44 この為新しく実装したPerlトランスコンパイラが利用するAPIは、 Perlのモジュール機能を利用しモジュールの形で実装した。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
45 以下に実装したモジュールファイルと、その概要を示す。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
46
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
47 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
48 \item \texttt{Gears::Context}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
49 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
50 \item context.hの自動生成時に呼び出されるモジュール
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
51 \item 変換後のCbCのコードを解析し、使用されているDataGearの数え上げを行う
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
52 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
53 \item \texttt{Gears::Interface}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
54 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
55 \item InterfaceおよびImplementのパーサー
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
56 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
57 \item \texttt{Gears::Template}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
58 Gears::Template以下はPerlスクリプトが生成する際に、テンプレートとして呼び出すファイルの定義などがある
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
59 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
60 \item \texttt{Gears::Template::Context}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
61 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
62 \item context.hのテンプレート
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
63 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
64 \item \texttt{Gears::Template::Context::XV6}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
65 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
66 \item CbC Xv6 専用のcontext.hのテンプレート
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
67 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
68 \item \texttt{Gears::Template::Gmain}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
69 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
70 \item GearsOS Main関数のテンプレート
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
71 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
72 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
73 \item \texttt{Gears::Stub}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
74 \begin{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
75 \item Stub Code Gear生成時に呼び出されるモジュール
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
76 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
77 \end{itemize}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
78
69
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 68
diff changeset
79 これらはgenerate\_stub.plおよびgenerate\_context.plおよび、本研究で作製したPerlのツールセットからも呼び出される。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 68
diff changeset
80
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
81 \section{context.hの自動生成}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
82 GearsOSのContextの定義はcontext.hにある。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
83 ContextはGearsOSの計算で使用されるすべてのCodeGear、 DataGearの情報を持っている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
84 context.hではDataGearに対応する\texttt{union Data}型の定義も行っている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
85 Data型はCの共用体であり、 Dataを構成する要素として各DataGearがある。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
86 各DataGearは構造体の形で表現されている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
87 各DataGear自体の定義もcontext.hのunion Dataの定義の中で行われている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
88
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
89 DataGearの定義はInterfaceファイルで行っていた。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
90 InterfaceファイルはGearsOS用に拡張されたシンタックスのヘッダファイルを使っており、 直接CbCからロードすることができない。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
91 その為従来はプログラマが静的にInterfaceファイルをCbCの文脈に変換し、 context.hに構造体に変換したものを書いていた。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
92 この手法では手書きでの構築のために自由度は高かったが、 GearsOSの例題によっては使わないDataGearも、 context.hから削除しない限りcontextに含んでしまう問題があった。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
93 さらにInterfaceファイルで定義した型をcontext.hに転記し、それをもとにImplの型を考えてCbCファイルを作製する必要があった。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
94 これらをすべてユーザーが行うと、ファイルごとに微妙な差異が発生したりとかなり煩雑な実装を要求されてしまう。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
95 DataGearの定義はInterfaceファイルを作製した段階で決まり、 使用しているDataGear、CodeGearはコンパイル時に確定するはずである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
96 使用している各Gearがコンパイル時に確定するならば、 コンパイルの直前に実行されるPerlトランスコンパイラでもGearの確定ができるはずである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
97 ここからcontext.hをコンパイルタイミングでPerlスクリプト経由で生成する手法を考案した。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
98
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
99 \subsection{context.hの作製フロー}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
100 GearsCbCからメタ計算を含むCbCファイルに変換するgenerate\_stub.plは各CbCファイルを1つ1つ呼び出していた。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
101 context.hを生成しようとする場合、 プロジェクトで利用する全CbCファイルを扱う必要がある。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
102
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
103 Contextの初期化ルーチンを作製するgenerate\_context.plは、その特性上すべてのCbCファイルをロードしていた。
61
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
104 したがってcontext.hを作製する場合はこのスクリプトで行うと現状のCMakeに手をつけずに変更ができる。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
105
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
106 \subsection{context.hのテンプレートファイル}
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
107
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
108 Perlのモジュールとして\texttt{Gears::Template::Context}を作製した。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
109 xv6プロジェクトの場合は一部ヘッダファイルに含める情報が異なる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
110
61
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
111 派生モジュールとして\texttt{Gears::Template::Context::XV6}も実装した。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
112 これらのテンプレートモジュールはgenerate\_context.plの実行時のオプションで選択可能である。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
113
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
114 呼び出しにはPerlの動的モジュールロード機能を利用している。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
115 各モジュールに共通のAPIを記述しており、 テンプレートに限らず共通して呼び出すことが可能である。
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
116
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
117
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
118 \section{メタ計算部分の入れ替え}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
119 GearsOSでは次のCodeGearに移行する前のMetaCodeGearとして、 デフォルトでは\texttt{\_\_code meta}が使われている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
120 \texttt{\_\_code meta}はcontextに含まれているCodeGearの関数ポインタを、 enumからディスパッチして次のStub CodeGearに継続するものである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
121
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
122 例えばモデル検査をGearsOSで実行する場合、 通常のStub CodeGearのほかに状態の保存などを行う必要がある。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
123 この状態の保存に関する一連の処理は明らかにメタ計算であるので、 ノーマルレベルのCodeGearではない箇所で行いたい。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
124 ノーマルレベル以外のCodeGearで実行する場合は、 通常のコード生成だとStubCodeGearの中で行うことになる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
125 StubCodeGearは自動生成されてしまうため、 値の取り出し以外のことを行う場合は自分で実装する必要がある。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
126 しかしモデル検査に関する処理は様々なCodeGearの後に行う必要があるため、 すべてのCodeGearのStubを静的に実装するのは煩雑である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
127
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
128 ノーマルレベルのCodeGearの処理の後に、StubCodeGear以外のMeta Code Gearを実行したい。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
129 Stub Code Gearに直ちに遷移してしまう\texttt{\_\_code meta}以外のMeta CodeGearに、 特定のCodeGearの計算が終わったら遷移したい。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
130 このためには、特定のCodeGearの遷移先のMetaCodeGearをユーザーが定義できるAPIが必要となる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
131 このAPIを実装すると、ユーザーが柔軟にメタ計算を選択することが可能となる。
60
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 59
diff changeset
132 これはいわゆるリフレクション処理に該当する。
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
133
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
134 GearsOSのビルドシステムのAPIとして\texttt{meta.pm}を作製した。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
135 これはPerlのモジュールファイルとして実装した。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
136 meta.pmはPerlで実装されたGearsOSのトランスコンパイラであるgenerate\_stub.plから呼び出される。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
137 meta.pmの中のサブルーチンである\texttt{replaceMeta}に変更対象のCodeGearと変更先のMetaCodeGearへのgotoを記述する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
138 ユーザーはmeta.pmのPerlファイルをAPIとしてGearsOSのトランスコンパイラにアクセスすることが可能となる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
139
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
140 具体的な使用例をコード\ref{src:metapm}に示す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
141 meta.pmはサブルーチン\texttt{replaceMeta}が返すリストの中に、特定のパターンで配列を設定する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
142 各配列の0番目には、goto metaを置換したいCodeGearの名前を示すPerl正規表現リテラルを入れる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
143 コード\ref{src:metapm}の例では、\texttt{PhilsImpl}が名前に含まれるCodeGearを指定している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
144 すべてのCodeGearのgotoの先を切り替える場合は\texttt{qr/.*\//}などの正規表現を指定する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
145
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
146 \lstinputlisting[label=src:metapm, caption=meta.pm]{src/meta.pm}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
147
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
148 generate\_stub.plはGears CbCファイルの変換時に、 CbCファイルがあるディレクトリにmeta.pmがあるかを確認する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
149 meta.pmがある場合はモジュールロードを行う。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
150 meta.pmがない場合はmeta Code Gearにgotoするものをデフォルト設定として使う。
61
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
151 これらの処理はPerlのクロージャの形で表現しており、 トランスコンパイラ側では共通のAPIで呼び出すことが可能である。
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
152 各Gode Gearが\texttt{goto文}を呼び出したタイミングでreplaceMetaを呼び出し、 ルールにしたがってgoto文を書き換える。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
153 変換するCodeGearがルールになかった場合は、 デフォルト設定が呼び出される。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
154
59
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
155
68
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
156
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
157 \section{コンパイルタイムでのコンストラクタの自動生成}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 61
diff changeset
158
59
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
159 \section{InterfaceのAPIの自動保管}
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
160
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
161
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
162
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
163 \section{別Interfaceからの書き出しを取得する必要があるCodeGear}
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
165 従来のMetaCodeGearの生成では、 別のInterfaceからの入力を受け取るCodeGearのStubの生成に問題があった。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
166 具体的なこの問題が発生する例題をソースコード\ref{src:insertTest1}に示す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
167 \lstinputlisting[label=src:insertTest1, caption=別Interfaceからの書き出しを取得するCodeGearの例]{src/pop2test.cbc}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
168 この例では\texttt{pop2Test}Code Gearから \texttt{stack->pop2}を呼び出し、 継続として\texttt{pop2Test1}を渡している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
169 \texttt{pop2Test}自体はStackTest Interfaceであり、 \texttt{stack->pop2}の\texttt{stack}はStack Interfaceである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
170 例題ではStack Interfaceの実装はSingleLinkedStackである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
171 SingleLinkedStackの\texttt{pop2}の実装をソースコード\ref{src:pop2}に示す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
172 \lstinputlisting[label=src:pop2, caption=SingleLinkedStackのpop2]{src/pop2.cbc}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
173 pop2はスタックから値を2つ取得するAPIである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
174 pop2の継続は\texttt{next}であり、 継続先に\texttt{data}と\texttt{data1}を渡している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
175 data、 data1は引数で受けている\texttt{union Data*}型の変数であり、 それぞれstackの中の値のポインタを代入している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
176 この操作でstackから値を2つ取得している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
177
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
178
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
179 このコードをgenerate\_stub.pl経由でメタ計算を含むコードに変換する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
180 変換した先のコードを\ref{src:pop2meta}に示す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
181 \lstinputlisting[label=src:pop2meta, caption=SingleLinkedStackのpop2のメタ計算]{src/pop2meta.cbc}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
182 実際は\texttt{next}は\texttt{goto meta}に変換されてしまう。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
183 data、data1は\texttt{goto meta}の前にポインタ変数\texttt{O\_data}が指す値にそれぞれ書き込まれる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
184 \texttt{O\_data}はpop2のStub CodeGearである\texttt{pop2SingleLinkedStack\_stub}で作製している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
185 つまり\texttt{O\_data}はcontext中に含まれているStack Interfaceのデータ保管場所にある変数dataのアドレスである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
186 \texttt{pop2}のAPIを呼び出すと、 Stack Interface中の\texttt{data}にStackに保存されていたデータのアドレスが書き込まれる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
187
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
188
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
189 当初Perlスクリプトが生成した\texttt{pop2Test1}のstub CodeGearはソースコード\ref{src:pop2stub-origin}のものである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
190 CodeGear間で処理されるデータの流れの概要図を図\ref{fig:stackTest1}に示す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
191 \lstinputlisting[label=src:pop2stub-origin, caption=生成されたStub]{src/pop2stub-origin.cbc}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
192 \texttt{\_\_code pop2Test}で遷移する先のCodeGearはStackInterfaceであり、 呼び出しているAPIは\texttt{pop2}である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
193 pop2で取り出したデータは、 上記で確認した通りContext中のStack Interfaceのデータ格納場所に書き込まれる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
194 しかしソースコード\ref{src:pop2stub-origin}の例では\texttt{Gearef(context, StackTest)}でContext中の\texttt{StackTest} Interfaceのdataの置き場所から値を取得している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
195 これはInterfaceのImplのCodeGearは、Interfaceから値を取得するというGearsOSのルールの為である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
196 現状ではpop2でせっかく取り出した値をStubCodeGearで取得できない。
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
198 ここで必要となってくるのは、 実装しているInterface以外の呼び出し元のInterfaceからの値の取得である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
199 今回の例ではStackTest InterfaceではなくStack Interfaceからdata、 data1を取得したい。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
200 どのInterfaceから呼び出されているかは、 コンパイルタイムには確定できるのでPerlのトランスコンパイラでStub Codeを生成したい。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
201
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
202 \begin{figure}[h]
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
203 \begin{center}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
204 \includegraphics[width=130mm]{drawio/stackTest1.pdf}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
205 \end{center}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
206 \caption{stackTest1のstubの概要}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
207 \label{fig:stackTest1}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
208 \end{figure}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
209
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
210 別Interfaceから値を取得するには別の出力があるCodeGearの継続で渡されたCodeGearをまず確定させる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
211 今回の例では\texttt{pop2Test1}が該当する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
212 このCodeGearの入力の値と、 出力があるCodeGearの出力を見比べ、 出力をマッピングすれば良い。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
213 Stack Interfaceのpop2はdataとdata1に値を書き込む。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
214 pop2Test1の引数はdata, data1, stackであるので、前2つにpop2の出力を代入したい。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
215
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
216 Contextから値を取り出すのはメタ計算であるStub CodeGearで行われる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
217 別Interfaceから値を取り出そうとする場合、 すでにPerlトランスコンパイラが生成しているStubを書き換える方法も取れる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
218 しかしStubCodeGearそのものを、 別Interfaceから値を取り出すように書き換えてはいけない。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
219 これは別Interfaceの継続として渡されるケースと、 次のgoto先として遷移するケースがあるためである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
220 前者のみの場合は書き換えで問題ないが、 後者のケースで書き換えを行ってしまうとStubで値を取り出す先が異なってしまう。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
221 どのような呼び出し方をしても対応できるようにするには、 Stubを別に別ける必要がある。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
222
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
223
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
224 GearsOSでは継続として渡す場合や、 次のgoto文で遷移する先のCodeGearはノーマルレベルではenumの番号として表現されていた。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
225 enumが降られるCodeGearは、厳密にはCodeGearそのものではなくStub CodeGearに対して降られる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
226 StubCodeGearを実装した分だけenumの番号が降られるため、 \texttt{goto meta}で遷移する際にenumの番号さえ合わせれば独自定義のStubに継続させることが可能である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
227 別Interfaceから値を取り出したいケースの場合、 取り出してくる先のInterfaceと呼び出し元のCodeGearが確定したタイミングで別のStubCodeGearを生成する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
228 呼び出し元のCodeGearが継続として渡すStubCodeGearのenumを、独自定義したenumに差し替えることでこの問題は解決する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
229 この機能をPerlのトランスコンパイラである\texttt{generate\_stub.pl}に導入した。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
230
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
231 \section{別Interfaceからの書き出しを取得するStubの生成}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
232 別Interfaceからの書き出しを取得する場合、 generate\_stub.plでは次の点をサポートする機能をいれれば実現可能である。
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 \begin{itemize}
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
235 \item goto先のCodeGearが出力を持つInterfaceでかつ継続で渡しているCodeGearが別Interfaceの場合の検知
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
236 \begin{itemize}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
237 \item この場合はgotoしている箇所で渡している継続のenumを、新たに作製したstubのenumに差し替える
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
238 \end{itemize}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
239 \item 継続で実行された場合に別にInterfaceから値をとってこないといけないCodeGear自身
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
240 \begin{itemize}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
241 \item Stubを別のInterfaceから値をとる実装のものを別に作製する
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
242 \end{itemize}
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 \end{itemize}
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
246 \texttt{generate\_stub.pl}内では変換対象のCbCのソースコードを2度読み込む。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
247 最初の読み込み時に継続の状況を確認し、 2度目の読み込み時に状況を踏まえてコードを生成すれば良い。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
248 初回の読み込み時にInterface経由の\texttt{goto}文があった場合に、別Interfaceからの出力があるかなどの情報を確認したい。
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
250 \subsection{初回CbCファイル読み込み時の処理}
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
252 Interface経由でのgoto文は\texttt{goto interface->method()}の形式で呼び出される。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
253 ソースコード\ref{src:parsedOutputStub.pl}はこの形式で来ていた行を読み込んだタイミングで実行される処理である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
254 \lstinputlisting[label=src:parsedOutputStub.pl, caption=goto時に使用するinterfaceの解析]{src/parsedOutputStub.pl}
6
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 4
diff changeset
255
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
256 1行目の正規表現はInterface経由でのgoto文の正規表現パターンである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
257 変数\texttt{\$instance}はInterfaceのインスタンスである。正規表現パターンでは\texttt{interface->method}の\texttt{->}の前に来ている変数名に紐づけられる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
258 変数\texttt{\$method}はgoto先のInterfaceのAPIである。正規表現パターンでは\texttt{interface->method}の\texttt{->}の後に来ているAPI名である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
259 ソースコード\ref{src:insertTest1}の\texttt{pop2Test}では、 \texttt{stack->pop2}の呼び出しをしているため、 \texttt{stack}がインスタンスであり、 \texttt{pop2}がAPIである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
260 現在解析しているgoto文が含まれているCodeGearの名前は、変数\texttt{\$currentCodeGear}で別途保存している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
261 連想配列である\texttt{\$codeGearInfo}の中には、 各CodeGearで使われている変数と変数の型などの情報が格納されている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
262 ソースコード\ref{src:parsedOutputStub.pl}の9行目では、 \texttt{\$codeGearInfo}経由でInterfaceのインスタンスから、具体的にどの型が呼ばれているかを取得する。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
263 \texttt{pop2Test}では、 インスタンス\texttt{stack}に対応する型名は\texttt{Stack}と解析される。
2
e543ba9a8e5c from git
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
265 ソースコード\ref{src:parsedOutputStub.pl}の10行目で実行されている\texttt{findExistsOutputDataGear}はgenerate\_stub.pl内の関数である。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
266 これはInterfaceの名前とメソッド名を与えると、 Interfaceの定義ファイルのパース結果から出力の有無を確認する動きをする。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
267 出力がある場合は出力している変数名の一覧を返す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
268 ソースコード\ref{src:insertTest1}の例では\texttt{pop2}は\texttt{data}と\texttt{data1}を出力している為、 これらがリストとして関数から返される。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
269 出力がない場合は偽値を返すために13行目からのif文から先は動かない。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
270 出力があった場合はgenerate\_stub.plの内部変数に出力する変数名と、 Interfaceの名前の登録を行う。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
271 生成するStubは命名規則は、 Stubの本来のCodeGearの名前の末尾に\texttt{\_}に続けて数値をいれる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
272 \texttt{\_\_code CodeGearStub}の場合は、 \texttt{\_\_code CodeGearStub\_1}となる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
273 この数値は変換した回数となるため、 この回数の計算を行う。
4
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
274
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 2
diff changeset
275
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
276 27行目で\texttt{\$generateHaveOutputStub}のlist要素に現在のCodeGearの名前と、 出力に関する情報を代入している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
277 現在のCodeGearの名前を保存しているのは、この後のコード生成部分でenumの番号を切り替える必要があるためである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
278 ソースコード\ref{src:insertTest1}の例では\texttt{pop2Test}が使うenumを書き換える必要がある為、 ここの\texttt{\$currentCodeGear}はpop2Testとなる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
279 ここで作製した\texttt{\$outputStubElem}は、返還後のCbCコードを生成しているフェーズで呼びされる。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
280
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
281 \subsection{enumの差し替え処理}
35
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 34
diff changeset
282
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
283 ソースコード\ref{src:generatePickNext.pl}の箇所は遷移先のenumをPerlスクリプトで生成し、 GearsOSが実行中にenumをcontextに書き込むコードを生成するフェーズである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
284 \lstinputlisting[label=src:generatePickNext.pl, caption=Gearefのコード生成部分]{src/generatePickNext.pl}
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
285 if文で条件判定をしているが、前者は出力があるケースかどうかのチェックである。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
286 続く条件式はGearsOSのビルドルールとして静的に書いたstubの場合は変更を加えない為に、 静的に書いているかどうかの確認をしている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
287 変数\texttt{\$pick\_next}で継続先のCodeGearの名前を作製している。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
288 CodeGearの名前は一度目の解析で確認した継続先に\texttt{\_}とカウント数をつけている。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
289 ここで作製したCodeGearの名前を、3行目でcontextに書き込むCbCコードとして生成している。
6
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 4
diff changeset
290
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 4
diff changeset
291
58
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
292 実際に生成された例題をソースコード\ref{src:replaceenum}に示す。
b1e2bcdd5191 fix order
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 50
diff changeset
293 \lstinputlisting[label=src:replaceenum, caption=enumの番号が差し替えられたCodeGear]{src/replaceenum.cbc}
59
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
294
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 58
diff changeset
295
61
anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
parents: 60
diff changeset
296 \section{ジェネリクスのサポート}