From 0bc88b77b2c4e3a752fbeba72b28442973b2cad0 Mon Sep 17 00:00:00 2001 From: ceriel Date: Tue, 7 Feb 1989 13:16:02 +0000 Subject: [PATCH] fixed several problems: - 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 | 17 +++---- lang/cem/cemcom.ansi/Makefile | 15 +++--- lang/cem/cemcom.ansi/arith.c | 12 +++++ lang/cem/cemcom.ansi/ch7.c | 16 +++---- lang/cem/cemcom.ansi/declar.g | 8 ++-- lang/cem/cemcom.ansi/eval.c | 32 ++++++++++--- lang/cem/cemcom.ansi/idf.c | 2 +- lang/cem/cemcom.ansi/program.g | 1 - lang/cem/cemcom.ansi/proto.c | 85 ++++++++++------------------------ 9 files changed, 90 insertions(+), 98 deletions(-) diff --git a/lang/cem/cemcom.ansi/LLlex.c b/lang/cem/cemcom.ansi/LLlex.c index 592bf0475..0064f6784 100644 --- a/lang/cem/cemcom.ansi/LLlex.c +++ b/lang/cem/cemcom.ansi/LLlex.c @@ -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 diff --git a/lang/cem/cemcom.ansi/Makefile b/lang/cem/cemcom.ansi/Makefile index 5c131d135..fa9ee5926 100644 --- a/lang/cem/cemcom.ansi/Makefile +++ b/lang/cem/cemcom.ansi/Makefile @@ -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) diff --git a/lang/cem/cemcom.ansi/arith.c b/lang/cem/cemcom.ansi/arith.c index 470aa203e..dbdf564ac 100644 --- a/lang/cem/cemcom.ansi/arith.c +++ b/lang/cem/cemcom.ansi/arith.c @@ -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; diff --git a/lang/cem/cemcom.ansi/ch7.c b/lang/cem/cemcom.ansi/ch7.c index cc664ff77..57bd94c57 100644 --- a/lang/cem/cemcom.ansi/ch7.c +++ b/lang/cem/cemcom.ansi/ch7.c @@ -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) diff --git a/lang/cem/cemcom.ansi/declar.g b/lang/cem/cemcom.ansi/declar.g index 9af9c957a..6395fb46b 100644 --- a/lang/cem/cemcom.ansi/declar.g +++ b/lang/cem/cemcom.ansi/declar.g @@ -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) diff --git a/lang/cem/cemcom.ansi/eval.c b/lang/cem/cemcom.ansi/eval.c index a34cb77b0..0f329de62 100644 --- a/lang/cem/cemcom.ansi/eval.c +++ b/lang/cem/cemcom.ansi/eval.c @@ -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; } diff --git a/lang/cem/cemcom.ansi/idf.c b/lang/cem/cemcom.ansi/idf.c index 49537a869..9ebd89505 100644 --- a/lang/cem/cemcom.ansi/idf.c +++ b/lang/cem/cemcom.ansi/idf.c @@ -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 [] */ diff --git a/lang/cem/cemcom.ansi/program.g b/lang/cem/cemcom.ansi/program.g index 658af3943..fbee3bc65 100644 --- a/lang/cem/cemcom.ansi/program.g +++ b/lang/cem/cemcom.ansi/program.g @@ -138,7 +138,6 @@ external_definition ';' ] | - empty {do_decspecs(&Ds);} declarator(&Dc) { diff --git a/lang/cem/cemcom.ansi/proto.c b/lang/cem/cemcom.ansi/proto.c index a99bf3ba3..e3b862670 100644 --- a/lang/cem/cemcom.ansi/proto.c +++ b/lang/cem/cemcom.ansi/proto.c @@ -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"); } } - -- 2.34.1