Mercurial > hg > CbC > old > device
comparison Idea @ 724:e60c3d8dadd6
convert to UTF-8
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 08 Nov 2008 15:11:06 +0900 |
parents | f536897fa3cb |
children |
comparison
equal
deleted
inserted
replaced
723:c2fb8e2b1dca | 724:e60c3d8dadd6 |
---|---|
1 | 1 |
2 Thu Nov 25 17:27:12 JST 1999 | 2 Thu Nov 25 17:27:12 JST 1999 |
3 | 3 |
4 subroutine call ʤ | 4 subroutine call がない |
5 ɽѿʤ | 5 局所変数もない |
6 ꡢѿ¿Ѥ | 6 その代わり、大域変数を多用する |
7 ѿΥפ϶ɽŪ | 7 大域変数のスコープは局所的 |
8 Fortran Ѥ˶ɽѿŪ˼ | 8 Fortran の用に局所変数は静的に取る |
9 recursion ˤϡʬ¸ | 9 recursion する時には、自分で保存する |
10 subroutine callΥ쥸Υ֤ɽŪ˹Ԥ | 10 subroutine call時のレジスタのセーブも局所的に行う |
11 ϡäѤʤ? | 11 それは、ちょっと変じゃない? |
12 äѤǥեȤΥե졼ϻ⤯? | 12 やっぱりデフォルトのフレームは持ち歩くか? |
13 | 13 |
14 recursive call ȤǤʤΤ̤뤫? | 14 recursive call とそうでないのを区別するか? |
15 | 15 |
16 fp Ѱդɤ | 16 fp は用意する方が良い |
17 | 17 |
18 ؿƱˡѤfpι¤ΤѰդ | 18 関数定義と同時に、それ専用のfpの構造体を用意する |
19 | 19 |
20 C compileˤϡstack⤯ | 20 C をcompileする時には、stackを持ち歩く |
21 fp = (struct func_state *)stack | 21 fp = (struct func_state *)stack |
22 äȡɤ? ⤢櫓͡ | 22 えっと、どこに代入するの? そういう問題もあるわけね。 |
23 㤢fp? ϵʤʡstatic | 23 じゃあ、fpは特別? それは気に入らないな。static |
24 fpˤɤ櫓͡ | 24 なfpにすれば良いわけね。 |
25 | 25 |
26 func(void *stack) { | 26 func(void *stack) { |
27 static struct func_state { | 27 static struct func_state { |
28 static struct func_state *fp; | 28 static struct func_state *fp; |
29 int local1; | 29 int local1; |
30 brahbrah... | 30 brahbrah... |
31 } func_state; // ޤ hidden | 31 } func_state; // ここまで hidden |
32 func_state.fp = (stack -= sizeof(struct func_state)); | 32 func_state.fp = (stack -= sizeof(struct func_state)); |
33 } | 33 } |
34 | 34 |
35 func_state ȤäƤ黻Ҥäɤ? ͡ | 35 func_state をとってくる演算子があった方が良い? そうね。 |
36 func.state | 36 func.state |
37 餤? | 37 ぐらい? |
38 | 38 |
39 fp->local1 ߤʤȤʤ顢C Ʊˤʤ롣 | 39 fp->local1 みたいなことだけするなら、C と同じになる。 |
40 | 40 |
41 call argument ⡢ | 41 call する時のargument も、 |
42 static func_state ֤ | 42 static な func_state に置く |
43 stack func_state ֤ | 43 stack 上の func_state に置く |
44 Ȥ̤褬롣Cȸߴʤ顢ԡ | 44 という二通りの選択肢がある。Cと互換なら、当然、後者。 |
45 | 45 |
46 Recursive ʤԤθϾܤҤ뤫顢static | 46 Recursive なら後者だが、この言語は状態遷移を記述するから、static |
47 ʤΤǤɤϤ | 47 なものでも良いはず。 |
48 | 48 |
49 Internal function ? äƤ⤤... | 49 Internal function は? あってもいいんだけど... |
50 | 50 |
51 Recursive call ˤϡ fp saveɬפ͡ | 51 Recursive call する時には、 fp をsaveする必要があるね。 |
52 (--(struct func_state *)stack) = fp; | 52 (--(struct func_state *)stack) = fp; |
53 call callee(&fp->arg,continuation,stack); | 53 call callee(&fp->arg,continuation,stack); |
54 call Ƥ⡢äʤ... continuation ϰŪˤcode | 54 call しても、戻って来ないから... continuation は一般的にはcode |
55 ... Internal function ˤ뤫 | 55 だから... それは Internal function にするか。 |
56 | 56 |
57 continuation ˰ŪcompileˡͤʤȤʤ | 57 continuation に一般的にcompileする方法を考えないといけないか。 |
58 self ɬפʤ櫓? | 58 self は必要なわけね? |
59 | 59 |
60 ̾ͤʤȤʤ | 60 言語の名前も考えないといかんなぁ。 |
61 | 61 |
62 C ΥѥʤȤʤΤ... | 62 C からのコンパイラも書かないといけないのか... |
63 | 63 |
64 Mon Dec 13 18:53:04 JST 1999 | 64 Mon Dec 13 18:53:04 JST 1999 |
65 | 65 |
66 compiler based ǡ partial evaluation Ǥ? | 66 compiler based で、内部で partial evaluation できる? |
67 | 67 |
68 func databaseȤưʤʤ顢ϤǤʤ | 68 func をdatabaseとして扱えないなら、それはできない。 |
69 | 69 |
70 ܤȤƤϼ갷롣 | 70 しかし、状態遷移としては取り扱える。 |
71 | 71 |
72 func.state | 72 func.state |
73 func.code | 73 func.code |
74 | 74 |
75 ߤʷˤpartial evaluationɤ | 75 みたいな形にしてpartial evaluationすれば良い |
76 | 76 |
77 ǤߤޤΤ? | 77 でも止まるのか? |
78 | 78 |
79 textual ǤʤŪʥɽäɤ? <-> interpreter? | 79 textual でない、中間的なコード表現があった方が良い? <-> interpreter? |
80 | 80 |
81 Prolog ǤϤʤǤʤ? --> Unification Ť | 81 Prolog ではなんでいけないの? --> Unification が重いから |
82 | 82 |
83 Sat Nov 27 13:50:41 JST 1999 | 83 Sat Nov 27 13:50:41 JST 1999 |
84 | 84 |
85 func.state ȤΤä顢 | 85 func.state とか作るのだったら、 |
86 struct { | 86 struct { |
87 struct { | 87 struct { |
88 int i; | 88 int i; |
89 } state; | 89 } state; |
90 state *code = { | 90 state *code = { |
91 i = i+1; | 91 i = i+1; |
92 }; | 92 }; |
93 } name; | 93 } name; |
94 ߤʷǡ켫Τ¤? ǡʬɾ롣 | 94 みたいな形で、それ自体を構造化すれば? で、代入すると部分評価される。 |
95 ǽʤۤɡ | 95 代入も可能。なるほど。 |
96 *name.code; | 96 *name.code; |
97 ͤϤ櫓? ͤ &state Ǥ礦͡ | 97 値はあるわけ? 値は &state でしょうね。 |
98 self С | 98 self があれば、 |
99 struct { | 99 struct { |
100 struct { | 100 struct { |
101 int i; | 101 int i; |
102 } state, | 102 } state, |
103 *code = { | 103 *code = { |
104 self->i = self->i+1; | 104 self->i = self->i+1; |
105 }; | 105 }; |
106 } name; | 106 } name; |
107 ʡself = state ͡ | 107 かな。self = state だよね。 |
108 | 108 |
109 union γĥ⤢碌Ƶ... | 109 union の拡張もあわせて議論すると... |
110 | 110 |
111 Partial evaluator ޥƥ¹ԷϤˤƤȤϲǽ? | 111 Partial evaluator をセマンティクスや実行系にいれておくことは可能か? |
112 | 112 |
113 byte code ȤۥޥäǽǤʤ? | 113 byte code とか仮想マシンだったら可能。そうでない場合は? |
114 | 114 |
115 ˤ衢¤ΤΥuniqueʤȤʡ | 115 いずれにせよ、構造体のタグのunique性を修正しないとだめだな。 |
116 | 116 |
117 إåեϤɤ? | 117 ヘッダファイルはどうするの? |
118 | 118 |
119 Mon Dec 13 18:53:18 JST 1999 | 119 Mon Dec 13 18:53:18 JST 1999 |
120 | 120 |
121 library Ȥ? | 121 library との整合性は? |
122 | 122 |
123 exec sequence Ǥϡ | 123 exec sequence では、 |
124 (--(struct func_state *)stack) = fp; | 124 (--(struct func_state *)stack) = fp; |
125 call callee(&fp->arg); | 125 call callee(&fp->arg); |
126 ȤpointerϤ? Ѥ͡ | 126 という形でpointerだけ渡すの? それは変だよね。 |
127 | 127 |
128 ϤˤȤСʣͤϤۤɤ | 128 値渡しにするとすれば、複数の値を渡せたほうが良い。 |
129 | 129 |
130 func(void *stack) { | 130 func(void *stack) { |
131 static struct func_state { | 131 static struct func_state { |
132 static struct func_state *fp; | 132 static struct func_state *fp; |
133 int local1; | 133 int local1; |
134 brahbrah... | 134 brahbrah... |
135 } func_state; // ޤ hidden | 135 } func_state; // ここまで hidden |
136 func_state.fp = (stack -= sizeof(struct func_state)); | 136 func_state.fp = (stack -= sizeof(struct func_state)); |
137 } | 137 } |
138 | 138 |
139 ΰΤ¤ΤǤ٤ | 139 の引数自体が、構造体であるべき。 |
140 | 140 |
141 func( | 141 func( |
142 struct void *stack | 142 struct void *stack |
143 ) { | 143 ) { |
144 static struct func_state { | 144 static struct func_state { |
145 static struct func_state *fp; | 145 static struct func_state *fp; |
146 int local1; | 146 int local1; |
147 brahbrah... | 147 brahbrah... |
148 } func_state; // ޤ hidden | 148 } func_state; // ここまで hidden |
149 func_state.fp = (stack -= sizeof(struct func_state)); | 149 func_state.fp = (stack -= sizeof(struct func_state)); |
150 } | 150 } |
151 | 151 |
152 ǡ¤Τ register storage | 152 で、構造体に register storage を許す。 |
153 | 153 |
154 func( | 154 func( |
155 static struct argument { | 155 static struct argument { |
156 register void *stack; | 156 register void *stack; |
157 register void *continuation; | 157 register void *continuation; |
159 ) { | 159 ) { |
160 static struct func_state { | 160 static struct func_state { |
161 static struct func_state *fp; | 161 static struct func_state *fp; |
162 int local1; | 162 int local1; |
163 brahbrah... | 163 brahbrah... |
164 } func_state; // ޤ hidden | 164 } func_state; // ここまで hidden |
165 func_state.fp = (stack -= sizeof(struct func_state)); | 165 func_state.fp = (stack -= sizeof(struct func_state)); |
166 } | 166 } |
167 | 167 |
168 ȡcaller ⡢¤ΤȤΤ | 168 すると、caller の方も、構造体を引数とするのが自然。 |
169 | 169 |
170 call caller( | 170 call caller( |
171 static struct argument { | 171 static struct argument { |
172 register void *stack; | 172 register void *stack; |
173 register void *continuation; | 173 register void *continuation; |
174 } arg = {a,b}; | 174 } arg = {a,b}; |
175 ) | 175 ) |
176 | 176 |
177 ߤʡι¤ΤϥեȸƤФ롣 | 177 みたいな。もちろん、この構造体はインタフェースと呼ばれる。 |
178 | 178 |
179 argument ϡcallee ˤäɤɡcaller ¦ˤäƤ | 179 argument は、callee にあった方が良いけど、caller 側にあっても |
180 ɤregister ʤϡ | 180 良い。register なんかは、そう。 |
181 | 181 |
182 caller(interface caller_arg = {a,b,c}) | 182 caller(interface caller_arg = {a,b,c}) |
183 ߤsyntax ʡ | 183 みたいなsyntax かな。 |
184 caller->interface = {a,b,c}; | 184 caller->interface = {a,b,c}; |
185 *caller->code; | 185 *caller->code; |
186 | 186 を、 |
187 caller(a,b,c); | 187 caller(a,b,c); |
188 ȾΤ롣 | 188 と称する。 |
189 | 189 |
190 function ˤϡinterface code state 뤳Ȥˤʤ롣 | 190 function には、interface と code と state があることになる。 |
191 | 191 |
192 state ˥lock? protected state? synchronized state ? | 192 state にアクセスする時のlockは? protected state? synchronized state かな? |
193 sequential implementationǤϡʤΤϤʤ | 193 もちろん、sequential implementationでは、そんなものはいらない。 |
194 | 194 |
195 function { | 195 function { |
196 interface: | 196 interface: |
197 register int a; | 197 register int a; |
198 register struct self self; | 198 register struct self self; |
201 serialized int c; | 201 serialized int c; |
202 code: | 202 code: |
203 b = a; | 203 b = a; |
204 } | 204 } |
205 | 205 |
206 int void value 롣ϽŤʤ뤱... | 206 int にvoid value を定義する。実装は重くなるけど... |
207 | 207 |
208 serialized semantics ? | 208 serialized の semantics は? |
209 | 209 |
210 ⤦micro-C˶! | 210 もう少しmicro-Cに近く! |
211 | 211 |
212 carrying state static state | 212 carrying state と static state。 |
213 | 213 |
214 Mon Dec 13 19:42:41 JST 1999 | 214 Mon Dec 13 19:42:41 JST 1999 |
215 | 215 |
216 interface register keyword ȤΤϡޤ | 216 interface に register keyword を使うのは、あまりに |
217 ꤹ롣Ǥ⡢ǤʤȾ֤ˤǤʤ? | 217 実装よりすぎる。でも、でないと状態にできない? |
218 ʤȤϤʤäѤcaller¦static ΰ | 218 そんなことはないか。やっぱりcaller側のstatic 領域に |
219 ľܽ? | 219 直接書き込む? |
220 | 220 |
221 C٤Ǥ⡢40ĤȤ줿... | 221 だとCより遅そう。でも、引数に40個とかかかれたら... |
222 | 222 |
223 Wed Dec 15 14:09:49 JST 1999 | 223 Wed Dec 15 14:09:49 JST 1999 |
224 | 224 |
225 C ȸߴˤ? | 225 C と互換にする? |
226 goto function(arguments); | 226 goto function(arguments); |
227 goto *continuation(arguments); | 227 goto *continuation(arguments); |
228 ߤʴǡ | 228 みたいな感じで。 |
229 | 229 |
230 stackδ? ɤlibrary ȤθߴϤȤʤ | 230 stackの管理は? どうせ、library との互換はとらないと |
231 ʤ... | 231 いけないんだから... |
232 | 232 |
233 local ѿ stack ưǤ⡢᤹ۤʤ | 233 local 変数がある場合は stack を動かす。でも、戻す奴がいない。 |
234 closure 뤫? | 234 closure 化するか? |
235 | 235 |
236 return εưʣˤʤ롣return櫓顣 | 236 return した時の挙動が複雑になる。大域returnするわけだら。 |
237 | 237 |
238 arguments static ΰˤȸߴȤʤ | 238 arguments をstatic 領域にかきこむ方式だと互換性がとれない。 |
239 stack frame pointer ˤʤȥ顣 | 239 stack 上の frame pointer 上にないとダメだから。 |
240 | 240 |
241 ξΩΤ̵? ĤޤꡢȡƤӽФ줿 | 241 両立させるのは無理か? つまり、これだと、呼び出された方の |
242 frame semantics ϡC ȸߴˤʤ롣顢stackľ | 242 frame semantics は、C と互換になる。だから、stackの直後に |
243 frame pointer ȻפäƤ (? ) frame pointer | 243 frame pointer があると思っている (そうか? ) frame pointer |
244 stack pointer ˱äưưľˡoffset | 244 stack pointer に沿って移動した直後に、そこからのoffset |
245 ǰ뤳Ȥˤʤ롣 | 245 で引数を操作することになる。 |
246 | 246 |
247 ĤޤꡢϤäȤʤ? Ĥޤꡢgoto ȡ | 247 つまり、それはだめだったことじゃない? つまり、goto だと、 |
248 frame pointer ϡstack ľȤϸ¤ʤ顣 | 248 frame pointer は、stack の直後とは限らないから。前の |
249 frame pointer Ф˰˥Ƥ̤ɤ͡ | 249 frame pointer 相対に引数にアクセスしてくれれば別だけどね。 |
250 | 250 |
251 stack ˰ѤΤǧơgoto ξϡ¦ | 251 stack に引数を積むのは容認して、goto の場合は、向こう側で |
252 stack äƤΤ? ȤȤϡ̤δؿ | 252 stack を畳むってのは? ということは、普通の関数と定義の |
253 ˡѤäƤȤޡϤʤ | 253 方法を変えるってことか。ま、悪くはないか。 |
254 | 254 |
255 ȡgoto semantics ϡC ȸߴˤʤ롣 | 255 すると、goto のsemantics は、C と互換になる。それを受ける |
256 ۤʤ뤳Ȥ롣ϡʤʡˡ | 256 方が異なることをする。それは、なんかおかしいな。それに、 |
257 ȴؿƤӽФڤʤʤ... | 257 それだと関数呼び出しが軽くならない... |
258 | 258 |
259 ȤȤϡϤꡢC call ϡcall function | 259 ということは、やはり、C のcall は、call function で |
260 ¸ơ¾θƤӽФϡ٤ơgoto | 260 実現して、その他の呼び出しは、すべて、goto 扱いに |
261 | 261 する方が正しいだろう。 |
262 | 262 |
263 ϡθδؿcall줿ʡdual entry ˤơ | 263 問題は、この言語の関数をcallされた時だな。dual entry にして、 |
264 call λȡgoto λ̤뤫 | 264 call の時と、goto の時を区別するか。 |
265 func: stack processing | 265 func: stack processing |
266 func_goto: normal processing | 266 func_goto: normal processing |
267 ... | 267 ... |
268 ߤʴǤ⡢return Ϥʤ... | 268 みたいな感じ。でも、return はないから... |
269 | 269 |
270 Τ⼫ʬǵҤǤǤ٤̤͡ꡣ | 270 このあたりも自分で記述できる言語であるべきだよね。その通り。 |
271 ĤޤꡢC Ȥstub ⼫ʬǵҤȸȤ | 271 つまり、C とのstub も自分で記述すると言うことか。 |
272 | 272 |
273 protocol function { | 273 protocol function { |
274 interface c { | 274 interface c { |
275 register "%esp" struct { | 275 register "%esp" struct { |
276 entry code ret(int); | 276 entry code ret(int); |
286 local->i = 1; | 286 local->i = 1; |
287 goto *fp->ret(local->i),sp=fp; // return(local->i); | 287 goto *fp->ret(local->i),sp=fp; // return(local->i); |
288 }; | 288 }; |
289 } | 289 } |
290 | 290 |
291 ߤʴǤä֥顣ޤreturnɡ | 291 みたいな感じでさ。さっすが、アセンブラ。いまいちreturnが汚いけど。 |
292 ޤreturn ϤΤޤreturnǤ⤤ɤ | 292 まぁ、return はそのままreturnでもいいけどさ。 |
293 | 293 |
294 ɤΤʤcode ʣ뤫顣 | 294 あ、これは良いかも知れない。code が複数かけるから。 |
295 | 295 |
296 state ʳϡconsistent state Ǥ뤳ȤݾڤʤäƤΤ? | 296 state 以外は、consistent state であることを保証しない。ってのは? |
297 local ѿϻȤäƤɤɡcall/goto ǡͤݾڤʤ... | 297 local 変数は使っても良いけど、call/goto の前後で、値を保証しないか... |
298 | 298 |
299 Ƥʤ | 299 うーん、だんだん炸裂してるなぁ。 |
300 | 300 |
301 顢쥸ФޥåԥεҤȡǤʤʬ | 301 だから、レジスタに対するマッピングの記述と、そうでない部分の |
302 ҤʬΥ٤Ǥ礦͡ | 302 記述は分離するべきでしょうね。 |
303 | 303 |
304 | 304 |
305 դ˼櫓ˤϤʤ餡... | 305 全部一辺に実装するわけにはいかないからぁ... |
306 | 306 |
307 Thu Dec 16 13:44:21 JST 1999 | 307 Thu Dec 16 13:44:21 JST 1999 |
308 | 308 |
309 lock Ͼܥ٥Ǽ¸Τ顢self ʤɤ | 309 lock は状態遷移レベルで実現するのだから、self などを |
310 ȤälockɬפϤʤϤ | 310 使ってlockする必要はないはず。 |
311 | 311 |
312 Τľϡܥ٥ǡ | 312 全体の直列化は、状態遷移レベルで、 |
313 lock(storage) -> transition | 313 lock(storage) -> transition |
314 ߤʷǵҤɤɤΤ褦˵Ҥ뤫 | 314 みたいな形で記述すれば良い。この当たりを、どのように記述するかは |
315 ⤦ꤷ褦 | 315 もう少し先送りしよう。 |
316 | 316 |
317 | 317 |
318 ϥ쥸Ϥˤ褦ĹϡƤӽФ¦ΰؤ | 318 引数はレジスタ渡しにしよう。長い引数は、呼び出し側の領域への |
319 ݥȤ롣ꤷƤɤСvarargs | 319 ポインタとする。実装を規定しても良い。そうすれば、varargs |
320 ߤʤΤϤʤʤ롣ʤǡʤΤ? | 320 みたいなものはなくなる。だいたい、なんで、そんなものがいるんだろう? |
321 ϤФ | 321 配列を渡せばいいじゃん。 |
322 | 322 |
323 ʤΤǡϰ(or )˸¤Ȥˡ⤢롣 | 323 なので、引数は一つ(or 二つ)に限るという方法もある。 |
324 | 324 |
325 ȤȡϤꡢäŪΰưŪΰݤ뤳Ȥ | 325 とすると、やはり、前もって静的領域や動的領域を確保することは |
326 Ǥʤ | 326 できない。 |
327 | 327 |
328 θǤưŪΰϼʬdzݤ櫓顢ʤ | 328 この言語では動的領域は自分で確保するわけだから、その点は問題ない。 |
329 | 329 |
330 Thu Dec 16 20:24:55 JST 1999 | 330 Thu Dec 16 20:24:55 JST 1999 |
331 | 331 |
332 ȤȴؿƤӽФϡ | 332 とすると関数呼び出しは、 |
333 # register save | 333 # register save |
334 # set 1st argument in register %eax | 334 # set 1st argument in register %eax |
335 # set 2nd argument in register %ecx | 335 # set 2nd argument in register %ecx |
336 # set extra arguments in save area | 336 # set extra arguments in save area |
337 # set extra argument pointer in %edx | 337 # set extra argument pointer in %edx |
338 jmp function | 338 jmp function |
339 Ȥˤʤ櫓͡second ΤϤɤ | 339 という形式になるわけね。second を処理するのはめんどくさいから一つ |
340 ˤ褦 | 340 にしよう。 |
341 | 341 |
342 ȡframe pointer Ϥʤɡѥμ礫餹 | 342 えーと、frame pointer はないけど、コンパイルの手順からすると |
343 äɤframe pointer ΤΤstatic | 343 あった方が良い。しかし、frame pointer そのものをstatic |
344 ˤȤΤϤޤ顢frame pointer first argument | 344 にとるのはまずい。だから、frame pointer がfirst argument |
345 ȤȤˤȤȰϡˡ | 345 ということにする方が正しい。とすると引数は、さらに、その |
346 ȸ櫓 | 346 後と言うわけか。 |
347 f(fp,argument) | 347 f(fp,argument) |
348 fp ϤΤˤargument 쥸ϤΤϤɡ | 348 fp を渡すのにさらにargument をレジスタで渡すのはおかしい。おかしいけど、 |
349 ޡɤ | 349 ま、良いか。 |
350 | 350 |
351 return ʤʤ顢return type ȤΤѤʡ | 351 return しないなら、return type の定義をとるのは変だな。 |
352 | 352 |
353 f(fp,arg1,arg2,arg3) Ȥȡ줾줬ޤä쥸äơ | 353 f(fp,arg1,arg2,arg3) とすると、それぞれが決まったレジスタに入って、 |
354 ¿ʬˤȻפ롣դդ... | 354 多い分は配列にあると思われる。ふむふむ... |
355 fp->xx | 355 fp->xx |
356 ǥСΤޤɽѿˤʤ롣 | 356 でアクセスすれば、そのまま局所変数になる。全部、配列で |
357 äƤɤ | 357 送っても良い。 |
358 | 358 |
359 .set label,value | 359 .set label,value |
360 | 360 |
361 as ͤåȤ褦Ǥ͡ | 361 で as は値をセットするようですね。 |
362 | 362 |
363 ؿθäʤοۤϤʤƤ褤 | 363 関数コールの後は戻って来ないから後始末の心配はしなくてよい。 |
364 frame pointer Ȥä鼫ʬݤ뤳ȡ | 364 frame pointer を使ったら自分で面倒を見ること。 |
365 | 365 |
366 | 366 だと |
367 a = atoi(s); | 367 a = atoi(s); |
368 ߤʤȤϤǤʤ... | 368 みたいなことはできない... |
369 | 369 |
370 ̤Cȸȴְ㤤䤹 | 370 普通のCの定義と交じると間違いやすい。 |
371 | 371 |
372 Ȥȡstruct Ʊͤˡ | 372 とすると、struct と同様に、 |
373 protocol | 373 protocol |
374 code | 374 code |
375 interface | 375 interface |
376 state | 376 state |
377 Ѱդ櫓֤͡Τ? | 377 を用意するわけね。時間あるのかぁ? |
378 | 378 |
379 Ȥꤢregister Ϥfunction gotoʸ롣 | 379 とりあえず、register 渡しのfunction 定義とgoto文を実装する。 |
380 | 380 |
381 code name(register "%ebp" void *arg) { | 381 code name(register "%ebp" void *arg) { |
382 goto name(arg); | 382 goto name(arg); |
383 } | 383 } |
384 | 384 |
385 餤? ǡfirst argument ɬregisterˤΤ褦ˤʤ | 385 ぐらいかな? で、first argument が必ずregisterにのるようにしないと |
386 ʤregister storage class ơ | 386 いけない。register storage class を入れて、 |
387 register "%ebp" void *arg | 387 register "%ebp" void *arg |
388 Ȥ櫓͡ | 388 とかするわけね。 |
389 | 389 |
390 äƤȤϡޤ쥸ʤȤʤ櫓͡ | 390 ってことは、まず、レジスタを実装しないといけないわけね。 |
391 | 391 |
392 ǡstack Ȥä黻ϡΤޤޤˤ? ǤưϤ | 392 で、stack を使った演算は、一応、そのままにする? それでも動くはず。 |
393 gotoϻȤʤ顢ǤϤ | 393 式の途中でgotoは使えないんだから、それでいいはず。 |
394 | 394 |
395 ǡ줫顢ĥƤ | 395 で、それから、これを拡張していく。 |
396 | 396 |
397 interface c { | 397 interface c { |
398 register "%ebp" void *arg; | 398 register "%ebp" void *arg; |
399 } | 399 } |
400 code name(interface c) { | 400 code name(interface c) { |
401 goto name(c.arg); // c. Ͼάǽ | 401 goto name(c.arg); // c. は省略可能 |
402 } | 402 } |
403 | 403 |
404 Ȥ͡ˡ | 404 とかね。さらに、 |
405 | 405 |
406 protocol name { | 406 protocol name { |
407 interface c { | 407 interface c { |
408 register "%ebp" void *arg; | 408 register "%ebp" void *arg; |
409 } | 409 } |
413 code name1(interface c) { | 413 code name1(interface c) { |
414 goto name(arg); | 414 goto name(arg); |
415 } | 415 } |
416 } | 416 } |
417 | 417 |
418 ʤɤȤ櫓ʤȡ줬 C ȶ¸櫓͡ | 418 などとするわけか。なんと、これが C と共存するわけね。うーん。 |
419 | 419 |
420 Fri Dec 31 11:44:03 JST 1999 | 420 Fri Dec 31 11:44:03 JST 1999 |
421 | 421 |
422 code Ǥʤơ̤̾Τۤɤʤ? segment? action? | 422 code でなくて、別な名前のほうが良くない? segment? action? |
423 | 423 |
424 쥸̾ΤϡäѤꤤ䡣optionalˤϵ | 424 レジスタ名が入るのは、やっぱりいや。optionalには許す。 |
425 | 425 |
426 interface Ϲ¤ΤΤ褦ʤΤ... ¤ΤǤʤ? | 426 interface は構造体のようなものだから... 構造体でいいんじゃない? |
427 ¤Τξ... malloc ? malloc Ȥơ | 427 構造体の場合は... malloc する? う、うーん。malloc するとして、 |
428 free ? | 428 いつfree するの? |
429 | 429 |
430 ȤˤϡƤƤʤ? multi-thread ǤʤФ͡ | 430 再入するときには、壊れてていいんじゃない? multi-thread でなければね。 |
431 multi thread Ǥϡ֤ϡ쥸ͳޤϡthread local ˻ | 431 multi thread では、状態は、レジスタ経由または、thread local に持つ |
432 ɬפ롣static ϡ thread local ˻ʤƤϤʤʤ | 432 必要がある。static は、だから thread local に持たなくてはならない。 |
433 ѿ˳꿶äᡣǤ⡢ޤϡ | 433 大域変数に割り振っちゃだめ。でも、いまは、やめて |
434 | 434 |
435 interface ϡȤꤢĤޤǤϤˤ褦 | 435 interface は、とりあえず、二つまでの値渡しにしよう。 |
436 self arg | 436 self と arg |
437 Ǥ͡ | 437 ですね。 |
438 | 438 |
439 ⤦ĥ䤹ѥ餬ʤ | 439 もう少し拡張しやすいコンパイラがいいなぁ。 |
440 | 440 |
441 code name (c,a) | 441 code name (c,a) |
442 struct state *c; struct arg *a; | 442 struct state *c; struct arg *a; |
443 { | 443 { |
444 goto name(arg); | 444 goto name(arg); |
445 } | 445 } |
446 | 446 |
447 local ѿ? θߴ꤫ | 447 local 変数は? この互換性の問題かぁ。 |
448 | 448 |
449 KL/1 ռơinterface heap ֤ȤˤƤɤ | 449 KL/1 を意識して、interface は heap に置くことにしても良い。 |
450 GC ϸƤ٤interface machine independent | 450 GC は言語に入れておくべきだが、interfaceは machine independent |
451 Ǥ٤Ȥ use/forget ߤΤϤ | 451 であるべき。だとすれば use/forget みたいものはいるだろう。 |
452 Ǥ⺣ΤȤϹͤɬפϤʤ | 452 でも今のところは考える必要はない。 |
453 | 453 |
454 ȡ | 454 えーと、 |
455 code name (c,a) | 455 code name (c,a) |
456 struct state *c; struct arg *a; | 456 struct state *c; struct arg *a; |
457 { | 457 { |
458 int i; | 458 int i; |
459 goto name(arg); | 459 goto name(arg); |
460 } | 460 } |
461 λΰѿiϤɤ? Ūˤϥ쥸Ƥ... | 461 の時の一時変数iはどうするの? 基本的にはレジスタ割り当てだけど... |
462 Ѥʤ? ʸոޤäѤheap˳Ƥ㤦 | 462 使用させない? んー、大胆な御意見。まぁ、やっぱりheapに割り当てちゃう |
463 ΤñǤ⡢ɤȴˤϤʤʤ櫓... | 463 のが簡単か。でも、どうせ抜ける時にはいらなくなるわけだから... |
464 | 464 |
465 ۤ餤ѿϡcallǤɬ̵ʤΤ̡ | 465 ほんらい、この変数は、次のcallでは必要無くなるのが普通。 |
466 | 466 |
467 Ȥˤ쥸ѿɬפʤǤ礦? | 467 とにかく、レジスタ変数は必要なんでしょう? |
468 | 468 |
469 顢GC ȹ碌Ƹ߷פ٤͡API ꤷơ | 469 だから、GC と合わせて言語を設計すべきだよね。API を規定して、 |
470 ۤʤGCǤ褦ˤ롣 | 470 異なるGCを選択できるようにする。 |
471 | 471 |
472 Sat Jan 1 22:40:22 JST 2000 | 472 Sat Jan 1 22:40:22 JST 2000 |
473 | 473 |
474 ȡˤ storage class register 褦 | 474 とーにかく、 storage class register を実装しよう。 |
475 | 475 |
476 stmode=REGISTER | 476 stmode=REGISTER |
477 | 477 |
478 ǡlocal storage ȤʤȤ | 478 で、local storage とおなじ扱いとする |
479 static register? ϡʤ | 479 static register? は、ない。 |
480 | 480 |
481 symbol table storage class ? dsp==EXTRN ȽꤷƤ뤫顢 | 481 symbol table に storage class をたせば? dsp==EXTRN で判定しているから、 |
482 local ѿ36ʾ夢Ȥʤ뤾? | 482 local 変数が36以上あるとおかしくなるぞ? |
483 | 483 |
484 sc GVAR/LVAR ɡregister LVAR üۤ顢 | 484 sc は GVAR/LVAR だけど、register は LVAR の特殊な奴だから、 |
485 sc ۤ... | 485 sc に入れるほうが正しいか... |
486 | 486 |
487 Sun Jan 2 01:47:17 JST 2000 | 487 Sun Jan 2 01:47:17 JST 2000 |
488 | 488 |
489 register ѿϤǤޤɡregister ĻȤȡ | 489 register 変数はできました。けど、register を二つ使うと、 |
490 դˤʤäƤޤΤǡREGISTER6 ǥѥ뤷ʤ | 490 一杯になってしまうので、REGISTER6 でコンパイルしないと |
491 빽Ҥɤregister ѿ%esi,%edi ˳Ƥ | 491 結構ひどい。が、register 変数を%esi,%edi に割り当てれば |
492 | 492 いいか。 |
493 | 493 |
494 Sun Jan 2 04:43:04 JST 2000 | 494 Sun Jan 2 04:43:04 JST 2000 |
495 | 495 |
496 ǡ | 496 で、 |
497 code name (c,a) | 497 code name (c,a) |
498 struct state *c; struct arg *a; | 498 struct state *c; struct arg *a; |
499 { | 499 { |
500 goto name(c); | 500 goto name(c); |
501 } | 501 } |
502 ΰѿ̵ϼǤޤĤޤǤ͡ | 502 の一時変数無しは実装できます。引数は二つまでね。 |
503 | 503 |
504 .file "tmp.c" | 504 .file "tmp.c" |
505 .version "01.01" | 505 .version "01.01" |
506 gcc2_compiled.: | 506 gcc2_compiled.: |
507 .text | 507 .text |
518 jmp name | 518 jmp name |
519 _5: | 519 _5: |
520 .size code,_5-code | 520 .size code,_5-code |
521 .ident "Micro-C compiled" | 521 .ident "Micro-C compiled" |
522 | 522 |
523 | 523 う、すごい。 |
524 | 524 |
525 goto ʸɤstack ǡjmp | 525 goto 文がめんどくさい。stack をたたんで、jmp すれば |
526 褤.. | 526 よいだけだが.. |
527 | 527 |
528 Sun Jan 2 11:17:50 JST 2000 | 528 Sun Jan 2 11:17:50 JST 2000 |
529 | 529 |
530 ̤callcontinuation baseˤ뤳ȤǤ? | 530 普通のcallをcontinuation baseにすることができる? |
531 | 531 |
532 Sun Jan 2 20:28:45 JST 2000 | 532 Sun Jan 2 20:28:45 JST 2000 |
533 | 533 |
534 goto ʸɡϤꡢ١expr Ƥ顢top level | 534 goto 文だけど、やはり、一度、expr で生成してから、top level |
535 jump code 褦 | 535 で jump code を生成しよう。 |
536 | 536 |
537 Tue Jan 4 03:32:55 JST 2000 | 537 Tue Jan 4 03:32:55 JST 2000 |
538 | 538 |
539 code typeˤʤȡ | 539 code をtypeにしないと、 |
540 code *p; | 540 code *p; |
541 Ȥʤ͡ | 541 とか書けないね。 |
542 int *p(); | 542 int *p(); |
543 Ʊɤ | 543 と同じだけどさ。 |
544 | 544 |
545 | 545 |
546 main(ac,av) | 546 main(ac,av) |
547 int ac; | 547 int ac; |
548 char *av[]; | 548 char *av[]; |
560 goto ac(ac,av); | 560 goto ac(ac,av); |
561 } | 561 } |
562 | 562 |
563 Tue Jan 4 04:56:56 JST 2000 | 563 Tue Jan 4 04:56:56 JST 2000 |
564 | 564 |
565 ʤ쥸ˤĤ㤦 | 565 うーん、なんかレジスタにつむ順序が違う |
566 ϡadecl reverseˤĤफ顣 | 566 これは、adecl がreverseにつむから。 |
567 | 567 |
568 code return | 568 code のreturn |
569 | 569 |
570 ϤcodetypeˤʤȤᡣ | 570 やはりcodeはtypeにしないとだめ。 |
571 | 571 |
572 main() | 572 main() |
573 { | 573 { |
574 goto code1(); | 574 goto code1(); |
575 } | 575 } |
576 | 576 |
577 Ȥȡmain äʤcode1() ʹߤǡ | 577 とかだと、main に戻って来れない。もちろん、code1() 以降で、 |
578 return 櫓ˤϤʤ(main disp code1 Τʤ) | 578 return するわけにはいかない。(main の disp をcode1 は知り得ない) |
579 goto label code1ΰ? | 579 goto label をcode1の引数に送れば? |
580 | 580 |
581 main() | 581 main() |
582 { | 582 { |
583 goto code1(ret); | 583 goto code1(ret); |
584 ret: | 584 ret: |
585 } | 585 } |
586 | 586 |
587 ȡret forward labelɤʬʤ? | 587 これだと、ret がforward labelかどうか分からないけど? |
588 | 588 |
589 code1 ǻȤѿ stack ˤȤΤϰʤ | 589 code1 中で使う中間変数を stack 上にとるのは悪くない。しかし、それを |
590 %ebp ͳǥȤȤϡmain ѿȤȡ | 590 %ebp 経由でアクセスするということは、main の中間変数を壊すということ。 |
591 ɤˤϡmain goto codeǡ%ebp Ƥɤ | 591 それを防ぐには、main 中のgoto codeで、%ebp を修正してやれば良い。 |
592 (äʤΤʤ) | 592 (今は戻って来ないので問題ない) |
593 | 593 |
594 code1 goto Ǥϡäʤ顢ɬפϤʤ | 594 code1 のgoto では、戻って来ないから、その必要はない。しかし、 |
595 label code1 Ϥȡäȵޤ | 595 label をcode1 中で渡されると、ちょっと気まずい。 |
596 | 596 |
597 Ȥȡ϶ػߤơmain() stackǤgoto뤫? | 597 とすると、それは禁止して、main() 中でstackをたたんでからgotoするか? |
598 ȡ̵¸षơɡʤȤˤʤ... | 598 そうすると、無限後退して、結局、帰れないことになる... うーん。 |
599 | 599 |
600 main() local code Сϲ褹뤬.. | 600 main() 中のlocal code を許せば、それは解決するが.. |
601 | 601 |
602 main() | 602 main() |
603 { | 603 { |
604 goto code1(code2); | 604 goto code1(code2); |
605 code code2() { | 605 code code2() { |
606 return; | 606 return; |
607 } | 607 } |
608 } | 608 } |
609 | 609 |
610 ߤʴǤ⡢scope rule ѤɬפΤǸ | 610 みたいな感じ。でも、そうするとscope rule を変える必要があるので厳しい。 |
611 ޡϤʤɤ͡ | 611 ま、悪くはないけどね。 |
612 | 612 |
613 continuation ˡ⤢롣 | 613 continuation を明示する方法もある。 |
614 | 614 |
615 main() | 615 main() |
616 { | 616 { |
617 goto code1(continuation); | 617 goto code1(continuation); |
618 } | 618 } |
620 code (*ret)(); | 620 code (*ret)(); |
621 { | 621 { |
622 goto *ret; | 622 goto *ret; |
623 } | 623 } |
624 | 624 |
625 ? call/cc ? | 625 かな? call/cc ? |
626 | 626 |
627 label ؤgotoΤ⤤ɡ | 627 label へのgotoを許すのもいいけど、 |
628 Ǥ⡢label ȡspaghettiˤʤʤ? | 628 でも、label を許すと、すごくspaghettiにならない? |
629 | 629 |
630 | 630 |
631 Tue Jan 4 11:47:24 JST 2000 | 631 Tue Jan 4 11:47:24 JST 2000 |
632 | 632 |
633 continuation ʤơreturn keyword Ȥ | 633 continuation じゃなくて、return keyword を使おう。 |
634 (ºݡcontinuation Ⱦ㤦) | 634 (実際、continuation と少し違うし) |
635 type Ѥˤʤ뤱ɡޤɤ | 635 type が少し変になるけど、まあ良い。 |
636 | 636 |
637 int | 637 int |
638 main() | 638 main() |
639 { | 639 { |
640 goto code1(return); | 640 goto code1(return); |
643 code (*ret)(int); | 643 code (*ret)(int); |
644 { | 644 { |
645 goto *ret(3); | 645 goto *ret(3); |
646 } | 646 } |
647 | 647 |
648 ʡprototype դʤȤʤ | 648 だな。prototype も付けないといけないか。 |
649 | 649 |
650 Tue Jan 4 12:21:44 JST 2000 | 650 Tue Jan 4 12:21:44 JST 2000 |
651 | 651 |
652 method٤static ˤʤäƤޤdynamic method | 652 これだとmethodがすべてstatic になってしまう。dynamic なmethod |
653 ƤӽФˤˤ? dispatcher ʬǺ뤳Ȥˤʤ롣ʤ | 653 呼び出しにするには? dispatcher を自分で作ることになる。かなり |
654 ɤ... | 654 めんどくさいが... |
655 | 655 |
656 code method(obj,arg) | 656 code method(obj,arg) |
657 { | 657 { |
658 } | 658 } |
659 | 659 |
660 뤤ϡinline ˤ뤫... #define Τ inline ͤ | 660 か、あるいは、inline にするか... #define のかわりに inline ねぇ。 |
661 ϤȤǹͤɤ | 661 これはあとで考えて良い。 |
662 | 662 |
663 Tue Jan 4 14:22:19 JST 2000 | 663 Tue Jan 4 14:22:19 JST 2000 |
664 | 664 |
665 main ѿ٤Τȡgoto (*reg)(123) Ǥͤϡ | 665 main の変数を書き潰すのと、goto (*reg)(123) での値は、 |
666 register Ϥǡcurrent register ˤΤʤΤǡ | 666 register 渡しで、current register にのらないので、 |
667 ɡreturn label Ѥ˺ɬפ롣 | 667 結局、return label は専用に作る必要がある。 |
668 | 668 |
669 Tue Jan 4 18:14:07 JST 2000 | 669 Tue Jan 4 18:14:07 JST 2000 |
670 | 670 |
671 stack ѤơƤӽФСcall by value | 671 stack を継ぎ足して、呼び出す方式を取れば、call by value |
672 register Ϥ¤ɬפ̵ʤ롣 | 672 のregister 渡しを制限する必要は無くなる。 |
673 | 673 |
674 ʣ֤ͤȤưפ | 674 複数の値を返すことも容易だ。 |
675 | 675 |
676 .file "tmp.c" | 676 .file "tmp.c" |
677 .version "01.01" | 677 .version "01.01" |
678 gcc2_compiled.: | 678 gcc2_compiled.: |
679 .text | 679 .text |
690 jmp name | 690 jmp name |
691 _5: | 691 _5: |
692 .size code,_5-code | 692 .size code,_5-code |
693 .ident "Micro-C compiled" | 693 .ident "Micro-C compiled" |
694 | 694 |
695 ?! | 695 おお?! |
696 %esp new %esp = old %esp - 12 -4 | 696 %esp new %esp = old %esp - 12 -4 |
697 %ebp-4 = g | 697 %ebp-4 = g |
698 %esi = a | 698 %esi = a |
699 %edi = b | 699 %edi = b |
700 %ebp = old %esp 0 | 700 %ebp = old %esp 0 |
701 %ebp+4 = c code_arg_offset=0 | 701 %ebp+4 = c code_arg_offset=0 |
702 %ebp+8 = d | 702 %ebp+8 = d |
703 %ebp+12 = e | 703 %ebp+12 = e |
704 %ebp+16 = f | 704 %ebp+16 = f |
705 | 705 |
706 interface դ褦! Ȥ | 706 interface は付けよう! というか、 |
707 goto name(struct {xxxx}) | 707 goto name(struct {xxxx}) |
708 ߤʴɤ櫓͡ɤregisterˤ뤫ȸϤ뤬 | 708 みたいな感じで良いわけね。どれをregisterにいれるかと言う問題はあるが。 |
709 | 709 |
710 ǡɤäcallФ櫓? emit_push뤫push | 710 で、どうやってcallすればいいわけ? emit_pushするかわりにpush |
711 ? | 711 する? |
712 | 712 |
713 Ǥϡᤫcode argument οѤȡ | 713 うう、これでは、だめか。code argument の数が変わると、 |
714 ebp ưȤˤʤ롣ˤold sp 뤫 | 714 ebp をいちいち動かすことになる。そこにはold sp があるから |
715 Ĥ⥳ԡɬפ롣 | 715 そいつもコピーする必要がある。 |
716 | 716 |
717 %esp new %esp = old %esp - 20 | 717 %esp new %esp = old %esp - 20 |
718 %ebp-20 = g | 718 %ebp-20 = g |
719 %esi = a | 719 %esi = a |
720 %edi = b | 720 %edi = b |
722 %ebp-12 = d | 722 %ebp-12 = d |
723 %ebp-8 = e | 723 %ebp-8 = e |
724 %ebp-4 = f | 724 %ebp-4 = f |
725 %ebp = old %esp 0 | 725 %ebp = old %esp 0 |
726 | 726 |
727 function callˤϡlocal ѿ٤ɤ | 727 そうか、function からcallする時には、local 変数を書き潰して良い。 |
728 | 728 |
729 # goto name(a,b,d,e,f); | 729 # goto name(a,b,d,e,f); |
730 | 730 |
731 %esp new %esp = old %esp - 20 | 731 %esp new %esp = old %esp - 20 |
732 %ebp-20 = g | 732 %ebp-20 = g |
742 %ecx -8 | 742 %ecx -8 |
743 %ebx -4 | 743 %ebx -4 |
744 %ebp = %esp 0 | 744 %ebp = %esp 0 |
745 %eip 4 <- arg_offset | 745 %eip 4 <- arg_offset |
746 | 746 |
747 Ȥʤ롣ȤȤϡpushl %ebp ϡְ㤤 | 747 となる。ということは、pushl %ebp は、間違い。 |
748 | 748 |
749 ɡ%ebp ΤޤȤΤɤʤdisp_offset äƤ뤫顣 | 749 だけど、%ebp をそのまま使うのは良くない。disp_offset がかかっているから。 |
750 顢⤦ pushl %ebp ۤ褤push ϡ | 750 だから、もう一度 pushl %ebp したほうがよい。しかし、push する先は、 |
751 Ρ(*) | 751 上の、(*)。 |
752 leave movl %ebp,%esp | 752 leave movl %ebp,%esp |
753 popl %ebp | 753 popl %ebp |
754 ʤä? | 754 じゃなかったか? |
755 | 755 |
756 Thu Jan 6 13:00:33 JST 2000 | 756 Thu Jan 6 13:00:33 JST 2000 |
757 | 757 |
758 Ǥ͡ǤȤꤢưϤ®٤... | 758 できたね。これでとりあえず動くはず。速度は問題だが... |
759 Ȥϡ | 759 あとは、 |
760 ANSI-C prototype | 760 ANSI-C prototype |
761 ANSI-C prototype check | 761 ANSI-C prototype check |
762 Interface Definietion | 762 Interface Definietion |
763 GC support | 763 GC support |
764 Direct handling of Frame | 764 Direct handling of Frame |
765 ͡ñ˽褽? ֤... | 765 だね。簡単に出来そう? たぶん... |
766 | 766 |
767 Fri Jan 7 09:42:53 JST 2000 | 767 Fri Jan 7 09:42:53 JST 2000 |
768 | 768 |
769 goto ʸưƤʤä peep hole optimization version | 769 goto 文が動いてなかった。あと peep hole optimization version も |
770 뤫? | 770 作るか? |
771 | 771 |
772 continuation Ȥ label 褦ˤ٤? | 772 continuation として label を送れるようにするべきか? |
773 ʤɡäȡץब | 773 そうすると便利なんだけど、ちょっと、汚いプログラムが |
774 褦ˤʤ롣ȡ¦δĶ(frame)ݻ | 774 出来るようになる。あと、送り側の環境(frame)を維持する |
775 ɬפ롣ޡǤʤϤʤ... | 775 必要がある。ま、できなくはないか... |
776 | 776 |
777 ȡlabel ͤĤ褦ˤʤ롣 | 777 そうすると、label が値を持つようになる。 |
778 a = label:; | 778 a = label:; |
779 Ȥlabel:(a,b,c) {}; ߤʷǡparallel ȸ | 779 とか。うーん。label:(a,b,c) {}; みたいな形で、parallel 代入を許すと言う |
780 ⤢͡ | 780 手もあるね。 |
781 | 781 |
782 CȤɤ... main() { label:(){ ... } } | 782 こちらの方がCとの相性は良いが... main() { label:(){ ... } } |
783 ߤnestɤȸ꤬롣 | 783 みたいなnestを許すかどうかと言う問題がある。 |
784 ѿλȤʤСäϤʤ | 784 変数の参照を許さなければ、特に問題はない。 |
785 | 785 |
786 a = label: ϡŤΰ̣ʤ | 786 a = label: は、二重の意味があるなぁ。 |
787 | 787 |
788 ̾DinnerBell II Ȥ? join ? | 788 言語の名前。DinnerBell II とか? join も入れる? |
789 code entry_a().entry_b() {} | 789 code entry_a().entry_b() {} |
790 Ǥ? parallel call ? | 790 ですか? parallel call も? |
791 | 791 |
792 Fri Jan 7 19:53:53 JST 2000 | 792 Fri Jan 7 19:53:53 JST 2000 |
793 | 793 |
794 ޤΤޤޤ return ĶäƤʤ顢æФǤʤ | 794 いまのままだと return が環境を持ってないから、大域脱出できない。 |
795 ޤĶƤ⤤ɡɤ֤ȸ꤬ | 795 まぁ、環境を入れてもいいんだけど、どこに置くかと言う問題が |
796 ͡ | 796 あるね。 |
797 | 797 |
798 ʤơreturn ¦ȽǤ뤫? | 798 そうじゃなくて、return 側で判断するか? |
799 return(ID) | 799 return(ID) |
800 ߤʷIDȽǤ롣Сreturn ¦ID | 800 みたいな形でIDで判断する。そうすれば、return 側でID |
801 ȽǤǤ롣... | 801 を見て判断できる。けど... |
802 | 802 |
803 ޤϤꡢĶä⤯ʤǤ⡢ | 803 まぁ、はやり、環境を持って歩く方がいいかなぁ。でも、 |
804 ϤƤ뤫顢İϤơȤ줿Ȥˡ | 804 引き渡しているから、二つ引き渡して、片方を使われたときに、 |
805 ȿ¦äƤޤΤϤ͡ΤޤޤʤС | 805 反対側が消えてしまうのはいたいよね。今のままならば、 |
806 Ȥϵʤ | 806 そういうことは起こらない。 |
807 | 807 |
808 continuation ͭʤ顢ΤޤޤǤ⤤... | 808 continuation 特有の問題を避けるなら、このままでもいいんだが... |
809 continuation ĶϡΥƥǤϼʬǺ뤳Ȥ | 809 continuation や環境は、このシステムでは自分で作ることが |
810 Ǥ뤫͡ | 810 できるからね。 |
811 | 811 |
812 ʤ.... retlabel retcont ϼ¤ϥ֥ | 812 そうなんだけど.... retlabel や retcont は実はオブジェクト |
813 Τ˰Ĥɤ | 813 全体に一つあれば良い。 |
814 | 814 |
815 ϤȤˡ˴ĶؤΥݥƤɤΤǡ | 815 引数を渡すときに、そこに環境へのポインタをいれてやれば良いので、 |
816 ϳȴñȡι¤ΤϤȸ | 816 解決は割と簡単だが、そうすると、例の構造体を引数で渡すと言う |
817 褹ɬפ롣 | 817 問題を解決する必要がある。 |
818 | 818 |
819 Ǥ⡢μʤСޤäƱѿιʤХԡ | 819 でも、今の実装ならば、まったく同じ変数の構成ならばコピーは |
820 ºݤˤϵʤ櫓ʤϤäˡݾڤ뤿ˡ | 820 実際には起こらないわけだから問題ないはず。特に、それを保証するために、 |
821 interface ɬפ롣 | 821 interface を実装する必要がある。 |
822 | 822 |
823 return -> | 823 return -> |
824 (void *)old bp | 824 (void *)old bp |
825 return address | 825 return address |
826 | 826 |
827 bp ľǤ褦ˤȤ.... | 827 bp を直接操作できるようにするといいんだけど.... |
828 | 828 |
829 Sat Jan 8 08:49:59 JST 2000 | 829 Sat Jan 8 08:49:59 JST 2000 |
830 | 830 |
831 ϡcode ǤreturnǤʤ櫓ɡ¤ϡreturn äơ | 831 今は、code 内ではreturnできないわけだけど。実は、return って、 |
832 code return0(i) int i; { return(i); } | 832 code return0(i) int i; { return(i); } |
833 ? ϶ػߤƤʤ㤦͡ɤcodeФ? | 833 か? 今は禁止してないから書けちゃうよね。どういうcodeが出るんだろう? |
834 | 834 |
835 doreturn() Ǥ retpending åȤƤ顢control=1 | 835 doreturn() では retpending をセットしているだけだから、control=1 |
836 Τޤޡǡcode νˤΤǥ顼ˤʤ롣checkret ϡ | 836 のまま。で、code の終りにくるのでエラーになる。checkret は、 |
837 statement ΰȽǤ褦ˤۤŪ | 837 statement の引数で判断するようにしたほうが合理的だろう。 |
838 | 838 |
839 æФϷ빽͡åפƤ줷? | 839 大域脱出は結構根が深いよね。途中をスキップされてうれしいか? |
840 destructor ƱǡcodeƤӤΤ̤ | 840 destructor と同じで、途中のcodeは全部呼びたいのが普通だろう。 |
841 | 841 |
842 bp Ʊˤʤޤ return ɤ櫓͡ | 842 bp が同じになるまで return すれば良いわけだよね。 |
843 return ƱǡŪ˴ĶϤ褦ˤ뤫 | 843 return と同じで、明示的に環境を引き渡すようにするか。 |
844 type void * ɤ? | 844 type は void * で良い? |
845 | 845 |
846 return stackξ¤ۤƤ뤫ɤʬǥå | 846 return する時にstackの上限を越えているかどうかを自分でチェックする |
847 ɬפ͡ïreturn뤫codeɤ櫓ɡ | 847 必要があるね。誰にreturnするかをcodeで明示すれば良いわけだけど。 |
848 | 848 |
849 code return0(i) int i; { return(i); } | 849 code return0(i) int i; { return(i); } |
850 | 850 |
851 ơǡframe pointer 褢뤤Ϥ | 851 を許して、そこで、frame pointer を大域あるいは渡した引数と |
852 Ӥƽ? | 852 比較して処理する? |
853 code return0(i,env) int i; env *env; { | 853 code return0(i,env) int i; env *env; { |
854 if (env==self) return(i); | 854 if (env==self) return(i); |
855 } | 855 } |
856 ? Ϥ͡ | 856 あれ? これはおかしいよね。 |
857 code return0(i,env) int i; env *env; { | 857 code return0(i,env) int i; env *env; { |
858 if (env!=self) { | 858 if (env!=self) { |
859 env->return(); | 859 env->return(); |
860 return(i); | 860 return(i); |
861 } | 861 } |
862 } | 862 } |
863 ⡢ʤѤʤƤӽФȵս˵ꤿ櫓... | 863 も、なんか変だよなぁ。呼び出しと逆順に帰りたいわけだが... |
864 ºݡսˤϵäƤ櫓͡ | 864 実際、逆順には帰っているわけだよね。 |
865 | 865 |
866 return ǤӤȤ⤢뤱ɡ | 866 return の中でこそこそ比較するという技もあるけど。 |
867 | 867 |
868 ϡdestructor Ϥ͡self ɤ櫓 | 868 問題は、destructor に渡す情報だよね。もちろん、self で良いわけだが、 |
869 Τϡ쳰ǡŪˤ顢θ | 869 このあたりは、言語外の問題で、それを明示的にしたいから、この言語を |
870 äƤ櫓ʤΤ顢ǽΤϤ | 870 作っているわけなのだから、これを内部で処理するのはおかしい。 |
871 | 871 |
872 code return0(i) int i; { return(i); } | 872 code return0(i) int i; { return(i); } |
873 | 873 |
874 ȡreturn ηʤȸ꤬ʡñˤ | 874 これだと、return の型が合わないと言う問題が生じるな。簡単には |
875 åǤʤ | 875 チェックできない。 |
876 int | 876 int |
877 main() { | 877 main() { |
878 code a() { | 878 code a() { |
879 } | 879 } |
880 code b() { | 880 code b() { |
881 return(i); | 881 return(i); |
882 } | 882 } |
883 } | 883 } |
884 ˤСcheck ϤǤ褦ˤʤ롣Ǥ⡢ȡ | 884 にすれば、check はできるようになる。でも、これだと、 |
885 int | 885 int |
886 main() { | 886 main() { |
887 a: { | 887 a: { |
888 } | 888 } |
889 b: { | 889 b: { |
890 return(i); | 890 return(i); |
891 } | 891 } |
892 } | 892 } |
893 Ⱥʤmodule 쳰ǤȤΤݤʤΤ顢Ǥ | 893 と差がない。module 化を言語外でやるというのが主旨なのだから、これでは |
894 ޤϹ饢֥ʤΤ顣 | 894 まずい。これは高級アセンブラなのだから。 |
895 | 895 |
896 return ȡæлabortȤϡ㤦顢 | 896 あそうか、return と、大域脱出時のabortとは、状況が違う。だから、 |
897 ̤code ƤӽФʤȤᡣ뤤ϡͤǶ̤뤫ϡ | 897 別なcode を呼び出さないとだめ。あるいは、値で区別するか。これは、 |
898 logic programming fail/success ȻƤ롣 | 898 logic programming のfail/success と似ている。 |
899 main() { } abort { ... } | 899 main() { } abort { ... } |
900 Ǥ⤤? | 900 でもいいけど? |
901 main() { code abort { ... }; code return { ... }} | 901 main() { code abort { ... }; code return { ... }} |
902 ? | 902 かな? |
903 | 903 |
904 衢subroutine callΤʤξάʤ櫓顢 | 904 本来、subroutine call自体が、かなりの省略形なわけだから、これは |
905 ʤΤޤޤ̾subroutine callߥ졼ȤǤΤ? | 905 仕方がない。今のままで通常のsubroutine callをシミュレートできるのか? |
906 code (struct arg {...},void *sp) { | 906 code (struct arg {...},void *sp) { |
907 struct env; | 907 struct env; |
908 push(sp,arg); | 908 push(sp,arg); |
909 push(env,arg); | 909 push(env,arg); |
910 } | 910 } |
911 Ǥ뤱ɡäȽŤϤꡢframe pointer ľʤ | 911 できるけど、ちょっと重い。やはり、frame pointer を直接操作しないと |
912 ᡣ | 912 だめ。 |
913 | 913 |
914 goto ʸΤۤˡenv ΤäۤΤ⡣ | 914 goto 文のほうに、env を一緒に送るものを作ったほうがいいのかも。 |
915 goto (*ret)(),environment; | 915 goto (*ret)(),environment; |
916 ʡtype ? (void *)? | 916 かな。type は? (void *)? |
917 goto ret(),environment; | 917 goto ret(),environment; |
918 ˤϤʤʤ? СʬthreadǤ롣environment | 918 にはならないの? そうすれば、自分でthreadを制御できる。environment |
919 ɾʤɤ? ޤͤ | 919 の正当性を評価しなくて良いの? まぁ、ねぇ。 |
920 | 920 |
921 ϼưפ... goto ȤΤˤΤ? | 921 これは実装は容易だが... goto といちいち書くのが本当にいいのか? |
922 env Фoperationäʤpush Ȥ? | 922 env に対するoperationがあった方がいいなぁ。push とか? |
923 | 923 |
924 code return0(i) int i; { return(i); } | 924 code return0(i) int i; { return(i); } |
925 | 925 |
926 ǧСreturn ѿϤʤʤ롣 | 926 を認めれば、return 擬変数はいらなくなる。 |
927 | 927 |
928 Ǥ⡢¤ϡreturn ϡcaller ΰοȰפƤʤȤʤ | 928 でも、実は、return は、caller の引数の数と一致してないといけない |
929 櫓顢 code return0(i) int i; { return(i); } Ϥᡣenv | 929 わけだから、 code return0(i) int i; { return(i); } はだめ。env |
930 ȰפƤʤȤʤȤȤʬΥȤޤʤ? | 930 と一致してないといけない。ということは分離するとまずいんじゃない? |
931 ? ʤϤʤʡ | 931 あれ? そんなはずないな。 |
932 | 932 |
933 Sun Jan 9 01:15:56 JST 2000 | 933 Sun Jan 9 01:15:56 JST 2000 |
934 | 934 |
935 ϤꡢʬΥƤϤޤȤȡ | 935 やはり、分離してはまずい。もともと、 |
936 goto func(arg); | 936 goto func(arg); |
937 Τ | 937 自体が、 |
938 goto func(arg) with current.env | 938 goto func(arg) with current.env |
939 ߤʤΤĤޤꡢϡDinnerBell Ρ | 939 みたいなものだ。つまり、これは、DinnerBell の、 |
940 self message: arg | 940 self message: arg |
941 Ʊself->func(arg); Ǥɤfunction callȶ̤դʤΤ | 941 と同じ。self->func(arg); でも良い。が、function callと区別が付かないのは |
942 ɤʤ | 942 良くない。 |
943 | 943 |
944 ȡtype code size int Ǥʤʤ롣 | 944 そうすると、type code はsize int でなくなる。 |
945 code *p = func; | 945 code *p = func; |
946 ǤϤʤơ | 946 ではいけなくて、 |
947 code p = {func,env}; | 947 code p = {func,env}; |
948 ǤʤȤʤºݡ | 948 でないといけない。実際、 |
949 goto func(arg) | 949 goto func(arg) |
950 Ǥϡcurrent environment pushl %ebp stack = current env | 950 では、current environment を pushl %ebp でstack = current env |
951 ѤǤ櫓顣 | 951 に積んでいるわけだから。 |
952 | 952 |
953 ˤ衢 | 953 いずれにせよ、 |
954 struct p = q; | 954 struct p = q; |
955 ϼɬפ롣localʡ | 955 は実装する必要がある。localな、 |
956 code p = {func,env}; | 956 code p = {func,env}; |
957 ưϤ... | 957 も動くはずだが... |
958 | 958 |
959 code (*p)(); | 959 code (*p)(); |
960 goto (*p)(arg); | 960 goto (*p)(arg); |
961 | 961 |
962 Ϥ龯ϡgoto env äƤȹͤ٤ | 962 はだから少しおかしい。これは、goto がenv を補っていると考えるべき。 |
963 | 963 |
964 Τ褦ˤȡˡ | 964 このようにすると、常に、 |
965 func,env | 965 func,env |
966 ȤcodeȤߤʤȤˤʤ롣ϡobject ȸƤ֤٤ | 966 の組をcodeとみなすことになる。これは、object と呼ぶべきだ。 |
967 ¸objectȤ̤ʡactor ɤ? | 967 ただ、既存のobjectとは別だよな。actor の方が良い? |
968 | 968 |
969 joinСDinnerBellʡϤʤɡ | 969 うーん、これでjoinを入れれば、完璧なDinnerBellだな。並列送信はないけど。 |
970 | 970 |
971 Sun Jan 9 01:40:05 JST 2000 | 971 Sun Jan 9 01:40:05 JST 2000 |
972 | 972 |
973 local ѿνallocation θ٤餻ɬפ롣 | 973 local 変数の初期化はallocation の後に遅らせる必要がある。 |
974 nptr Ϥ? nptr ˽ե饰? | 974 nptr に入れられるはずだよね? nptr に初期化フラグを足すか? |
975 | 975 |
976 ʸǽиlocalѿνưƤ? | 976 文途中で出現するlocal変数の初期化。ちゃんと動いているの? |
977 | 977 |
978 ¤Τcopyϡlcheck ٤Ǥʤ | 978 構造体のcopyは、lcheck を修正すべきでない。 |
979 | 979 |
980 Sun Jan 9 08:49:43 JST 2000 | 980 Sun Jan 9 08:49:43 JST 2000 |
981 | 981 |
982 ʤ¿ʤȡؿƤӽФgoto ʸ | 982 うーん、なんか修正が多いなぁ。あと、関数呼び出し、goto 文の |
983 ¤Τؤб | 983 構造体への対応か。 |
984 | 984 |
985 goto (*code)(); | 985 goto (*code)(); |
986 | 986 |
987 self env ȤΤcode ͤȤΤ̤ | 987 が、self env を使うのか、code の先の値を使うのかを区別する |
988 ɬפ롣⤷*ȤʤȤlabel(FNAME)Ȥζ̤ | 988 必要がある。もし*を使わないとするとlabel(FNAME)との区別が |
989 ĤʤǤ⡢Ķ⤯Ȥˤ顢label | 989 つかないぞ。あ、でも、環境を持ち歩くことにしたから、label |
990 ؤjump褦ȻפФǤ͡ | 990 へもjumpしようと思えばできるね。 |
991 | 991 |
992 ϤʤƤ⡢ιʤstatementñ̤ФΤ | 992 並列送信はなくても、この構成ならばstatement単位の並列性を検出するのは |
993 ưפ | 993 容易だろう。 |
994 | 994 |
995 ФǤ뤱ɡν̤1㽪ʤʤ | 995 やればできるけど、この修正の量だと1日じゃ終らないかなぁ。 |
996 ưΤǤ礦? | 996 不動小数点も入れるのでしょう? |
997 | 997 |
998 Mon Jan 10 09:00:12 JST 2000 | 998 Mon Jan 10 09:00:12 JST 2000 |
999 | 999 |
1000 ˹¤ΤˤϡɬANSI-Cˤɬפ롣 | 1000 引数に構造体を許すには、必ずANSI-Cにする必要がある。難しくは |
1001 ʤ... | 1001 ないが... |
1002 | 1002 |
1003 goto ʸˤ label, code, continuation 3Ĥ롣 | 1003 goto 文には label, code, continuation の3つが来る。 |
1004 continuation = code + env | 1004 continuation = code + env |
1005 | label +env | 1005 | label +env |
1006 ʤΤcode/label Ǥϡenv Ƥۤʤ롣Ǥ | 1006 なのだが、code/label では、env の内容が異なる。できれば面白いが、 |
1007 βͤϤΤ? | 1007 その価値はあるのか? |
1008 | 1008 |
1009 code , env ʬΥȤޤ˴롣ɤgoto | 1009 しかし、code , env を分離するとあまりに危険すぎる。どうせgoto |
1010 ʤ餤? ññʤ顢äˡ | 1010 が危険なんだからいいか? その方が簡単。簡単なら、そっちの方法を |
1011 Ȥ٤ʤ? | 1011 とるべきじゃない? うーん。 |
1012 | 1012 |
1013 return δؿ¸Ϥʤɤ | 1013 return の関数依存性はなくした方が良い。 |
1014 ĤˤΤϡpop ꤬Τɤʤ... | 1014 一つにするのは、pop の問題があるので良くないが... |
1015 | 1015 |
1016 ret envꤷ褦ˤ顢leave ɬפ | 1016 そうか、ret をenvを指定して戻るようにしたから、leave する必要は |
1017 ʤʤäơpush %ebp ʬϡlea -disp(%ebp),%sp | 1017 なくなった。そして、push %ebp に相当する部分は、lea -disp(%ebp),%sp |
1018 ǾõƤ롣ȤȤϡjump function¸ʬϤʤ | 1018 で消去されている。ということは、jump のfunction依存部分はいらない |
1019 ȤȤ͡ | 1019 ということだね。 |
1020 | 1020 |
1021 Ǥ⡢ʤread only°hardware supportǤФʤ | 1021 でも、汚いなぁ。read only属性をhardware supportできればなあ。 |
1022 | 1022 |
1023 sched_yeilds() 뤫? lock ? | 1023 sched_yeilds() 相当を書けるかな? lock は? |
1024 | 1024 |
1025 ǤɡäѤ | 1025 一応、できたけど、やっぱり汚い。 |
1026 | 1026 |
1027 Wed Jan 12 16:12:27 JST 2000 | 1027 Wed Jan 12 16:12:27 JST 2000 |
1028 | 1028 |
1029 ϡANSI prototype Ϥɤ | 1029 あは。ANSI prototype はめんどい。 |
1030 bexpr() | 1030 bexpr() |
1031 ǡؿǤΰνȡΤȤνѤ뤳Ȥ롣 | 1031 で、関数での引数の順序と、そのあとの宣言の順序が変わることがある。 |
1032 ȡͥ褵Ƥޤϡޤ롣 | 1032 そうすると、うしろの方が優先されてしまう。これは、こまる。 |
1033 | 1033 |
1034 code_arg_offset Τ褦ˡȡANSI style Ǥϡ | 1034 そうか、code_arg_offset のような方法だと、ANSI style では、 |
1035 äƤޤ | 1035 困ってしまう。 |
1036 | 1036 |
1037 Thu Jan 13 04:46:12 JST 2000 | 1037 Thu Jan 13 04:46:12 JST 2000 |
1038 | 1038 |
1039 # goto name(a,b,d,e,f); | 1039 # goto name(a,b,d,e,f); |
1040 code name { int g; ... | 1040 code name { int g; ... |
1056 %eip 4 <- arg_offset | 1056 %eip 4 <- arg_offset |
1057 | 1057 |
1058 | 1058 |
1059 Thu Jan 13 13:38:24 JST 2000 | 1059 Thu Jan 13 13:38:24 JST 2000 |
1060 | 1060 |
1061 Ǥɡtest/tmp7.c printf type mismatch | 1061 だいたいできたけど、test/tmp7.c のprintf のtype mismatch は |
1062 ʤʤ? ASNI Ѥʤ | 1062 なんなんだろう? ASNI の副作用だろうなぁ。 |
1063 | 1063 |
1064 ȡץؤΤȤˤϡ빽̤Υǡ | 1064 これだと、プロセスの切替えのときには、結構な量のデータを |
1065 ԡ뤳Ȥˤʤ롣Ǥ⤤... | 1065 コピーすることになる。それでもいいんだけど... |
1066 | 1066 |
1067 줴ȡɤäˤȤä֤continuationؤλȤߤʤ | 1067 それごと、どっかにとって置く。continuationへの参照みたいなもの |
1068 Ǥʤʡ | 1068 ができないかな。 |
1069 | 1069 |
1070 ԡǤСenvironment/return Ȥư櫓顢 | 1070 コピーができれば、environment/return の組は動くわけだから、 |
1071 ؤλȤؤäƤɤ͡ | 1071 それへの参照と切替えがあっても良いよね。 |
1072 | 1072 |
1073 Fri Jan 14 12:03:35 JST 2000 | 1073 Fri Jan 14 12:03:35 JST 2000 |
1074 | 1074 |
1075 Libretto keyboard줿... control key ʤ... | 1075 Libretto のkeyboardが壊れた... control key が効かない... |
1076 | 1076 |
1077 printf λȤϲ褷ޤlist2 localheap | 1077 printf の参照の問題は解決しました。list2 がlocalなheap |
1078 ˳ƤƤΤʤä͡ | 1078 に割り当てているのがいけなかったね。 |
1079 | 1079 |
1080 return νϡgoto ʸǽꡢenvironment | 1080 return の処理は、goto 文で処理するより、environment に |
1081 returnto ɤϤʤ? | 1081 returnto する方が良くはないか? |
1082 | 1082 |
1083 environment ϼ¤Ǥʤνɬס | 1083 environment は実は送り先でそれなりの準備が必要。 |
1084 new-environment() ߤlibrary Сthread ˤǤ롣 | 1084 new-environment() みたいなlibrary があれば、thread にできる。 |
1085 | 1085 |
1086 join ? | 1086 join は? |
1087 | 1087 |
1088 funcall Ѱդɤ͡ | 1088 funcall を用意すると良いね。 |
1089 | 1089 |
1090 Mon Jan 17 15:23:34 JST 2000 | 1090 Mon Jan 17 15:23:34 JST 2000 |
1091 | 1091 |
1092 struct aa f1() { | 1092 struct aa f1() { |
1093 return bb; | 1093 return bb; |
1094 } | 1094 } |
1095 | 1095 |
1096 ߤʤΤ? ؿηηơcrn pointerϤơ | 1096 みたいなのは? 関数の型か代入の型を見て、crn にpointerを渡して、 |
1097 ȤcopyƤ stack ࡣ | 1097 あとでcopyしてから stack を畳む。 |
1098 | 1098 |
1099 # bb=f1(aaa); | 1099 # bb=f1(aaa); |
1100 movl $bb,%eax | 1100 movl $bb,%eax |
1101 pushl %eax | 1101 pushl %eax |
1102 movl $aaa,%eax | 1102 movl $aaa,%eax |
1105 popl %edx | 1105 popl %edx |
1106 copy %eax,%edx,$400 | 1106 copy %eax,%edx,$400 |
1107 addl $400,%esp | 1107 addl $400,%esp |
1108 # return a1; | 1108 # return a1; |
1109 | 1109 |
1110 Ǥ⡢ȡlocalѿ֤Ȥ˺͡leave; ret; | 1110 あ、でも、それだと、local変数を返したときに困るね。leave; ret; |
1111 ƤϤʤ... | 1111 してはいけなくて... |
1112 | 1112 |
1113 äѤꡢϥԡmain2˰ϤƤߤ͡ | 1113 あ、やっぱり、こういう場合はコピー先をmain2に引き渡しているみたいね。 |
1114 void f1(struct aa *ret) { | 1114 void f1(struct aa *ret) { |
1115 *ret = bb ; | 1115 *ret = bb ; |
1116 return; | 1116 return; |
1117 } | 1117 } |
1118 Ʊϴñ | 1118 と同じか。これは簡単。 |
1119 f1().a[55] | 1119 f1().a[55] |
1120 ߤʾϡɽѿ˶Ū˼äƤޤߤ͡Ϥ... | 1120 みたいな場合は、局所変数に強制的に取ってしまうみたいね。それはそうだ... |
1121 μȤäȸ | 1121 が、うちの実装だとちょっと厳しいか。 |
1122 leal $-sizeof(struct),%esp | 1122 leal $-sizeof(struct),%esp |
1123 pushl %esp | 1123 pushl %esp |
1124 ʤɡؿƤӽФǤϤǤʤ.... | 1124 なんだけど、関数呼び出しの途中ではできないから.... |
1125 | 1125 |
1126 # main(ac,av) | 1126 # main(ac,av) |
1127 # int ac; | 1127 # int ac; |
1128 .align 2 | 1128 .align 2 |
1129 .globl main | 1129 .globl main |
1142 # struct { int b; void (*c)(struct aa); } q = {3,main1},r; | 1142 # struct { int b; void (*c)(struct aa); } q = {3,main1},r; |
1143 # | 1143 # |
1144 # j = 3; | 1144 # j = 3; |
1145 subl $20,%esp | 1145 subl $20,%esp |
1146 | 1146 |
1147 subl夫ꤷƤOk | 1147 このsublを後から指定してやればOk。 |
1148 | 1148 |
1149 Ǥ⡢ jump λˤʤ? 뤫? ͡ | 1149 でも、それだと jump の時にずれない? ずれるか? ずれるね。うーん。 |
1150 ¹Ի˥åƤΤѤ | 1150 実行時にチェックしてやるのも変だし。 |
1151 | 1151 |
1152 ޤۤɬפʵǽǤϤʤɡ | 1152 まぁ、それほど必要な機能ではないんだけど。 |
1153 | 1153 |
1154 continuationϤƤȸˡȤʤȤϤʤ... | 1154 これもcontinuationを渡してやると言う手法が使えないことはないんだが... |
1155 | 1155 |
1156 ؿƤӽФκǽˤäƤФǤǤ뤫? | 1156 関数呼び出しの最初にやってやればいいか。それでできるかな? |
1157 | 1157 |
1158 | 1158 |
1159 Sun Feb 20 23:59:16 JST 2000 | 1159 Sun Feb 20 23:59:16 JST 2000 |
1160 | 1160 |
1161 MIPS call frame | 1161 MIPS のcall frame |
1162 | 1162 |
1163 $sp = $fp | 1163 $sp = $fp |
1164 local variables | 1164 local variables |
1165 saved register (including $31 = return address) | 1165 saved register (including $31 = return address) |
1166 | 1166 |
1167 mask ϻѤ쥸bit pattern | 1167 mask は使用したレジスタのbit pattern |
1168 -4 ϲ? | 1168 -4 は何? |
1169 | 1169 |
1170 18 .mask 0xc0000000,-4 | 1170 18 .mask 0xc0000000,-4 |
1171 19 .fmask 0x00000000,0 | 1171 19 .fmask 0x00000000,0 |
1172 20 0000 D0FFBD27 subu $sp,$sp,48 | 1172 20 0000 D0FFBD27 subu $sp,$sp,48 |
1173 21 0004 2C00BFAF sw $31,44($sp) | 1173 21 0004 2C00BFAF sw $31,44($sp) |
1189 36 003c 2800BE8F lw $fp,40($sp) | 1189 36 003c 2800BE8F lw $fp,40($sp) |
1190 37 0040 0800E003 addu $sp,$sp,48 | 1190 37 0040 0800E003 addu $sp,$sp,48 |
1191 38 0044 3000BD27 j $31 | 1191 38 0044 3000BD27 j $31 |
1192 39 .end main | 1192 39 .end main |
1193 | 1193 |
1194 Ʊ褦ˤʤСregiterλѿǽĴ٤ɬפ | 1194 これと同じようにするならば、regiterの使用数を最初に調べる必要が |
1195 Τɡone path compiler Ǥ micro-C Ǥϡ | 1195 あるのだけど、one path compiler である micro-C では、それは |
1196 Ǥʤäơenter ϸǤɤ | 1196 できない。したがって、enter は後ろでする方が良い。 |
1197 Mon Jan 20 18:25:27 JST 2003 | 1197 Mon Jan 20 18:25:27 JST 2003 |
1198 | 1198 |
1199 3ǯ֤äƤʤΤ衣äƤ? | 1199 3年間さわってないのかよ。何やってんだ? |
1200 | 1200 |
1201 goto ʸΥХȤʤȤʤ | 1201 goto 文のバグをとらないといけない。 |
1202 | 1202 |
1203 ޤؿι¤ΤŸϡɤäƤȤʤϤ | 1203 まず、関数引数の構造体の展開。これは、どうってことないはず。 |
1204 | 1204 |
1205 goto (*code)(i+1,j,...) | 1205 goto (*code)(i+1,j,...) |
1206 | 1206 |
1207 ޤʤƤѿŦФ롣 | 1207 まず、いじらなくてすむ変数を摘出する。 |
1208 | 1208 |
1209 foreach arg | 1209 foreach arg |
1210 compare | 1210 compare |
1211 | 1211 |
1212 ñ黻 ( op+const , pointer , const assign ) ʤɤϡǸФ롣 | 1212 単純演算 ( op+const , pointer , const assign ) などは、ここで検出する。 |
1213 ȾϡΤ褦ˤʤϤ | 1213 大半は、そのようになるはず。 |
1214 쥸˾褻ʬ뤫... ˤϿʤȤ... | 1214 レジスタに乗せる分があるから... それには触らないとして... |
1215 | 1215 |
1216 ʣʤΤϡäƷƤ(get_register ) | 1216 複雑なものは、前もって計算しておく。(get_register する) |
1217 å夫쥸˺롣 | 1217 スタック上かレジスタ上に作る。 |
1218 | 1218 |
1219 ĤȤʤ롣ƵŪ˷롣 | 1219 残りは並列代入となる。再帰的に計算する。 |
1220 | 1220 |
1221 ȡ礭ʽˤä? ʽˤä? | 1221 えーと、大きな順にやるんだっけ? 小さな順にやるんだっけ? |
1222 code f( int a, int b, int c ) { | 1222 code f( int a, int b, int c ) { |
1223 goto g(b,c,a); | 1223 goto g(b,c,a); |
1224 } | 1224 } |
1225 ߤʤĤ͡ | 1225 みたいなやつだよね。 |
1226 | 1226 |
1227 ưΤĸФ롣 | 1227 移動するものを一つ検出する。 |
1228 Τ˰ưɬפʤΤưƤ(Ƶ) | 1228 そのために移動が必要なものを移動しておく(再帰) |
1229 | 1229 代入する |
1230 | 1230 |
1231 ʤǤΤ? 롼פʤ? ͡롼פ | 1231 こんなんでいいのか? ループしない? するよね。ループしたら |
1232 get_register 롣 | 1232 get_register する。 |
1233 | 1233 |
1234 ȡ | 1234 前の例だと、 |
1235 | 1235 |
1236 g(b,c,a) bܤ롣 | 1236 g(b,c,a) のbに着目する。 |
1237 b륳ɤФȡa 롣 | 1237 bに代入するコードを出すと、a が壊れる。 |
1238 a ɬפɤĴ٤롣ϡΥꥹȤФ狼롣 | 1238 a が必要かどうかを調べる。それは、引数のリストを見ればわかる。 |
1239 ˡa ư롣a ΰươ | 1239 その前に、a を移動する。a の移動先を見て、 |
1240 ƤСưOkc | 1240 空いていれば、移動してOk。しかし、c |
1241 ʤΤǡ c 롣 b ˤʤΤǡ롼פΤ狼Τǡ | 1241 なので、 c を見る。と b になるので、ループするのがわかるので、 |
1242 b get_register 롣 | 1242 b を get_register する。 |
1243 ǡc ưǤ롣ǡaươȤäƤb | 1243 で、c が移動できる。で、aを移動して、とっておいたbを代入。 |
1244 | 1244 |
1245 Tue Jan 21 22:45:09 JST 2003 | 1245 Tue Jan 21 22:45:09 JST 2003 |
1246 | 1246 |
1247 Ȥꤢjump ʣ롣äȴñˤ뤳Ȥͤ롣 | 1247 とりあえず、jump は複雑すぎる。もっと簡単にすることを考える。 |
1248 parser ¦ǤٽǤʤ? | 1248 parser 側である程度処理できない? |
1249 | 1249 |
1250 goto f(a+3,b(),c); | 1250 goto f(a+3,b(),c); |
1251 | 1251 |
1252 ʤɤ | 1252 などを、 |
1253 | 1253 |
1254 a = a+3; | 1254 a = a+3; |
1255 b = b(); | 1255 b = b(); |
1256 goto f(a,b,c); | 1256 goto f(a,b,c); |
1257 | 1257 |
1258 ٤˴ά롣λf(a,b,c) (Ǥ) | 1258 程度に簡略化する。この時、f(a,b,c) は(できるだけ)、元の |
1259 ؿΰꥹȤ˶դ롣Τ̵ʤΤǡñѿ | 1259 関数の引数リストに近付ける。のは無理なので、単純変数 |
1260 ޤ | 1260 まで落す。 |
1261 | 1261 |
1262 ޤطʤѿϤɤ櫓äƤ | 1262 あまり関係ないか。一時変数はどうせいるわけだし。ってこと |
1263 ߤ͡ | 1263 みたいね。 |
1264 | 1264 |
1265 ȤȡΥɤȡѤ͡Τ⡢ʤ | 1265 だとすると、元のコードと、そう変わらんね。前のも、そんなに |
1266 ʤäƤȤ | 1266 悪くないってことか。 |
1267 | 1267 |
1268 Wed Jan 22 14:33:12 JST 2003 | 1268 Wed Jan 22 14:33:12 JST 2003 |
1269 | 1269 |
1270 äѤꡢǶɽѿ䤷͡ | 1270 やっぱり、途中で局所変数を増やしたいよね。 |
1271 | 1271 |
1272 Fri Jan 31 20:30:36 JST 2003 | 1272 Fri Jan 31 20:30:36 JST 2003 |
1273 | 1273 |
1274 ʤ #ifdef / #if ʤȤʡ? | 1274 なんか #ifdef / #if がないとだめだな。実装する? |
1275 ޤ | 1275 しました。 |
1276 | 1276 |
1277 Tue Feb 4 01:04:12 JST 2003 | 1277 Tue Feb 4 01:04:12 JST 2003 |
1278 | 1278 |
1279 ## while ((*chptr++ = c = getc(filep->fcb)) != '\n') { | 1279 ## while ((*chptr++ = c = getc(filep->fcb)) != '\n') { |
1280 _1120: | 1280 _1120: |
1282 movl $8,%ecx | 1282 movl $8,%ecx |
1283 movl filep,%edx | 1283 movl filep,%edx |
1284 addl %ecx,%edx | 1284 addl %ecx,%edx |
1285 movl (%edx),%edx | 1285 movl (%edx),%edx |
1286 pushl %edx | 1286 pushl %edx |
1287 xchg %edx,%eax .... edx $10 (ʤxchg?) | 1287 xchg %edx,%eax .... edx に$10が入る (なんでxchg?) |
1288 call getc | 1288 call getc |
1289 addl $4,%esp | 1289 addl $4,%esp |
1290 movl %eax,-20(%ebp) c | 1290 movl %eax,-20(%ebp) c に代入 |
1291 movl $chptr,%ecx | 1291 movl $chptr,%ecx |
1292 pushl %ecx | 1292 pushl %ecx |
1293 popl %ebx | 1293 popl %ebx |
1294 movl (%ebx),%ecx ecx chptr | 1294 movl (%ebx),%ecx ecx にchptrの中身 |
1295 addl $1,(%ebx) | 1295 addl $1,(%ebx) |
1296 movb %al,(%ecx) | 1296 movb %al,(%ecx) |
1297 subl %edx,%eax eax-edx ($10) | 1297 subl %edx,%eax eax-edx ($10) |
1298 je _1119 | 1298 je _1119 |
1299 | 1299 |
1300 ͳʤ... | 1300 が壊れる理由なんだけど... |
1301 | 1301 |
1302 edx,ecx ˲㤦ߤ͡ | 1302 edx,ecx が破壊されちゃうみたいね。 |
1303 | 1303 |
1304 Tue Feb 4 12:17:07 JST 2003 | 1304 Tue Feb 4 12:17:07 JST 2003 |
1305 | 1305 |
1306 褦äľ... | 1306 ようやっと直したよ... |
1307 | 1307 |
1308 use_pointer äơʤˤ⤷ʤƤ? eax,ebx | 1308 use_pointer って、なにもしなくていいんだよね? eax,ebx を避ける |
1309 äƤȤ餷ɡ | 1309 ってことらしいけど。 |
1310 | 1310 |
1311 inline/դ #define ߤʤ? ֤ϡlocal name stack Ѥ㤦 | 1311 inline/引数付き #define 欲しくない? 置き換えは、local name stack に積んじゃう。 |
1312 Ÿ function ǹԤ | 1312 展開は function で行う。 |
1313 | 1313 |
1314 getch פɬפϤ뤬֤åɬס | 1314 getch を工夫する必要はあるが。置き換えスタックが必要。 |
1315 | 1315 |
1316 | 1316 |
1317 Wed Feb 5 01:16:00 JST 2003 | 1317 Wed Feb 5 01:16:00 JST 2003 |
1318 | 1318 |
1319 줿 struct field ѿȽŤʤäƤ롣 | 1319 大域で定義された struct field が大域変数と重なっていると落ちる。 |
1320 㤽ɡɤ? (ľɤʤ...) | 1320 そりゃそうだけど。どうするの? (直した記憶があるんだけどなぁ...) |
1321 struct field ̾offset/type ȤƤФɤ͡ | 1321 struct 毎に field 名とoffset/type の組を持てばい良いんだよね。 |
1322 | 1322 |
1323 ʤɡ̵ι¤Τ⤢뤫顢̾դɬ | 1323 なんだけど、タグ無しの構造体もあるから、型名の方に付ける必要 |
1324 ⤢롣ȤΤϡ̾Τʤ¤Τ⤢뤫顣̾ˤϡ | 1324 もある。というのは、型名のない構造体もあるから。タグ名には、 |
1325 ꥹȤĤƤ롣ʤ˻ȤɬפäǤ礦 | 1325 一応、リストがついている。なんかに使う必要があったんでしょう |
1326 ͡ɤ̵ˤäƤѿ̾Τľ | 1326 ね。あ、めんどう。無条件にやっても大域変数名を汚すのを直すの |
1327 | 1327 が難しい。 |
1328 | 1328 |
1329 äȡɡַ̾.ե̾פϿƤޤΤϤɤ? | 1329 ちょっと、あれだけど、「型名.フィールド名」で登録してしまうのはどう? |
1330 ̾ǽФȤޤ... | 1330 型名が後で出て来るところが気まずいが... |
1331 | 1331 |
1332 def ϿȤˡnptrdispˡstruct field list | 1332 def で登録するときに、nptrにdispを代入せずに、struct field list |
1333 (ѿ) ơtype ˡfield list (list3(nptr,offset, | 1333 (大域変数) に入れて、type の方に、field list (list3(nptr,offset, |
1334 type)) ɤ | 1334 type)) を入れれば良い。 |
1335 | 1335 |
1336 Ȥϡstrop typelist褦ˤɤ櫓 | 1336 あとは、strop の方でtypeのlistを見るようにすれば良いわけだ。 |
1337 | 1337 |
1338 ʤ顢ñľϤLUSTR/GUSTRʤɤζ̤ʤʤ뤷 | 1338 これなら、簡単に直せるはず。LUSTR/GUSTRなどの区別もなくなるし。 |
1339 | 1339 |
1340 Wed Feb 5 02:10:14 JST 2003 | 1340 Wed Feb 5 02:10:14 JST 2003 |
1341 | 1341 |
1342 ưͤANSI CˤΤѡǤ⡢ | 1342 浮動小数点ねぇ。完全なANSI Cにするのは大変。でも、 |
1343 ư餤ʤȡ | 1343 浮動小数点ぐらいないと。 |
1344 | 1344 |
1345 code generation part ʬ䤷ơ | 1345 code generation part を、さらに分割して、 |
1346 ʣΥбˤ䤹褦ˤ롣 | 1346 複数のコード対応にしやすいようにする。 |
1347 餯ۤɶͭʬϤʤɤ͡ | 1347 おそらく、それほど共有する部分はないけどね。 |
1348 | 1348 |
1349 Sample C code ѥ뤷ơη̤(Ⱦʬư) | 1349 Sample C code をコンパイルして、その結果から(半分手動で) |
1350 Micro CbC code generation part ˡѰդ롣 | 1350 Micro CbC code generation part を生成する方法を用意する。 |
1351 | 1351 |
1352 | 1352 |
1353 | 1353 |
1354 Thu Feb 6 11:47:03 JST 2003 | 1354 Thu Feb 6 11:47:03 JST 2003 |
1355 | 1355 |
1356 Code Segment ñ̤ȤƻȤȤˡѿϤɤ | 1356 Code Segment を単位として使うときに、大域変数はどういう |
1357 褦ʬ? static ʤϰ̣ʤ͡ | 1357 ように分けるの? static なんかは意味ないよね。 |
1358 | 1358 |
1359 ˥롼ʬ櫓ɡ | 1359 もちろん、自然にグループ分けされるわけだけど。 |
1360 | 1360 |
1361 ȥǡե͡ǡե˴ؤƤϡ | 1361 あとデータフローだよね。データフローに関しては、 |
1362 ޤäƤʤʤ | 1362 あんまりやってないなぁ |
1363 | 1363 |
1364 Fri Feb 7 14:36:15 JST 2003 | 1364 Fri Feb 7 14:36:15 JST 2003 |
1365 | 1365 |
1366 inline Ǥϡɬ餺ɽѿä롣ޤinline | 1366 inline では、必らず、局所変数の増加がある。また、inline |
1367 ̤δؿȤŸƤɬפ⤢餷(?) | 1367 は普通の関数として展開しておく必要もあるらしい。(何故?) |
1368 | 1368 |
1369 #define ͤ | 1369 #define ねぇ。 |
1370 | 1370 |
1371 #define c(a,b) g(a+1,b+1) | 1371 #define c(a,b) g(a+1,b+1) |
1372 #define g(a,b) printf("%d %d\n",a+1,b+1); | 1372 #define g(a,b) printf("%d %d\n",a+1,b+1); |
1373 | 1373 |
1374 main() { | 1374 main() { |
1375 int a,b; | 1375 int a,b; |
1376 a =1; b = 3; | 1376 a =1; b = 3; |
1377 c(a,b); | 1377 c(a,b); |
1378 } | 1378 } |
1379 | 1379 |
1380 local #define ͡g a Ф褿ˤϡ | 1380 local #define がいるんだよね。g の中で a が出て来た時には、 |
1381 c a ֤ϵäƤϤʤȤȤϡc | 1381 c のa の置き換えは起こってはいけない。ということは、c |
1382 ֤g Ϥޤ˽äƤɬפ롣dynamic | 1382 の置き換えはg が始まる前に終っている必要がある。dynamic |
1383 scope ʤ顢assoc ξ褻ɤϤ | 1383 scope なんだから、assoc の上乗せで良いはず。 |
1384 macro levelơ٥ǤϡŸ | 1384 macro のlevelを定義して、あるレベルでは、それ以前の展開 |
1385 ԤʤȤˡɤʡ | 1385 を行わないという手法が良いかな。 |
1386 | 1386 |
1387 c(a,b) => a=>"a+1", b=>"b+1" | 1387 c(a,b) => a=>"a+1", b=>"b+1" |
1388 g(a,b) => (a=>"a+1+1",a=>"a+1"), (b=>"b+1+1",a=>"a+1") | 1388 g(a,b) => (a=>"a+1+1",a=>"a+1"), (b=>"b+1+1",a=>"a+1") |
1389 | 1389 |
1390 ߤʴ? | 1390 みたいな感じ? |
1391 | 1391 |
1392 äѤؿϤǥޥ餻Τ̵? ɤߤ㤦 | 1392 やっぱり関数解析でマクロ処理をやらせるのは無理かな? 先読みされちゃうし。 |
1393 | 1393 |
1394 Sat Feb 8 00:53:52 JST 2003 | 1394 Sat Feb 8 00:53:52 JST 2003 |
1395 | 1395 |
1396 macro ޤǽޤ֤ޥƤӽФ줿 | 1396 macro は途中まで書きました。置き換えをマクロが呼び出された |
1397 cheap ֤ȡä륿ߥʤ | 1397 時点で cheap に置くと、それを解消するタイミングがない。 |
1398 mallocƤɤ.. | 1398 ここだけmallocしても良いが.. |
1399 | 1399 |
1400 chptrsave listˤɬפ롣list ɤ | 1400 chptrsave はlistにする必要がある。list で良い。 |
1401 | 1401 |
1402 äѤmacro levelơʬȰפassoc valueޤ | 1402 やっぱりmacro levelを見て、自分と一致したassoc valueまで |
1403 귫äִǤ礦С֤ɬפ̵ | 1403 手繰って置換するんでしょう。そうすれば、置き換える必要は無い。 |
1404 ȤȤϡlocal_define mflagsǼɬפ롣 | 1404 ということは、local_define にmflagsを格納する必要がある。 |
1405 | 1405 |
1406 c(a,b) => a=>"a", b=>"b" | 1406 c(a,b) => a=>"a", b=>"b" |
1407 a=>"a" .. mflag == 1 | 1407 a=>"a" .. mflag == 1 |
1408 g(a,b) => (a=>"a+1+1",a=>"a+1"), (b=>"b+1+1",a=>"a+1") | 1408 g(a,b) => (a=>"a+1+1",a=>"a+1"), (b=>"b+1+1",a=>"a+1") |
1409 a=>"a+1" .. mflag == 2 | 1409 a=>"a+1" .. mflag == 2 |
1410 | 1410 |
1411 macro ΤȤnptr ĤäƤʤȡꥸʥ֤ʤ | 1411 macro のもとのnptr が残ってないと、オリジナルを返せない。オ |
1412 ꥸʥϡsc ʤɤ˲ƤޤäƤȤϡlocal macro | 1412 リジナルは、sc などが破壊されてしまう。ってことは、local macro |
1413 ϡlocal table ƤϤʤäƤȤ͡äƤȤϡ | 1413 は、local table を汚してはいけないってことだよね。ってことは、 |
1414 macro table ϡȤΤȤ̤Ѱդɬפ롣 | 1414 macro table は、もとのとは別に用意する必要がある。 |
1415 | 1415 |
1416 #define c(a,b) g(a+1,b+1) | 1416 #define c(a,b) g(a+1,b+1) |
1417 #define g(a,b) printf("%d %d\n",a+2,b+2); | 1417 #define g(a,b) printf("%d %d\n",a+2,b+2); |
1418 | 1418 |
1419 main() { | 1419 main() { |
1429 b); | 1429 b); |
1430 /* 3,5 expected */ | 1430 /* 3,5 expected */ |
1431 #endif | 1431 #endif |
1432 } | 1432 } |
1433 | 1433 |
1434 ࡣ䤳 | 1434 うーむ。ややこしい。 |
1435 | 1435 |
1436 main() | 1436 main() |
1437 c(a,b) mflag++ | 1437 c(a,b) mflag++ |
1438 a=>"a" mflag ==1 | 1438 a=>"a" mflag ==1 |
1439 g(a,b) mflag++; | 1439 g(a,b) mflag++; |
1440 a=>"a+1" mflag ==2 | 1440 a=>"a+1" mflag ==2 |
1441 ^ is replaced by c's "a" not g's a; | 1441 ^ is replaced by c's "a" not g's a; |
1442 ä mflag level n Ÿ顢 mflag level n-1 Ȥʤ롣 | 1442 いったん mflag level n で展開したら、それは mflag level n-1 となる。 |
1443 | 1443 |
1444 Sat Feb 8 18:13:43 JST 2003 | 1444 Sat Feb 8 18:13:43 JST 2003 |
1445 | 1445 |
1446 mflag ޤǤϥǥХå.... mflag ᤷƤʤʤ? | 1446 いちおう、mflag まではデバッグしたが.... mflag を戻してないんじゃないの? |
1447 | 1447 |
1448 ---c(a,b)----------------------- mflag ==1 | 1448 ---c(a,b)----------------------- mflag ==1 |
1449 a=>hoge, b=>hoga (mflag==1) | 1449 a=>hoge, b=>hoga (mflag==1) |
1450 ----g(ac,bc)----------------- mflag ==2 | 1450 ----g(ac,bc)----------------- mflag ==2 |
1451 ac=>goge, bc=>goga(mflag==2) | 1451 ac=>goge, bc=>goga(mflag==2) |
1452 ----printf(a,b)---------- mflag ==3 | 1452 ----printf(a,b)---------- mflag ==3 |
1453 a=>poge, b=>poga(mflag==3) | 1453 a=>poge, b=>poga(mflag==3) |
1454 | 1454 |
1455 g ƤӽФȡac,bc mflag==1 ǤΤִ롣 | 1455 g が呼び出されると、ac,bc は mflag==1 でのみ置換される。 |
1456 | 1456 |
1457 ƥȤ֤ȡ֤ޥmflag level | 1457 あるテキストを置き換えると、それは置き換えたマクロのmflag level |
1458 (Ĥޤľʤ٥)ˤʤ롣 | 1458 (つまり一つ少ないレベル)になる。 |
1459 ֤ä顢level᤹ | 1459 置き換え終ったら、元のlevelに戻す。 |
1460 | 1460 |
1461 mflag==2level Ǥϡmflag==2local macroŸʤ | 1461 mflag==2のlevel では、mflag==2のlocal macroの展開しかしない。 |
1462 | 1462 |
1463 ֤ȡmflag level 1 ˤʤΤǡ mflag==1 local | 1463 置き換えると、mflag level 1 になるので、そこで mflag==1 のlocal |
1464 macro Ÿ롣mflag==0 ϾŸԤ | 1464 macro を展開する。mflag==0 は常に展開を行う。 |
1465 | 1465 |
1466 Sun Feb 9 11:35:23 JST 2003 | 1466 Sun Feb 9 11:35:23 JST 2003 |
1467 | 1467 |
1468 ʤtypelist CHARʤɤäƤ뤸 | 1468 うーん、なんかtypeが、list とCHARなどと入混じっているじゃん。 |
1469 int save = chptrsave; | 1469 int save = chptrsave; |
1470 ǡchptrsave $chptrsave ˤʤäƤޤ | 1470 で、chptrsave が、$chptrsave になってしまう。 |
1471 | 1471 |
1472 Sun Feb 9 22:33:36 JST 2003 | 1472 Sun Feb 9 22:33:36 JST 2003 |
1473 | 1473 |
1474 | 1474 |
1475 #define car(e) (heap[(int)(e)]) | 1475 #define car(e) (heap[(int)(e)]) |
1476 #define cadr(e) (heap[((int)(e))+1]) | 1476 #define cadr(e) (heap[((int)(e))+1]) |
1477 car(cadr(e)) | 1477 car(cadr(e)) |
1478 | 1478 |
1479 | 1479 だろ。 |
1480 car -> | 1480 car -> |
1481 #define e cadr(e) (mleve=1) | 1481 #define e cadr(e) (mleve=1) |
1482 cadr -> | 1482 cadr -> |
1483 #define e e (mleve=2) | 1483 #define e e (mleve=2) |
1484 | 1484 |
1485 थ졢ޤʤޤäʤ | 1485 むぅ。これ、うまくいかないんじゃん。こまったなぁ。 |
1486 | 1486 |
1487 #define c(a,b) g(a+1,b+1) | 1487 #define c(a,b) g(a+1,b+1) |
1488 #define g(a,b) printf("%d %d\n",a+1,b+1); | 1488 #define g(a,b) printf("%d %d\n",a+1,b+1); |
1489 c(a, b); | 1489 c(a, b); |
1490 | 1490 |
1491 äᤸաࡣlisp interpreter Τ褦 | 1491 こっちもだめじゃん。ふーむ。lisp interpreter のように |
1492 ФϤʤɡ | 1492 作ればいいはずなんだけど。 |
1493 | 1493 |
1494 Mon Feb 10 08:10:25 JST 2003 | 1494 Mon Feb 10 08:10:25 JST 2003 |
1495 | 1495 |
1496 ɡlist base interpreter ޤʤ | 1496 結局、list base のinterpreter を実装しました。きちゃないが。 |
1497 ˡǤ⡢ĥФǤǤ礦ɤ͡ | 1497 前の方法でも、頑張ればできるんでしょうけどね。 |
1498 | 1498 |
1499 Tue Feb 11 13:50:03 JST 2003 | 1499 Tue Feb 11 13:50:03 JST 2003 |
1500 | 1500 |
1501 struct copy ... ؿstruct֤Ȥˡä | 1501 struct copy だけど... 関数がstructを返すときに、引数に前もって |
1502 ѤǤΤǤϡͤԡƤޤȤǡ | 1502 積んでおくのでは、そこに値がコピーされてしまうし、あとで、 |
1503 å֤Ȥˤޤ | 1503 スタックをたたんで置くときにきまずい。 |
1504 | 1504 |
1505 function call λˡηΥåƤʤ | 1505 function call の時に、引数の型のチェックをしてない |
1506 | 1506 |
1507 type -1 heapΰߤƤĤ.. | 1507 type に -1 とheapの引数が混在しているやつだけど.. |
1508 äѤޤʤ? | 1508 やっぱまずいんじゃないか? |
1509 | 1509 |
1510 temporal struct ϺѤǤɡdispѹǤʤΤ | 1510 temporal struct は再利用できるんだけど、dispの変更ができないので |
1511 뤷ʤ礭ȤʤƤ | 1511 新しく作るしかない。大きいときだけ新しく作るなんていうセコイ |
1512 Ϥ뤱ɡ(ȡä褿ͤؤΥݥȤʤ | 1512 技はあるけど。(そうすると、帰って来た値へのポインタを使えなく |
1513 ʤ뤬.... ̤ˤͤ͡켫Ȥľ return | 1513 なるが.... 別にいいよね。戻り値それ自身を直接 return する |
1514 礦֤ʤϤ) | 1514 時もだいじょうぶなはず) |
1515 | 1515 |
1516 ɡƽ¦ǡΰݤưϤȤˤޤˡȡ | 1516 結局、呼出側で、領域を確保して引き渡すことにしました。この方法だと、 |
1517 ΤȤ٥ԡɬפʤ | 1517 代入のときに二度コピーする必要もない。 |
1518 | 1518 |
1519 register ѤƤ뤫ʤơºݤcreg/dreg | 1519 register を使用しているかだけじゃなくて、実際にcreg/dregに |
1520 ͤ뤫ɤɬפ롣 | 1520 値があるかどうかを記憶する必要がある。 |
1521 | 1521 |
1522 Wed Feb 12 11:09:22 JST 2003 | 1522 Wed Feb 12 11:09:22 JST 2003 |
1523 | 1523 |
1524 ɤ... äѤꥢɥۥå˼¸Τʤ? | 1524 それだけどさ... やっぱりアドホックに実現するのは難しいんじゃないの? |
1525 | 1525 |
1526 ޤͤregister ξγݤȡ̤̿顢 | 1526 まぁねぇ。register の場所の確保と、寿命は別だから、それで |
1527 ɡregs flag ǤʤȤʤʤΤʡ | 1527 いいんだけど、regs flag だけでなんとかならないのかな。 |
1528 ѹϤϤޤ뤬 | 1528 こういう変更ははまるが虚しい。 |
1529 | 1529 |
1530 Thu Feb 13 18:37:36 JST 2003 | 1530 Thu Feb 13 18:37:36 JST 2003 |
1531 | 1531 |
1532 ơ jump ˤȤ꤫ޤ | 1532 さて、そろそろ jump にとりかかりますか。 |
1533 | 1533 |
1534 ¤ΤΰϤΥ˻Ȥɽѿΰ֤gccȰ㤦... | 1534 構造体の引き渡しのシークエンスに使う局所変数の位置がgccと違う... |
1535 | 1535 |
1536 register Ϲ¤Τˤ٤͡ | 1536 そろそろ register は構造体にすべきだね。 |
1537 struct register { | 1537 struct register { |
1538 int used; | 1538 int used; |
1539 int valued; | 1539 int valued; |
1540 char *name; | 1540 char *name; |
1541 char *wname; | 1541 char *wname; |
1542 char *bname; | 1542 char *bname; |
1543 int type; /* register variable or not */ | 1543 int type; /* register variable or not */ |
1544 int number; | 1544 int number; |
1545 } | 1545 } |
1546 virtual/real ϡɤ롣 | 1546 virtual/real は、どうする。 |
1547 | 1547 |
1548 Sat Feb 15 14:00:03 JST 2003 | 1548 Sat Feb 15 14:00:03 JST 2003 |
1549 | 1549 |
1550 fdecl_struct ʸŪ˰иȤ˹Ԥȡint *f(int | 1550 fdecl_struct を構文的に引数が出現するときに行うと、int *f(int |
1551 a) ʤɤǡ* ɾˡint aɾ줷ޤ*obj | 1551 a) などで、* の評価が終る前に、int aが評価されしまう。*obj |
1552 obj ɾʤfΥפꤷʤint*f()[] | 1552 のobj を評価し終らないとfのタイプが確定しない。int*f()[] み |
1553 ʾ礬뤫顣(?) ʤΤǡgcc ȡ뤿ˤϡ | 1553 たいな場合があるから。(?) なので、gcc と、そろえるためには、 |
1554 arg Ƭ fdecl_struct ԤˡǤϤǡfdecl Ǥ | 1554 arg の先頭で fdecl_struct を行う方法ではだめで、fdecl 中であ |
1555 Ȥ齤ɤ | 1555 とから修正する方が良い。 |
1556 | 1556 |
1557 fix 褦ˤꥹȤʤơ¸ߤʤ! | 1557 fix しようにも引数リストなんて、存在しないじゃん! |
1558 | 1558 |
1559 varargs ΤϤɤ... | 1559 varargs を実装するのはめんどくさかろう... |
1560 | 1560 |
1561 rvalue(expr(),type) Ǥϡexpr() typervalue˰Ϥ | 1561 rvalue(expr(),type) では、expr() のtypeをrvalueに引き渡せな |
1562 Ǥ⡢type ѿˤȡrvalueۤʤ륿פǸ | 1562 い。でも、type を大域変数にすると、rvalueを異なるタイプで呼 |
1563 ӽФȤtypeѹɬפ롣rvaluetype ΰ | 1563 び出すときにtypeを変更する必要がある。このrvalueのtype の扱 |
1564 ϡʤϤޤäȤΤǡrvalue(int e,int type) | 1564 いは、かなりはまったことがあるので、rvalue(int e,int type)の |
1565 ɤȤϳΤʤ... | 1565 方が良いことは確かなんだが... |
1566 | 1566 |
1567 struct_push registerΰʣʤä | 1567 struct_push のregisterの扱いが複雑すぎ。なんか、もっと |
1568 ñˤʤʤ? | 1568 簡単にならないの? |
1569 | 1569 |
1570 Sun Feb 16 07:58:23 JST 2003 | 1570 Sun Feb 16 07:58:23 JST 2003 |
1571 | 1571 |
1572 ʤɤȸäơ | 1572 代入しなくて良いからと言って、ソース |
1573 ΥꥹȤƤϡɤʤ | 1573 のリストから除いては、上書きを防げない。 |
1574 | 1574 |
1575 Sun Feb 16 22:55:58 JST 2003 | 1575 Sun Feb 16 22:55:58 JST 2003 |
1576 | 1576 |
1577 vdisp äƤʤä? | 1577 vdisp ってなんだったんだ? |
1578 | 1578 |
1579 Mon Feb 17 12:35:39 JST 2003 | 1579 Mon Feb 17 12:35:39 JST 2003 |
1580 | 1580 |
1581 Ͻ褿ߤϾΤˤ٤ʤΤ? | 1581 並列代入は出来たみたい。代入は小さいものを先にすべきなのか? |
1582 ޤǤ㤤ɡΤ礭ΤϤ | 1582 まぁ、できりゃいいんだけど、横に避けるものが大きいのはいや |
1583 ͡ | 1583 だよね。 |
1584 | 1584 |
1585 Tue Feb 18 11:56:10 JST 2003 | 1585 Tue Feb 18 11:56:10 JST 2003 |
1586 | 1586 |
1587 overlapped Ѥ emit_copy | 1587 overlapped 用の emit_copy |
1588 float/double | 1588 float/double |
1589 long long | 1589 long long |
1590 | 1590 |
1591 Tue Feb 18 19:34:31 JST 2003 | 1591 Tue Feb 18 19:34:31 JST 2003 |
1592 | 1592 |
1593 code argument ȿžȡlist2(LVAR,offset) | 1593 code argument の符号を反転させると、list2(LVAR,offset) |
1594 offsetɥ쥹ȰפƤȤ | 1594 のoffsetがアドレスの方向と一致しているという前提が |
1595 롣ǡ¤ΤγǼƤޤ... | 1595 崩れる。それで、構造体の格納順序がずれてしまう... |
1596 | 1596 |
1597 ȤȤ... def(n) codeλargumentϡɽѿƱ | 1597 ということは... def(n) でcodeの時はargumentは、局所変数と同じ |
1598 ǥޥʥǽɤ | 1598 扱いでマイナス符号で処理した方が良い。 |
1599 | 1599 |
1600 ǤߤǤ⤵ | 1600 できたみたい。でもさ、 |
1601 | 1601 |
1602 int main( int ac, char *av[]) | 1602 int main( int ac, char *av[]) |
1603 { | 1603 { |
1604 int n; | 1604 int n; |
1605 goto arg1(0,1,2,3,4,return,environment); | 1605 goto arg1(0,1,2,3,4,return,environment); |
1606 } | 1606 } |
1607 | 1607 |
1608 äơä return ʸʤȡʸ | 1608 って、きっと return 文がないと、文句を |
1609 ͡ࡣ | 1609 言われるよね。むむむ。 |
1610 | 1610 |
1611 post processing overlapƤʤȤݾڤʤ | 1611 post processing する時にoverlapしてないという保証がない。 |
1612 | 1612 |
1613 Wed Feb 19 15:38:55 JST 2003 | 1613 Wed Feb 19 15:38:55 JST 2003 |
1614 | 1614 |
1615 ʬȤȤoverlapƤʤΤǡ | 1615 自分自身とのoverlapを見てないので、 |
1616 struct a a,int i | 1616 struct a a,int i |
1617 int i,struct a a | 1617 int i,struct a a |
1618 ߤʻ˼ʬȤƤޤʤΤǡemit_copy | 1618 みたいな時に自分自身を壊してしまう。なので、emit_copy |
1619 Ʋʤ褦˽ɬפ롣 | 1619 が、ちゃんと方向を見て壊さないように処理する必要がある。 |
1620 | 1620 |
1621 call bcopy Ǥޤ͡ | 1621 call bcopy でいいじゃん。まね。 |
1622 | 1622 |
1623 Wed Feb 19 20:42:07 JST 2003 | 1623 Wed Feb 19 20:42:07 JST 2003 |
1624 | 1624 |
1625 ̤ C2CbC CbC2C micro C ˼ࡣƽˡ | 1625 楊さんの C2CbC と CbC2C を、micro C に取り込む。各所に、 |
1626 conv->func(); ࡣconv ϡ¤Ρ | 1626 conv->func(); を埋め込む。conv は、構造体。 |
1627 | 1627 |
1628 conv: original | 1628 conv: original |
1629 c2cbc | 1629 c2cbc |
1630 cbc2c | 1630 cbc2c |
1631 | 1631 |
1632 Ȥ롣ʤۤɡ | 1632 とする。なるほど。 |
1633 | 1633 |
1634 Thu May 6 08:32:05 JST 2004 | 1634 Thu May 6 08:32:05 JST 2004 |
1635 | 1635 |
1636 äѤ library ⼫ʬǺʤȤ͡С | 1636 やっぱり library も自分で作らないとね。そうすれば、 |
1637 CbC only Ǻ뤫顣 | 1637 CbC only で作れるから。 |
1638 | 1638 |
1639 conv ϡޤɤǥǤϤʤߤ뤫 | 1639 conv は、あんまり良いアイデアではないみたい。取るか。。。 |
1640 | 1640 |
1641 Thu May 13 12:59:16 JST 2004 | 1641 Thu May 13 12:59:16 JST 2004 |
1642 | 1642 |
1643 byte code interpreter CbC Ȥǽ? | 1643 byte code interpreter を CbC 自身で書いたら? |
1644 | 1644 |
1645 ǤäѤưʤ顢ޤ̣Ϥʤ... | 1645 それでもやっぱり動かないから、あんまり意味はないんだけど... |
1646 | 1646 |
1647 C ǽƤ⤤ | 1647 C で書いてもいいか。 |
1648 | 1648 |
1649 Wed Dec 22 15:17:49 JST 2004 | 1649 Wed Dec 22 15:17:49 JST 2004 |
1650 | 1650 |
1651 reset { | 1651 reset { |
1652 shift; | 1652 shift; |
1653 } | 1653 } |
1654 | 1654 |
1655 ͤ ʤǡreturn ʸˤΤ̡ˤΤ | 1655 ねぇ。 なんで、return 構文にしたのか。しかも別々にしたのか。 |
1656 | 1656 |
1657 goto ret(value),env; | 1657 goto ret(value),env; |
1658 | 1658 |
1659 ޤͤ | 1659 まぁ、ねぇ。 |
1660 try { | 1660 try { |
1661 .... goto event .... | 1661 .... goto event .... |
1662 } catch (event) { | 1662 } catch (event) { |
1663 } | 1663 } |
1664 Ƥ⤤ɡ | 1664 をいれてもいいんだけど。 |
1665 | 1665 |
1666 ࡢޤʡ | 1666 うーむ、いまいちだな。 |
1667 | 1667 |
1668 inline function return,env äƤ⤢뤱ɡ | 1668 inline function のreturn,env を実装するっていう技もあるけど。 |
1669 | 1669 |
1670 äѤꡣsetjmp = return ߤˤ? Ϥǡ | 1670 やっぱり。setjmp = return みたいにする? それはそれで、 |
1671 䤵.... | 1671 やさしいんだけど.... |
1672 | 1672 |
1673 | 1673 |
1674 Fri Jan 6 20:26:24 JST 2006 | 1674 Fri Jan 6 20:26:24 JST 2006 |
1675 | 1675 |
1676 environment = interface frame ؤѰդʤȤ͡ | 1676 environment = interface frame の切替えを用意しないとね。 |
1677 | 1677 |
1678 Mon Jan 30 21:53:11 JST 2006 | 1678 Mon Jan 30 21:53:11 JST 2006 |
1679 | 1679 |
1680 packet_put ..... fork | 1680 packet_put ..... fork |
1681 packdet_put(interface hoge); | 1681 packdet_put(interface hoge); |
1717 code hoge(int a, code f(int k,...), ...) | 1717 code hoge(int a, code f(int k,...), ...) |
1718 { | 1718 { |
1719 goto f(a,...); | 1719 goto f(a,...); |
1720 } | 1720 } |
1721 | 1721 |
1722 syntax ... type λϤʤȤʤȤ͡ | 1722 syntax が汚い... type の指定はなんとかしないとだめだね。 |
1723 | 1723 |
1724 ... | 1724 ... |
1725 | 1725 |
1726 int a, | 1726 int a, |
1727 | 1727 |
1728 줿ȤΥȤʤɤʤ͡ | 1728 ずれたときのコストがなぁ。良く見えないんだよね。 |
1729 | 1729 |
1730 ǽȤϻפɡ | 1730 可能だとは思うんだけど。 |
1731 | 1731 |
1732 __meta goto { | 1732 __meta goto { |
1733 } | 1733 } |
1734 | 1734 |
1735 ߤʴ? | 1735 みたいな感じ? |
1736 | 1736 |
1737 Sun Nov 26 21:14:57 JST 2006 | 1737 Sun Nov 26 21:14:57 JST 2006 |
1738 | 1738 |
1739 | frame pointer | stack pointer | 1739 | frame pointer | stack pointer |
1740 v----> argument local <--|-----v | 1740 v----> argument local <--|-----v |
1741 caller_arg | 1741 caller_arg |
1742 | 1742 |
1743 ǤϤʤơ | 1743 ではなくて、 |
1744 | 1744 |
1745 | previous $fp | 1745 | previous $fp |
1746 |<-intr_size---><--------r1_offset----------->| | 1746 |<-intr_size---><--------r1_offset----------->| |
1747 | | frame pointer | stack pointer | 1747 | | frame pointer | stack pointer |
1748 v<--- interface-+---- local ----->|<--------->v | 1748 v<--- interface-+---- local ----->|<--------->v |
1749 <0 >0 caller_arg | 1749 <0 >0 caller_arg |
1750 | 1750 |
1751 ʤ顢ʤ? caller_arg sp ФѤɤ | 1751 なら、いいんじゃない? caller_arg は sp 相対で積めば良い。 |
1752 local ѿ max_caller_arg ʤΤ sp ФǤѤʤ | 1752 local 変数は max_caller_arg が不定なので sp 相対では積めない。 |
1753 | 1753 |
1754 ȡframe pointer goto DzѤˤʤ롣interface arugment | 1754 これだと、frame pointer がgoto で可変になる。interface がarugment |
1755 ˤʤΤǡ¤ʤsubroutine call ˶ʤ뤱ɡ | 1755 扱いになるので、限りなくsubroutine call に近くなるけど。 |
1756 (ޤʡ...) | 1756 (まぁ、そうだよな、そういう狙いだし...) |
1757 | 1757 |
1758 ä顢function call˹碌뤳Ȥǽʤʤ? | 1758 だったら、完全にfunction callに合わせることも可能なんじゃないか? |
1759 ĹξȤޤäƱˤʤ롣gcc (ͽꤷƤƱ) | 1759 可変長引数の場合とまったく同じになる。gcc の(予定ししてる実装と同じ) |
1760 ȡC-- paraterized goto ȡޤäƱˤʤ롣 | 1760 これだと、C-- の paraterized goto と、まったく同じになる。 |
1761 | 1761 |
1762 | previous $fp | 1762 | previous $fp |
1763 |<-intr_size---><-------------r1_offset------------>| | 1763 |<-intr_size---><-------------r1_offset------------>| |
1764 | |frame pointer | stack pointer | 1764 | |frame pointer | stack pointer |
1765 v<--- interface-+-------|--- local ----->|<-------->v | 1765 v<--- interface-+-------|--- local ----->|<-------->v |
1766 <0 >0 xxx caller_arg | 1766 <0 >0 xxx caller_arg |
1767 |frame pointer | stack pointer | 1767 |frame pointer | stack pointer |
1768 v<--- interface----+-------|--- local ----->|<-------->v | 1768 v<--- interface----+-------|--- local ----->|<-------->v |
1769 <0 >0 xxx caller_arg | 1769 <0 >0 xxx caller_arg |
1770 | 1770 |
1771 caller_arg spѤȡСalloca ʤ | 1771 caller_arg はsp上に積むと。そうすれば、alloca も問題ない。 |
1772 | 1772 |
1773 ѤʤäΤϡ֤fp ưʤФʤ | 1773 これを採用しなかったのは、たぶん、fp を移動しなければならな |
1774 Τäʡϡparse tree äƤ顢code | 1774 いのを嫌ったんだろうな。今は、parse tree 作ってから、code |
1775 ǽʤΤǡƤɤ | 1775 生成も可能なので、そうしても良いんだが。 |
1776 | 1776 |
1777 Ǥ⡢ɤ衣ɤɤǤ | 1777 でも、めんどくさいよ。めんどくさい。めんどくさいです。 |
1778 Ǥ⡢뤷ʤ | 1778 でも、やるしかない。 |
1779 | 1779 |
1780 СC Ѵ⤫ʤ䤵ʤ뤫Τʤ | 1780 これを、やれば、C からの変換もかなりやさしくなるかも知れない。 |
1781 | 1781 |
1782 Sun Nov 26 19:41:38 JST 2006 | 1782 Sun Nov 26 19:41:38 JST 2006 |
1783 | 1783 |
1784 max interface ߤʤΤɬפǡСlocal ѿȤ | 1784 max interface みたいなのが必要で、そうすれば、local 変数との |
1785 ߺѤ롣դ˸СѤϽʤ | 1785 相互作用は避けられる。逆に言えば、利用は出来ない。 |
1786 | 1786 |
1787 Ǥ⡢max_interface 1 path ǤϷޤʤ顢long offset | 1787 でも、max_interface は1 path では決まらない。だから、long offset |
1788 λϡäȤϤޤ롣äARMξ硣äѤꡢmax_interface | 1788 の時は、ちょっとはまる。特にARMの場合。やっぱり、max_interface |
1789 ϷǤΤ? ȡfunction call Ƥ | 1789 は決め打ちがいいのかな? そうすると、function call から呼ぶ |
1790 ȤˤϤޤ뤬... | 1790 ときにはまるが... |
1791 | 1791 |
1792 offset 0 ¦ˤСmax_interface fpΤߤ | 1792 offset を 0 側からにすれば、max_interface はfp設定時のみに |
1793 ʤ뤬ȡinterface ѹȤcopyȯ䤹 | 1793 なるが、そうすると、interface を変更したときのcopyが発生しやすく |
1794 ʤ롣䡢ʤȤϤʤΤ? | 1794 なる。いや、そんなことはないのかな? |
1795 | 1795 |
1796 __code f(int a,int b) { | 1796 __code f(int a,int b) { |
1797 goto g(int c,int b,int a); | 1797 goto g(int c,int b,int a); |
1798 } | 1798 } |
1799 | 1799 |
1802 v<--- interface-+-------|--- local ----->|<-------->v f | 1802 v<--- interface-+-------|--- local ----->|<-------->v f |
1803 a,b | 1803 a,b |
1804 v<--- interface-+-------|--- local ----->|<-------->v goto g | 1804 v<--- interface-+-------|--- local ----->|<-------->v goto g |
1805 a,b,c | 1805 a,b,c |
1806 | 1806 |
1807 ߤʴǤ? 櫓͡ | 1807 みたいな感じですか? 後ろをそろえるわけね。その方が自然か。 |
1808 | 1808 |
1809 ȡäѤꡢmax_interface ˤʤ롣äѤꡢǡ | 1809 これだと、やっぱり、max_interface が問題になる。やっぱり、それで、 |
1810 fp ˤƤʡ | 1810 fp を下にしてあるんだろうな。 |
1811 | 1811 |
1812 __code f(int a,int b) { | 1812 __code f(int a,int b) { |
1813 goto g(int c,__code *f,int a,int b); | 1813 goto g(int c,__code *f,int a,int b); |
1814 } | 1814 } |
1815 | 1815 |
1829 a,b,fp,n,c | 1829 a,b,fp,n,c |
1830 |frame pointer | stack pointer | 1830 |frame pointer | stack pointer |
1831 v<--- interface---------|--- local ----->|<-------->v goto n | 1831 v<--- interface---------|--- local ----->|<-------->v goto n |
1832 a,b | 1832 a,b |
1833 | 1833 |
1834 ȡgoto n(...); ǡɤäfp ᤹? ... ΰ֤ǡ | 1834 えーと、goto n(...); で、どうやってfp を元に戻すの? ... の位置で、 |
1835 fp ФƤɤ(*) | 1835 前の fp を覚えておけば良い。(*) |
1836 | 1836 |
1837 ȡfunction call Τޤ¸Ǥ? ߤ͡ | 1837 これだと、function call を、そのまま実現できそうだけど? みたいだね。 |
1838 | 1838 |
1839 __code f(int a,int b,...) { | 1839 __code f(int a,int b,...) { |
1840 goto g(int c,f,int a,int b,...); | 1840 goto g(int c,f,int a,int b,...); |
1841 } | 1841 } |
1842 | 1842 |
1843 __code g(int c,__code *n(int a,int b,...),...) { | 1843 __code g(int c,__code *n(int a,int b,...),...) { |
1844 goto n(int d,int e,int g,...); | 1844 goto n(int d,int e,int g,...); |
1845 } | 1845 } |
1846 | 1846 |
1847 Ȥȡ̵¤stackӤ롣ա | 1847 とかすると、無限にstackが延びる。ふーん。 |
1848 | 1848 |
1849 __code g(int c,__code *n(...),...) { | 1849 __code g(int c,__code *n(...),...) { |
1850 goto n(int d,int e); | 1850 goto n(int d,int e); |
1851 } | 1851 } |
1852 | 1852 |
1853 ϡɤ? fp ϡΤޤޤʤ͡ | 1853 は、どうする? fp は、そのままなんだろうね。 |
1854 | 1854 |
1855 |<----------------------------r1_offset------------>| | 1855 |<----------------------------r1_offset------------>| |
1856 |frame pointer | stack pointer | 1856 |frame pointer | stack pointer |
1857 v<--- interface-+-------|--- local ----->|<---------v f | 1857 v<--- interface-+-------|--- local ----->|<---------v f |
1858 a,b,(n,c) | 1858 a,b,(n,c) |
1864 v<-interface----+----|-- local --->|<---------v g | 1864 v<-interface----+----|-- local --->|<---------v g |
1865 a,b,fp,n,c | 1865 a,b,fp,n,c |
1866 v<-interface-+----|-- local --->|<---------v g | 1866 v<-interface-+----|-- local --->|<---------v g |
1867 d,e | 1867 d,e |
1868 | 1868 |
1869 ǡfp ϾϡɤʤʤΤǡfp ʬ餹 | 1869 で、fp は上書きか。それは、良くない。なので、fp の分ずらす。 |
1870 Ȥϡfp μؤ褦ˤΤɤΤ | 1870 というよりは、fp の次を指すようにするのが良いのか。 |
1871 | 1871 |
1872 __code f(int a,int b,...) { | 1872 __code f(int a,int b,...) { |
1873 goto g(int c,__code *f,int a,int b,...); | 1873 goto g(int c,__code *f,int a,int b,...); |
1874 } | 1874 } |
1875 | 1875 |
1890 a,b,fp,n,c | 1890 a,b,fp,n,c |
1891 |frame pointer | stack pointer | 1891 |frame pointer | stack pointer |
1892 v---- interface-+----------|-- local --->|<---------v goto n | 1892 v---- interface-+----------|-- local --->|<---------v goto n |
1893 a,b | 1893 a,b |
1894 | 1894 |
1895 Ȥ櫓frame pointer Υץäɤ櫓͡ | 1895 というわけか。frame pointer のオプションがあった方が良いわけだね。 |
1896 | 1896 |
1897 ȡΤѹ⾯ʤƺѤߤ(ۤȤ?) | 1897 これだと、全体の変更も少なくて済みそうだ。(ほんとうか?) |
1898 | 1898 |
1899 g ... ΰ֤äΤ뤳Ȥɬܡʤꥳɤ˻ | 1899 g の ... の位置を前もって知ることが必須。かなりコードが繁雑に |
1900 ʤ뤱ɡ | 1900 なるけど。 |
1901 __code g(int c,__code n,...) { | 1901 __code g(int c,__code n,...) { |
1902 ɤȡΥåʤºݤˤϡ | 1902 の方が良いが、それだと、型のチェックが出来ない。実際には、 |
1903 ʤ˻ʷܤˤʤ롣typedef Фɤ͡ | 1903 かなり繁雑な型を書く羽目になる。typedef すればいいんだけどね。 |
1904 | 1904 |
1905 __code ϰۤtypedef ˤ? | 1905 __code は暗黙のtypedef にする? |
1906 | 1906 |
1907 | 1907 |
1908 max_interface¤ϸŪǤϤʤ? Ǥʤ... | 1908 これを許すとmax_interfaceの制限は現実的ではない? でもないか... |
1909 codeǥ³͡ä顢max_interface | 1909 そのcodeでアクセス限界だからね。だったら、max_interface を |
1910 äơ(1024?) 䡢äѤ fp ưʤȤ | 1910 作って、(1024程度?) いや、やっぱり fp は動かさないとだめ |
1911 ʤΤǡɤʤ | 1911 なので、良くない。 |
1912 | 1912 |
1913 fp Ѥȡ᤹Ȥζ̤? 빽̯ | 1913 fp を積む場合と、戻す場合との区別は? 結構微妙か。 |
1914 goto ¦ ...(Ʊ)褿᤹ | 1914 goto 側の定義 ...が先に(か同時に)来たら戻す |
1915 goto ¦ ...°褿Ѥ | 1915 goto 側の定義 ...が実引数より後に来たら積む |
1916 ǡ櫓? | 1916 で、いいわけね? |
1917 | 1917 |
1918 äȡSemantics ʣˤʤꤹ롣ǽʤɡ | 1918 ちょっと、Semantics が複雑になりすぎる。可能なんだけど。 |
1919 environment Ǥ goto Ǥޤ˥ꥻåȤʤȤʤꤽ | 1919 environment での goto でたまにリセットしないとおかしくなりそう。 |
1920 Stack ƤϡWarning 餤⡣ | 1920 Stack 増えている場合は、Warning ぐらいだした方がいいかも。 |
1921 Ū˸ʤȤ狼ʤͭ¤ɤ⡣ | 1921 大域的に見ないとわからない。有限かどうかも。 |
1922 | 1922 |
1923 tail recursive call ǤΤȡޤѤʤʡ | 1923 全部、tail recursive call でやるのと、あまり変わらないかな。 |
1924 ȡc-- parametarized goto Ⱥʤ⡣ | 1924 そうすると、c-- のparametarized goto と差がないかも。 |
1925 | 1925 |
1926 | 1926 |
1927 | 1927 あ、そうか。 |
1928 | 1928 |
1929 __code g(int c,__code *n(int a,int b,...),...) { | 1929 __code g(int c,__code *n(int a,int b,...),...) { |
1930 goto n(int d,int e,int g,...); | 1930 goto n(int d,int e,int g,...); |
1931 } | 1931 } |
1932 | 1932 |
1933 n ϡưŪ줿 | 1933 の n は、自動的に定義された方が便利だろう。 |
1934 | 1934 |
1935 __code g(int c,...) { | 1935 __code g(int c,...) { |
1936 goto __cotinuation(int d,int e,int g,...); | 1936 goto __cotinuation(int d,int e,int g,...); |
1937 } | 1937 } |
1938 | 1938 |
1939 ߤʴ | 1939 みたいな感じ。 |
1940 | 1940 |
1941 go g(int c,int b,...) to hoge(...); | 1941 go g(int c,int b,...) to hoge(...); |
1942 | 1942 |
1943 Ǥ? ϡᤫ... Ǥʤɡ꤬ | 1943 ですか? それは、だめか... だめでもないんだけど、型の設定が |
1944 롣 | 1944 難しすぎる。 |
1945 | 1945 |
1946 K&R style ʤΤ... | 1946 K&R style の宣言の方が綺麗なのか... |
1947 | 1947 |
1948 Sun Nov 26 21:53:05 JST 2006 | 1948 Sun Nov 26 21:53:05 JST 2006 |
1949 | 1949 |
1950 (*) interface 礭ϡʬinterface | 1950 (*) interface の大きさの増減は、自分のinterface を見れば |
1951 狼Ϥ? 顢fp saveɬפʤϤ... | 1951 わかるはずだよね? だから、fp のsaveは必要ないはずだが... |
1952 | 1952 |
1953 __code f(int a,int b,...) { | 1953 __code f(int a,int b,...) { |
1954 goto g(int c,__code *f,int a,int b,...); | 1954 goto g(int c,__code *f,int a,int b,...); |
1955 } | 1955 } |
1956 | 1956 |
1957 __code g(int c,__code (*n)(...),...) { | 1957 __code g(int c,__code (*n)(...),...) { |
1958 goto n(...); | 1958 goto n(...); |
1959 } | 1959 } |
1960 | 1960 |
1961 Τˤ狼ɡְ㤨Ȥˡˤʤ롣 | 1961 確かにわかるんだけど、宣言を間違えたときに、おじゃんになる。 |
1962 ɤǤϤηϰʳޤǤ | 1962 どうせ、だめではあるんだが。引数の型は一段階までしか、 |
1963 åʤΤǡ͡ | 1963 チェックしないので、だめだね。 |
1964 | 1964 |
1965 | 1965 |
1966 ΤꡢŪ꤬ߤʡ | 1966 このあたり、理論的な問題があるみたいだな。 |
1967 | 1967 |
1968 stack ޤͭ¤ʷդ | 1968 stack を含めた有限な型付け |
1969 ȡɽ | 1969 と、その表現 |
1970 | 1970 |
1971 ä꤬櫓? | 1971 って問題があるわけね? |
1972 | 1972 |
1973 parallel assignment ǤϡƱʬäõ | 1973 そうか、parallel assignment では、同じ部分を前もって探した |
1974 Ψ褤櫓(ɤäƤ뤳Ȥ) | 1974 方が効率がよいわけか。(どうせ、やっていることだが) |
1975 | 1975 |
1976 Sun Nov 26 23:22:12 JST 2006 | 1976 Sun Nov 26 23:22:12 JST 2006 |
1977 | 1977 |
1978 fp save ɬסΤȸȡ | 1978 fp のsave は必要。何故かと言うと、 |
1979 goto f(a,b,...) | 1979 goto f(a,b,...) |
1980 ǡʬɤ뤫ϡŪʰǤ | 1980 で、後ろの部分がどれだけあるかは、間接的な引数での |
1981 ǤϤ狼ʤ顣 | 1981 宣言ではわからないから。 |
1982 | 1982 |
1983 stack interface ʤ顢ɤ | 1983 stack 上に全部 interface があるなら、良いが、 |
1984 ʬ register ˾äƤ롣 | 1984 部分は register に乗っている。 |
1985 | 1985 |
1986 goto f(a,b,c,...) | 1986 goto f(a,b,c,...) |
1987 | 1987 |
1988 ȤȤˡ... ΰregister˾äƤ롣ɤ | 1988 としたときに、... の一部はregisterに乗っている。どれだけ |
1989 äƤΤΤɬפ뤬fp仡 | 1989 乗っているのかを知る必要があるが、それをfpから推察する |
1990 ȤϤǤʤưȤΰۤʤ뷿ߤƤ | 1990 ことはできない。浮動小数点とかの異なる型が散在している |
1991 顣 | 1991 から。 |
1992 | 1992 |
1993 ... ǰϤϡ˾äƤɬפ롣 | 1993 ... で引き渡す引数は、メモリに乗っている必要がある。 |
1994 ʤ顢쥸Ǥ֤ʤϤ | 1994 型が明解なら、レジスタ上でもだいじょぶなはずだが。 |
1995 | 1995 |
1996 ŪʰŪˤѴǤϤɡopen | 1996 明示的な引数に大域的には変換できるはずだけど、open |
1997 ʴĶǤϡϤǤʤ | 1997 な環境では、それはできない。 |
1998 | 1998 |
1999 ȤС | 1999 だとすれば、 |
2000 __code f(int a, int b : int h, ...) { | 2000 __code f(int a, int b : int h, ...) { |
2001 ... | 2001 ... |
2002 goto g(a,b,c : d,e,f,...) | 2002 goto g(a,b,c : d,e,f,...) |
2003 } | 2003 } |
2004 ߤʷǡstack ˾褻ɬפ롣 | 2004 みたいな形で、stack 上に乗せる引数を明示する必要がある。 |
2005 | 2005 |
2006 ϡʤʤ? | 2006 これは、なんなの? |
2007 | 2007 |
2008 : ΰϲѤ˽ʤ | 2008 : の前の引数は可変に出来ない |
2009 : θޤǤϲѤ˽ | 2009 : の後までは可変に出来る |
2010 | 2010 |
2011 äƤȤ | 2011 っていうことか。 |
2012 | 2012 |
2013 ¤Τϡ˼ȤƤ.. | 2013 構造体は、メモリ上に取るとしても.. |
2014 | 2014 |
2015 ޤ... ΤȤޤǥ쥸ǡʹߤϡǤ | 2015 まぁ、... のところまでレジスタで、それ以降は、メモリでも |
2016 ʬɤ͡ˤ衢ʣ뤳ȤϳΤ | 2016 十分だけどね。いずれにせよ、複雑すぎることは確か。 |
2017 | 2017 |
2018 __code g(int c,__code (*n)(int a,int b,int d,...),...) { | 2018 __code g(int c,__code (*n)(int a,int b,int d,...),...) { |
2019 goto n(int d,int e,int c,...); | 2019 goto n(int d,int e,int c,...); |
2020 } | 2020 } |
2021 | 2021 |
2022 ǡ... ϡ٤ơƱΤ֤Ϥ ... | 2022 で、この... は、すべて、同じものに置き換わるはず。 ... が |
2023 ⤢뤬 | 2023 入る場合もあるが。 |
2024 | 2024 |
2025 ¦ | 2025 受け側が |
2026 __code c(int d,int e,int c,int k,int j) {} | 2026 __code c(int d,int e,int c,int k,int j) {} |
2027 ƤȤˡk,j 쥸˾äƤ뤫Τ줺 | 2027 で定義されているときに、k,j がレジスタに乗っているかも知れず、 |
2028 äƤᡣʤΤǡѤˤʤʬɬפ롣 | 2028 乗っていたらダメダメ。なので、可変になる部分を明示する必要がある。 |
2029 | 2029 |
2030 Mon Nov 27 11:17:39 JST 2006 | 2030 Mon Nov 27 11:17:39 JST 2006 |
2031 | 2031 |
2032 ɡn ȡºݤn 뤳Ȥʤ͡ | 2032 結局、このn の定義と、実際のn の定義がずれることが問題なんだよね。 |
2033 __code c(int d,int e,int c,...) {} | 2033 __code c(int d,int e,int c,...) {} |
2034 ǡ뤳Ȥ⤢С | 2034 で、受けることもあれば、 |
2035 __code c(int d,int e,int c,int k,int j) {} | 2035 __code c(int d,int e,int c,int k,int j) {} |
2036 Ǽ뤳Ȥ⤢롣뤤ϡ | 2036 で受けることもある。あるいは、 |
2037 __code c(int d,int e,int c,int k,int j,...) {} | 2037 __code c(int d,int e,int c,int k,int j,...) {} |
2038 Ȥ⡣ | 2038 とかも。 |
2039 | 2039 |
2040 implements Ȥaccetps Ȥʷ̤ | 2040 implements というか、accetps というか、そんな形の別な |
2041 Τʡ | 2041 宣言がいいのかな。 |
2042 __code f(int a, int b : int h, ...) { | 2042 __code f(int a, int b : int h, ...) { |
2043 Ǥ⤤... | 2043 でもいいんだが... |
2044 | 2044 |
2045 Mon Nov 27 11:34:33 JST 2006 | 2045 Mon Nov 27 11:34:33 JST 2006 |
2046 | 2046 |
2047 __code f(int a,int b,...) { | 2047 __code f(int a,int b,...) { |
2048 goto g(int c,__code *f,int a,int b,...); | 2048 goto g(int c,__code *f,int a,int b,...); |
2051 __code g(int c,__code (*n)(...),...) { | 2051 __code g(int c,__code (*n)(...),...) { |
2052 goto n(...); | 2052 goto n(...); |
2053 } | 2053 } |
2054 | 2054 |
2055 | 2055 |
2056 g Ȥˡfp ϡn ƬˤʤФʤʤ | 2056 g に入るときに、fp は、n の頭になければならない。これを |
2057 ưΤϡf 䡣ФƹԤȤˤϡb Ƭ | 2057 移動するのは、f の役割。出て行くときには、b の頭に |
2058 碌ɬפ롣ϡg 䡣g ϡƬ(fp) | 2058 合わせる必要がある。これは、g の役割。g は、元の頭(fp) |
2059 Τʤ顢ϼäƤɬפ롣Ǥ | 2059 を知らないから、これは取っておく必要がある。差では |
2060 ȽǤǤʤg ¦ǼäƤȤϲǽ | 2060 判断できない。g 側で取っておくことは可能だが、その |
2061 ˤ⡢f ¦餺餹礭Ϥɬפ롣 | 2061 時にも、f 側からずらす大きさを渡す必要がある。 |
2062 | 2062 |
2063 Ƥɤɤ... | 2063 明示しても良いんだけどね... |
2064 goto g(int c,__code *f,__environment,interface &rest), | 2064 goto g(int c,__code *f,__environment,interface &rest), |
2065 __envronment+sizeof(interface); | 2065 __envronment+sizeof(interface); |
2066 __code g(int c,__code (*n)(...),(void*)parent,...) { | 2066 __code g(int c,__code (*n)(...),(void*)parent,...) { |
2067 goto n(...),parent; | 2067 goto n(...),parent; |
2068 } | 2068 } |
2069 ߤʷǤ... Τʡ˻ɡ: ꤫ޤ? | 2069 みたいな形でさ... その方がいいのかな。繁雑だけど。: よりかまし? |
2070 | 2070 |
2071 : Ȥˡȡ: fp ߤʴˤʤ롣 | 2071 : を使う方法だと、: が fp みたいな感じになる。 |
2072 | 2072 |
2073 ͡줤syntaxˤʤʤ | 2073 難しいね。きれいなsyntaxにならない。 |
2074 | 2074 |
2075 Wed Jul 25 14:48:16 JST 2007 | 2075 Wed Jul 25 14:48:16 JST 2007 |
2076 | 2076 |
2077 inline code __goto ߤʷˤȡ | 2077 inline code __goto みたいな形にすると、 |
2078 | 2078 |
2079 __goto hoge(); | 2079 __goto hoge(); |
2080 | 2080 |
2081 goto reflection 롣 | 2081 goto を reflection 出来る。 |
2082 | 2082 |
2083 meta ʡinterface Ϥɤ? | 2083 meta な、interface はどうするの? |
2084 | 2084 |
2085 ǥեȤǡ,.... äƤȻפɤ | 2085 デフォルトで、,.... が入っていると思う方が良い。 |
2086 | 2086 |
2087 goto hoge(hoge.... , __code (*cont)(i) : meta ...); | 2087 goto hoge(hoge.... , __code (*cont)(i) : meta ...); |
2088 | 2088 |
2089 goto cont(i); -> goto cont(i: meta...); | 2089 goto cont(i); -> goto cont(i: meta...); |
2090 | 2090 |
2091 Ȥ? 줬ʤȡҤʤݡsubroutine Ȥ | 2091 という感じか? これがないと、記述がかなり面倒。subroutine とは |
2092 㤦? | 2092 違うの? |
2093 | 2093 |
2094 env ؤʤ? 뤱ɡ˻ʤΤ | 2094 env の切替えで明示出来ないの? 出来るけど、繁雑なのか。 |
2095 | 2095 |
2096 gcc ȤɤʤΤ... | 2096 gcc との相性が良くないのだが... |
2097 | 2097 |
2098 __code Ĥ餹롣script 뤫compiler | 2098 __code の先行宣言つらすぎる。script で生成するか、compiler で |
2099 ư褹ɤ | 2099 自動解決する方が良い。 |
2100 | 2100 |
2101 tcc goto f(); ǤϤʤơgoto (*f)(); | 2101 tcc の方が goto f(); ではなくて、goto (*f)(); を |
2102 롣ϡäɤ | 2102 強制する。これは、けっこう、めんどくさい。 |
2103 | 2103 |
2104 ... äƤΤѿߤʤΤ? stack scope 롣 | 2104 ... ってのは大域変数みたいなものだよね? ただ、stack scope がある。 |
2105 ʤΤǡsub routine ƱʤΤǤ? | 2105 なので、sub routine と同じなのでは? |
2106 | 2106 |
2107 | 2107 |
2108 | 2108 |
2109 | 2109 |
2110 | 2110 |
2111 | 2111 |
2112 | 2112 |
2113 | 2113 |
2114 | 2114 |
2115 | 2115 |