annotate paper/memo.txt @ 7:bcacfe595c2a

add memo.txt
author Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 12 Jun 2012 01:03:27 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 We have implemented Continuation based C (CbC).CbC is an extension of C, which has parameterized goto statement.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 It is useful for finite state automaton or many core tasks.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Goto statement is a way to force tail call elimination.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 The destination of goto statement is called Code Segment, which is actually a normal function of C.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 To represent recursive function call, the type system of C is not enough, because
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 it has no recursive types.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 We introduce __rectype keyword for recursive type, and it is implemented in GCC-4.6.0.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 We will compare the conventional methods, __rectype keyword and a method using C structure.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 Also we show usage of CbC and it's benchmark.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 ・__rectype と GCC-4.6.0 における実装の説明
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 ・普通に宣言した場合と __rectype , 構造体を使用した場合に比較
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 ・それと CbC のベンチマークをみせる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 ・Continuation based C
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 ・・CbC によるプログラミング
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 (なぜrectypeが必要になったのかを書く。1.引数の型チェックを行いたかった 2.Cの構文で宣言するとソースが長い、)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 CbC では継続を基本としている。継続は goto の後にコードセグメントと引数をかくことで行われる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 CbC においてはループ処理もこの goto による継続を用いて行われる。以下に loop の例を示す。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 今回我々は__rectype 構文を新たに実装した。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 __rectype はリカーシブタイプを宣言するものである。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 __rectype は引数に使われる型で、宣言中の引数の型と同じ型を持つ関数ポインタであることを示す。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 //ここでいうリカーシブタイプとは、同じ引数の型を持つタイプのことである。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 //C においては、以下のようなリカーシブタイプを宣言することはできない。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 void func( func *p )
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 関数ポインタを引数にもつ関数がある時、以下のように宣言される。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 __code csA( void (*p)() )
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 しかし、この宣言では p を使用する場合、p の引数の型チェックが行われない。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 p の引数の型チェックを行いたい時は以下の様に宣言しなければならない。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 __code csA( __code (*p)(void *) ) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 goto p(csB);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 これで p の引数の型チェックは行われるようになる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 だが、これでもまだ正しくはない。なぜなら、p が引数として受け取った関数も引数を持つからである。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 引数で受け取る関数ポインタがそれぞれ引数で関数ポインタを持つ場合、以下のような宣言になる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 __code csA( __code (*p)(__code (*)(__code (*)( __code (*)( __code (*)(,,) )))))
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 (,, の部分には同じような宣言が続いていく。)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 C において引数で再帰的な関数ポインタを受け取る場合は上記のような宣言になり。宣言しきることができない。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 (再帰的な関数ポインタ…?)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 そこで、__rectype 構文により以下のような宣言を行えるようにした。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 __code csA( __rectype *p )
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 この時、*p は csA のポインタを表している。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 ・__rectype の実装方法
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 __rectype の実装は、Generic Tree を書き換えることで行なっている。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 GCC では~のプログラムは次のようにGeneric Treeが作成される。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 void func(void (*)() );
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 fig1.
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 TREE_LIST には引数の情報が入っている。第一引数にはFUNCTION_TYPEへのポインタがさされているのがわかる。(第二引数にVOID_TYPEがあるのは固定長引数の為)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 この第一引数が指すFUNCTION_TYPEを自分自身へと書き換えることで __rectype は実装されている。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 GCC 内部に実際に書き込んであるコードは以下になる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 gcc/c-decl.c
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 cbc_return_f = NULL_TREE;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 cbc_env = NULL_TREE;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 if ( declspecs->typespec_word == cts_CbC_code )
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 cbc_set_codesegment(decl1);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 /* implementation of rectype */
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 tree func_tree = TREE_TYPE(decl1);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 // parm is PARM_DECL
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 tree parm = declarator->u.arg_info->parms;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 while (parm) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 tree tmptype = parm;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 if (!IS_RECTYPE(TREE_TYPE(tmptype))) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 parm = TREE_CHAIN(parm);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 continue;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 tree t = TREE_TYPE(tmptype);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 while (TREE_CODE(t) == POINTER_TYPE) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 tmptype = t;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 t= TREE_TYPE(tmptype);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 TREE_TYPE(tmptype) = func_tree;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 parm = TREE_CHAIN(parm);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 decl1 は宣言中の自分自身にあたる変数である。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 ・__rectype 実装による問題
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 warning チェックによる無限再帰。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 __rectype を上記の方法で実装を行った所、以下の呼び出しをおこうとした場合 compile 中に segmen tation fault が発生した。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 __code csA(__rectype *p) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 goto p(3);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 これは GCC においては以下の構文と同じである。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 void func(void (*p)(void*)) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 p(3);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 上記の場合、GCC の内部では宣言された p の正しい引数の型を調べるためにポインタが辿られていく。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 その後、int の 3 が void の pointer へと convert(cast) される。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 しかし、__rectype の実装では pointer の先は csA となる。その csA の第一引数が関数ポインタだった場合その引数の型もみるのだが、この場合それが csA である。csA の引数の型をみにいき続けてしまい無限再帰となってしまっていた。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 この問題を解決するために、現在の実装では __rectype で宣言されたモノの型を辿らないようにしている。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 以下はその実装の部分である。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 gcc/c-family/c-pretty-print.c
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 static void
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 pp_c_abstract_declarator (c_pretty_printer *pp, tree t)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 if (TREE_CODE (t) == POINTER_TYPE)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 pp_c_right_paren (pp);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 #ifndef noCbC
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 if(IS_RECTYPE(t)) return;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 #endif
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 t = TREE_TYPE (t);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 pp_direct_abstract_declarator (pp, t);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 上記のコードの変数 t には引数の情報が入っている。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 ~行目の t = TREE_TYPE (t); におり、 t が pointer タイプだった場合そのタイプを辿るようになっているのが分かる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 ここで、もし t が __rectype で宣言されたのならただ return を行うという処理を追加した。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 この実装により warning チェックの際の無限再帰を抑えることができた。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 ・構造体を使用してのリカーシブタイプ
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 リカーシブタイプの問題は引数を構造体にすることでも解決できる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 以下はその例である。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 struct interface {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 __code (*next)(struct interface);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 };
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 __code csA(struct interface p) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 :
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 goto p.next(ds);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 int main() {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 struct interface ds = { print };
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 goto csA(ds);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 return 0;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 構造体で包むことで先に上げた関数ポインタの引数の型チェックの問題はクリアされる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 ・GCC 版 CbC コンパイラのベンチマーク:
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 最後に、GCC 版 CbC コンパイラのベンチマークをMicro-C版 CbC と比較しながら以下に示す。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 使用したプログラムは conv1 プログラムで、内部では加算と継続を交互に行なっている。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 実装の確認と問題:
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 ・関数ポインタ中の引数の型に__rectype
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 __code csA(__code (*p)(__rectype*)) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 goto p(csA);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 特に問題なく実行できる。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 ・typedef の問題
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 //typedef __code (*csPtr)(__rectype);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 typedef __code (*csPtr)(__rectype*); // error
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 上記の場合、宣言自体失敗する。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 修正が必要。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 ・struct 内部での __rectype
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 struct interface {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 __rectype *next;
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 };
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 __code csA(struct interface p) {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 struct interface ds = { csA };
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 goto p.next(ds);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 void main1() {
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 struct interface ds = { print };
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 goto csA(ds);
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 }
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 この時、errorがでる…が、一応 struct の宣言自体は通っている。
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 struct の宣言時に __rectype がきたらエラーが出るようにすべき…
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260
bcacfe595c2a add memo.txt
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261