fixed int to unsigned conversions, declarations, pp-list initialization
authoreck <none@none>
Fri, 13 Jul 1990 10:18:27 +0000 (10:18 +0000)
committereck <none@none>
Fri, 13 Jul 1990 10:18:27 +0000 (10:18 +0000)
lang/cem/cemcom.ansi/LLlex.c
lang/cem/cemcom.ansi/conversion.c
lang/cem/cemcom.ansi/declar.g
lang/cem/cemcom.ansi/decspecs.c
lang/cem/cemcom.ansi/decspecs.str
lang/cem/cemcom.ansi/options.c
lang/cem/cemcom.ansi/tokenname.c
lang/cem/cemcom.ansi/type.c

index a0fe5e7..14838cb 100644 (file)
@@ -342,10 +342,11 @@ garbage:
                }
 #endif NOPP
                ptok->tk_symb = (
-                       idef->id_reserved ? idef->id_reserved
-                       : idef->id_def && idef->id_def->df_sc == TYPEDEF ?
-                               TYPE_IDENTIFIER
-                       : IDENTIFIER
+                       idef->id_reserved
+                           ? idef->id_reserved
+                           : idef->id_def && idef->id_def->df_sc == TYPEDEF
+                               ? TYPE_IDENTIFIER
+                               : IDENTIFIER
                );
                return IDENTIFIER;
        }
index 9344984..22e8691 100644 (file)
@@ -56,6 +56,14 @@ conversion(from_type, to_type)
                                C_cii();
                                from_size = word_size;
                        }
+                       /* 3.2.1.2 */
+                       if (to_cnvtype == T_UNSIGNED
+                           && (int)from_size < (int)to_size) {
+                               C_loc(from_size);
+                               C_loc(to_size);
+                               C_cii();
+                               from_size = to_size;
+                       }
                        C_loc(from_size);
                        C_loc(to_size);
                        if (to_cnvtype == T_UNSIGNED) C_ciu();
index 92c8bae..4848cbb 100644 (file)
@@ -67,28 +67,43 @@ declaration
                short typedef yepp;
        makes all hope of writing a specific grammar for typedefs illusory.
 */
+/*     We do not accept the whole of the grammar, since when we see
+       something like 'unsigned plain' (where plain is a typedef) is
+       illegal if 'plain' is a typedef.  Therefore, we assume that
+       'plain' is the identifier of a declarator.  Unfortunately, this
+       causes declarations like 'unsigned plain x;' to be rejected on the
+       grounds of syntax, even though it is syntactically right.  This may
+       cause a lot of extra messages.
+       To do this, decl_specifiers is divided into:
+       1: normal specifiers == storage class specifiers + type_qualifiers
+       2: special specifiers == short + long + signed + unsigned
+       3: basic types == void + char + int + float + double
+       4: single type specifiers == struct or union specifiers
+                                   + enum specifiers + typedef names
 
+ */
 decl_specifiers        /* non-empty */ (register struct decspecs *ds;)
        /*      Reads a non-empty decl_specifiers and fills the struct
                decspecs *ds.
        */
 :
