BSD 3 development
[unix-history] / usr / src / cmd / pi / lab.c
/* Copyright (c) 1979 Regents of the University of California */
#
/*
* pi - Pascal interpreter code translator
*
* Charles Haley, Bill Joy UCB
* Version 1.2 November 1978
*/
#include "whoami"
#include "0.h"
#include "tree.h"
#include "opcode.h"
/*
* Label enters the definitions
* of the label declaration part
* into the namelist.
*/
label(r, l)
int *r, l;
{
#ifndef PI0
register *ll;
register struct nl *p, *lp;
lp = NIL;
#else
send(REVLAB, r);
#endif
line = l;
#ifndef PI1
if (parts & (CPRT|TPRT|VPRT))
error("Label declarations must precede const, type and var declarations");
if (parts & LPRT)
error("All labels must be declared in one label part");
parts |= LPRT;
#endif
#ifndef PI0
for (ll = r; ll != NIL; ll = ll[2]) {
l = getlab();
p = enter(defnl(ll[1], LABEL, 0, l));
/*
* Get the label for the eventual target
*/
p->value[1] = getlab();
p->chain = lp;
p->nl_flags |= (NFORWD|NMOD);
p->value[NL_GOLEV] = NOTYET;
p->entloc = l;
lp = p;
/*
* This operator is between
* the bodies of two procedures
* and provides a target for
* gotos for this label via TRA.
*/
putlab(l);
put2(O_GOTO | cbn<<9, p->value[1]);
}
gotos[cbn] = lp;
# ifdef PTREE
{
pPointer Labels = LabelDCopy( r );
pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels;
}
# endif
#endif
}
#ifndef PI0
/*
* Gotoop is called when
* we get a statement "goto label"
* and generates the needed tra.
*/
gotoop(s)
char *s;
{
register struct nl *p;
gocnt++;
p = lookup(s);
if (p == NIL)
return (NIL);
put2(O_TRA4, p->entloc);
if (bn == cbn)
if (p->nl_flags & NFORWD) {
if (p->value[NL_GOLEV] == NOTYET) {
p->value[NL_GOLEV] = level;
p->value[NL_GOLINE] = line;
}
} else
if (p->value[NL_GOLEV] == DEAD) {
recovered();
error("Goto %s is into a structured statement", p->symbol);
}
}
/*
* Labeled is called when a label
* definition is encountered, and
* marks that it has been found and
* patches the associated GOTO generated
* by gotoop.
*/
labeled(s)
char *s;
{
register struct nl *p;
p = lookup(s);
if (p == NIL)
return (NIL);
if (bn != cbn) {
error("Label %s not defined in correct block", s);
return;
}
if ((p->nl_flags & NFORWD) == 0) {
error("Label %s redefined", s);
return;
}
p->nl_flags &= ~NFORWD;
patch4(p->entloc);
if (p->value[NL_GOLEV] != NOTYET)
if (p->value[NL_GOLEV] < level) {
recovered();
error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]);
}
p->value[NL_GOLEV] = level;
}
#endif