gnumeric r16986 - in trunk: . src



Author: mortenw
Date: Tue Dec  2 20:14:02 2008
New Revision: 16986
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16986&view=rev

Log:
2008-12-02  Morten Welinder  <terra gnome org>

	* src/parser.y (is_signed): New function.
	(yylex/^): If left side is negated, as a parenthesis.
	Fixes last part of #115941.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/src/expr.c
   trunk/src/parser.y

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Tue Dec  2 20:14:02 2008
@@ -43,6 +43,7 @@
 	* Disallow deleting last visible sheet.  [#557153]
 	* Merge the sheet tabs into the status bar.  [#561733]
 	* Fix crash in multi-view mode.  [#562053]
+	* Introduce explicit () on parsing -2^2.  [#115941]
 
 --------------------------------------------------------------------------
 Gnumeric 1.9.3

Modified: trunk/src/expr.c
==============================================================================
--- trunk/src/expr.c	(original)
+++ trunk/src/expr.c	Tue Dec  2 20:14:02 2008
@@ -1539,10 +1539,14 @@
 			prec - operations[op].assoc_left, out);
 
 		/*
-		 * Avoid getting "-2^2".  We want to make sure files do not contain
-		 * that construct as we might later change precedence.
+		 * Avoid getting "-2^2".  We want to make sure files do not
+		 * contain that construct as we might later change precedence.
 		 *
 		 * Always produce either "-(2^2)" or "(-2)^2".
+		 *
+		 * Note, that the parser introduces an explicit parenthesis in
+		 * this case also, so parsed expressions should not be
+		 * affected by the code here.
 		 */
 		if (op == GNM_EXPR_OP_EXP &&
 		    (target->str[prelen] == '-' || target->str[prelen] == '+')) {

Modified: trunk/src/parser.y
==============================================================================
--- trunk/src/parser.y	(original)
+++ trunk/src/parser.y	Tue Dec  2 20:14:02 2008
@@ -231,6 +231,23 @@
 		g_error_free (err);
 }
 
+static gboolean
+is_signed (const GnmExpr *expr)
+{
+	if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_UNARY_NEG)
+		return TRUE;
+
+	if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_UNARY_PLUS)
+		return TRUE;
+
+	if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_CONSTANT) {
+		GnmValue const *v = expr->constant.value;
+		return VALUE_IS_FLOAT (v) && value_get_as_float (v) < 0;
+	}
+
+	return FALSE;
+}
+
 /* Handle -cst for use in arrays.  Don't handle other types here.  */
 static GnmExpr *
 fold_negative_constant (GnmExpr *expr)
@@ -584,7 +601,16 @@
 	| exp '-' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_SUB,	$3); }
 	| exp '*' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_MULT,	$3); }
 	| exp '/' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_DIV,	$3); }
-	| exp '^' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_EXP,	$3); }
+	| exp '^' exp	{
+		GnmExpr *l = $1;
+
+		/* See bug 115941 */
+		if (is_signed (l)) {
+			l = build_unary_op (GNM_EXPR_OP_PAREN, l);
+		}
+
+		$$ = build_binop (l, GNM_EXPR_OP_EXP, $3);
+	}
 	| exp '&' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_CAT,	$3); }
 	| exp '=' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_EQUAL,	$3); }
 	| exp '<' exp	{ $$ = build_binop ($1, GNM_EXPR_OP_LT,		$3); }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]