LOCAL
char ioroutine
[XL
+1];
#define V(z) ioc[z].iocval
{ "fmt", M(IOREAD
) | M(IOWRITE
) },
{ "rec", M(IOREAD
) | M(IOWRITE
) },
{ "recl", M(IOOPEN
) | M(IOINQUIRE
) },
{ "file", M(IOOPEN
) | M(IOINQUIRE
) },
{ "status", M(IOOPEN
) | M(IOCLOSE
) },
{ "access", M(IOOPEN
) | M(IOINQUIRE
) },
{ "form", M(IOOPEN
) | M(IOINQUIRE
) },
{ "blank", M(IOOPEN
) | M(IOINQUIRE
) },
{ "exist", M(IOINQUIRE
) },
{ "opened", M(IOINQUIRE
) },
{ "number", M(IOINQUIRE
) },
{ "named", M(IOINQUIRE
) },
{ "name", M(IOINQUIRE
) },
{ "sequential", M(IOINQUIRE
) },
{ "direct", M(IOINQUIRE
) },
{ "formatted", M(IOINQUIRE
) },
{ "unformatted", M(IOINQUIRE
) },
{ "nextrec", M(IOINQUIRE
) }
#define NIOS (sizeof(ioc)/sizeof(struct ioclist) - 1)
#define MAXIO SZFLAG + 10*SZIOINT + 15*SZADDR
#define IOSUNFORMATTED 21
#define IOSTP V(IOSIOSTAT)
/* offsets in generated structures */
#define XEND SZFLAG + SZIOINT
#define XFMT 2*SZFLAG + SZIOINT
#define XREC 2*SZFLAG + SZIOINT + SZADDR
#define XRLEN 2*SZFLAG + 2*SZADDR
#define XRNUM 2*SZFLAG + 2*SZADDR + SZIOINT
#define XIFMT 2*SZFLAG + SZADDR
#define XIEND SZFLAG + SZADDR
#define XFNAME SZFLAG + SZIOINT
#define XFNAMELEN SZFLAG + SZIOINT + SZADDR
#define XSTATUS SZFLAG + 2*SZIOINT + SZADDR
#define XACCESS SZFLAG + 2*SZIOINT + 2*SZADDR
#define XFORMATTED SZFLAG + 2*SZIOINT + 3*SZADDR
#define XRECLEN SZFLAG + 2*SZIOINT + 4*SZADDR
#define XBLANK SZFLAG + 3*SZIOINT + 4*SZADDR
#define XCLSTATUS SZFLAG + SZIOINT
#define XFILE SZFLAG + SZIOINT
#define XFILELEN SZFLAG + SZIOINT + SZADDR
#define XEXISTS SZFLAG + 2*SZIOINT + SZADDR
#define XOPEN SZFLAG + 2*SZIOINT + 2*SZADDR
#define XNUMBER SZFLAG + 2*SZIOINT + 3*SZADDR
#define XNAMED SZFLAG + 2*SZIOINT + 4*SZADDR
#define XNAME SZFLAG + 2*SZIOINT + 5*SZADDR
#define XNAMELEN SZFLAG + 2*SZIOINT + 6*SZADDR
#define XQACCESS SZFLAG + 3*SZIOINT + 6*SZADDR
#define XQACCLEN SZFLAG + 3*SZIOINT + 7*SZADDR
#define XSEQ SZFLAG + 4*SZIOINT + 7*SZADDR
#define XSEQLEN SZFLAG + 4*SZIOINT + 8*SZADDR
#define XDIRECT SZFLAG + 5*SZIOINT + 8*SZADDR
#define XDIRLEN SZFLAG + 5*SZIOINT + 9*SZADDR
#define XFORM SZFLAG + 6*SZIOINT + 9*SZADDR
#define XFORMLEN SZFLAG + 6*SZIOINT + 10*SZADDR
#define XFMTED SZFLAG + 7*SZIOINT + 10*SZADDR
#define XFMTEDLEN SZFLAG + 7*SZIOINT + 11*SZADDR
#define XUNFMT SZFLAG + 8*SZIOINT + 11*SZADDR
#define XUNFMTLEN SZFLAG + 8*SZIOINT + 12*SZADDR
#define XQRECL SZFLAG + 9*SZIOINT + 12*SZADDR
#define XNEXTREC SZFLAG + 9*SZIOINT + 13*SZADDR
#define XQBLANK SZFLAG + 9*SZIOINT + 14*SZADDR
#define XQBLANKLEN SZFLAG + 9*SZIOINT + 15*SZADDR
register struct labelblock
*lp
;
execerr("unlabeled format statement" , 0);
if(lp
->labtype
== LABUNKNOWN
)
lp
->labelno
= newlabel();
else if(lp
->labtype
!= LABFORMAT
)
execerr("bad format number", 0);
prlabel(asmfile
, lp
->labelno
);
ioformatted
= UNFORMATTED
;
for(i
= 1 ; i
<=NIOS
; ++i
)
struct labelblock
*mklabel();
ioblkp
= autovar( (MAXIO
+SZIOINT
-1)/SZIOINT
, TYIOINT
, NULL
);
/* set up for error recovery */
ioerrlab
= ioendlab
= skiplab
= jumplab
= 0;
ioendlab
= mklabel(p
->const.ci
)->labelno
;
ioerrlab
= mklabel(p
->const.ci
)->labelno
;
if(IOSTP
==NULL
&& ioerrlab
!=0 && ioendlab
!=0 && ioerrlab
!=ioendlab
)
IOSTP
= mktemp(TYINT
, NULL
);
if(IOSTP
->tag
!=TADDR
|| ! ISINT(IOSTP
->vtype
) )
err("iostat must be an integer variable");
if( (iostmt
==IOREAD
|| iostmt
==IOWRITE
) &&
(ioerrlab
!=ioendlab
|| ioerrlab
==0) )
jumplab
= skiplab
= newlabel();
ioset(TYIOINT
, XERR
, ICON(IOSTP
!=NULL
|| ioerrlab
!=0) );
endbit
= IOSTP
!=NULL
|| ioendlab
!=0; /* for use in startrw() */
dofmove("f_back"); break;
fatal1("impossible iostmt %d", iostmt
);
for(i
= 1 ; i
<=NIOS
; ++i
)
if(i
!=IOSIOSTAT
|| (iostmt
!=IOREAD
&& iostmt
!=IOWRITE
) )
for(i
= 1 ; i
<= NIOS
; ++i
)
if(toklen
==strlen(ioc
[i
].iocname
) && eqn(toklen
, token
, ioc
[i
].iocname
))
err1("invalid control %s for statement", ioc
[found
].iocname
);
err1("unknown iocontrol %s", varstr(toklen
, token
) );
err("illegal positional iocontrol");
p
= (iostmt
==IOREAD
? IOSTDIN
: IOSTDOUT
);
err("illegal * iocontrol");
ioformatted
= (p
==NULL
? LISTDIRECTED
: FORMATTED
);
if(n
!=IOSFMT
&& ( n
!=IOSUNIT
|| (p
!=NULL
&& p
->vtype
!=TYCHAR
) ) )
err1("iocontrol %s repeated", iocp
->iocname
);
struct exprblock
*call0();
putiocall( call0(TYINT
, ioroutine
) );
register struct nameblock
*qn
;
struct addrblock
*tp
, *mkscalar();
for (p
= p0
; p
; p
= p
->nextp
)
exdo(range
=newlabel(), q
->varnp
);
if(q
->tag
==TPRIM
&& q
->argsp
==NULL
&& q
->namep
->vdim
!=NULL
)
putio( fixtype(cpexpr(qn
->vdim
->nelt
)),
err("attempt to i/o array of unknown size");
else if(q
->tag
==TPRIM
&& q
->argsp
==NULL
&& (qe
= memversion(q
->namep
)) )
else if( (qe
= fixtype(cpexpr(q
)))->tag
==TADDR
)
else if(qe
->vtype
!= TYERROR
)
tp
= mktemp(qe
->vtype
, qe
->vleng
);
err("non-left side in READ list");
register struct exprblock
*q
;
struct exprblock
*call2(), *call3();
if(ioformatted
!=LISTDIRECTED
&& ISCOMPLEX(type
) )
nelt
= mkexpr(OPSTAR
, ICON(2), nelt
);
type
-= (TYCOMPLEX
-TYREAL
);
/* pass a length with every item. for noncharacter data, fake one */
addr
->vleng
= ICON( typesize
[type
] );
nelt
= fixtype( mkconv(TYLENG
,nelt
) );
if(ioformatted
== LISTDIRECTTED
)
q
= call3(TYINT
, "do_lio", mkconv(TYLONG
, ICON(type
)), nelt
, addr
);
q
= call2(TYINT
, (ioformatted
==FORMATTED
? "do_fio" : "do_uio"),
putif( mkexpr(OPGE
, cpexpr(IOSTP
), ICON(0)), ioendlab
);
putif( mkexpr( ( (iostmt
==IOREAD
||iostmt
==IOWRITE
) ? OPLE
: OPEQ
),
cpexpr(IOSTP
), ICON(0)) , ioerrlab
);
register struct exprblock
*q
;
q
= fixexpr( mkexpr(OPASSIGN
, cpexpr(IOSTP
), q
));
putif( mkexpr(OPEQ
, q
, ICON(0) ), jumplab
);
register struct nameblock
*np
;
register struct addrblock
*unitp
, *nump
;
struct constblock
*mkaddcon();
ioset(TYIOINT
, XREC
, cpexpr(p
) );
ioset(TYIOINT
, XUNIT
, cpexpr(p
) );
else if(p
->vtype
== TYCHAR
)
if(p
->tag
==TPRIM
&& p
->argsp
==NULL
&& (np
= p
->namep
)->vdim
!=NULL
)
nump
= cpexpr(np
->vdim
->nelt
);
err("attempt to use internal unit array of unknown size");
unitp
= fixtype(cpexpr(p
));
ioset(TYIOINT
, XRNUM
, nump
);
ioset(TYIOINT
, XRLEN
, cpexpr(unitp
->vleng
) );
ioset(TYADDR
, XUNIT
, addrof(unitp
) );
err("bad unit specifier");
ioset(TYIOINT
, (intfile
? XIEND
: XEND
), ICON(endbit
) );
fmtoff
= (intfile
? XIFMT
: XFMT
);
if(p
->tag
==TPRIM
&& p
->argsp
==NULL
)
ioset(TYADDR
, fmtoff
, addrof(mkscalar(np
)) );
ioset(TYADDR
, fmtoff
, p
);
p
= V(IOSFMT
) = fixtype(p
);
ioset(TYADDR
, fmtoff
, addrof(cpexpr(p
)) );
if( (k
= fmtstmt( mklabel(p
->const.ci
) )) > 0 )
ioset(TYADDR
, fmtoff
, mkaddcon(k
) );
ioformatted
= UNFORMATTED
;
err("bad format descriptor");
ioformatted
= UNFORMATTED
;
ioset(TYADDR
, fmtoff
, ICON(0) );
ioroutine
[2] = (iostmt
==IOREAD
? 'r' : 'w');
ioroutine
[3] = (sequential
? 's' : 'd');
ioroutine
[4] = "ufl" [ioformatted
];
ioroutine
[5] = (intfile
? 'i' : 'e');
putiocall( call1(TYINT
, ioroutine
, cpexpr(ioblkp
) ));
if( (p
= V(IOSUNIT
)) && ISINT(p
->vtype
) )
ioset(TYIOINT
, XUNIT
, cpexpr(p
) );
if( (p
= V(IOSFILE
)) && p
->vtype
==TYCHAR
)
ioset(TYIOINT
, XFNAMELEN
, cpexpr(p
->vleng
) );
ioset(TYIOINT
, XRECLEN
, cpexpr(p
) );
ioset(TYIOINT
, XRECLEN
, ICON(0) );
iosetc(XSTATUS
, V(IOSSTATUS
));
iosetc(XACCESS
, V(IOSACCESS
));
iosetc(XFORMATTED
, V(IOSFORM
));
iosetc(XBLANK
, V(IOSBLANK
));
putiocall( call1(TYINT
, "f_open", cpexpr(ioblkp
) ));
if( (p
= V(IOSUNIT
)) && ISINT(p
->vtype
) )
ioset(TYIOINT
, XUNIT
, cpexpr(p
) );
iosetc(XCLSTATUS
, V(IOSSTATUS
));
putiocall( call1(TYINT
, "f_clos", cpexpr(ioblkp
)) );
err("bad unit in close statement");
err("inquire by unit or by file, not both");
ioset(TYIOINT
, XUNIT
, cpexpr(p
) );
err("must inquire by unit or by file");
iosetlc(IOSFILE
, XFILE
, XFILELEN
);
iosetip(IOSEXISTS
, XEXISTS
);
iosetip(IOSOPENED
, XOPEN
);
iosetip(IOSNUMBER
, XNUMBER
);
iosetip(IOSNAMED
, XNAMED
);
iosetlc(IOSNAME
, XNAME
, XNAMELEN
);
iosetlc(IOSACCESS
, XQACCESS
, XQACCLEN
);
iosetlc(IOSSEQUENTIAL
, XSEQ
, XSEQLEN
);
iosetlc(IOSDIRECT
, XDIRECT
, XDIRLEN
);
iosetlc(IOSFORM
, XFORM
, XFORMLEN
);
iosetlc(IOSFORMATTED
, XFMTED
, XFMTEDLEN
);
iosetlc(IOSUNFORMATTED
, XUNFMT
, XUNFMTLEN
);
iosetip(IOSRECL
, XQRECL
);
iosetip(IOSNEXTREC
, XNEXTREC
);
putiocall( call1(TYINT
, "f_inqu", cpexpr(ioblkp
) ));
if( (p
= V(IOSUNIT
)) && ISINT(p
->vtype
) )
ioset(TYIOINT
, XUNIT
, cpexpr(p
) );
putiocall( call1(TYINT
, subname
, cpexpr(ioblkp
) ));
err("bad unit in move statement");
LOCAL
ioset(type
, offset
, p
)
register struct addrblock
*q
;
q
->memoffset
= fixtype( mkexpr(OPPLUS
, q
->memoffset
, ICON(offset
)) );
ioset(TYADDR
, offset
, ICON(0) );
else if(p
->vtype
== TYCHAR
)
ioset(TYADDR
, offset
, addrof(cpexpr(p
) ));
err("non-character control clause");
if(p
->tag
==TADDR
&& ONEOF(p
->vtype
, M(TYLONG
)|M(TYLOGICAL
)) )
ioset(TYADDR
, offset
, addrof(cpexpr(p
)) );
err1("impossible inquire parameter %s", ioc
[i
].iocname
);
ioset(TYADDR
, offset
, ICON(0) );
LOCAL
iosetlc(i
, offp
, offl
)
if( (p
= V(i
)) && p
->vtype
==TYCHAR
)
ioset(TYIOINT
, offl
, cpexpr(p
->vleng
) );