fixed several problems:
authorceriel <none@none>
Tue, 7 Feb 1989 13:16:02 +0000 (13:16 +0000)
committerceriel <none@none>
Tue, 7 Feb 1989 13:16:02 +0000 (13:16 +0000)
- hex numbers and floating point numbers were wrong
- grammar was wrong; did not accept correct ANSI C
- prototype updates did not work
- float parameters to routines without prototype were not upgraded to double
- the dot operator no longer requires lvalue as left-hand-side

lang/cem/cemcom.ansi/LLlex.c
lang/cem/cemcom.ansi/Makefile
lang/cem/cemcom.ansi/arith.c
lang/cem/cemcom.ansi/ch7.c
lang/cem/cemcom.ansi/declar.g
lang/cem/cemcom.ansi/eval.c
lang/cem/cemcom.ansi/idf.c
lang/cem/cemcom.ansi/program.g
lang/cem/cemcom.ansi/proto.c

index 592bf04..0064f67 100644 (file)
@@ -349,10 +349,10 @@ firstline:
                                floating point number or field operator or
                                ELLIPSIS.
                        */
-                       ch = GetChar();
-                       if (!is_dig(ch)) {      /* . or ... */
-                               if (ch == '.') {
-                                       if ((ch = GetChar()) == '.')
+                       vch = GetChar();
+                       if (!is_dig(vch)) {     /* . or ... */
+                               if (vch == '.') {
+                                       if ((vch = GetChar()) == '.')
                                                return ptok->tk_symb = ELLIPSIS;
                                        /* This is funny: we can't push the
                                           second dot back. But then again
@@ -364,12 +364,12 @@ firstline:
                                }
                                UnGetChar();
                                return ptok->tk_symb = '.';
-                       } else
-                               *np++ = '0';
+                       }
+                       *np++ = '0';
                        UnGetChar();
 #else
-                       if ((ch = GetChar()) == '.') {
-                               if ((ch = GetChar()) == '.')
+                       if ((vch = GetChar()) == '.') {
+                               if ((vch = GetChar()) == '.')
                                        return ptok->tk_symb = ELLIPSIS;
                                UnGetChar();
                                lexerror("illegal combination '..'");
@@ -693,6 +693,7 @@ val_in_base(ch, base)
        case 8:
                return (is_dig(ch) && ch < '9') ? ch - '0' : -1;
        case 10:
+               return is_dig(ch) ? ch - '0' : -1;
        case 16:
                return is_dig(ch) ? ch - '0'
                        : is_hex(ch) ? (ch - 'a' + 10) & 017
index 5c131d1..fa9ee59 100644 (file)
@@ -4,8 +4,8 @@
 # Machine and environ dependent definitions
 EMHOME = ../../..
 CC = /proj/em/Work/bin/fcc.cc
+CC = cc
 CFLOW = cflow
-MAKE = make
 MKDEP = $(EMHOME)/bin/mkdep
 PRID = $(EMHOME)/bin/prid
 CID = $(EMHOME)/bin/cid
@@ -55,7 +55,7 @@ COPTIONS =
 
 # What parser generator to use and how
 GEN = $(EMHOME)/bin/LLgen
-GENOPTIONS = -v
+GENOPTIONS = -vvvx
 
 # Special #defines during compilation
 PROF = #-pg
@@ -128,8 +128,8 @@ SRC =       $(CSRC) $(LCSRC) $(GCSRC)
 LINT = /usr/bin/lint
 LINTFLAGS =
 
-MYLINT = /usr/star/dick/bin/lint       #../lint
-MYLINTFLAGS = #-xh
+MYLINT = ../lpass2/lint
+MYLINTFLAGS = -xh
 
 #EXCLEXCLEXCLEXCL
 
@@ -159,7 +159,6 @@ CEmain:     Cfiles
 
 Lnt:   Cfiles
        sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) $(CURRDIR)lnt ; else EMHOME=$(EMHOME); export EMHOME; ./Resolve lnt ; fi'
-       make "EMHOME="$(EMHOME) $(CURRDIR)lnt
        @rm -f nmclash.o a.out
 
 install:       Main
@@ -178,7 +177,7 @@ pr:
        @pr Makefile make.* char.tab Parameters $(HSRC) $(STRSRC) $(LSRC) $(CSRC)
 
 opr:
-       $(MAKE) pr | opr
+       make pr | opr
 
 clean:
        rm -f $(OBJ)
@@ -189,11 +188,11 @@ cflow:    Cfiles
        $(CFLOW) $(CDEFS) $(SRC)
 
 lint:  Cfiles
-       sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then $(MAKE) "EMHOME="$(EMHOME) Xlint ; else sh Resolve Xlint ; fi'
+       sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) Xlint ; else sh Resolve Xlint ; fi'
        @rm -f nmclash.o a.out
 
 mylint:        Cfiles
-       sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then $(MAKE) "EMHOME="$(EMHOME) Xmylint ; else sh Resolve Xmylint ; fi'
+       sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) Xmylint ; else sh Resolve Xmylint ; fi'
        @rm -f nmclash.o a.out
 
 longnames:     $(SRC) $(HFILES)
index 470aa20..dbdf564 100644 (file)
@@ -527,6 +527,18 @@ any2opnd(expp, oper)
        }
 }
 
+any2parameter(expp)
+       register struct expr **expp;
+{
+       /*      To handle default argument promotions
+       */
+       any2opnd(expp, '(');
+#ifndef NOFLOAT
+       if ((*expp)->ex_type->tp_fund == FLOAT)
+               float2float(expp, double_type);
+#endif NOFLOAT
+}
+
 #ifndef NOBITFIELD
 field2arith(expp)
        register struct expr **expp;
index cc664ff..57bd94c 100644 (file)
@@ -70,13 +70,6 @@ ch7sel(expp, oper, idf)
                        }
                }
        } /* oper == ARROW */
