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版は以下の通り。
セコメントをする