mods to handle forward references better

This commit is contained in:
ceriel 1988-06-30 14:50:30 +00:00
parent fa9e4c5ea3
commit 74c779b81e
5 changed files with 94 additions and 57 deletions

View file

@ -1137,7 +1137,6 @@ ChkStandard(expp)
case S_ORD: case S_ORD:
if (! (left = getarg(&arg, T_NOSUB, 0, edf))) return 0; if (! (left = getarg(&arg, T_NOSUB, 0, edf))) return 0;
MkCoercion(&(arg->nd_left), BaseType(left->nd_type));
expp->nd_type = card_type; expp->nd_type = card_type;
if (arg->nd_left->nd_class == Value) { if (arg->nd_left->nd_class == Value) {
arg->nd_left->nd_type = card_type; arg->nd_left->nd_type = card_type;

View file

@ -137,7 +137,7 @@ define(id, scope, kind)
another one, or we may have found the definition another one, or we may have found the definition
for this module. for this module.
*/ */
if (kind == D_FORWMODULE) { if (kind & (D_FORWMODULE|D_FORWARD)) {
return df; return df;
} }
@ -168,7 +168,7 @@ define(id, scope, kind)
/* A forward reference, for which we may now have /* A forward reference, for which we may now have
found a definition. found a definition.
*/ */
if (kind != D_FORWARD) { if (! (kind & (D_FORWARD | D_FORWMODULE))) {
FreeNode(df->for_node); FreeNode(df->for_node);
} }
@ -179,6 +179,9 @@ define(id, scope, kind)
it found an error. Maybe, the user gives a it found an error. Maybe, the user gives a
definition after all. definition after all.
*/ */
if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
df->df_flags = D_DEFINED;
}
df->df_kind = kind; df->df_kind = kind;
return df; return df;
} }

View file

