引数付きマクロ処理(一部修正)
2017-01-26


マクロの定義に、引数が使えるようになると、利便性が非常に向上する。簡単な例を 示す。まずは、マクロの定義は、以下のようになる。マクロgetc,putcの定義の中、$1が マクロの引数にである。引数は、$1から$9までである。

          define(STDIN,5)
          define(STDOUT,6)
          define(getc,getch(STDIN,$1))
          define(putc,putch(STDOUT,$1))

プログラム中では、以下のように、記述する。

          c = getc(c)
          call putc(c)

これが展開されると、以下のようになる。

          c = getch(5,c)
          call putch(6,c)

もう少し長いマクロの例を以下に示す。

          define(BLANK,32)
          define(TAB,9)
          define(skipbl,while($1($2) == BLANK | $1($2) == TAB)
               $2 = $2 + 1)

プログラム中では、

          skipbl(s,i)

展開されると、

          while(s(i) == 32 | s(i) == 9)
              i = i + 1

読み込み中にマクロに出会ったら、引数も含めてマクロ評価用スタックに積む。 引数の中にマクロ呼び出しがあったら、新しいマクロ評価用スタック領域を取り、 スタックに積む。そして、マクロを完全に評価して、入力に送り返す。そして、元の マクロの評価を続ける。

マクロ評価用スタックevalstは配列で表現され、マクロの名前、定義型、 引数が入る。一方、配列argstkは、evalstに格納された文字列の場所の 位置を示す。いくつものモジュールで共通の用いられるevalstは以下の通り。

RATFOR版は、

# cmacro.ri
      common /cmacro/cp,ep,evalst(EVALSIZE)
      integer cp       # current call stack pointer
      integer ep       # next free position in evalst
      character evalst # evaluation stack

WATCOM fortran 77版は、

! cmacro.fi
      common /cmacro/cp,ep,evalst(EVALSIZE)
      integer cp       ! current call stack pointer
      integer ep       ! next free position in evalst
      integer*1 evalst ! evaluation stack

このマクロでは、マクロや組み込み操作は出現したとき、 その場で全て展開することになっているので、それではまずいことがある。 たとえば、defをdefineの同義語として定義したいとき、

      define(def,define($1,$2))

とすれば良さそうだが、うまくいかない。まず、マクロ名"def"が、評価用スタックに積まれる。 次に、置き換え文字列"define($1,$2)"が評価されてしまい、"def"に対応する置き換え文字列が 空となってしまう。 これでは、目的を達成できないので、"["と"]"でくくられた範囲は、評価を遅らせる仕組みを 付け加える。

      define(def,[define($1,$2)])
      def(ABC,DEF)

とすると

      ABC

は、変換されて、

      DEF

となる。実は、引数なしのマクロプログラムのソースは、defineを通せない。 プログラム中のマクロ定義ではない"define"文字列がマクロの定義と 見間違えられてしまうのである。

引数なしのマクロには、"()"がつかない、これを特別扱いしないように、 "()"がついていないマクロに出会ったら、"()"を入力に送り返し、あたかも"()"が つぃているかのように振る舞わせる。

以上を踏まえた、引数付きマクロのRATFOR版は、以下の通り。



続きを読む

[コンピューター]
[RATFOR]

コメント(全50件)
※コメントの受付件数を超えているため、この記事にコメントすることができません。


記事を書く
powered by ASAHIネット