view Gears/introduction/interface.md @ 93:04cff9568106

backup 2021-10-05
author autobackup
date Tue, 05 Oct 2021 00:10:04 +0900
parents b6c284fd5ae4
children
line wrap: on
line source

# GearsOSのinterface

- GearsOSにはモジュール化の仕組みとしてInterface構文が存在します
    - JavaやgolangのInterface, Haskellの型クラスに相当する構文です
    
## Interfaceで定義するもの    
- golangのInterfaceでは、関数の集合、及び関数の引数と返り値がinterfaceとして定義されていました
- GearsOSのItnerfaceでも同様に、使用するデータ構造と、関数を記述します
- 使用するデータ(DataGear)はPerlスクリプト側の改良により、`__code`の中に定義しておけば問題ないようになった

## 書き方(~2019/02/03)

```
typedef struct InterfaceName<Type, Impl>{
        //入出力で使用するデータ構造を記述する
        union Data* stack;
        union Data* data;
        union Data* data1;
        
        // APIとして使用するCodeGearを列挙する
        //ここで利用する引数|出力は必ず上で列挙する必要がある
        __code whenEmpty(...);
        __code clear(Impl* stack,__code next(...));
        __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
        
        //継続先のCodeGear
        __code next(...);
} InterfaceName;
```
- Type
    - 自分自身の型
- Impl
    - 自分自身の実装の型
        - Stackの場合はSingleLinkedStackなど...
        
## 書き方(2019/02/03~)

- Perl側を改良したので引数を別で定義する必要がなくなった

```
typedef struct InterfaceName<Type, Impl>{
        // APIとして使用するCodeGearを列挙する
        __code whenEmpty(...);
        __code clear(Impl* stack,__code next(...));
        __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
        
        //継続先のCodeGear
        __code next(...);
} InterfaceName;
```
## 仕様QA
`__code`の記述が始まる前に引数を宣言していた場合、宣言された引数のみが使われる。

(`__code`の中の引数はキャプチャされない)
        
## Interfaceのファイルを利用するスクリプト
- interfaceのファイルは次のPerlスクリプトで利用され、CbCレベルでは実は参照されません
- `trans_impl.pl`
   -   cbcファイルの雛形を生成する際に、実装しているファイルから動的に呼び出されます
- ` generate_stub.pl`   
- ` generate_context.pl`   
    - 入出力の引数チェックで行われます
    - `generate_context`では、 `context.h`を生成する際に読み込まれます

## CbCレベルでのInterface
- CbCレベルでは、 stub 及び, `context.h` の `union Data` の定義内で定義されています
    - その為 `context.h` を `include`することで、これらの型を利用できます

## Interfaceの具体例
- [Stack](/Gears/introduction/interface/Stack)

## Interfaceの実装の具体例
- [SingleLinkedStack](/Gears/introduction/interface/impl/SingleLinkedStack)

## Q&A

### Q.「Interefaceに書いたDataGearはどうやって実装側から使うの?」

**A.「引数で与える」**

### Q.「引数で使ってないけどContextにDataGearを登録したい」

**A.「専用の構文があります」**
- `// data_gear "WantStruct.h"` と書いておくと `generate_context.pl`時に解決される

#### 例

- 例えば `"DataGearExample`をcontextに加えたい場合
    - まず最初に対象のヘッダファイルをどこかに作っておく
    - `struct DataGearExample`を使いたいCbCファイルに以下の記述を書いておく

```c
#include "hoge.h"
//data_gear "DataGearExample.h"
```

- `#interface "hoge.h"`構文もあるが、 `generate_stub`の時点でこの文が消えるので、コメントで追加している

### Q.Intefaceに値持たせたいんだけど

**A. 値は実装側に持たせるのでInterfaceには書いちゃだめ!!**

- interfaceはあくまでもCodeGearの入出力だけのDataしかない
- 細かなDataはすべて実装に持たせる
    - 同じfieldを持つ実装が複数存在する