* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)type.c 5.1 (Berkeley) 6/5/85";
typebeg( lineofytype
, r
)
static bool type_order
= FALSE
;
static bool type_seen
= FALSE
;
* 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");
error("Type declarations should precede var and routine declarations");
if (parts
[ cbn
] & TPRT
) {
error("All types should be declared in one type part");
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
register struct tnode
*tdecl
;
tnp
= defnl(tid
, TYPE
, np
, 0);
enter(tnp
)->nl_flags
|= (char) NMOD
;
send(REVTYPE
, tline
, tid
, tdecl
);
stabgtype(tid
, np
, line
);
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.
register struct tnode
*r
;
oline
= line
= r
->lined
.line_no
;
r
= (struct tnode
*) (&(r
->tyid_node
.line_no
));
np
= lookup(r
->char_const
.cptr
);
error("%s is a %s, not a type as required", r
->char_const
.cptr
, classes
[np
->class]);
np
= defnl((char *) 0, PTR
, NLNIL
, 0 );
np
-> ptr
[0] = ((struct nl
*) r
->ptr_ty
.id_node
);
np
= gtype(r
->comp_ty
.type
);
np
= tyrec(r
->comp_ty
.type
, 0);
* mung T_TYREC[3] to point to the record
r
->comp_ty
.nl_entry
= np
;
np
= gtype(r
->comp_ty
.type
);
if (np
->nl_flags
& NFILES
)
error("Files cannot be members of files");
np
= defnl((char *) 0, FILET
, np
, 0);
np
= gtype(r
->comp_ty
.type
);
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((char *) 0, SET
, np
, 0);
error("Storage requirement of %s exceeds the implementation limit of %D by %D bytes",
nameof(np
), (char *) (long)(TOOMUCH
-1), (char *) (long)(w
-TOOMUCH
+1));
* Scalar (enumerated) types
struct tnode
*r
; /* T_TYSCAL */
register struct nl
*np
, *op
, *zp
;
register struct tnode
*v
;
np
= defnl((char *) 0, SCAL
, NLNIL
, 0);
for (; v
!= TR_NIL
; v
= v
->list_node
.next
) {
op
= enter(defnl((char *) v
->list_node
.list
, CONST
, np
, ++i
));
* Declare a subrange for conformant arrays.
register struct tnode
*r
;
register struct nl
*p
, *op
, *tp
;
tp
= gtype(r
->crang_ty
.type
);
* Just make a new type -- the lower and upper bounds must be
p
= defnl ( 0, CRANGE
, tp
, 0 );
register struct tnode
*r
; /* T_TYRANG */
register struct nl
*lp
, *hp
;
gconst(r
->rang_ty
.const2
);
gconst(r
->rang_ty
.const1
);
if (lp
== NLNIL
|| hp
== NLNIL
)
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((char *) 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 tnode
*tl
, *s
;
register struct nl
*tp
, *ltp
;
/* Count the dimensions */
for (n
= 0; s
->tag
== T_TYARY
|| s
->tag
== T_TYCARY
;
np
= defnl((char *) 0, ARRAY
, tp
, 0);
np
->nl_flags
|= (tp
->nl_flags
) & NFILES
;
for (s
= r
; s
->tag
== T_TYARY
|| s
->tag
== T_TYCARY
;
for (tl
= s
->ary_ty
.type_list
; tl
!= TR_NIL
; tl
=tl
->list_node
.next
){
tp
= gtype(tl
->list_node
.list
);
if ((tp
->class == RANGE
|| tp
->class == CRANGE
) &&
tp
->type
== nl
+TDOUBLE
) {
error("Index type for arrays cannot be real");
if (tp
->class != RANGE
&& tp
->class != SCAL
&& tp
->class !=CRANGE
){
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.
for (p
= forechain
; p
!= NLNIL
; p
= p
->nl_next
) {
if (p
->class == PTR
&& p
-> ptr
[0] != 0)
p
->type
= gtype((struct tnode
*) p
-> ptr
[0]);
if ( pUSE( p
-> inTree
).PtrTType
== pNIL
) {
pPointer PtrTo
= tCopy( p
-> ptr
[0] );
pDEF( p
-> inTree
).PtrTType
= PtrTo
;