Переглянути джерело

expression nodes now can have a flag EX_ERROR

dick 38 роки тому
батько
коміт
1581b2ecd8

+ 5 - 5
lang/cem/cemcom/arith.c

@@ -110,12 +110,10 @@ ch76pointer(expp, oper, tp)
 	)		/* ch 7.7 */
 		ch7cast(expp, CAST, tp);
 	else	{
-		if ((*expp)->ex_type != error_type)
-			expr_error(*expp, "%s on %s and pointer",
+		expr_error(*expp, "%s on %s and pointer",
 				symbol2str(oper),
 				symbol2str((*expp)->ex_type->tp_fund)
 			);
-		(*expp)->ex_type = error_type;
 		ch7cast(expp, oper, tp);
 	}
 }
@@ -177,8 +175,11 @@ erroneous2int(expp)
 	/*	the (erroneous) expression *expp is replaced by an
 		int expression
 	*/
+	int flags = (*expp)->ex_flags;
+	
 	free_expression(*expp);
 	*expp = intexpr((arith)0, INT);
+	(*expp)->ex_flags = (flags | EX_ERROR);
 }
 
 struct expr *
@@ -291,8 +292,7 @@ opnd2integral(expp, oper)
 	register int fund = (*expp)->ex_type->tp_fund;
 
 	if (fund != INT && fund != LONG)	{
-		if (fund != ERRONEOUS)
-			expr_error(*expp, "%s operand to %s",
+		expr_error(*expp, "%s operand to %s",
 				symbol2str(fund), symbol2str(oper));
 		erroneous2int(expp);
 		/* fund = INT; */

+ 16 - 8
lang/cem/cemcom/ch7.c

@@ -61,7 +61,6 @@ ch7sel(expp, oper, idf)
 		/* filter out illegal expressions "non_lvalue.sel" */
 		if (!(*expp)->ex_lvalue) {
 			expr_error(*expp, "dot requires lvalue");
-			(*expp)->ex_type = error_type;
 			return;
 		}
 	}
@@ -102,6 +101,8 @@ ch7sel(expp, oper, idf)
 			*/
 			(*expp)->VL_VALUE += sd->sd_offset;
 			(*expp)->ex_type = sd->sd_type;
+			if ((*expp)->ex_type == error_type)
+				(*expp)->ex_flags |= EX_ERROR;
 		}
 		else
 		if ((*expp)->ex_class == Oper)	{
@@ -110,16 +111,20 @@ ch7sel(expp, oper, idf)
 			if (op->op_oper == '.' || op->op_oper == ARROW)	{
 				op->op_right->VL_VALUE += sd->sd_offset;
 				(*expp)->ex_type = sd->sd_type;
+				if ((*expp)->ex_type == error_type)
+					(*expp)->ex_flags |= EX_ERROR;
 			}
 			else
 				*expp = new_oper(sd->sd_type, *expp, '.',
 						intexpr(sd->sd_offset, INT));
 		}
 	}
-	else /* oper == ARROW */
+	else	{
+		/* oper == ARROW */
 		*expp = new_oper(sd->sd_type,
 			*expp, oper, intexpr(sd->sd_offset, INT));
-	(*expp)->ex_lvalue = sd->sd_type->tp_fund != ARRAY;
+	}
+	(*expp)->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
 }
 
 ch7incr(expp, oper)
