/* Copyright (c) 1979 Regents of the University of California */
* pi - Pascal interpreter code translator
* Charles Haley, Bill Joy UCB
* Version 1.2 November 1978
* pascal case statement code
register struct ct
*ctab
;
* Obtain selector attributes:
p
= rvalue((int *) r
[2], NLNIL
);
error("Case selectors cannot be %ss", nameof(p
));
for (cl
= r
[3]; cl
!= NIL
; cl
= cl
[2]) {
for (cs
= cs
[2]; cs
!= NIL
; cs
= cs
[2])
* Allocate case table space
ctab
= i
= malloc(n
* sizeof *ctab
);
error("Ran out of memory (case)");
* Check the legality of the
* labels and count the number
for (cl
= r
[3]; cl
!= NIL
; cl
= cl
[2]) {
for (cs
= cs
[2]; cs
!= NIL
; cs
= cs
[2]) {
if (p
== NIL
|| con
.ctype
== NIL
)
if (incompat(con
.ctype
, p
, NIL
)) {
cerror("Case label type clashed with case selector expression type");
if (con
.crval
< low
|| con
.crval
> high
) {
error("Case label out of range");
ctab
[m
].clong
= con
.crval
;
* Check for duplicate labels
if (ctab
[i
].clong
== ctab
[j
].clong
) {
error("Multiply defined label in case, lines %d and %d", ctab
[i
].cline
, ctab
[j
].cline
);
* Put out case operator and
put2(O_CASE1OP
+ (w
>> 1), n
);
put( 3 , O_CASE1
+ (w
>> 1), ctab
[i
].clong
);
* statement. Patch branch
* table to beginning of each
* statement and follow each
* statement with a branch back
for (cl
= r
[3]; cl
!= NIL
; cl
= cl
[2]) {
for (cs
= cs
[2]; cs
!= NIL
; cs
= cs
[2]) {
patchfil(brtab
- 1, lc
- brtab0
, 1);
* Patch the termination branch