-       else { /* oper == '.' */
-               /* filter out illegal expressions "non_lvalue.sel" */
-               if (!exp->ex_lvalue) {
-                       expr_error(exp, "dot requires lvalue");
-                       return;
-               }
-       }
        exp = *expp;
        switch (tp->tp_fund)    {
        case POINTER:   /* for int *p;  p->next = ...   */
@@ -126,15 +119,18 @@ ch7sel(expp, oper, idf)
                                if (exp->ex_type == error_type)
                                        exp->ex_flags |= EX_ERROR;
                        }
-                       else
+                       else {
                                exp = new_oper(sd->sd_type, exp, '.',
                                                intexpr(sd->sd_offset, INT));
+                               exp->ex_lvalue = exp->OP_LEFT->ex_lvalue;
+                       }
                }
        }
-       else /* oper == ARROW */
+       else /* oper == ARROW */
                exp = new_oper(sd->sd_type,
                        exp, oper, intexpr(sd->sd_offset, INT));
-       exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
+               exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
+       }
        if (sd->sd_type->tp_typequal & TQ_CONST)
                exp->ex_flags |= EX_READONLY;
        if (sd->sd_type->tp_typequal & TQ_VOLATILE)
index 9af9c95..6395fb4 100644 (file)
@@ -518,9 +518,11 @@ abstract_declarator(register struct declarator *dc;)
        {add_decl_unary(dc, POINTER, qual, (arith)0, NO_PARAMS, NO_PROTO);}
 ;
 
+%first first_of_parameter_type_list, parameter_type_list;
+
 primary_abstract_declarator(struct declarator *dc;)
 :
