/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)type.c 1.4 9/4/80";
* this allows for multiple
* declaration parts unless
* standard option has been
* If routine segment is being
* compiled, do level one processing.
if ( parts
[ cbn
] & ( VPRT
| RPRT
) ) {
error("Type declarations should precede var and routine declarations");
if (parts
[ cbn
] & TPRT
) {
error("All types should be declared in one type part");
* Forechain is the head of a list of types that
* might be self referential. We chain them up and
enter(defnl(tid
, TYPE
, np
, 0))->nl_flags
|= NMOD
;
enter(defnl(tid
, TYPE
, np
, 0));
send(REVTYPE
, tline
, tid
, tdecl
);
pPointer Type
= TypeDecl( tid
, tdecl
);
pSeize( PorFHeader
[ nesting
] );
Types
= &( pDEF( PorFHeader
[ nesting
] ).PorFTypes
);
*Types
= ListAppend( *Types
, Type
);
pRelease( PorFHeader
[ nesting
] );
* Return a type pointer (into the namelist)
* from a parse tree for a type, building
* namelist entries as needed.
error("%s is a %s, not a type as required", r
[1], classes
[np
->class]);
np
= defnl(0, PTR
, 0, 0 );
* mung T_TYREC[3] to point to the record
if (np
->nl_flags
& NFILES
)
error("Files cannot be members of files");
np
= defnl(0, FILET
, np
, 0);
if (np
->type
== nl
+TDOUBLE
) {
error("Set of real is not allowed");
if (np
->class != RANGE
&& np
->class != SCAL
) {
error("Set type must be range or scalar, not %s", nameof(np
));
error("Implementation restriction: sets must be indexed by 16 bit quantities");
np
= defnl(0, SET
, np
, 0);
error("Storage requirement of %s exceeds the implementation limit of %d by %d bytes",
nameof(np
), TOOMUCH
-1, w
-TOOMUCH
+1);
* Scalar (enumerated) types
register struct nl
*np
, *op
, *zp
;
np
= defnl(0, SCAL
, 0, 0);
for (; v
!= NIL
; v
= v
[2]) {
op
= enter(defnl(v
[1], CONST
, np
, ++i
));
register struct nl
*lp
, *hp
;
if (lp
== NIL
|| hp
== NIL
)
if (norange(lp
) || norange(hp
))
error("Can't mix %ss and %ss in subranges", nameof(lp
), nameof(hp
));
if (c
== TSCAL
&& scalar(lp
) != scalar(hp
)) {
error("Scalar types must be identical in subranges");
error("Range lower bound exceeds upper bound");
lp
= defnl(0, RANGE
, hp
->type
, 0);
lp
->range
[0] = con
.crval
;
error("Subrange of real is not allowed");
error("Subrange bounds must be Boolean, character, integer or scalar, not %s", nameof(p
));
* Declare arrays and chain together the dimension specification
register struct nl
*tp
, *ltp
;
np
= defnl(0, ARRAY
, tp
, 0);
np
->nl_flags
|= (tp
->nl_flags
) & NFILES
;
for (tl
= r
[2]; tl
!= NIL
; tl
= tl
[2]) {
if (tp
->class == RANGE
&& tp
->type
== nl
+TDOUBLE
) {
error("Index type for arrays cannot be real");
if (tp
->class != RANGE
&& tp
->class != SCAL
) {
error("Array index type is a %s, not a range or scalar as required", classes
[tp
->class]);
if (tp
->class == RANGE
&& bytes(tp
->range
[0], tp
->range
[1]) > 2) {
error("Value of dimension specifier too large or small for this implementation");
* Delayed processing for pointers to
* allow self-referential and mutually
* recursive pointer constructs.
register struct nl
*p
, *q
;
for (p
= forechain
; p
!= NIL
; p
= p
->nl_next
) {
if (p
->class == PTR
&& p
-> ptr
[0] != 0)
p
->type
= gtype(p
-> ptr
[0]);
if (p
->type
!= NIL
&& ( ( p
->type
)->nl_flags
& NFILES
))
error("Files cannot be members of dynamic structures");
if ( pUSE( p
-> inTree
).PtrTType
== pNIL
) {
pPointer PtrTo
= tCopy( p
-> ptr
[0] );
pDEF( p
-> inTree
).PtrTType
= PtrTo
;