ack/lang/m2/comp/scope.c

219 lines
5 KiB
C
Raw Normal View History

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
1986-03-26 15:11:02 +00:00
/* S C O P E M E C H A N I S M */
1994-06-24 14:02:31 +00:00
/* $Id$ */
#include "parameters.h"
1986-05-01 19:06:53 +00:00
#include "debug.h"
1986-03-26 15:11:02 +00:00
#include <stdlib.h>
1986-03-26 15:11:02 +00:00
#include <assert.h>
#include "alloc.h"
#include "em_arith.h"
#include "em_label.h"
1986-04-22 22:36:16 +00:00
1986-03-27 17:37:41 +00:00
#include "LLlex.h"
#include "idf.h"
1986-03-26 15:11:02 +00:00
#include "scope.h"
1986-03-27 17:37:41 +00:00
#include "type.h"
#include "def.h"
1986-04-08 18:15:46 +00:00
#include "node.h"
#include "lookup.h"
#include "error.h"
1986-04-22 22:36:16 +00:00
struct scope *PervasiveScope;
struct scopelist *CurrVis, *GlobalVis;
1986-05-16 17:15:36 +00:00
extern int proclevel;
1986-11-05 14:33:00 +00:00
extern char options[];
1986-03-26 15:11:02 +00:00
#define new_scope() ((struct scope*) calloc(1, sizeof(struct scope)))
#define free_scope(p) free(p)
1986-03-26 15:11:02 +00:00
#define new_scopelist() ((struct scopelist*) calloc(1, sizeof(struct scopelist)))
#define free_scopelist(p) free(p)
1986-04-28 18:06:58 +00:00
1990-07-30 15:56:25 +00:00
static int sc_count;
void open_scope(int scopetype)
1986-03-26 15:11:02 +00:00
{
1986-04-03 00:44:39 +00:00
/* Open a scope that is either open (automatic imports) or closed.
*/
register struct scope *sc = new_scope();
register struct scopelist *ls = new_scopelist();
1986-05-30 18:48:00 +00:00
1986-04-15 17:51:53 +00:00
assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
1986-05-30 18:48:00 +00:00
1986-04-15 17:51:53 +00:00
sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
1986-05-16 17:15:36 +00:00
sc->sc_level = proclevel;
1986-10-06 20:36:30 +00:00
ls->sc_scope = sc;
ls->sc_encl = CurrVis;
1988-03-22 17:54:01 +00:00
if (! sc->sc_scopeclosed) {
1987-07-16 19:51:40 +00:00
ls->sc_next = ls->sc_encl;
1986-03-26 15:11:02 +00:00
}
1990-07-30 15:56:25 +00:00
ls->sc_count = sc_count++;
1986-04-28 18:06:58 +00:00
CurrVis = ls;
1986-03-26 15:11:02 +00:00
}
struct scope * open_and_close_scope(int scopetype)
{
struct scope *sc;
open_scope(scopetype);
sc = CurrentScope;
1987-05-18 15:57:33 +00:00
close_scope(0);
return sc;
}
void InitScope(void)
1986-03-26 15:11:02 +00:00
{
register struct scope *sc = new_scope();
register struct scopelist *ls = new_scopelist();
1986-03-26 15:11:02 +00:00
1986-05-16 17:15:36 +00:00
sc->sc_level = proclevel;
1986-04-15 17:51:53 +00:00
PervasiveScope = sc;
1986-04-28 18:06:58 +00:00
ls->sc_scope = PervasiveScope;
CurrVis = ls;
1986-03-27 17:37:41 +00:00
}
static void chk_proc(register struct def *df)
1986-04-08 18:15:46 +00:00
{
1986-04-15 17:51:53 +00:00
/* Called at scope closing. Check all definitions, and if one
1986-10-06 20:36:30 +00:00
is a D_PROCHEAD, the procedure was not defined.
1986-12-01 10:06:53 +00:00
Also check that hidden types are defined.
1986-04-12 02:21:24 +00:00
*/
1986-04-15 17:51:53 +00:00
while (df) {
1986-12-01 10:06:53 +00:00
if (df->df_kind == D_HIDDEN) {
error("hidden type \"%s\" not declared",
df->df_idf->id_text);
}
else if (df->df_kind == D_PROCHEAD) {
1986-04-15 17:51:53 +00:00
/* A not defined procedure
*/
1986-10-06 20:36:30 +00:00
error("procedure \"%s\" not defined",
df->df_idf->id_text);
1986-04-15 17:51:53 +00:00
FreeNode(df->for_node);
}
df = df->df_nextinscope;
}
}
static void chk_forw(struct def **pdf)
1986-04-15 17:51:53 +00:00
{
/* Called at scope close. Look for all forward definitions and
if the scope was a closed scope, give an error message for
them, and otherwise move them to the enclosing scope.
*/
register struct def *df;
1986-10-06 20:36:30 +00:00
while ( (df = *pdf) ) {
while (df->df_kind == D_FORWTYPE) {
register struct def *df2 = df->df_nextinscope;
pdf = NULL;
ForceForwardTypeDef(df); /* removes df */
df = df2;
1986-11-26 16:40:45 +00:00
}
if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
1986-04-15 17:51:53 +00:00
/* These definitions must be found in
the enclosing closed scope, which of course
may be the scope that is now closed!
*/
if (scopeclosed(CurrentScope)) {
/* Indeed, the scope was a closed
scope, so give error message
*/
1986-11-26 16:40:45 +00:00
node_error(df->for_node, "identifier \"%s\" not declared",
1986-10-06 20:36:30 +00:00
df->df_idf->id_text);
1986-04-12 02:21:24 +00:00
}
1986-10-06 20:36:30 +00:00
else {
/* This scope was an open scope.
1986-04-15 17:51:53 +00:00
Maybe the definitions are in the
enclosing scope?
1986-04-12 02:21:24 +00:00
*/
register struct scopelist *ls =
1986-10-06 20:36:30 +00:00
nextvisible(CurrVis);
register struct def *df1 = lookup(df->df_idf, ls->sc_scope, 0, 0);
if (pdf)
*pdf = df->df_nextinscope;
1986-10-06 20:36:30 +00:00
if (! df1) {
if (df->df_kind == D_FORWMODULE) {
df->for_vis->sc_next = ls;
}
df->df_nextinscope = ls->sc_scope->sc_def;
ls->sc_scope->sc_def = df;
df->df_scope = ls->sc_scope;
continue;
1986-04-12 02:21:24 +00:00
}
/* leave it like this ??? */
1986-04-12 02:21:24 +00:00
}
FreeNode(df->for_node);
1986-04-12 02:21:24 +00:00
}
1986-10-06 20:36:30 +00:00
pdf = &df->df_nextinscope;
1986-04-12 02:21:24 +00:00
}
1986-04-08 18:15:46 +00:00
}
void Reverse(struct def **pdf)
1986-04-17 09:28:09 +00:00
{
/* Reverse the order in the list of definitions in a scope.
This is neccesary because this list is built in reverse.
1986-04-21 17:27:06 +00:00
Also, while we're at it, remove uninteresting definitions
1986-06-17 12:04:05 +00:00
from this list.
1986-04-17 09:28:09 +00:00
*/
register struct def *df, *df1;
1990-07-30 15:56:25 +00:00
#define INTERESTING (D_MODULE|D_PROCEDURE|D_PROCHEAD|D_VARIABLE|D_IMPORTED|D_TYPE|D_CONST|D_FIELD)
1986-04-17 09:28:09 +00:00
df = 0;
df1 = *pdf;
1986-04-21 17:27:06 +00:00
while (df1) {
1986-10-06 20:36:30 +00:00
if (df1->df_kind & INTERESTING) {
struct def *prev = df;
1986-10-06 20:36:30 +00:00
df = df1;
1986-04-21 17:27:06 +00:00
df1 = df1->df_nextinscope;
1986-10-06 20:36:30 +00:00
df->df_nextinscope = prev;
1986-04-21 17:27:06 +00:00
}
1986-10-06 20:36:30 +00:00
else df1 = df1->df_nextinscope;
1986-04-17 09:28:09 +00:00
}
1986-10-06 20:36:30 +00:00
*pdf = df;
1986-04-17 09:28:09 +00:00
}
void close_scope(int flag)
1986-04-15 17:51:53 +00:00
{
/* Close a scope. If "flag" is set, check for forward declarations,
either POINTER declarations, or EXPORTs, or forward references
to MODULES
*/
register struct scope *sc = CurrentScope;
1986-04-15 17:51:53 +00:00
assert(sc != 0);
FreeNode(sc->sc_end);
sc->sc_end = dot2leaf(Link);
1986-04-15 17:51:53 +00:00
if (flag) {
DO_DEBUG(options['S'],(print("List of definitions in currently ended scope:\n"), DumpScope(sc->sc_def)));
1986-04-15 17:51:53 +00:00
if (flag & SC_CHKPROC) chk_proc(sc->sc_def);
if (flag & SC_CHKFORW) chk_forw(&(sc->sc_def));
1986-04-22 22:36:16 +00:00
if (flag & SC_REVERSE) Reverse(&(sc->sc_def));
1986-04-15 17:51:53 +00:00
}
1986-04-28 18:06:58 +00:00
CurrVis = enclosing(CurrVis);
1986-04-15 17:51:53 +00:00
}
#ifdef DEBUG
void DumpScope(register struct def *df)
1986-04-15 17:51:53 +00:00
{
while (df) {
PrDef(df);
df = df->df_nextinscope;
}
}
#endif