newer version
authorceriel <none@none>
Sat, 12 Apr 1986 02:21:24 +0000 (02:21 +0000)
committerceriel <none@none>
Sat, 12 Apr 1986 02:21:24 +0000 (02:21 +0000)
lang/m2/comp/declar.g
lang/m2/comp/def.H
lang/m2/comp/def.c
lang/m2/comp/expression.g
lang/m2/comp/node.c
lang/m2/comp/program.g
lang/m2/comp/scope.C
lang/m2/comp/scope.h

index 857f35c..0624458 100644 (file)
@@ -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,
index 30fc1b4..35f7579 100644 (file)
@@ -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;
 };
index d8888c6..c47b321 100644 (file)
@@ -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;
        }
 }
 
index 60c33ca..dfe210b 100644 (file)
@@ -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);
index 35cd416..e852541 100644 (file)
@@ -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);
index 0cca090..3ff352b 100644 (file)
@@ -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);
                        }
        '.'
index 5162923..e7a0fcf 100644 (file)
@@ -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);
                }
index c8e6d9c..e009ccf 100644 (file)
@@ -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;