マクロ処理 -- 表の検索2017年01月12日 21:26

マクロ名と置き換え文字列の対応表を取り扱うのか、lookup()、とinstal()である。 lookup()は表の検索をinstal()は表に新たなマクロを登録する。いずれにしても、表の データ構造に依存するコードになる。表は単純な次のような構造とする。

      名前 EOS 置き換え文字列 EOS 名前 EOS 置き換え文字列 EOS ,,,,,,,,,,,,

また、上の表のどの位置に名前があるのかを示す指標を第2の配列に保持する。

これらの共通ブロックは、次のようになる。

RATFOR版は、

# clook.r4
      common /clook/lastp,lastt,namptr(MAXPTR),table(MAXTBL)
      integer lastp   # last used in namptr; init = 0
      integer lastt   # last used in table; init = 0
      integer namptr  # name pointers
      character table # actual text of names and defns

WATCOM fortran 77版は、

c clook.fi
      common /clook/lastp,lastt,namptr(500),table(5000) ! MAXPTR(500) MAXTBL(5000)
      integer lastp   ! last used in namptr; init = 0
      integer lastt   ! last used in table; init = 0
      integer namptr  ! name pointers
      integer*1 table ! actual text of names and defns

lookup()は以下の通り。

RATFOR版は、

# lookup.r4 -- locate name, extract definition from table
      integer function lookup(name,defn)
      character name(MAXDEF),defn(MAXTOK)
      integer i,j,k
      include clook.fi

      for (i = lastp;i > 0; i = i - 1) {
         j = namptr(i)
         for (k = 1;name(k) == table(j) & name(k) != EOS; k = k + 1)
             j = j + 1
         if (name(k) == table(j)) {     # got one
             call scopy(table,j+1,defn,1)
             lookup = YES
             return
             }
         }
      lookup = NO
      return
      end

WATCOM fortran 77版は、

c lookup.f -- locate name, extract definition from table
      integer function lookup(name,defn)
      integer*1 name(82),defn(82)       ! MAXDEF(82) MAXTOK(82)
      integer i,j,k
      include clook.fi

      i = lastp
      while (i .gt. 0) do
         j = namptr(i)
         k = 1
         while ((name(k) .eq. table(j)) .and. (name(k) .ne. -2)) do ! EOS(-2)
             j = j + 1
             k = k + 1
         end while
         if (name(k) .eq. table(j)) then ! got one
             call scopy(table,j+1,defn,1)
             lookup = 1                 ! YES(1)
             return
         end if
          i = i - 1
      end while
      lookup = 0                        ! NO(0)
      return
      end

instal()は、以下の通り。

RATFOR版は、

# instal.r4 -- add name and definition to table
      subroutine instal(name,defn)
      character name(MAXTOK),defn(MAXDEF)
      integer length
      integer dlen,nlen
      include clook.ri

      nlen = length(name) + 1
      dlen = length(defn) + 1
      if (lastt+nlen+dlen > MAXTBL | lastp >= MAXPTR) {
         call putlin(name,ERROUT)
         call remark(':too many definitions.')
         }
      lastp = lastp + 1
      namptr(lastp) = lastt + 1
      call scopy(name,1,table,lastt+1)
      call scopy(defn,1,table,lastt+nlen+1)
      lastt = lastt + nlen + dlen
      return
      end

WATCOM fortran 77版は、

c instal.f -- add name and definition to table
      subroutine instal(name,defn)
      integer*1 name(82),defn(82)       ! MAXTOK(82) MAXDEF(82)
      integer length
      integer dlen,nlen
      include clook.fi

      nlen = length(name) + 1
      dlen = length(defn) + 1
      if ((lastt+nlen+dlen .gt. 5000) .or. (lastp .ge. 500)) then ! MAXTBL(5000) MAXPTR(500)
         call putlin(name,6)            ! ERROUT(6)
         call remark(':too many definitions.')
      end if
      lastp = lastp + 1
      namptr(lastp) = lastt + 1
      call scopy(name,1,table,lastt+1)
      call scopy(defn,1,table,lastt+nlen+1)
      lastt = lastt + nlen + dlen
      return
      end

表の初期化は、inittbl()で行う。

RATFOR版は、

# inittbl.r4 -- initialize macro table
      subroutine inittbl
      include clook.ri

      lastp = 0
      lastt = 0
      return
      end

WATCOM fortran 77版は、

c inittbl.f -- initialize macro table
      subroutine inittbl
      include clook.fi

      lastp = 0
      lastt = 0
      return
      end

ここまでで、defineが動き出した。実際の運用は、マクロ定義は別ファイルで 行い、ソースファイルでそれをインクルードし、その結果をdefineに通すようにするとよい。 これを支援するバッチファイルfid.batを以下に示す。

      @echo off
      rem fid.bat
      cd ..\src
      ..\exe\include < %1.f | ..\exe\define > %1.for
      cd ..\bat