Преглед на файлове

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

ceriel преди 35 години
родител
ревизия
d3a832bd33

+ 9 - 8
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

+ 7 - 8
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)

+ 12 - 0
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;

+ 6 - 10
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)

+ 5 - 3
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)

+ 25 - 7
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;
 		}

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

+ 0 - 1
lang/cem/cemcom.ansi/program.g

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

+ 25 - 60
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");
 	}
 }
-