-[
-       other_specifier(ds)+
-       [%if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
-               /* the thin ice in R.M. 11.1 */
-               single_type_specifier(ds) other_specifier(ds)*
-       |
-               empty
-       ]
+[ %if (AHEAD == IDENTIFIER)                    /* like: register i; */
+       normal_specifier(ds)
 |
-       single_type_specifier(ds) other_specifier(ds)*
+       normal_specifier(ds)*
+       [       special_specifier(ds)
+       |       basic_type(ds)
+       |       single_type_specifier(ds)
+       ]
+       [       normal_specifier(ds)
+       |       special_specifier(ds)
+       |       basic_type(ds)
+       ]*
 ]
        {do_decspecs(ds);}
 ;
 
-/* 3.5.1 & 3.5.2 (partially) & 3.5.3 (partially) */
-other_specifier(register struct decspecs *ds;)
+normal_specifier(register struct decspecs *ds;)
 :
        [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
        {       if (ds->ds_sc_given)
@@ -96,18 +111,6 @@ other_specifier(register struct decspecs *ds;)
                ds->ds_sc_given = 1;
                ds->ds_sc = DOT;
        }
-|
-       [ SHORT | LONG ]
-       {       if (ds->ds_size)
-                       error("repeated size specifier");
-               ds->ds_size = DOT;
-       }
-|
-       [ SIGNED | UNSIGNED ]
-       {       if (ds->ds_unsigned != 0)
-                       error("repeated sign specifier");
-               ds->ds_unsigned = DOT;
-       }
 |
        /*      This qualifier applies to the top type.
                E.g. volatile float * is a pointer to volatile float.
@@ -129,6 +132,21 @@ other_specifier(register struct decspecs *ds;)
        }
 ;
 
+special_specifier(register struct decspecs *ds;)
+:
+       [ SHORT | LONG ]
+       {       if (ds->ds_size)
+                       error("repeated size specifier");
+               ds->ds_size = DOT;
+       }
+|
+       [ SIGNED | UNSIGNED ]
+       {       if (ds->ds_unsigned != 0)
+                       error("repeated sign specifier");
+               ds->ds_unsigned = DOT;
+       }
+;
+
 /* 3.5.2 */
 type_specifier(struct type **tpp;)
        /*      Used in struct/union declarations and in casts; only the
@@ -146,9 +164,20 @@ type_specifier(struct type **tpp;)
        {*tpp = Ds.ds_type;}
 ;
 
+basic_type(register struct decspecs *ds;):
+       [ VOID | CHAR | INT | FLOAT | DOUBLE ]
+       {
+               idf2type(dot.tk_idf, &ds->ds_type);
+               ds->ds_typedef = 0;
+       }
+;
+
 single_type_specifier(register struct decspecs *ds;):
        %default TYPE_IDENTIFIER        /* this includes INT, CHAR, etc. */
-       {idf2type(dot.tk_idf, &ds->ds_type);}
+       {
+               idf2type(dot.tk_idf, &ds->ds_type);
+               ds->ds_typedef = 1;
+       }
 |
        IDENTIFIER
        {
@@ -283,7 +312,7 @@ declarator(register struct declarator *dc;)
                |
                        formal_list(&fm)
                |
-                       empty
+                       /* empty */
                ]
                ')'
                {       add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
@@ -308,6 +337,7 @@ arrayer(arith *sizep;)
        { struct expr *expr; }
 :
        '['
+               { *sizep = (arith)-1; }
                [
                        constant_expression(&expr)
                        {
@@ -315,10 +345,7 @@ arrayer(arith *sizep;)
                                *sizep = expr->VL_VALUE;
                                free_expression(expr);
                        }
-               |
-                       empty
-                       { *sizep = (arith)-1; }
-               ]
+               ]?
        ']'
 ;
 
@@ -358,7 +385,7 @@ enum_specifier(register struct type **tpp;)
                        enumerator_pack(*tpp, &l)
                |
                        {apply_struct(ENUM, idf, tpp);}
-                       empty
+                       /* empty */
                ]
        ]
 ;
@@ -433,7 +460,7 @@ struct_or_union_specifier(register struct type **tpp;)
                          if (DOT == ';') declare_struct(fund, idf, tpp);
                          else apply_struct(fund, idf, tpp);
                        }
-                       empty
+                       /* empty */
                ]
        ]
 ;
@@ -533,7 +560,7 @@ abstract_declarator(register struct declarator *dc;)
                [
                        parameter_type_list(&pl)
                |
-                       empty
+                       /* empty */
                ]
                ')'
                {add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);}
@@ -551,7 +578,7 @@ abstract_declarator(register struct declarator *dc;)
 primary_abstract_declarator(struct declarator *dc;)
 :
 [%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
-       empty
+       /* empty */
 |
        '(' abstract_declarator(dc) ')'
 ]
@@ -663,7 +690,7 @@ primary_parameter_declarator(register struct declarator *dc;)
 :
 [%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
                                    && (AHEAD != IDENTIFIER))
-       empty
+       /* empty */
 |
        identifier(&dc->dc_idf)
 |
index c3944dd..167ea2b 100644 (file)
@@ -71,62 +71,42 @@ do_decspecs(ds)
                ds->ds_notypegiven = 1;
                tp = int_type;
        }
