Ratforプリプロセッサー -- コード生成 "if"と"if-else"
2017-06-07


"if"文に出会ったら、2つのラベル、LとL+1を生成し、

          if(.not(条件)) goto L
を出力します。それは、ifcode()で行ない、ラベルを返します。

ifcode()のRatofor版は以下の通り。

# ifcode.r4 -- generate initial code for if
      subroutine ifcode(lab)
      integer lab
      integer labgen

      lab = labgen(2)
      call ifgo(lab)
      return
      end

WATCOM Fortran77版は以下の通り。

c ifcode.f -- generate initial code for if
      subroutine ifcode(lab)
      integer lab
      integer labgen

      lab = labgen(2)
      call ifgo(lab)
      return
      end

ifgo()は、

          if(.not.(条件)) goto lab
を作り出します。

ifgo()のRatofor版は以下の通り。

# ifgo.r4 -- generate "if (.not. (...)) goto lab"
      include ratfor.def
      subroutine ifgo(lab)
      integer lab
      string ifnot "if (.not. "

      call outtab           # get to column 7
      call outstr(ifnot)    # "if (.not. "
      call balpar           # collect and output condition
      call outch(RPAREN)    # ")"
      call outch(BLANK)     # " "
      call outgo(lab)       # "goto lab"
      return
      end

WATCOM Fortran77版は以下の通り。

c ifgo.f -- generate "if (.not. (...)) goto lab"
      include ratfor.def
      subroutine ifgo(lab)
      integer lab
      integer*1 ifnot(11)
      data ifnot(1)/LETi/
      data ifnot(2)/LETf/
      data ifnot(3)/BLANK/
      data ifnot(4)/LPAREN/
      data ifnot(5)/PERIOD/
      data ifnot(6)/LETn/
      data ifnot(7)/LETo/
      data ifnot(8)/LETt/
      data ifnot(9)/PERIOD/
      data ifnot(10)/BLANK/
      data ifnot(11)/EOS/

      call outtab                       ! get to column 7
      call outstr(ifnot)                ! "if (.not. "
      call balpar                       ! collect and output condition
      call outch(RPAREN)                ! ")"
      call outch(BLANK)                 ! " "
      call outgo(lab)                   ! "goto lab"
      return
      end

elseの開始、ifまたはelse ifの終了は、

          goto L + 1
        L continue
を作り出します。ここでLはスタックに積んであったラベルです。

elseif()のRatofor版は以下の通り。

# elseif.f -- generate code for end of if before else
      subroutine elseif(lab)
      integer lab

      call outgo(lab+1)
      call outcon(lab)
      return
      end

WATCOM Fortran77版は以下の通り。

c elseif.f -- generate code for end of if before else
      subroutine elseif(lab)
      integer lab

      call outgo(lab+1)
      call outcon(lab)
      return
      end

labgen()は、必要な数だけのラベルを生成します。ラベルは、50000からとします。

labgen()のRatofor版は以下の通り。

# labgen.r4 -- generates n consecutive labels, return first one
      integer function labgen(n)
      integer n
      integer label
      data label/50000/

      labgen = label
      label = label + n
      return
      end

WATCOM Fortran77版は以下の通り。

c labgen.f -- generates n consecutive labels, return first one
      integer function labgen(n)
      integer n
      integer label
      data label/50000/

      labgen = label
      label = label + n
      return
      end

balpar()は、条件を(複数行に渡っているのもまとめて)取り出し、出力します。 また、cnvop()で、演算子"<"、"<="、">"、">="、"=="、"!="、"&"、"|"を ".lt."、".le."、".gt."、".ge."、".eq."、".ne."、".and."、".or."に変換します。

balpar()のRatofor版は以下の通り。

# balpar.r4 -- copy balanced paren string
      include ratfor.def
      subroutine balpar
      character gtoken
      character t,token(MAXTOK)
      integer nlpar
      integer iindex
      string opcode "=> 0)
              call cnvop(token,opstr)   # convert logical operator
              call outstr(opstr)
          else
              call outstr(token)
          } until (nlpar <= 0)
      if (nlpar != 0)
          call synerr('missing parenthesis in condition.')
      return
      end

WATCOM Fortran77版は以下の通り。



続きを読む

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

コメント(全1件)
コメントをする


記事を書く
powered by ASAHIネット