From: ceriel Date: Sat, 12 Apr 1986 02:21:24 +0000 (+0000) Subject: newer version X-Git-Tag: release-5-5~5309 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=7d76f2829a34c9ae2d72ecd31eabef3d98086026;p=ack.git newer version --- diff --git a/lang/m2/comp/declar.g b/lang/m2/comp/declar.g index 857f35c06..062445836 100644 --- a/lang/m2/comp/declar.g +++ b/lang/m2/comp/declar.g @@ -24,7 +24,7 @@ ProcedureDeclaration ';' block IDENT { match_id(dot.TOK_IDF, df->df_idf); df->prc_scope = CurrentScope->sc_scope; - close_scope(); + close_scope(SC_CHKFORW); } ; @@ -39,6 +39,7 @@ ProcedureHeading(struct def **pdf; int type;) { 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, diff --git a/lang/m2/comp/def.H b/lang/m2/comp/def.H index 30fc1b497..35f75794f 100644 --- a/lang/m2/comp/def.H +++ b/lang/m2/comp/def.H @@ -43,12 +43,15 @@ struct dfproc { }; 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 */ @@ -92,6 +95,7 @@ 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; }; diff --git a/lang/m2/comp/def.c b/lang/m2/comp/def.c index d8888c66a..c47b32189 100644 --- a/lang/m2/comp/def.c +++ b/lang/m2/comp/def.c @@ -61,13 +61,23 @@ define(id, scope, kind) } 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; } @@ -77,11 +87,11 @@ error("identifier \"%s\" already declared", id->id_text); 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 */ @@ -100,30 +110,17 @@ lookup(id, 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) { @@ -131,7 +128,7 @@ lookup(id, scope) df->next = id->id_def; id->id_def = df; } - return df; + return retval; } df1 = df; df = df->next; @@ -148,9 +145,19 @@ Export(ids, qualified) 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; } @@ -175,6 +182,7 @@ Export(ids, qualified) } ids = ids->next; } + FreeNode(nd); } Import(ids, idn, local) @@ -195,6 +203,7 @@ Import(ids, idn, local) identifiers defined in this module. */ register struct def *df; + struct def *df1 = 0; int scope; int kind; int imp_kind; @@ -204,7 +213,8 @@ Import(ids, idn, local) 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) { @@ -217,25 +227,39 @@ Import(ids, idn, 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", @@ -250,13 +274,18 @@ ids->nd_IDF->id_text); 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) { @@ -266,6 +295,7 @@ ids->nd_IDF->id_text); } ids = ids->next; } + FreeNode(idn); } exprt_literals(df, toscope) @@ -290,26 +320,18 @@ RemImports(pdf) 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; } } diff --git a/lang/m2/comp/expression.g b/lang/m2/comp/expression.g index 60c33ca2f..dfe210ba8 100644 --- a/lang/m2/comp/expression.g +++ b/lang/m2/comp/expression.g @@ -49,8 +49,12 @@ qualident(int types; struct def **pdf; char *str; struct node **p;) 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); diff --git a/lang/m2/comp/node.c b/lang/m2/comp/node.c index 35cd416d0..e852541eb 100644 --- a/lang/m2/comp/node.c +++ b/lang/m2/comp/node.c @@ -38,6 +38,7 @@ 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); diff --git a/lang/m2/comp/program.g b/lang/m2/comp/program.g index 0cca0902d..3ff352b20 100644 --- a/lang/m2/comp/program.g +++ b/lang/m2/comp/program.g @@ -15,7 +15,11 @@ static char *RcsId = "$Header$"; #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; } /* @@ -45,8 +49,11 @@ ModuleDeclaration 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; @@ -55,7 +62,7 @@ ModuleDeclaration import(1)* export(0)? block - IDENT { close_scope(); + IDENT { close_scope(SC_CHKFORW|SC_CHKPROC); match_id(id, dot.TOK_IDF); } ; @@ -78,9 +85,13 @@ export(int def;) ]? 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); + } } ; @@ -101,8 +112,6 @@ import(int local;) */ { Import(ImportList, id, local); - FreeNode(ImportList); - if (id) FreeNode(id); } ; @@ -130,7 +139,7 @@ DefinitionModule */ definition* END IDENT { - if (id == impl_name) { + if (DEFofIMPL) { /* Just read the definition module of the implementation module being compiled */ @@ -143,7 +152,7 @@ DefinitionModule 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); } @@ -185,9 +194,10 @@ ProgramModule(int state;) 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); @@ -196,7 +206,7 @@ ProgramModule(int state;) priority? ';' import(0)* block IDENT - { close_scope(); + { close_scope(SC_CHKFORW|SC_CHKPROC); match_id(id, dot.TOK_IDF); } '.' diff --git a/lang/m2/comp/scope.C b/lang/m2/comp/scope.C index 5162923a0..e7a0fcf74 100644 --- a/lang/m2/comp/scope.C +++ b/lang/m2/comp/scope.C @@ -92,21 +92,73 @@ Forward(tk, ptp) 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 @@ -121,7 +173,7 @@ rem_forwards(fo) 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); } diff --git a/lang/m2/comp/scope.h b/lang/m2/comp/scope.h index c8e6d9c92..e009ccf7a 100644 --- a/lang/m2/comp/scope.h +++ b/lang/m2/comp/scope.h @@ -5,6 +5,13 @@ #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;