-[%if (AHEAD == ')')
+[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
        empty
 |
        '(' abstract_declarator(dc) ')'
@@ -609,7 +611,7 @@ parameter_declarator(register struct declarator *dc;)
        primary_parameter_declarator(dc)
        [
                '('
-               [ %if(DOT != IDENTIFIER && DOT != ')')
+               [ %if (DOT != IDENTIFIER)
                        parameter_type_list(&pl)
                |
                        formal_list(&fm)
@@ -629,7 +631,7 @@ parameter_declarator(register struct declarator *dc;)
 
 primary_parameter_declarator(register struct declarator *dc;)
 :
-[ %if(AHEAD == ')')
+[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
        empty
 |
        identifier(&dc->dc_idf)
index a34cb77..0f329de 100644 (file)
@@ -367,15 +367,27 @@ EVAL(expr, val, code, true_label, false_label)
                        }
 #endif NOBITFIELD
                        EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL);
-                       if (gencode)
+                       if (gencode && val == RVAL)
                                C_dup(ATW(tp->tp_size));
                        if (left->ex_class != Value) {
                                EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL);
-                               if (newcode)
+                               if (newcode && gencode && val == LVAL) {
+                                       arith tmp = LocalPtrVar();
+                                       C_dup(pointer_size);
+                                       StoreLocal(tmp, pointer_size);
+                                       store_block(tp->tp_size, tp->tp_align);
+                                       LoadLocal(tmp, pointer_size);
+                                       FreeLocal(tmp);
+                               }
+                               else if (newcode)
                                        store_block(tp->tp_size, tp->tp_align);
                        }
-                       else if (newcode)
+                       else if (newcode) {
                                store_val(&(left->EX_VALUE), left->ex_type);
+                               if (gencode && val == LVAL) {
+                                       EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL);
+                               }
+                       }
                        }
                        break;
                case PLUSAB:
@@ -517,7 +529,8 @@ EVAL(expr, val, code, true_label, false_label)
                        if (gencode) {
                                if (is_struct_or_union(tp->tp_fund)) {
                                        C_lfr(pointer_size);
-                                       load_block(tp->tp_size, (int) word_size);
+                                       if (val == RVAL)
+                                         load_block(tp->tp_size, (int) word_size);
                                }
                                else
                                        C_lfr(ATW(tp->tp_size));
@@ -527,8 +540,13 @@ EVAL(expr, val, code, true_label, false_label)
                case '.':
                        EVAL(left, LVAL, gencode, NO_LABEL, NO_LABEL);
                        ASSERT(is_cp_cst(right));
-                       if (gencode)
+                       if (gencode) {
                                C_adp(right->VL_VALUE);
+                               if (val == RVAL && expr->ex_lvalue == 0) {
+                                       load_block(expr->ex_type->tp_size,
+                                               expr->ex_type->tp_align);
+                               }
+                       }
                        break;
                case ARROW:
                        EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
@@ -553,10 +571,10 @@ EVAL(expr, val, code, true_label, false_label)
 
                        EVAL(left, RVAL, TRUE, l_true, l_false);
                        C_df_ilb(l_true);
-                       EVAL(right->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL);
+                       EVAL(right->OP_LEFT, val, gencode, NO_LABEL, NO_LABEL);
                        C_bra(l_end);
                        C_df_ilb(l_false);
-                       EVAL(right->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL);
+                       EVAL(right->OP_RIGHT, val, gencode, NO_LABEL, NO_LABEL);
                        C_df_ilb(l_end);
                        break;
                }
index 49537a8..9ebd895 100644 (file)
@@ -426,7 +426,7 @@ global_redecl(idf, new_sc, tp)
 
        if (!equal_type(tp, def->df_type))
                error("redeclaration of %s with different type", idf->id_text);
-       update_proto(tp, def->df_type);
+       else update_proto(tp, def->df_type);
        if (tp->tp_fund == ARRAY) {
                /* Multiple array declaration; this may be interesting */
                if (tp->tp_size < 0)    {               /* new decl has [] */
index 658af39..fbee3bc 100644 (file)
@@ -138,7 +138,6 @@ external_definition
                        ';'
                ]
        |
-               empty
                {do_decspecs(&Ds);}
                declarator(&Dc)
                {
index a99bf3b..e3b8626 100644 (file)
@@ -168,7 +168,7 @@ declare_protos(idf, dc)
                                break;
 
                        if (!pl->pl_idf || !(def = pl->pl_idf->id_def)) {
-                               error("no parameter supplied");
+                               error("no parameter identifier supplied");
                                pl = pl->next;
                                continue;
                        }
@@ -221,84 +221,45 @@ update_proto(tp, otp)
        */
        register struct proto *pl, *opl;
 
-#if 0
-       /*      THE FOLLOWING APPROACH IS PRESUMABLY WRONG.
-               THE ONLY THING THIS CODE IS SUPPOSED TO DO
-               IS TO UPDATE THE PROTOTYPELISTS, I HAVEN'T
-               EVEN CONSIDERED THE DISPOSAL OF REDUNDANT
-               SPACE !!.
-               THIS ROUTINE DUMPS CORE. SORRY, BUT IT'S 10
-               P.M. AND I'M SICK AN TIRED OF THIS PROBLEM.
-       */
-       print("Entering\n");
        if (tp == otp) {
-               print("OOPS - they are equal\n");
                return;
        }
        if (!tp || !otp) {
-               print("OOPS - Nil pointers tp=@%o otp=@%o\n", tp, otp);
                return;
        }
 
-       print("Search function\n");
        while (tp && tp->tp_fund != FUNCTION) {
-               if (!(tp->tp_up)) {
-                       print("TP is NIL\n");
-                       return;
-               }
                tp = tp->tp_up;
-               if (!(otp->tp_up)) {
-                       print("OTP is NIL\n");
-                       return;
-               }
                otp = otp->tp_up;
                if (!tp) return;
        }
 
-       print("Do it\n");
        pl = tp->tp_proto;
        opl = otp->tp_proto;
        if (pl && opl) {
                /* both have prototypes */
-               print("Both have proto type\n");
-               print("New proto type list\n");
-               dump_proto(pl);
-               print("Old proto type list\n");
-               dump_proto(opl);
                while (pl && opl) {
                        update_proto(pl->pl_type, opl->pl_type);
                        pl = pl->next;
-                       opl = pl->next;
+                       opl = opl->next;
                }
-               /*free_proto_list(tp->tp_proto);*/
-               tp->tp_proto = otp->tp_proto;
+               free_proto_list(otp->tp_proto);
+               otp->tp_proto = tp->tp_proto;
        } else if (opl) {
                /* old decl has type */
-               print("Old decl has type\n");
-               print("Old proto type list\n");
-               dump_proto(opl);
-               tp->tp_proto = opl;
        } else if (pl) {
                /* new decl has type */
-               print("New decl has type\n");
-               print("New proto type list\n");
-               dump_proto(pl);
-               print("otp = @%o\n", otp);
                otp->tp_proto = pl;
-               print("after assign\n");
-       } else
-               print("none has prototype\n");
+       }
 
-       print("Going for another top type\n");
        update_proto(tp->tp_up, otp->tp_up);
-# endif
 }
 
 free_proto_list(pl)
        register struct proto *pl;
 {
        while (pl) {
-               register struct proto *tmp = pl->next;
+               struct proto *tmp = pl->next;
                free_proto(pl);
                pl = tmp;
        }
@@ -355,6 +316,7 @@ call_proto(expp)
        register struct expr *left = (*expp)->OP_LEFT;
        register struct expr *right = (*expp)->OP_RIGHT;
        register struct proto *pl = NO_PROTO;
+       static struct proto ellipsis = { 0, 0, 0, ELLIPSIS };
 
        if (left != NILEXPR) {  /* in case of an error */
                register struct type *tp = left->ex_type;
@@ -376,13 +338,11 @@ call_proto(expp)
 
                        if (left->ex_class != Value || left->VL_CLASS != Name) {
                                strict("no prototype supplied");
-                               return;
                        }
-                       if ((idf = left->VL_IDF)->id_proto)
-                               return;
-                       strict("'%s' no prototype supplied", idf->id_text);
-                       idf->id_proto++;
-                       return;
+                       else if (! (idf = left->VL_IDF)->id_proto) {
+                               strict("'%s' no prototype supplied", idf->id_text);
+                               idf->id_proto++;
+                       }
                }
 
                /* stack up the parameter expressions */
@@ -404,16 +364,22 @@ call_proto(expp)
                */
                if (pl && pl->pl_flag == VOID) {
                        strict("no parameters expected");
-                       return;
+                       pl = NO_PROTO;
                }
 
                /* stack up the prototypes */
-               while (pl) {
-                       /* stack prototypes */
-                       pstack[pcnt++] = pl;
-                       pl = pl->next;
+               if (pl) {
+                       do {
+                               /* stack prototypes */
+                               pstack[pcnt++] = pl;
+                               pl = pl->next;
+                       } while (pl);
+                       pcnt--;
+               }
+               else {
+                       pcnt = 0;
+                       pstack[0] = &ellipsis;
                }
-               pcnt--;
 
                for (--ecnt; ecnt >= 0; ecnt--) {
                        /*      Only the parameters specified in the prototype
@@ -425,11 +391,11 @@ call_proto(expp)
                                error("more parameters than specified in prototype");
                                break;
                        }
-                       if (pstack[pcnt]->pl_flag != ELLIPSIS) {
+                       else if (pstack[pcnt]->pl_flag != ELLIPSIS) {
                                ch7cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type);
                                pcnt--;
                        } else
-                               break;  /* against unnecessary looping */
+                               any2parameter(estack[ecnt]);
                }
                if (pcnt >= 0 && pstack[0]->pl_flag != ELLIPSIS)
                        error("less parameters than specified in prototype");
@@ -439,4 +405,3 @@ call_proto(expp)
                        error("less parameters than specified in prototype");
        }
 }
-