Commit | Line | Data |
---|---|---|
cfa3372e CH |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | # | |
3 | /* | |
4 | * pi - Pascal interpreter code translator | |
5 | * | |
6 | * Charles Haley, Bill Joy UCB | |
7 | * Version 1.2 November 1978 | |
8 | */ | |
9 | ||
10 | #include "whoami" | |
11 | #include "0.h" | |
12 | #include "tree.h" | |
13 | #include "opcode.h" | |
14 | ||
15 | /* | |
16 | * Label enters the definitions | |
17 | * of the label declaration part | |
18 | * into the namelist. | |
19 | */ | |
20 | label(r, l) | |
21 | int *r, l; | |
22 | { | |
23 | #ifndef PI0 | |
24 | register *ll; | |
25 | register struct nl *p, *lp; | |
26 | ||
27 | lp = NIL; | |
28 | #else | |
29 | send(REVLAB, r); | |
30 | #endif | |
31 | line = l; | |
32 | #ifndef PI1 | |
33 | if (parts & (CPRT|TPRT|VPRT)) | |
34 | error("Label declarations must precede const, type and var declarations"); | |
35 | if (parts & LPRT) | |
36 | error("All labels must be declared in one label part"); | |
37 | parts |= LPRT; | |
38 | #endif | |
39 | #ifndef PI0 | |
40 | for (ll = r; ll != NIL; ll = ll[2]) { | |
41 | l = getlab(); | |
42 | p = enter(defnl(ll[1], LABEL, 0, l)); | |
43 | /* | |
44 | * Get the label for the eventual target | |
45 | */ | |
46 | p->value[1] = getlab(); | |
47 | p->chain = lp; | |
48 | p->nl_flags |= (NFORWD|NMOD); | |
49 | p->value[NL_GOLEV] = NOTYET; | |
50 | p->entloc = l; | |
51 | lp = p; | |
52 | /* | |
53 | * This operator is between | |
54 | * the bodies of two procedures | |
55 | * and provides a target for | |
56 | * gotos for this label via TRA. | |
57 | */ | |
58 | putlab(l); | |
59 | put2(O_GOTO | cbn<<9, p->value[1]); | |
60 | } | |
61 | gotos[cbn] = lp; | |
62 | # ifdef PTREE | |
63 | { | |
64 | pPointer Labels = LabelDCopy( r ); | |
65 | ||
66 | pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; | |
67 | } | |
68 | # endif | |
69 | #endif | |
70 | } | |
71 | ||
72 | #ifndef PI0 | |
73 | /* | |
74 | * Gotoop is called when | |
75 | * we get a statement "goto label" | |
76 | * and generates the needed tra. | |
77 | */ | |
78 | gotoop(s) | |
79 | char *s; | |
80 | { | |
81 | register struct nl *p; | |
82 | ||
83 | gocnt++; | |
84 | p = lookup(s); | |
85 | if (p == NIL) | |
86 | return (NIL); | |
87 | put2(O_TRA4, p->entloc); | |
88 | if (bn == cbn) | |
89 | if (p->nl_flags & NFORWD) { | |
90 | if (p->value[NL_GOLEV] == NOTYET) { | |
91 | p->value[NL_GOLEV] = level; | |
92 | p->value[NL_GOLINE] = line; | |
93 | } | |
94 | } else | |
95 | if (p->value[NL_GOLEV] == DEAD) { | |
96 | recovered(); | |
97 | error("Goto %s is into a structured statement", p->symbol); | |
98 | } | |
99 | } | |
100 | ||
101 | /* | |
102 | * Labeled is called when a label | |
103 | * definition is encountered, and | |
104 | * marks that it has been found and | |
105 | * patches the associated GOTO generated | |
106 | * by gotoop. | |
107 | */ | |
108 | labeled(s) | |
109 | char *s; | |
110 | { | |
111 | register struct nl *p; | |
112 | ||
113 | p = lookup(s); | |
114 | if (p == NIL) | |
115 | return (NIL); | |
116 | if (bn != cbn) { | |
117 | error("Label %s not defined in correct block", s); | |
118 | return; | |
119 | } | |
120 | if ((p->nl_flags & NFORWD) == 0) { | |
121 | error("Label %s redefined", s); | |
122 | return; | |
123 | } | |
124 | p->nl_flags &= ~NFORWD; | |
125 | patch4(p->entloc); | |
126 | if (p->value[NL_GOLEV] != NOTYET) | |
127 | if (p->value[NL_GOLEV] < level) { | |
128 | recovered(); | |
129 | error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]); | |
130 | } | |
131 | p->value[NL_GOLEV] = level; | |
132 | } | |
133 | #endif |