@ -233,62 +233,75 @@ EnterParamList(ppr, Idlist, type, VARp, off)
FreeNode(Idlist); FreeNode(Idlist);
} }
STATIC t_def * STATIC t_def *DoImport();
DoImport(df, scope)
register t_def *df; ImportEffects(idef, scope, flag)
t_def *idef;
t_scope *scope; t_scope *scope;
{ {
/* Definition "df" is imported to scope "scope". /* Handle side effects of an import:
Handle the case that it is an enumeration type or a module. - a module could have unqualified exports ???
- importing an enumeration type also imports literals
*/ */
register t_def *idef = define(df->df_idf, scope, D_IMPORT); register t_def *df = idef;
register t_type *tp;
idef->imp_def = df;
while (df->df_kind & D_IMPORTED) { while (df->df_kind & D_IMPORTED) {
df = df->imp_def; df = df->imp_def;
} }
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) { tp = BaseType(df->df_type);
if ((df->df_kind & (D_TYPE|D_FTYPE)) &&
tp->tp_fund == T_ENUMERATION) {
/* Also import all enumeration literals /* Also import all enumeration literals
*/ */
for (df = df->df_type->enm_enums; df; df = df->enm_next) { for (df = tp->enm_enums; df; df = df->enm_next) {
register t_def *df1 = define(df->df_idf, scope, D_IMPORT); if (! DoImport(df, scope, flag|D_USED)) assert(0);
/* don't complain when not used ... */
df1->imp_def = df;
df1->df_flags |= D_USED;/* don't complain when these
are not used
*/
} }
idef->df_flags |= D_USED; /* don't complain ... */ idef->df_flags |= D_USED; /* don't complain ... */
} }
else if (df->df_kind == D_MODULE) { else if (df->df_kind == D_MODULE) {
/* Also import all definitions that are exported from this
module
*/
if (df->mod_vis == CurrVis) { if (df->mod_vis == CurrVis) {
error("cannot import current module \"%s\"", error("cannot import current module \"%s\"",
df->df_idf->id_text); df->df_idf->id_text);
return idef; return;
} }
if (df->df_scope == GlobalScope) return;
/* Also import all definitions that are exported from this
module
*/
for (df = df->mod_vis->sc_scope->sc_def; for (df = df->mod_vis->sc_scope->sc_def;
df; df;
df = df->df_nextinscope) { df = df->df_nextinscope) {
if (df->df_flags & D_EXPORTED) { if (df->df_flags & D_EXPORTED) {
register t_def *df1 = if (!DoImport(df, scope, D_IMP_BY_EXP|D_USED)){
define(df->df_idf, scope, D_IMPORT); assert(0);
}
df1->imp_def = df;
df1->df_flags |= D_USED;
/* don't complain when these are not used */ /* don't complain when these are not used */
} }
} }
idef->df_flags |= D_USED; /* don't complain ... */ idef->df_flags |= D_USED; /* don't complain ... */
} }
}
STATIC t_def *
DoImport(df, scope, flag)
register t_def *df;
t_scope *scope;
{
/* Definition "df" is imported to scope "scope".
*/
t_def *idef = define(df->df_idf, scope, D_IMPORT);
idef->imp_def = df;
idef->df_flags |= flag;
ImportEffects(idef, scope, flag);
return idef; return idef;
} }
STATIC t_scopelist *
STATIC
ForwModule(df, nd) ForwModule(df, nd)
register t_def *df; register t_def *df;
t_node *nd; t_node *nd;
@ -314,7 +327,6 @@ ForwModule(df, nd)
/* Here ! */ /* Here ! */
df->for_vis = vis; df->for_vis = vis;
df->for_node = nd; df->for_node = nd;
return vis;
} }
STATIC t_def * STATIC t_def *
@ -361,6 +373,7 @@ EnterExportList(Idlist, qualified)
node_error(idlist, node_error(idlist,
"multiple occurrences of \"%s\" in export list", "multiple occurrences of \"%s\" in export list",
idlist->nd_IDF->id_text); idlist->nd_IDF->id_text);
continue;
} }
df->df_flags |= qualified; df->df_flags |= qualified;
@ -373,12 +386,10 @@ EnterExportList(Idlist, qualified)
while (df1) { while (df1) {
if ((df1->df_kind & D_IMPORTED) && if ((df1->df_kind & D_IMPORTED) &&
df1->imp_def == CurrentScope->sc_definedby) { df1->imp_def == CurrentScope->sc_definedby) {
DoImport(df, df1->df_scope)->df_flags |= if (! DoImport(df, df1->df_scope, D_IMP_BY_EXP)) assert(0);
D_IMP_BY_EXP;
} }
df1 = df1->df_next; df1 = df1->df_next;
} }
/* Also handle the definition as if the enclosing /* Also handle the definition as if the enclosing
scope imports it. scope imports it.
*/ */
@ -404,20 +415,40 @@ EnterExportList(Idlist, qualified)
continue; continue;
} }
if (df1->df_kind == D_HIDDEN && if (df1->df_kind == D_HIDDEN &&
df2->df_kind == D_TYPE) { (df2->df_kind & (D_TYPE|D_FTYPE))) {
DeclareType(idlist, df1, df2->df_type); DeclareType(idlist, df1, df2->df_type);
df1->df_kind = D_TYPE; df1->df_kind = D_TYPE;
continue; continue;
} }
} }
DoImport(df, enclosing(CurrVis)->sc_scope)->df_flags |= if (! DoImport(df,enclosing(CurrVis)->sc_scope,D_IMP_BY_EXP)) assert(0);
D_IMP_BY_EXP;
} }
} }
FreeNode(Idlist); FreeNode(Idlist);
} }
CheckForImports(df)
t_def *df;
{
/* We have a definition for "df"; check all imports of
it for side-effects
*/
register t_def *df1 = df->df_idf->id_def;
while (df1) {
if (df1->df_kind & D_IMPORTED) {
register t_def *df2 = df1->imp_def;
while (df2->df_kind & D_IMPORTED) df2 = df2->imp_def;
if (df2 == df) {
ImportEffects(df1, df1->df_scope, 0);
}
}
df1 = df1->df_next;
}
}
EnterFromImportList(idlist, FromDef, FromId) EnterFromImportList(idlist, FromDef, FromId)
register t_node *idlist; register t_node *idlist;
register t_def *FromDef; register t_def *FromDef;
@ -425,13 +456,13 @@ EnterFromImportList(idlist, FromDef, FromId)
{ {
/* Import the list Idlist from the module indicated by Fromdef. /* Import the list Idlist from the module indicated by Fromdef.
*/ */
register t_scopelist *vis; register t_scope *sc;
register t_def *df; register t_def *df;
char *module_name = FromDef->df_idf->id_text; char *module_name = FromDef->df_idf->id_text;
int forwflag = 0;
switch(FromDef->df_kind) { switch(FromDef->df_kind) {
case D_ERROR: case D_ERROR:
case D_FORWARD:
/* The module from which the import was done /* The module from which the import was done
is not yet declared. I'm not sure if I must is not yet declared. I'm not sure if I must
accept this, but for the time being I will. accept this, but for the time being I will.
@ -439,16 +470,14 @@ EnterFromImportList(idlist, FromDef, FromId)
be found. be found.
??? ???
*/ */
vis = ForwModule(FromDef, FromId); ForwModule(FromDef, FromId);
forwflag = 1; /* Fall through */
break;
case D_FORWMODULE: case D_FORWMODULE:
vis = FromDef->for_vis; EnterImportList(idlist, 1, FromDef->for_vis->sc_scope);
forwflag = 1; return;
break;
case D_MODULE: case D_MODULE:
vis = FromDef->mod_vis; sc = FromDef->mod_vis->sc_scope;
if (vis == CurrVis) { if (sc == CurrentScope) {
node_error(FromId, "cannot import from current module \"%s\"", module_name); node_error(FromId, "cannot import from current module \"%s\"", module_name);
return; return;
} }
@ -459,15 +488,14 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
} }
for (; idlist; idlist = idlist->nd_left) { for (; idlist; idlist = idlist->nd_left) {
if (forwflag) df = ForwDef(idlist, vis->sc_scope); if (! (df = lookup(idlist->nd_IDF, sc, 0, 0))) {
else if (! (df = lookup(idlist->nd_IDF, vis->sc_scope, 0, 0))) {
if (! is_anon_idf(idlist->nd_IDF)) { if (! is_anon_idf(idlist->nd_IDF)) {
node_error(idlist, node_error(idlist,
"identifier \"%s\" not declared in module \"%s\"", "identifier \"%s\" not declared in module \"%s\"",
idlist->nd_IDF->id_text, idlist->nd_IDF->id_text,
module_name); module_name);
} }
df = define(idlist->nd_IDF,vis->sc_scope,D_ERROR); df = define(idlist->nd_IDF,sc,D_ERROR);
} }
else if (! (df->df_flags & (D_EXPORTED|D_QEXPORTED))) { else if (! (df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
node_error(idlist, node_error(idlist,
@ -476,20 +504,20 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
module_name); module_name);
df->df_flags |= D_QEXPORTED; df->df_flags |= D_QEXPORTED;
} }
if (! DoImport(df, CurrentScope)) assert(0); if (! DoImport(df, CurrentScope, 0)) assert(0);
} }
if (!forwflag) FreeNode(FromId); FreeNode(FromId);
} }
EnterImportList(idlist, local) EnterImportList(idlist, local, sc)
register t_node *idlist; register t_node *idlist;
t_scope *sc;
{ {
/* Import "idlist" from the enclosing scope. /* Import "idlist" from scope "sc".
If the import is not local, definition modules must be read If the import is not local, definition modules must be read
for "idlist". for "idlist".
*/ */
t_scope *sc = enclosing(CurrVis)->sc_scope;
extern t_def *GetDefinitionModule(); extern t_def *GetDefinitionModule();
struct f_info f; struct f_info f;
@ -499,7 +527,7 @@ EnterImportList(idlist, local)
if (! DoImport(local ? if (! DoImport(local ?
ForwDef(idlist, sc) : ForwDef(idlist, sc) :
GetDefinitionModule(idlist->nd_IDF, 1), GetDefinitionModule(idlist->nd_IDF, 1),
CurrentScope)) assert(0); CurrentScope, 0)) assert(0);
file_info = f; file_info = f;
} }
} }

View file

@ -116,7 +116,9 @@ import(int local;)
{ if (FromId) { { if (FromId) {
EnterFromImportList(ImportList, df, FromId); EnterFromImportList(ImportList, df, FromId);
} }
else EnterImportList(ImportList, local); else EnterImportList(ImportList,
local,
enclosing(CurrVis)->sc_scope);
FreeNode(ImportList); FreeNode(ImportList);
} }
; ;

View file

@ -637,7 +637,12 @@ DeclareType(nd, df, tp)
df->df_idf->id_text); df->df_idf->id_text);
} }
} }
else df->df_type = tp; else {
df->df_type = tp;
if (BaseType(tp)->tp_fund == T_ENUMERATION) {
CheckForImports(df);
}
}
} }
t_type * t_type *