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:
parent
9dcae8fcd0
commit
0bc88b77b2
9 changed files with 90 additions and 98 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 [] */
|
||||
|
|
|
@ -138,7 +138,6 @@ external_definition
|
|||
';'
|
||||
]
|
||||
|
|
||||
empty
|
||||
{do_decspecs(&Ds);}
|
||||
declarator(&Dc)
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue