';' block IDENT
{ match_id(dot.TOK_IDF, df->df_idf);
df->prc_scope = CurrentScope->sc_scope;
- close_scope();
+ close_scope(SC_CHKFORW);
}
;
{ assert(type & (D_PROCEDURE | D_PROCHEAD));
if (type == D_PROCHEAD) {
df = define(dot.TOK_IDF, CurrentScope, type);
+ df->for_node = MkNode(Name, NULLNODE, NULLNODE, &dot);
}
else {
df = lookup(dot.TOK_IDF,
};
struct import {
- union {
- struct def *im_def; /* imported definition */
- struct node *im_nodef; /* imported from undefined name */
- } im_u;
-#define imp_def df_value.df_import.im_u.im_def
-#define imp_nodef df_value.df_import.im_u.im_nodef
+ struct def *im_def; /* imported definition */
+#define imp_def df_value.df_import.im_def
+};
+
+struct dforward {
+ int fo_scope;
+ struct node *fo_node;
+#define for_node df_value.df_forward.fo_node
+#define for_scope df_value.df_forward.fo_scope
};
struct def { /* list of definitions for a name */
struct field df_field;
struct import df_import;
struct dfproc df_proc;
+ struct dforward df_forward;
int df_stdname; /* define for standard name */
} df_value;
};
}
break;
case D_FORWMODULE:
- if (kind & (D_FORWMODULE|D_MODULE)) {
+ if (kind == D_FORWMODULE) {
+ df->df_kind = kind;
+ return df;
+ }
+ if (kind == D_MODULE) {
+ FreeNode(df->for_node);
+ df->mod_scope = df->for_scope;
df->df_kind = kind;
return df;
}
break;
- case D_ERROR:
case D_FORWARD:
+ if (kind != D_FORWARD) {
+ FreeNode(df->for_node);
+ }
+ /* Fall Through */
+ case D_ERROR:
df->df_kind = kind;
return df;
}
return df;
}
df = new_def();
+ df->df_flags = 0;
df->df_idf = id;
df->df_scope = scope->sc_scope;
df->df_kind = kind;
df->next = id->id_def;
- df->df_flags = 0;
id->id_def = df;
/* enter the definition in the list of definitions in this scope */
otherwise return 0.
*/
register struct def *df, *df1;
+ struct def *retval;
df1 = 0;
df = id->id_def;
DO_DEBUG(5, debug("Looking for identifier \"%s\" in scope %d", id->id_text, scope));
while (df) {
if (df->df_scope == scope) {
+ retval = df;
if (df->df_kind == D_IMPORT) {
- df = df->imp_def;
- assert(df != 0);
- return df;
- }
-
- if (df->df_kind == D_UNDEF_IMPORT) {
- df1 = df->imp_def;
- assert(df1 != 0);
- if (df1->df_kind == D_MODULE) {
- df1 = lookup(id, df1->mod_scope);
- if (df1) {
- df->df_kind = D_IMPORT;
- df->imp_def = df1;
- }
- return df1;
- }
- return df;
+ retval = df->imp_def;
+ assert(retval != 0);
}
if (df1) {
df->next = id->id_def;
id->id_def = df;
}
- return df;
+ return retval;
}
df1 = df;
df = df->next;
in this scope as "imported".
*/
register struct def *df, *df1;
+ struct node *nd = ids;
while (ids) {
- df = define(ids->nd_IDF, CurrentScope, D_FORWARD);
+ df = lookup(ids->nd_IDF, CurrentScope->sc_scope);
+ if (df && (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
+node_error(ids, "Identifier \"%s\" occurs more than once in export list",
+df->df_idf->id_text);
+ }
+ else if (!df) {
+ df = define(ids->nd_IDF, CurrentScope, D_FORWARD);
+ df->for_node = MkNode(Name,NULLNODE,NULLNODE,
+ &(ids->nd_token));
+ }
if (qualified) {
df->df_flags |= D_QEXPORTED;
}
}
ids = ids->next;
}
+ FreeNode(nd);
}
Import(ids, idn, local)
identifiers defined in this module.
*/
register struct def *df;
+ struct def *df1 = 0;
int scope;
int kind;
int imp_kind;
kind = D_IMPORT;
scope = enclosing(CurrentScope)->sc_scope;
- if (!idn) imp_kind = FROM_ENCLOSING;
+
+ if (! idn) imp_kind = FROM_ENCLOSING;
else {
imp_kind = FROM_MODULE;
if (local) {
*/
df->df_scope = scope;
df->df_kind = D_FORWMODULE;
- df->mod_scope = -1;
- kind = D_UNDEF_IMPORT;
+ open_scope(CLOSEDSCOPE, 0);
+ df->for_scope = CurrentScope->sc_scope;
+ df->for_node = MkNode(Name, NULLNODE,
+ NULLNODE, &(idn->nd_token));
+ close_scope();
+ df1 = df;
}
}
- else {
- df = GetDefinitionModule(idn->nd_IDF);
- }
+ else df = GetDefinitionModule(idn->nd_IDF);
+
if (!(df->df_kind & (D_MODULE|D_FORWMODULE))) {
/* enter all "ids" with type D_ERROR */
kind = D_ERROR;
if (df->df_kind != D_ERROR) {
-node_error(idn, "identifier \"%s\" does not represent a module", idn->nd_IDF->id_text);
+node_error(idn, "identifier \"%s\" does not represent a module",
+idn->nd_IDF->id_text);
}
}
else scope = df->mod_scope;
+ FreeNode(idn);
}
+
+ idn = ids;
while (ids) {
if (imp_kind == FROM_MODULE) {
- if (scope == -1) {
+ if (df1 != 0) {
+ open_scope(CLOSEDSCOPE, df1->mod_scope);
+ df = define(ids->nd_IDF,
+ CurrentScope,
+ D_FORWARD);
+ df->for_node = MkNode(Name, NULLNODE,
+ NULLNODE, &(ids->nd_token));
+ close_scope(0);
}
else if (!(df = lookup(ids->nd_IDF, scope))) {
node_error(ids, "identifier \"%s\" not declared in qualifying module",
else {
if (local) {
df = lookfor(ids, enclosing(CurrentScope), 0);
- } else df = GetDefinitionModule(ids->nd_IDF);
+ } else df = GetDefinitionModule(ids->nd_IDF);
if (df->df_kind == D_ERROR) {
-node_error(ids, "identifier \"%s\" not visible in enclosing scope",
-ids->nd_IDF->id_text);
+ /* It was not yet defined in the enclosing
+ scope.
+ */
+ df->df_kind = D_FORWARD;
+ df->for_node = MkNode(Name, NULLNODE, NULLNODE,
+ &(ids->nd_token));
}
}
- DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text, df->df_kind));
+DO_DEBUG(2, debug("importing \"%s\", kind %d", ids->nd_IDF->id_text,
+df->df_kind));
define(ids->nd_IDF, CurrentScope, kind)->imp_def = df;
if (df->df_kind == D_TYPE &&
df->df_type->tp_fund == T_ENUMERATION) {
}
ids = ids->next;
}
+ FreeNode(idn);
}
exprt_literals(df, toscope)
neccesary because the implementation module might import
them again.
*/
- register struct def *df = *pdf, *df1 = 0;
+ register struct def *df = *pdf;
while (df) {
if (df->df_kind == D_IMPORT) {
RemFromId(df);
- if (df1) {
- df1->df_nextinscope = df->df_nextinscope;
- free_def(df);
- df = df1->df_nextinscope;
- }
- else {
- *pdf = df->df_nextinscope;
- free_def(df);
- df = *pdf;
- }
+ *pdf = df->df_nextinscope;
+ free_def(df);
}
else {
- df1 = df;
- df = df->df_nextinscope;
+ pdf = &(df->df_nextinscope);
}
+ df = *pdf;
}
}
assert(nd->nd_class == Def);
*pdf = df = nd->nd_def;
if ( !((types|D_ERROR) & df->df_kind)) {
- error("identifier \"%s\" is not a %s",
- df->df_idf->id_text, str);
+ if (df->df_kind == D_FORWARD) {
+node_error(*pnd,"%s \"%s\" not declared", str, df->df_idf->id_text);
+ }
+ else {
+node_error(*pnd,"identifier \"%s\" is not a %s", df->df_idf->id_text, str);
+ }
}
}
if (!p) FreeNode(nd);
/* Put nodes that are no longer needed back onto the free
list
*/
+ if (!nd) return;
if (nd->nd_left) FreeNode(nd->nd_left);
if (nd->nd_right) FreeNode(nd->nd_right);
free_node(nd);
#include "node.h"
#include "debug.h"
-static struct idf *impl_name = 0;
+static int DEFofIMPL = 0; /* Flag indicating that we are currently
+ parsing the definition module of the
+ implementation module currently being
+ compiled
+ */
static struct def *impl_df;
}
/*
MODULE IDENT {
id = dot.TOK_IDF;
df = define(id, CurrentScope, D_MODULE);
- open_scope(CLOSEDSCOPE, 0);
- df->mod_scope = CurrentScope->sc_scope;
+ if (!df->mod_scope) {
+ open_scope(CLOSEDSCOPE, 0);
+ df->mod_scope = CurrentScope->sc_scope;
+ }
+ else open_scope(CLOSEDSCOPE, df->mod_scope);
df->df_type =
standard_type(T_RECORD, 0, (arith) 0);
df->df_type->rec_scope = df->mod_scope;
import(1)*
export(0)?
block
- IDENT { close_scope();
+ IDENT { close_scope(SC_CHKFORW|SC_CHKPROC);
match_id(id, dot.TOK_IDF);
}
;
]?
IdentList(&ExportList) ';'
{
- if (!def) Export(ExportList, QUALflag);
- else warning("export list in definition module ignored");
- FreeNode(ExportList);
+ if (!def) {
+ Export(ExportList, QUALflag);
+ }
+ else {
+ warning("export list in definition module ignored");
+ FreeNode(ExportList);
+ }
}
;
*/
{
Import(ImportList, id, local);
- FreeNode(ImportList);
- if (id) FreeNode(id);
}
;
*/
definition* END IDENT
{
- if (id == impl_name) {
+ if (DEFofIMPL) {
/* Just read the definition module of the
implementation module being compiled
*/
df->df_flags |= D_QEXPORTED;
df = df->df_nextinscope;
}
- if (!SYSTEMModule) close_scope();
+ if (!SYSTEMModule) close_scope(SC_CHKFORW);
DefinitionModule = 0;
match_id(id, dot.TOK_IDF);
}
IDENT {
id = dot.TOK_IDF;
if (state == IMPLEMENTATION) {
- impl_name = id;
+ DEFofIMPL = 1;
df = GetDefinitionModule(id);
scope = df->mod_scope;
+ DEFofIMPL = 0;
}
DefinitionModule = 0;
open_scope(CLOSEDSCOPE, scope);
priority?
';' import(0)*
block IDENT
- { close_scope();
+ { close_scope(SC_CHKFORW|SC_CHKPROC);
match_id(id, dot.TOK_IDF);
}
'.'
CurrentScope->sc_forw = f;
}
-close_scope()
+close_scope(flag)
{
+ /* 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;
+ register struct def *df, *dfback = 0;
assert(sc != 0);
DO_DEBUG(1, debug("Closing a scope"));
- if (sc->sc_forw) rem_forwards(sc->sc_forw);
- if (sc->next && (sc->next->sc_scope == 0)) {
- struct scope *sc1 = sc;
+ if (flag) {
+ if (sc->sc_forw) rem_forwards(sc->sc_forw);
+ df = sc->sc_def;
+ while(df) {
+ if (flag & SC_CHKPROC) {
+ if (df->df_kind == D_PROCHEAD) {
+ /* A not defined procedure
+ */
+node_error(df->for_node, "procedure \"%s\" not defined", df->df_idf->id_text);
+ FreeNode(df->for_node);
+ }
+ }
+ if ((flag & SC_CHKFORW) &&
+ df->df_kind & (D_FORWARD|D_FORWMODULE)) {
+ /* These definitions must be found in
+ the enclosing closed scope, which of course
+ may be the scope that is now closed!
+ */
+ struct def *df1 = df->df_nextinscope;
+
+ if (scopeclosed(CurrentScope)) {
+ /* Indeed, the scope was a closed
+ scope, so give error message
+ */
+node_error(df->for_node, "identifier \"%s\" not declared", df->df_idf->id_text);
+ FreeNode(df->for_node);
+ dfback = df;
+ }
+ else {
+ /* This scope was an open scope.
+ Maybe the definitions are in the
+ enclosing scope?
+ */
+ struct scope *sc;
+
+ sc = enclosing(CurrentScope);
+ df->df_nextinscope = sc->sc_def;
+ sc->sc_def = df;
+ df->df_scope = sc->sc_scope;
+ if (dfback) dfback->df_nextinscope = df1;
+ else sc->sc_def = df1;
+ }
+ df = df1;
+ }
+ else {
+ dfback = df;
+ df = df->df_nextinscope;
+ }
+ }
+ }
+
+ if (sc->next && (sc->next->sc_scope == 0)) {
sc = sc->next;
- free_scope(sc1);
}
CurrentScope = sc->next;
- free_scope(sc);
}
static
while (f = fo) {
df = lookfor(&(f->fo_tok), CurrentScope, 1);
- if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
+ if (!(df->df_kind & (D_TYPE|D_HTYPE|D_ERROR))) {
node_error(&(f->fo_tok), "identifier \"%s\" not a type",
df->df_idf->id_text);
}
#define OPENSCOPE 0 /* Indicating an open scope */
#define CLOSEDSCOPE 1 /* Indicating a closed scope (module) */
+#define SC_CHKFORW 1 /* Check for forward definitions when closing
+ a scope
+ */
+#define SC_CHKPROC 2 /* Check for forward procedure definitions
+ when closing a scope
+ */
+
struct scope {
struct scope *next;
struct forwards *sc_forw;