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
}
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 '..'");
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
# 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
# What parser generator to use and how
GEN = $(EMHOME)/bin/LLgen
-GENOPTIONS = -v
+GENOPTIONS = -vvvx
# Special #defines during compilation
PROF = #-pg
LINT = /usr/bin/lint
LINTFLAGS =
-MYLINT = /usr/star/dick/bin/lint #../lint
-MYLINTFLAGS = #-xh
+MYLINT = ../lpass2/lint
+MYLINTFLAGS = -xh
#EXCLEXCLEXCLEXCL
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
@pr Makefile make.* char.tab Parameters $(HSRC) $(STRSRC) $(LSRC) $(CSRC)
opr:
- $(MAKE) pr | opr
+ make pr | opr
clean:
rm -f $(OBJ)
$(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)
}
}
+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;
}
}
} /* 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 = ... */
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)
{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) ')'
primary_parameter_declarator(dc)
[
'('
- [ %if(DOT != IDENTIFIER && DOT != ')')
+ [ %if (DOT != IDENTIFIER)
parameter_type_list(&pl)
|
formal_list(&fm)
primary_parameter_declarator(register struct declarator *dc;)
:
-[ %if(AHEAD == ')')
+[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
empty
|
identifier(&dc->dc_idf)
}
#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:
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));
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);
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;
}
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 [] */
';'
]
|
- empty
{do_decspecs(&Ds);}
declarator(&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;
}
*/
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;
}
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;
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 */
*/
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
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");
error("less parameters than specified in prototype");
}
}
-