fixed some problems:
authorceriel <none@none>
Tue, 15 Nov 1988 14:45:59 +0000 (14:45 +0000)
committerceriel <none@none>
Tue, 15 Nov 1988 14:45:59 +0000 (14:45 +0000)
- removed null-reference in illegal use of pointers in constant expressions
- FOR-loops that count downwards did not work
- POINTER TO mechanism changed; works better now

lang/m2/comp/chk_expr.c
lang/m2/comp/def.H
lang/m2/comp/def.c
lang/m2/comp/enter.c
lang/m2/comp/program.g
lang/m2/comp/scope.C
lang/m2/comp/type.c
lang/m2/comp/walk.c

index a5c8916..68f755f 100644 (file)
@@ -161,7 +161,8 @@ ChkArrow(expp)
                return ex_error(expp, "illegal operand type");
        }
 
-       expp->nd_type = RemoveEqual(PointedtoType(tp));
+       if ((tp = RemoveEqual(PointedtoType(tp))) == 0) tp = error_type;
+       expp->nd_type = tp;
        return 1;
 }
 
index b9c4903..0b93ce6 100644 (file)
@@ -71,7 +71,9 @@ struct dforward {
 
 struct forwtype {
        struct node *f_node;
+       struct def *f_def;
 #define df_forw_node   df_value.df_fortype.f_node
+#define df_forw_def    df_value.df_fortype.f_def
 };
 
 struct def     {               /* list of definitions for a name */
@@ -94,14 +96,13 @@ struct def  {               /* list of definitions for a name */
 #define D_FORWARD      0x0400  /* not yet defined */
 #define D_FORWMODULE   0x0800  /* module must be declared later */
 #define D_FORWTYPE     0x1000  /* forward type */
-#define D_FTYPE                0x2000  /* resolved forward type */
 #define D_ERROR                0x4000  /* a compiler generated definition for an
                                   undefined variable
                                */
 #define D_INUSE                0x8000  /* identification in this scope (like D_IMPORT)
                                */
 #define D_VALUE        (D_PROCEDURE|D_VARIABLE|D_FIELD|D_ENUM|D_CONST|D_PROCHEAD)
-#define D_ISTYPE       (D_HIDDEN|D_TYPE|D_FTYPE)
+#define D_ISTYPE       (D_HIDDEN|D_TYPE)
 #define D_IMPORTED     (D_IMPORT|D_INUSE)
 #define is_type(dfx)   ((dfx)->df_kind & D_ISTYPE)
        unsigned short  df_flags;
index dd92ef7..260f2c5 100644 (file)
@@ -157,10 +157,7 @@ define(id, scope, kind)
                        if (kind == D_FORWTYPE) return df;
                        break;
                case D_FORWTYPE:
-                       if (kind == D_FORWTYPE) return df;
-                       if (kind == D_TYPE) {
-                               df->df_kind = D_FTYPE;
-                       }
+                       if (kind & (D_FORWTYPE|D_TYPE)) return df;
                        else {
                                error("identifier \"%s\" must be a type",
                                        id->id_text);
index cca0e24..6994d41 100644 (file)
@@ -251,8 +251,7 @@ ImportEffects(idef, scope, flag)
        }
 
        tp = BaseType(df->df_type);
-       if ((df->df_kind & (D_TYPE|D_FTYPE)) &&
-           tp->tp_fund == T_ENUMERATION) {
+       if (df->df_kind == D_TYPE && tp->tp_fund == T_ENUMERATION) {
                /* Also import all enumeration literals
                */
                for (df = tp->enm_enums; df; df = df->enm_next) {
@@ -416,7 +415,7 @@ EnterExportList(Idlist, qualified)
                                        continue;
                                }
                                if (df1->df_kind == D_HIDDEN &&
-                                   (df2->df_kind & (D_TYPE|D_FTYPE))) {
+                                   df2->df_kind == D_TYPE) {
                                        DeclareType(idlist, df1, df2->df_type);
                                        df1->df_kind = D_TYPE;
                                        continue;
index b2d85a3..1e98a3e 100644 (file)
@@ -189,6 +189,7 @@ definition
        [ %persistent
          IDENT         { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
          [ '=' type(&(df->df_type))
+                       { SolveForwardTypeRefs(df); }
          | /* empty */
            /*
               Here, the exported type has a hidden implementation.
index fcd976c..5ca972a 100644 (file)
@@ -109,34 +109,10 @@ chk_forw(pdf)
 
        while (df = *pdf) {
                if (df->df_kind == D_FORWTYPE) {
-                       register t_def *df1 = df;
-                       register t_node *nd = df->df_forw_node;
-
-                       *pdf = df->df_nextinscope;
-                       RemoveFromIdList(df);
-                       df = lookfor(nd, CurrVis, 1, 0);
-                       if (! df->df_kind & (D_ERROR|D_FTYPE|D_TYPE)) {
-node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
-                       }
-                       while (nd) {
-                               nd->nd_type->tp_next = df->df_type;
-                               nd = nd->nd_right;
-                       }
-                       FreeNode(df1->df_forw_node);
-                       free_def(df1);
+                       ForceForwardTypeDef(df);        /* removes df */
                        continue;
                }
-               else if (df->df_kind == D_FTYPE) {
-                       register t_node *nd = df->df_forw_node;
-
-                       df->df_kind = D_TYPE;
-                       while (nd) {
-                               nd->nd_type->tp_next = df->df_type;
-                               nd = nd->nd_right;
-                       }
-                       FreeNode(df->df_forw_node);
-               }
-               else if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
+               if (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!
index 6a78627..265ce7f 100644 (file)
@@ -269,7 +269,11 @@ node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text);
                        }
                        FreeNode(nd);
                        if (df->df_kind == D_FORWTYPE) {
-                               df->df_kind = D_FTYPE;
+                               /*      Here, df->df_type was already set,
+                                       so there is an actual definition in the
+                                       surrounding scope, which is now used.
+                               */
+                               ForceForwardTypeDef(df);
                        }
                        return df->df_type;
                }
@@ -646,6 +650,58 @@ DeclareType(nd, df, tp)
                        CheckForImports(df);
                }
        }
+
+       SolveForwardTypeRefs(df);
+}
+
+SolveForwardTypeRefs(df)
+       register t_def *df;
+{
+       register t_node *nd;
+
+       if (df->df_kind == D_FORWTYPE) {
+               nd = df->df_forw_node;
+
+               df->df_kind = D_TYPE;
+               while (nd) {
+                       nd->nd_type->tp_next = df->df_type;
+                       nd = nd->nd_right;
+               }
+               FreeNode(df->df_forw_node);
+       }
+}
+
+
+ForceForwardTypeDef(df)
+       register t_def *df;
+{
+       register t_def *df1 = df, *df2;
+       register t_node *nd = df->df_forw_node;
+
+       while (df && df->df_kind == D_FORWTYPE) {
+               RemoveFromIdList(df);
+               if ((df2 = df->df_scope->sc_def) == df) {
+                       df->df_scope->sc_def = df->df_nextinscope;
+               }
+               else {
+                       while (df2->df_nextinscope != df) {
+                               df2 = df2->df_nextinscope;
+                       }
+                       df2->df_nextinscope = df->df_nextinscope;
+               }
+               df = df->df_forw_def;
+       }
+       df = lookfor(nd, CurrVis, 1, 0);
+       if (! df->df_kind & (D_ERROR|D_TYPE)) {
+               node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
+       }
+       while (df1 && df1->df_kind == D_FORWTYPE) {
+               t_def *df2 = df1->df_forw_def;
+               df1->df_type = df->df_type;
+               SolveForwardTypeRefs(df1);
+               free_def(df1);
+               df1 = df2;
+       }
 }
 
 t_type *
@@ -686,6 +742,8 @@ type_or_forward(ptp)
                   existing compilers do it like this, and the
                   alternative is difficult with a lookahead of only
                   one token.
+                  This path should actually only be taken if the next token
+                  is a '.'.
                   ???
                */
                FreeNode(nd);
@@ -697,17 +755,17 @@ type_or_forward(ptp)
                same scope.
        */
        df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE);
+       assert(df->df_kind == D_FORWTYPE);
        df->df_flags |= D_USED | D_DEFINED;
-
-       if (df->df_kind == D_TYPE) {
-               (*ptp)->tp_next = df->df_type;
-               FreeNode(nd);
-               return 0;
-       }
        nd->nd_type = *ptp;
        df->df_forw_node = nd;
-       if (df1->df_kind == D_TYPE) {
+       if (df != df1 && (df1->df_kind & (D_TYPE | D_FORWTYPE))) {
+               /*      "df1" refers to a possible identification, but
+                       we cannot be sure at this point. For the time
+                       being, however, we use this one.
+               */
                df->df_type = df1->df_type;
+               df->df_forw_def = df1;
        }
        return 0;
 }
index 28a52f8..29f2ec4 100644 (file)
@@ -552,8 +552,10 @@ WalkStat(nd, exit_label)
                                C_lol(tmp);
                                if (uns) C_cmu(int_size);
                                else C_cmi(int_size);
-                               C_zgt(l2);
+                               if (left->nd_INT >= 0) C_zgt(l2);
+                               else C_zlt(l2);
                                C_lol(tmp2);
+                               RangeCheck(nd->nd_type, left->nd_left->nd_type);
                                CodeDStore(nd);
                                C_lol(tmp);
                                ForLoopVarExpr(nd);
@@ -736,6 +738,7 @@ DoForInit(nd)
 {
        register t_node *left = nd->nd_left;
        register t_def *df;
+       register t_type *base_tp;
        t_type *tpl, *tpr;
 
        nd->nd_left = nd->nd_right = 0;
@@ -778,12 +781,13 @@ DoForInit(nd)
                return 1;
        }
 
+       base_tp = BaseType(df->df_type);
        tpl = left->nd_left->nd_type;
        tpr = left->nd_right->nd_type;
 #ifndef STRICT_3RD_ED
        if (! options['3']) {
-         if (!ChkAssCompat(&(left->nd_left), df->df_type, "FOR statement") ||
-             !ChkAssCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) {
+         if (!ChkAssCompat(&(left->nd_left), base_tp, "FOR statement") ||
+             !ChkAssCompat(&(left->nd_right), base_tp, "FOR statement")) {
                return 1;
          }
          if (!TstCompat(df->df_type, tpl) ||
@@ -792,8 +796,8 @@ node_warning(nd, W_OLDFASHIONED, "compatibility required in FOR statement");
          }
        } else
 #endif
-       if (!ChkCompat(&(left->nd_left), df->df_type, "FOR statement") ||
-           !ChkCompat(&(left->nd_right), BaseType(df->df_type), "FOR statement")) {
+       if (!ChkCompat(&(left->nd_left), base_tp, "FOR statement") ||
+           !ChkCompat(&(left->nd_right), base_tp, "FOR statement")) {
                return 1;
        }