-       switch (ds->ds_size)    {
-       case SHORT:
-               if (tp == int_type)
-                       tp = short_type;
-               else
-                       error("short with illegal type");
-               break;
-       case LONG:
-               if (tp == int_type)
-                       tp = long_type;
-               else
-               if (tp == double_type)
+       if (ds->ds_size) {
+               register int ds_isshort = (ds->ds_size == SHORT);
+
+               if (ds->ds_typedef) goto SIZE_ERROR;            /* yes */
+               if (tp == int_type) {
+                       if (ds_isshort) tp = short_type;
+                       else tp = long_type;
+               } else if (tp == double_type && !ds_isshort ) {
                        tp = lngdbl_type;
-               else
-                       error("long with illegal type");
-               break;
-       }
-       if (ds->ds_unsigned == UNSIGNED) {
-               switch (tp->tp_fund)    {
-               case CHAR:
-                       tp = uchar_type;
-                       break;
-               case SHORT:
-                       tp = ushort_type;
-                       break;
-               case INT:
-                       tp = uint_type;
-                       break;
-               case LONG:
-                       tp = ulong_type;
-                       break;
-               default:
-                       error("unsigned with illegal type");
-                       break;
+               } else {
+       SIZE_ERROR:
+                       error("%s with illegal type",symbol2str(ds->ds_size));
                }
        }
-       if (ds->ds_unsigned == SIGNED) {
-               switch (tp->tp_fund) {
-               case CHAR:
-                       tp = schar_type;
-                       break;
-               case SHORT:
-                       tp = short_type;
-                       break;
-               case INT:
-                       tp = int_type;
-                       break;
-               case LONG:
-                       tp = long_type;
-                       break;
-               default:
-                       error("signed with illegal type");
-                       break;
+       if (ds->ds_unsigned) {
+               register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED);
+
+               if (ds->ds_typedef) goto SIGN_ERROR;            /* yes */
+               /*
+                * All integral types are signed by default (char too),
+                * so the case that ds->ds_unsigned == SIGNED can be ignored.
+                */
+               if (tp == schar_type) {
+                       if (ds_isunsigned) tp = uchar_type;
+               } else if (tp == short_type) {
+                       if (ds_isunsigned) tp = ushort_type;
+               } else if (tp == int_type) {
+                       if (ds_isunsigned) tp = uint_type;
+               } else if (tp == long_type) {
+                       if (ds_isunsigned) tp = ulong_type;
+               } else {
+       SIGN_ERROR:
+                       error("%s with illegal type"
+                               , symbol2str(ds->ds_unsigned));
                }
        }
-
        ds->ds_type = qualifier_type(tp, ds->ds_typequal);
 }
 
index 59bc24f..0895f97 100644 (file)
@@ -9,6 +9,7 @@ struct decspecs {
        struct decspecs *next;
        struct type *ds_type;   /* single type */
        int ds_notypegiven;     /* set if type not given explicitly */
+       int ds_typedef;         /* 1 if type was a user typedef */
        int ds_sc_given;        /* 1 if the st. class is explicitly given */
        int ds_sc;              /* storage class, given or implied */
        int ds_size;            /* LONG, SHORT or 0 */
index bef33f2..0e9b135 100644 (file)
@@ -175,21 +175,14 @@ deleted, is now a debug-flag
                        register char *new = text;
                        
                        if (++inc_total > inc_max) {
-                               char **n = (char **)
-                                  Malloc((10+inc_max)*sizeof(char *));
-                               for (i = 0; i < inc_max; i++) {
-                                       n[i] = inctable[i];
-                               }
-                               free((char *) inctable);
-                               inctable = n;
-                               inc_max += 10;
+                               inctable = (char **)
+                                  Realloc(inctable,(inc_max+=10)*sizeof(char *));
                        }
                                
-                       i = inc_pos++;
-                       while (new)     {
+                       for (i = inc_pos++; i<= inc_total ; i++) {
                                char *tmp = inctable[i];
                                
-                               inctable[i++] = new;
+                               inctable[i] = new;
                                new = tmp;
                        }
                }
index 1610f6b..ffaa488 100644 (file)
@@ -91,18 +91,26 @@ struct tokenname tkidf[] =  {       /* names of the identifier tokens */
        {UNSIGNED, "unsigned"},
        {VOLATILE, "volatile"},
        {WHILE, "while"},
-       {0, ""}
-};
 
-#ifdef ____
-struct tokenname tkfunny[] =   {       /* internal keywords */
+       {VOID, "void"},
        {CHAR, "char"},
        {INT, "int"},
        {FLOAT, "float"},
        {DOUBLE, "double"},
+       {0, ""}
+};
+
+#ifdef ____
+struct tokenname tkfunny[] =   {       /* internal keywords */
+/* The following may be removed after testing:
+       {Q_VOID, "void"},
+       {Q_CHAR, "char"},
+       {Q_INT, "int"},
+       {Q_FLOAT, "float"},
+       {Q_DOUBLE, "double"},
+*/
        {LNGDBL, "long double"},
        {ULONG, "unsigned long"},
-       {VOID, "void"},
 
        {ARRAY, "array"},
        {FUNCTION, "function"},
index 2081661..d29b8f9 100644 (file)
@@ -249,13 +249,14 @@ idf2type(idf, tpp)
        struct idf *idf;
        struct type **tpp;
 {
-       /*      Decoding  a typedef-ed identifier: if the size is yet
-               unknown we have to make copy of the type descriptor to
-               prevent garbage at the initialisation of arrays with
-               unknown size.
+       /*      Decoding  a typedef-ed identifier or basic type: if the
+               size is yet unknown we have to make copy of the type
+               descriptor to prevent garbage at the initialisation of
+               arrays with unknown size.
        */
        register struct type *tp = idf->id_def->df_type;
 
+       if (*tpp) error("multiple types in declaration");
        if (    tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) {
                *tpp = new_type();
                **tpp = *tp;