mods to handle forward references better
This commit is contained in:
parent
fa9e4c5ea3
commit
74c779b81e
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
Loading…
Reference in a new issue