416
|
1 Interfaceのtypedef はコールフレームを定義する
|
|
2 Interfaceの呼び出しの時に使える引数はtypedefに定義されている必要がある
|
|
3 ... は呼び出し側のコールフレームを保存するのに使う
|
|
4
|
|
5
|
|
6 typedef struct Stack<Type, Impl>{
|
|
7 Type* stack;
|
|
8 Type* data;
|
|
9 Type* data1;
|
|
10 __code whenEmpty(...);
|
|
11 __code clear(Impl* stack,__code next(...));
|
|
12 __code push(Impl* stack,Type* data, __code next(...));
|
|
13 __code pop(Impl* stack, __code next(Type* data, ...));
|
|
14 __code pop2(Impl* stack, __code next(Type* data, Type* data1, ...));
|
|
15 __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...));
|
|
16 __code get(Impl* stack, __code next(Type* data, ...));
|
|
17 __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
|
|
18 __code next(...);
|
|
19 } Stack;
|
|
20
|
|
21 呼び出し方の例
|
|
22 goto nodeStack->push(newNode, replaceNode1);
|
|
23 newNode はdataに対応する replaceNode1はnextに対応する。
|
|
24 replaceNode1のコールフレームは...に格納される。
|
|
25 つまり、replaceNode1はCodeGearのクロージャに相当する。
|
|
26
|
|
27 Interfaceから値を返す場合は継続経由で値を返す
|
|
28 __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
|
|
29 継続の型はInterfaceで定義されていて、この型に合うCodeGearを引数として渡す
|
|
30 goto nodeStack->get2(insertCase1,tree) //意味的にはtreeの後ろに...
|
|
31
|
|
32
|
|
33 __code insertCase1(struct Node *parent, struct Node *grandparent, struct RedBlackTree* tree) { //こっちも後ろに...があるはず
|
|
34
|
|
35 goto next(data, data1, ...);
|
|
36
|
|
37 createはinterfaceの実装を定義する
|
|
38 interfaceのメソッドの番号をここで指定する
|
|
39
|
|
40 implimentation側のDataGearは格納される実装依存の状態を持つ
|
|
41
|
|
42
|
|
43 struct SingleLinkedStack {
|
|
44 struct Element* top;
|
|
45 } SingleLinkedStack;
|
|
46
|
|
47 Stack* createSingleLinkedStack(struct Context* context) {
|
|
48 struct Stack* stack = new Stack();
|
|
49 struct SingleLinkedStack* singleLinkedStack = new SingleLinkedStack();
|
|
50 stack->stack = (union Data*)singleLinkedStack;
|
|
51 singleLinkedStack->top = NULL;
|
|
52 stack->push = C_pushSingleLinkedStack;
|
|
53 stack->pop = C_popSingleLinkedStack;
|
|
54 stack->pop2 = C_pop2SingleLinkedStack;
|
|
55 stack->get = C_getSingleLinkedStack;
|
|
56 stack->get2 = C_get2SingleLinkedStack;
|
|
57 stack->isEmpty = C_isEmptySingleLinkedStack;
|
|
58 stack->clear = C_clearSingleLinkedStack;
|
|
59 return stack;
|
|
60 }
|
|
61
|
|
62
|
|
63 実装内部で使うCodeGearの引数はコールフレームで決まる
|
|
64 コールフレームに含まれない中間変数を使っても良いが、辻褄は合ってる必要はある
|
|
65 一般的にはコールフレームに含まれている引数しか書けない
|
|
66 実装側の引数を書いても良い(ようにするか?)
|
|
67
|
|
68 実装の状態にアクセスする時にはコールフレーム内の実装を表すDataGearから取り出してくる
|
|
69
|
|
70
|
|
71 __code replaceNode1(struct RedBlackTree* tree, struct Node* node, __code next(...)) {
|
|
72
|
|
73 呼び出しの例
|
|
74 goto insertNode(tree, tree->nodeStack, node);
|
|
75
|
|
76
|
|
77
|