/* Copyright (c) 1979 Regents of the University of California */
* pi - Pascal interpreter code translator
* Charles Haley, Bill Joy UCB
* Version 1.2 January 1979
* prog/proc/func into the
* namelist. It also handles
* the arguments and puts out
* a transfer which defines
* the entry point of a procedure.
yyretrieve(); /* kludge */
if (r
[3] == NIL
&& (p
=lookup1(r
[2])) != NIL
&& bn
== cbn
) {
* in this block. it is either
* a redeclared symbol (error)
* or a forward declaration.
if ((p
->class == FUNC
|| p
->class == PROC
) && (p
->nl_flags
& NFORWD
) != 0) {
if (p
->class == FUNC
&& r
[4])
error("Function type should be given only in forward declaration");
* Declare the prog/proc/func
program
= p
= defnl(r
[2], PROG
, 0, 0);
error("Procedures do not have types, only functions do");
p
= enter(defnl(r
[2], PROC
, 0, 0));
error("Function type must be specified");
else if (il
[0] != T_TYID
) {
error("Function type can be specified only by using a type identifier");
p
= enter(defnl(r
[2], FUNC
, il
, NIL
));
* An arbitrary restriction
switch (o
= classify(p
->type
)) {
error("Functions should not return %ss", clnames
[o
]);
error("Procedure/function nesting too deep");
* For functions, the function variable
cp
= defnl(r
[2], FVAR
, p
->type
, 0);
for (rl
= r
[3]; rl
!= NIL
; rl
= rl
[2]) {
if (rl
[1][0] != T_PPROC
) {
error("Types for arguments can be specified only by using type identifiers");
for (il
= rl
[1][1]; il
!= NIL
; il
= il
[2]) {
error("Files cannot be passed by value");
else if (p
->nl_flags
& NFILES
)
error("Files cannot be a component of %ss passed by value",
dp
= defnl(il
[1], VAR
, p
, 0);
dp
= defnl(il
[1], REF
, p
, 0);
error("Procedure/function parameters not implemented");
for (rl
= r
[3]; rl
; rl
= rl
[2]) {
dp
= defnl(rl
[1], VAR
, 0, 0);
* when the actual (resolved)
* declaration of a procedure is
* encountered. It puts the names
* of the (function) and parameters
register struct nl
*q
, *p
;
error("Too many levels of function/procedure nesting");
for (q
= fp
->chain
; q
!= NIL
; q
= q
->chain
)
* For functions, enter the fvar
enter(fp
->value
[NL_FVAR
]);
* finish a block by generating
* the code for the statements.
* It then looks for unresolved declarations
* of labels, procedures and functions,
* and cleans up the name list.
* For the program, it checks the
* semantics of the program
funcend(fp
, bundle
, endline
)
send(REVFEND
, bundle
, endline
, syneflg
== errcnt
[cbn
]);
* Clean up the symbol table displays and check for unresolves
for (i
= 0; i
<= 077; i
++) {
for (p
= disptab
[i
]; p
!= NIL
&& (p
->nl_block
& 037) == b
; p
= p
->nl_next
)
if (p
->class == BADUSE
) {
if (p
->chain
->ud_next
== NIL
)
if (p
->value
[NL_KINDS
] & ISUNDEF
)
nerror("%s undefined on line%s", p
->symbol
, cp
);
nerror("%s improperly used on line%s", p
->symbol
, cp
);
dumpnl(fp
->value
[2], fp
->symbol
);
if (inpflist(fp
->symbol
)) {
printf(" %d", p
->ud_line
);
printf("In %s %s:\n", classes
[Fp
->class], Fp
->symbol
);