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
This commit is contained in:
ceriel 1989-02-07 13:16:02 +00:00
parent 9dcae8fcd0
commit 0bc88b77b2
9 changed files with 90 additions and 98 deletions

View 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

View 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)

View 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;

View 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)

View 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)

View 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;
}

View 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 [] */

View file

@ -138,7 +138,6 @@ external_definition
';'
]
|
empty
{do_decspecs(&Ds);}
declarator(&Dc)
{

View 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");
}
}