for文にであったら、初期設定・終了条件・再設定を取り出して、再設定は再設定用スタックに積み、 ラベルL、L+1、L+2を作りだし、
continue 初期設定 L if ( .not. (終了条件)) goto L+2を出力します。そして、forの終わりに達したら、
L+1 continue 再設定 goto L L+2 continueを出力します。ここで、ラベルL+2は、breakに出会ったときの行き先になります。また、ラベルL+1は、 nextに出会った時の行き先になります。具体的には、forcod()でfor文のはじめを生成します。
forcod()のRatofor版は以下の通り。
# forcod.r4 -- generate code for beginning of for include ratfor.def subroutine forcod(lab) integer lab character t,token(MAXTOK) lab = labgen(3) call outcon(0) t = gtoken(token,MAXTOK) if (token(1) != LPAREN) { call outstr(token) call eatup call synerr('missing left parenthesis.') } else { call forini call forcnd(lab) call forrei } return end
WATCOM Fortran77版は以下の通り。
c forcod.f -- generate code for beginning of for include ratfor.def subroutine forcod(lab) integer lab integer*1 t,token(MAXTOK) lab = labgen(3) call outcon(0) t = gtoken(token,MAXTOK) if (token(1) .ne. LPAREN) then call outstr(token) call eatup call synerr('missing left parenthesis.') else call forini call forcnd(lab) call forrei end if return end
ここで、forini()は初期設定を取り出しコードを生成し、 同様にforcnd()は終了条件を取り出し必要なコードを生成し、さらに、 forrei()は再設定を取り出しコードを生成します。
forini()のRatofor版は以下の通り。
# forini.r4 -- generate code for initialize include ratfor.def subroutine forini character gtoken,stmnt(MAXLINE),t,token(MAXTOK) integer junk,sappnd stmnt(1) = EOS for (t = gtoken(token,MAXTOK);t != SEMICOL & t != EOF;t = gtoken(token,MAXTOK)) junk = sappnd(token,stmnt,MAXTOK) if (stmnt(1) != EOS) { call outtab call outstr(stmnt) call outdon } if (t != EOF) call synerr('unexpected EOF.') return end
WATCOM Fortran77版は以下の通り。
c forini.f -- generate code for beginning of for include ratfor.def subroutine forini integer*1 gtoken,stmnt(MAXLINE),t,token(MAXTOK) integer junk,sappnd stmnt(1) = EOS t = gtoken(token,MAXTOK) while ((t .ne. SEMICOL) .and. (t .ne. EOF)) do junk = sappnd(token,stmnt,MAXTOK) t = gtoken(token,MAXTOK) end while if (stmnt(1) .ne. EOS) then call outtab call outstr(stmnt) call outdon end if if (t .eq. EOF) then call synerr('unexpected EOF.') end if return end
ここで、sappnd()は、文字バッファーがあふれないように確認しながら、文字列を追加します。
sappnd()のRatofor版は以下の通り。
# sappnd.r4 -- append str to body include ratfor.def integer function sappnd(str,body,maxsiz) character str(ARB),body(maxsiz) integer maxsiz integer i,j,length i = 1 j = length(body) + 1 sappnd = YES while (str(i) != EOS) { if (j >= maxsiz) then sappnd = NO exit end if body(j) = str(i) i = i + 1 j = j + 1 } body(j) = EOS return end
WATCOM Fortran77版は以下の通り。
c sappnd.f -- append str to body include ratfor.def integer function sappnd(str,body,maxsiz) integer*1 str(ARB),body(maxsiz) integer maxsiz integer i,j,length i = 1 j = length(body) + 1 sappnd = YES while (str(i) .ne. EOS) do if (j .ge. maxsiz) then sappnd = NO exit end if body(j) = str(i) i = i + 1 j = j + 1 end while body(j) = EOS return end
outdon()は、生成しているコードを実際に出力先に書き出します。
outdon()のRatofor版は以下の通り。
# outdon.r4 -- finish off an output line include ratfor.def subroutine outdon include coutln.ri outbuf(outp+1) = NEWLINE outbuf(outp+2) = EOS call putlin(outbuf,STDOUT) outp = 0 return end
WATCOM Fortran77版は以下の通り。
コメントをする