COBOLでインタープリタ的なものを作るには？

#やりたいこと：
トランザクションレコードを利用者が指定したチェック条件でチェックし、条件にヒットしたら指定のアクションを実行し、ヒットしなかったら次のチェック条件を実行するチェックインタープリタを作る。

このチェック条件は、プログラムの外部からテキストファイルで渡すことができる。
つまり、ソースファイル内にチェック条件をIF文でハードコーディングするのではなく、テキストファイルで渡せるようにする。

世の中的には「**Business Rules Management System (BRMS)** 」とか言うやつ。
**JBOSS Rules**とかの製品があったりする。

これをCOBOLで実現する。テストのしやすさからOpenCOBOLを使う。
この後にCOBOLならではの課題がいくつか出てくるが、それを解決しながら投稿を進めたいと思うので、投稿記事がいくつかに分かれそうな感じがしている。

#チェックインタープリタの概要図：
こんなイメージを実現しようと考えている。
![インタープリタ.jpg](https://qiita-image-store.s3.amazonaws.com/0/76786/f2fef59b-029b-f95f-452c-682825b93ede.jpeg)

#GitHub上のチェックインタープリタCOBOLソース
[チェックインタープリタCOBOLプロジェクト](https://github.com/madilloar/PRJ_Calico)
test-main.xmlをantで「create_exe」すると、「TEST-MAIN.exe」ができます。
test-main.xmlをantで「exec」すると、チェック条件ファイルを読み込んでチェックを実行します。

#課題整理：
1.データタイプは何を使うか？→文字、数値の両方が使えるXタイプを使う。
2.できるだけ汎用的なCOBOLでコードを書きたいので動的メモリ割り当てはしないこととするが、その場合、可変長文字列の取り扱いや、スタックなどをどうするか？→GitHubのチェックインタープリタCOBOLプロジェクト参照。
3.字句解析や構文解析どうするか？→字句解析、構文解析は難しいので対象外とする。それは別途行われ、仮想的なマシンのコード(アセンブラ風なやつ)をテキストファイルに出力されていて、それを実行するインタープリタを作るイメージ。
4.変数と定数のメモリ割り当てをどうするか？→後続の記事参照。
5.**課題が増え次第順次追加し、別記事で投稿していきます。**


#課題の解決：
##COBOLで動的メモリ割り当てしないで可変長文字列をどうやって扱うか？
特にメインルーチンとサブルーチン間で可変長文字列をやり取りするにはどうするか？
こんな単純なことで悩まなければならない。

![IMG_20150419_0002_NEW.jpg](https://qiita-image-store.s3.amazonaws.com/0/76786/9fe9f96f-fb2b-5e1f-edbc-bb11c4c9bc53.jpeg)

可変長を扱うには文字列長を何らかの形で調べる、もしくは区切り文字(デリミタ)になる文字(HIGH-VALUE等)を決めておいて、そこまで読むというような仕組みが必要。

**COBOLで指定した開始桁位置から指定桁数分の文字列を切り出すコード断片：**
例：変数Aで5桁目から3桁切り出す。変数名の後にカッコ開始桁位置と桁数を書く。
```DISPLAY 変数A(5 : 3)```

**メインルーチンとサブルーチン間で可変長文字列をやり取りする：**
今度はメインルーチンとサブルーチンで可変長文字列をどうやって授受するか？であるが、結局COBOLではやり方がわからなかった。

とはいえ、サブルーチン側をできるだけ汎用的な作りにしたかったので、メインルーチン側でメモリ領域を固定長で十分に確保し、サブルーチン側ではそのアドレスを参照するようなイメージで対応する。

で、ちょっとトリッキーなコードの書き方をする。
メインルーチン側のWORKING STRAGE SECTIONで、可変長文字列の授受に必要な領域を十分確保し、サブルーチン側のLINKAGE SECTIONでは、X(1)しか定義しない。
つまりサブルーチン側が短い。

サブルーチン側が短いので、index out of boundsや記憶保護違反が起きそうなコードの書き方。
ただ、メインルーチン側で十分に領域を確保しているなら問題ないはず。

OpenCobol1.1で試しているが、”-debug”オプション付きでcobcすると、実行時にout of boundsで異常終了します。OpenCobolで試すときは、”-debug”オプションはつけてはダメ。

***コード断片：***
***メインルーチン側：***
```
000050 WORKING-STORAGE SECTION.
000100*--------------------------------------------------------------
000110*-可変長文字列長さ
000120*--------------------------------------------------------------
000130 01       PMYMEM-PRM        SYNC.
000140   03     PMYMEM-VLL        PIC 9(5).
000150*--------------------------------------------------------------
000160*-可変長文字列授受エリア
000170*--------------------------------------------------------------
000180 01       PMYMEM-VAL        SYNC.
000190   03     FILLER                   PIC X(100).
```

***サブルーチン側：***
```
000050 LINKAGE SECTION.
000100*--------------------------------------------------------------
000110*-可変長文字列長さ
000120*--------------------------------------------------------------
000130 01       PMYMEM-PRM        SYNC.
000140   03     PMYMEM-VLL        PIC 9(5).
000150*--------------------------------------------------------------
000160*-可変長文字列授受エリア
000170*--------------------------------------------------------------
000180 01       PMYMEM-VAL        SYNC.
000190   03     FILLER                   PIC X(1).
```

***サブルーチン側の処理：***
LINKAGE SECTIONで受けた値をDISPLAY
```001280   DISPLAY PMYMEM-VAL(1:PMYMEM-VLL).```