1988-10-26 15:21:11 +00:00
|
|
|
/* S C O P E M E C H A N I S M */
|
|
|
|
|
2013-05-14 19:47:04 +00:00
|
|
|
#include "parameters.h"
|
1988-10-26 15:21:11 +00:00
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
#include <alloc.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <em_arith.h>
|
|
|
|
#include <em_label.h>
|
|
|
|
|
|
|
|
#include "LLlex.h"
|
|
|
|
#include "def.h"
|
|
|
|
#include "idf.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "node.h"
|
|
|
|
#include "scope.h"
|
|
|
|
#include "type.h"
|
2019-02-23 17:15:23 +00:00
|
|
|
#include "lookup.h"
|
|
|
|
#include "error.h"
|
1988-10-26 15:21:11 +00:00
|
|
|
|
|
|
|
struct scope *GlobalScope, *PervasiveScope, *BlockScope;
|
|
|
|
struct scopelist *CurrVis;
|
|
|
|
extern int proclevel; /* declared in declar.g */
|
1990-12-11 13:52:08 +00:00
|
|
|
static int sccount;
|
1988-10-26 15:21:11 +00:00
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void InitScope(void)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
register struct scope *sc = new_scope();
|
|
|
|
register struct scopelist *ls = new_scopelist();
|
|
|
|
|
|
|
|
sc->sc_level = proclevel;
|
|
|
|
PervasiveScope = sc;
|
|
|
|
ls->sc_scope = PervasiveScope;
|
1990-12-11 13:52:08 +00:00
|
|
|
ls->sc_count = ++sccount;
|
1988-10-26 15:21:11 +00:00
|
|
|
CurrVis = ls;
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void open_scope(void)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
register struct scope *sc = new_scope();
|
|
|
|
register struct scopelist *ls = new_scopelist();
|
|
|
|
|
|
|
|
sc->sc_level = proclevel;
|
|
|
|
ls->sc_scope = sc;
|
|
|
|
ls->next = CurrVis;
|
1990-12-11 13:52:08 +00:00
|
|
|
ls->sc_count = ++sccount;
|
1988-10-26 15:21:11 +00:00
|
|
|
CurrVis = ls;
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void close_scope(int doclean)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* When this procedure is called, the next visible scope is equal to
|
|
|
|
the statically enclosing scope
|
|
|
|
*/
|
1991-03-21 10:45:42 +00:00
|
|
|
register struct def *df;
|
1988-10-26 15:21:11 +00:00
|
|
|
|
|
|
|
assert(CurrentScope != 0);
|
1991-03-21 10:45:42 +00:00
|
|
|
df = CurrentScope->sc_def;
|
|
|
|
if (doclean) while (df) {
|
|
|
|
struct def *next = df->df_nextinscope;
|
1994-10-27 14:57:48 +00:00
|
|
|
if (! (df->df_flags & (D_VARPAR|D_VALPAR))) remove_def(df);
|
1991-03-21 10:45:42 +00:00
|
|
|
df = next;
|
|
|
|
}
|
1988-10-26 15:21:11 +00:00
|
|
|
CurrVis = CurrVis->next;
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void Forward(register struct node *nd, register struct type *tp)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* Enter a forward reference into the current scope. This is
|
|
|
|
* used in pointertypes.
|
|
|
|
*/
|
|
|
|
register struct def *df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE);
|
|
|
|
register struct forwtype *fw_type = new_forwtype();
|
|
|
|
|
|
|
|
fw_type->f_next = df->df_fortype;
|
|
|
|
df->df_fortype = fw_type;
|
|
|
|
|
|
|
|
fw_type->f_node = nd;
|
|
|
|
fw_type->f_type = tp;
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void chk_prog_params(void)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* the program parameters must be global variables of some file type */
|
|
|
|
register struct def *df = CurrentScope->sc_def;
|
|
|
|
|
|
|
|
while( df ) {
|
|
|
|
if( df->df_kind & D_PARAMETER ) {
|
|
|
|
if( !is_anon_idf(df->df_idf) ) {
|
|
|
|
if( df->df_type == error_type )
|
1989-05-03 10:30:22 +00:00
|
|
|
error("program parameter \"%s\" must be a global variable",
|
1988-10-26 15:21:11 +00:00
|
|
|
df->df_idf->id_text);
|
|
|
|
else if( df->df_type->tp_fund != T_FILE )
|
|
|
|
error("program parameter \"%s\" must have a file type",
|
|
|
|
df->df_idf->id_text);
|
|
|
|
|
|
|
|
df->df_kind = D_VARIABLE;
|
|
|
|
}
|
|
|
|
else df->df_kind = D_ERROR;
|
|
|
|
}
|
|
|
|
df = df->df_nextinscope;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-23 16:44:50 +00:00
|
|
|
void chk_directives(void)
|
1988-10-26 15:21:11 +00:00
|
|
|
{
|
|
|
|
/* check if all forward declarations are defined */
|
|
|
|
register struct def *df = CurrentScope->sc_def;
|
|
|
|
|
|
|
|
while( df ) {
|
|
|
|
if( df->df_kind == D_FWPROCEDURE )
|
|
|
|
error("procedure \"%s\" not defined", df->df_idf->id_text);
|
|
|
|
else if( df->df_kind == D_FWFUNCTION )
|
|
|
|
error("function \"%s\" not defined", df->df_idf->id_text);
|
|
|
|
|
|
|
|
df = df->df_nextinscope;
|
|
|
|
}
|
|
|
|
}
|