@@ -152,8 +157,7 @@ ch7incr(expp, oper)
 		addend = (arith)1;
 #endif NOBITFIELD
 	else	{
-		if ((*expp)->ex_type != error_type)
-			expr_error(*expp, "%s on %s",
+		expr_error(*expp, "%s on %s",
 				symbol2str(oper),
 				symbol2str((*expp)->ex_type->tp_fund)
 			);
@@ -280,18 +284,22 @@ ch7cast(expp, oper, tp)
 			(*expp)->ex_type = tp;
 	}
 	else
+	if (oldtp->tp_fund == ERRONEOUS)	{
+		/* we just won't look */
+		(*expp)->ex_type = tp;		/* brute force */
+	}
+	else
 	if (oldtp->tp_size == tp->tp_size && oper == CAST)	{
 		expr_warning(*expp, "dubious conversion based on equal size");
 		(*expp)->ex_type = tp;		/* brute force */
 	}
-	else
-	{
+	else	{
 		if (oldtp->tp_fund != ERRONEOUS && tp->tp_fund != ERRONEOUS)
 			expr_error(*expp, "cannot convert %s to %s",
 				symbol2str(oldtp->tp_fund),
 				symbol2str(tp->tp_fund)
 			);
-		(*expp)->ex_type = tp;
+		(*expp)->ex_type = tp;		/* brute force */
 	}
 }
 

+ 2 - 4
lang/cem/cemcom/ch7bin.c

@@ -64,9 +64,8 @@ ch7bin(expp, oper, expr)
 			ch7mon('*', expp);
 		}
 		if ((*expp)->ex_type->tp_fund != FUNCTION)	{
-			if ((*expp)->ex_type != error_type)
-				expr_error(*expp, "call of non-function (%s)",
-					symbol2str((*expp)->ex_type->tp_fund));
+			expr_error(*expp, "call of non-function (%s)",
+				symbol2str((*expp)->ex_type->tp_fund));
 			/* leave the expression; it may still serve */
 			free_expression(expr);	/* there go the parameters */
 		}
