view doc/Interface.mm @ 590:9146d6017f18 default tip

hg mv parallel_execution/* ..
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Thu, 16 Jan 2020 15:12:06 +0900
parents 6f873aad1b06
children
line wrap: on
line source

Interfaceのtypedef はコールフレームを定義する
Interfaceの呼び出しの時に使える引数はtypedefに定義されている必要がある
... は呼び出し側のコールフレームを保存するのに使う


typedef struct Stack<Type, Impl>{
        Type* stack;
        Type* data;
        Type* data1;
        __code whenEmpty(...);
        __code clear(Impl* stack,__code next(...));
        __code push(Impl* stack,Type* data, __code next(...));
        __code pop(Impl* stack, __code next(Type* data, ...));
        __code pop2(Impl* stack, __code next(Type* data, Type* data1, ...));
        __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...));
        __code get(Impl* stack, __code next(Type* data, ...));
        __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
        __code next(...);
} Stack;

呼び出し方の例
    goto nodeStack->push(newNode, replaceNode1);
newNode はdataに対応する replaceNode1はnextに対応する。
replaceNode1のコールフレームは...に格納される。
つまり、replaceNode1はCodeGearのクロージャに相当する。

Interfaceから値を返す場合は継続経由で値を返す
__code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
継続の型はInterfaceで定義されていて、この型に合うCodeGearを引数として渡す
    goto nodeStack->get2(insertCase1,tree) //意味的にはtreeの後ろに...


__code insertCase1(struct Node *parent, struct Node *grandparent, struct RedBlackTree* tree) { //こっちも後ろに...があるはず

goto next(data, data1, ...);

createはinterfaceの実装を定義する
interfaceのメソッドの番号をここで指定する

implimentation側のDataGearは格納される実装依存の状態を持つ


    struct SingleLinkedStack {
        struct Element* top;
    } SingleLinkedStack;

Stack* createSingleLinkedStack(struct Context* context) {
    struct Stack* stack = new Stack();
    struct SingleLinkedStack* singleLinkedStack = new SingleLinkedStack();
    stack->stack = (union Data*)singleLinkedStack;
    singleLinkedStack->top = NULL;
    stack->push = C_pushSingleLinkedStack;
    stack->pop  = C_popSingleLinkedStack;
    stack->pop2  = C_pop2SingleLinkedStack;
    stack->get  = C_getSingleLinkedStack;
    stack->get2  = C_get2SingleLinkedStack;
    stack->isEmpty = C_isEmptySingleLinkedStack;
    stack->clear = C_clearSingleLinkedStack;
    return stack;
}


実装内部で使うCodeGearの引数はコールフレームで決まる
コールフレームに含まれない中間変数を使っても良いが、辻褄は合ってる必要はある
一般的にはコールフレームに含まれている引数しか書けない
実装側の引数を書いても良い(ようにするか?)

実装の状態にアクセスする時にはコールフレーム内の実装を表すDataGearから取り出してくる


__code replaceNode1(struct RedBlackTree* tree, struct Node* node, __code next(...)) {

呼び出しの例
    goto insertNode(tree, tree->nodeStack, node);