BSD 3 development
[unix-history] / usr / src / cmd / pi / lab.c
CommitLineData
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 */
20label(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 */
78gotoop(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 */
108labeled(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