@@ -202,7 +201,6 @@ ch7bin(expp, oper, expr)
 		)	{
 			if ((*expp)->ex_type != expr->ex_type)	{
 				expr_error(*expp, "illegal balance");
-				(*expp)->ex_type = error_type;
 			}
 		}
 		else	{

+ 3 - 8
lang/cem/cemcom/ch7mon.c

@@ -28,11 +28,9 @@ ch7mon(oper, expp)
 		if ((*expp)->ex_type->tp_fund == ARRAY)
 			array2pointer(expp);
 		if ((*expp)->ex_type->tp_fund != POINTER)	{
-			if ((*expp)->ex_type != error_type)
-				expr_error(*expp,
-					"* applied to non-pointer (%s)",
-					symbol2str((*expp)->ex_type->tp_fund));
-			(*expp)->ex_type = error_type;
+			expr_error(*expp,
+				"* applied to non-pointer (%s)",
+				symbol2str((*expp)->ex_type->tp_fund));
 		}
 		else {
 			expr = *expp;
@@ -59,13 +57,11 @@ ch7mon(oper, expp)
 #ifndef NOBITFIELD
 		if ((*expp)->ex_type->tp_fund == FIELD)	{
 			expr_error(*expp, "& applied to field variable");
-			(*expp)->ex_type = error_type;
 		}
 		else
 #endif NOBITFIELD
 		if (!(*expp)->ex_lvalue)	{
 			expr_error(*expp, "& applied to non-lvalue");
-			(*expp)->ex_type = error_type;
 		}
 		else {
 			/* assume that enums are already filtered out	*/
@@ -79,7 +75,6 @@ ch7mon(oper, expp)
 				if (def->df_sc == REGISTER) {
 					expr_error(*expp,
 					"& on register variable not allowed");
-					(*expp)->ex_type = error_type;
 					break;	/* break case '&' */
 				}
 				def->df_register = REG_NONE;

+ 2 - 2
lang/cem/cemcom/dumpidf.c

@@ -318,11 +318,11 @@ p1_expr(lvl, expr)
 		printf("NILEXPR\n");
 		return;
 	}
-	printf("expr: L=%u, T=%s, %cV, F=%02o, D=%d, %s: ",
+	printf("expr: L=%u, T=%s, %cV, F=%03o, D=%d, %s: ",
 		expr->ex_line,
 		type2str(expr->ex_type),
 		expr->ex_lvalue ? 'l' : 'r',
-		expr->ex_flags,
+		expr->ex_flags & 0xFF,
 		expr->ex_depth,
 		expr->ex_class == Value ? "Value" :
 		expr->ex_class == String ? "String" :

+ 5 - 0
lang/cem/cemcom/error.c

@@ -56,7 +56,10 @@ expr_error(expr, fmt, args)
 	struct expr *expr;
 	char *fmt;
 {
+	if (expr->ex_flags & EX_ERROR)
+		return;			/* to prevent proliferation */
 	_error(ERROR, expr, fmt, &args);
+	expr->ex_flags |= EX_ERROR;
 }
 
 /*VARARGS1*/
@@ -71,6 +74,8 @@ expr_warning(expr, fmt, args)
 	struct expr *expr;
 	char *fmt;
 {
+	if (expr->ex_flags & EX_ERROR)
+		return;			/* to prevent proliferation */
 	_error(WARNING, expr, fmt, &args);
 }
 

+ 3 - 3
lang/cem/cemcom/expr.c

@@ -169,12 +169,13 @@ idf2expr(expr)
 	}
 	/* now def != 0 */
 	if (def->df_type->tp_fund == LABEL) {
-		error("illegal use of label %s", idf->id_text);
-		expr->ex_type = error_type;
+		expr_error(expr, "illegal use of label %s", idf->id_text);
 	}
 	else {
 		def->df_used = 1;
 		expr->ex_type = def->df_type;
+		if (expr->ex_type == error_type)
+			expr->ex_flags |= EX_ERROR;
 	}
 	expr->ex_lvalue =
 		(	def->df_type->tp_fund == FUNCTION ||
@@ -381,7 +382,6 @@ chk_cst_expr(expp)
 	
 	if (err) {
 		erroneous2int(expp);
-		(*expp)->ex_type = error_type;
 	}
 }
 

+ 6 - 5
lang/cem/cemcom/expr.str

@@ -68,11 +68,12 @@ struct expr	{
 /*	some bits for the ex_flag field, to keep track of various
 	interesting properties of an expression.
 */
-#define	EX_SIZEOF	001		/* contains sizeof operator */
-#define	EX_CAST		002		/* contains cast */
-#define	EX_LOGICAL	004		/* contains logical operator */
-#define	EX_COMMA	010		/* contains expression comma */
-#define	EX_PARENS	020		/* the top level is parenthesized */
+#define	EX_SIZEOF	0001		/* contains sizeof operator */
+#define	EX_CAST		0002		/* contains cast */
+#define	EX_LOGICAL	0004		/* contains logical operator */
+#define	EX_COMMA	0010		/* contains expression comma */
+#define	EX_PARENS	0020		/* the top level is parenthesized */
+#define	EX_ERROR	0200		/* the expression is wrong */
 
 #define	NILEXPR		((struct expr *)0)
 

+ 1 - 2
lang/cem/cemcom/ival.c

@@ -668,8 +668,7 @@ con_int(expr)
 illegal_init_cst(expr)
 	struct expr *expr;
 {
-	if (expr->ex_type->tp_fund != ERRONEOUS)
-		expr_error(expr, "illegal initialisation constant");
+	expr_error(expr, "illegal initialisation constant");
 }
 
 too_many_initialisers(expr)

+ 2 - 1
lang/cem/cemcom/program.g

@@ -71,7 +71,8 @@ control_if_expression
 		{
 #ifndef NOPP
 			if (expr->ex_flags & EX_SIZEOF)
-				error("sizeof not allowed in preprocessor");
+				expr_error(expr,
+					"sizeof not allowed in preprocessor");
 			ifval = expr->VL_VALUE;
 			free_expression(expr);
 #endif NOPP

+ 5 - 0
lang/cem/cemcom/switch.c

@@ -129,6 +129,11 @@ code_case(expr)
 		return;
 	}
 	
+	if (expr->ex_flags & EX_ERROR)	{
+		/* is probably 0 anyway */
+		return;
+	}
+	
 	expr->ex_type = sh->sh_type;
 	cut_size(expr);