expr.c 50.9 KB
Newer Older
1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
Miguel de Icaza's avatar
Miguel de Icaza committed
2
/*
Morten Welinder's avatar
Morten Welinder committed
3
 * expr.c: Expression evaluation in Gnumeric
Miguel de Icaza's avatar
Miguel de Icaza committed
4 5 6 7
 *
 * Author:
 *   Miguel de Icaza (miguel@gnu.org).
 */
8 9
#include <gnumeric-config.h>
#include "gnumeric.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
10
#include "expr.h"
11

12
#include "expr-impl.h"
13
#include "expr-name.h"
14
#include "dependent.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
15
#include "format.h"
16
#include "func.h"
Jody Goldberg's avatar
Jody Goldberg committed
17
#include "cell.h"
Jody Goldberg's avatar
Jody Goldberg committed
18 19
#include "sheet.h"
#include "str.h"
20
#include "value.h"
21
#include "parse-util.h"
22
#include "ranges.h"
23
#include "number-match.h"
24
#include "workbook.h"
Jeffrey Stedfast's avatar
Jeffrey Stedfast committed
25
#include "gutils.h"
26
#include "parse-util.h"
27
#include "mathfunc.h"
28

29 30
#include <math.h>
#include <string.h>
31
#include <libgnome/gnome-i18n.h>
32

33 34
/***************************************************************************/

35 36
GnmExpr const *
gnm_expr_new_constant (Value *v)
37
{
38
	GnmExprConstant *ans;
39

40
	ans = g_new (GnmExprConstant, 1);
41 42
	if (!ans)
		return NULL;
43
	gnm_expr_constant_init (ans, v);
44

45
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
46 47
}

48 49
GnmExpr const *
gnm_expr_new_error (char const *txt)
50
{
Jody Goldberg's avatar
Jody Goldberg committed
51
	FunctionDefinition *func;
52
	GnmExprList *args = NULL;
53

Jody Goldberg's avatar
Jody Goldberg committed
54 55
	if (strcmp (txt, gnumeric_err_NA) != 0) {
		func = func_lookup_by_name ("ERROR", NULL);
56 57
		args = gnm_expr_list_prepend (NULL,
			gnm_expr_new_constant (value_new_string (txt)));
Jody Goldberg's avatar
Jody Goldberg committed
58 59
	} else
		func = func_lookup_by_name ("NA", NULL);
60

Jody Goldberg's avatar
Jody Goldberg committed
61
	func_ref (func);
62
	return gnm_expr_new_funcall (func, args);
63 64
}

65 66
GnmExpr const *
gnm_expr_new_funcall (FunctionDefinition *func, GnmExprList *args)
67
{
68
	GnmExprFunction *ans;
Jody Goldberg's avatar
Jody Goldberg committed
69
	g_return_val_if_fail (func, NULL);
70

71
	ans = g_new (GnmExprFunction, 1);
72 73
	if (!ans)
		return NULL;
74

75
	ans->ref_count = 1;
76
	ans->oper = GNM_EXPR_OP_FUNCALL;
Jody Goldberg's avatar
Jody Goldberg committed
77
	func_ref (func);
Jody Goldberg's avatar
Jody Goldberg committed
78
	ans->func = func;;
79 80
	ans->arg_list = args;

81
	return (GnmExpr *)ans;
82
}
83

84 85
GnmExpr const *
gnm_expr_new_unary  (GnmExprOp op, GnmExpr const *e)
Morten Welinder's avatar
Morten Welinder committed
86
{
87
	GnmExprUnary *ans;
Morten Welinder's avatar
Morten Welinder committed
88

89
	ans = g_new (GnmExprUnary, 1);
90 91 92 93
	if (!ans)
		return NULL;

	ans->ref_count = 1;
94
	ans->oper = op;
95
	ans->value = e;
96

97
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
98 99 100
}


101 102
GnmExpr const *
gnm_expr_new_binary (GnmExpr const *l, GnmExprOp op, GnmExpr const *r)
Morten Welinder's avatar
Morten Welinder committed
103
{
104
	GnmExprBinary *ans;
Morten Welinder's avatar
Morten Welinder committed
105

106
	ans = g_new (GnmExprBinary, 1);
107 108
	if (!ans)
		return NULL;
109

110
	ans->ref_count = 1;
111
	ans->oper = op;
112 113
	ans->value_a = l;
	ans->value_b = r;
114

115
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
116 117
}

118 119
GnmExpr const *
gnm_expr_new_name (GnmNamedExpr *name,
120
		    Sheet *optional_scope, Workbook *optional_wb_scope)
Morten Welinder's avatar
Morten Welinder committed
121
{
122
	GnmExprName *ans;
Morten Welinder's avatar
Morten Welinder committed
123

124
	ans = g_new (GnmExprName, 1);
125 126
	if (!ans)
		return NULL;
127

128
	ans->ref_count = 1;
129
	ans->oper = GNM_EXPR_OP_NAME;
130
	ans->name = name;
131
	expr_name_ref (name);
132

133 134 135
	ans->optional_scope = optional_scope;
	ans->optional_wb_scope = optional_wb_scope;

136
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
137
}
138

139 140
GnmExpr const *
gnm_expr_new_cellref (CellRef const *cr)
141
{
142
	GnmExprCellRef *ans;
143

144
	ans = g_new (GnmExprCellRef, 1);
145 146
	if (!ans)
		return NULL;
147

148
	ans->ref_count = 1;
149
	ans->oper = GNM_EXPR_OP_CELLREF;
150 151
	ans->ref = *cr;

152
	return (GnmExpr *)ans;
153 154
}

155 156
GnmExpr const *
gnm_expr_new_array (int x, int y, int cols, int rows)
157
{
158
	GnmExprArray *ans;
159

160
	ans = g_new (GnmExprArray, 1);
161 162
	if (ans == NULL)
		return NULL;
163

164
	ans->ref_count = 1;
165
	ans->oper = GNM_EXPR_OP_ARRAY;
166 167 168 169
	ans->x = x;
	ans->y = y;
	ans->rows = rows;
	ans->cols = cols;
170 171
	ans->corner.value = NULL;
	ans->corner.expr = NULL;
172
	return (GnmExpr *)ans;
173 174
}

175 176
GnmExpr const *
gnm_expr_new_set (GnmExprList *set)
177
{
178
	GnmExprSet *ans;
179

180
	ans = g_new (GnmExprSet, 1);
181 182
	if (!ans)
		return NULL;
183

184
	ans->ref_count = 1;
185
	ans->oper = GNM_EXPR_OP_SET;
186
	ans->set = set;
187

188
	return (GnmExpr *)ans;
189 190
}

191
static Cell *
192
expr_array_corner (GnmExpr const *expr,
193
			Sheet const *sheet, CellPos const *pos)
194
{
195 196
	Cell *corner = sheet_cell_get (sheet,
		pos->col - expr->array.x, pos->row - expr->array.y);
197

198
	/* Sanity check incase the corner gets removed for some reason */
199
	g_return_val_if_fail (corner != NULL, NULL);
200
	g_return_val_if_fail (cell_has_expr (corner), NULL);
201
	g_return_val_if_fail (corner->base.expression != (void *)0xdeadbeef, NULL);
202
	g_return_val_if_fail (corner->base.expression->any.oper == GNM_EXPR_OP_ARRAY, NULL);
203 204
	g_return_val_if_fail (corner->base.expression->array.x == 0, NULL);
	g_return_val_if_fail (corner->base.expression->array.y == 0, NULL);
205

206
	return corner;
207 208
}

209 210 211
/**
 * gnm_expr_ref:
 * Increments the ref_count for an expression node.
Arturo Espinosa's avatar
Arturo Espinosa committed
212
 */
213
void
214
gnm_expr_ref (GnmExpr const *expr)
215
{
216 217
	g_return_if_fail (expr != NULL);
	g_return_if_fail (expr->any.ref_count > 0);
218

219
	((GnmExpr *)expr)->any.ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
220 221 222
}

static void
223
do_gnm_expr_unref (GnmExpr const *expr)
Arturo Espinosa's avatar
Arturo Espinosa committed
224
{
225
	if (--((GnmExpr *)expr)->any.ref_count > 0)
Morten Welinder's avatar
Morten Welinder committed
226 227
		return;

228 229
	switch (expr->any.oper) {
	case GNM_EXPR_OP_CELLREF:
Arturo Espinosa's avatar
Arturo Espinosa committed
230
		break;
231

232 233
	case GNM_EXPR_OP_CONSTANT:
		value_release ((Value *)expr->constant.value);
Arturo Espinosa's avatar
Arturo Espinosa committed
234
		break;
235

236 237
	case GNM_EXPR_OP_FUNCALL:
		gnm_expr_list_unref (expr->func.arg_list);
238
		func_unref (expr->func.func);
Arturo Espinosa's avatar
Arturo Espinosa committed
239 240
		break;

241
	case GNM_EXPR_OP_NAME:
242
		expr_name_unref (expr->name.name);
Michael Meeks's avatar
Michael Meeks committed
243 244
		break;

245 246 247
	case GNM_EXPR_OP_ANY_BINARY:
		do_gnm_expr_unref (expr->binary.value_a);
		do_gnm_expr_unref (expr->binary.value_b);
Arturo Espinosa's avatar
Arturo Espinosa committed
248 249
		break;

250 251
	case GNM_EXPR_OP_ANY_UNARY:
		do_gnm_expr_unref (expr->unary.value);
Arturo Espinosa's avatar
Arturo Espinosa committed
252
		break;
253
	case GNM_EXPR_OP_ARRAY:
254 255 256
		if (expr->array.x == 0 && expr->array.y == 0) {
			if (expr->array.corner.value)
				value_release (expr->array.corner.value);
257
			do_gnm_expr_unref (expr->array.corner.expr);
258
		}
259
		break;
260 261
	case GNM_EXPR_OP_SET:
		gnm_expr_list_unref (expr->set.set);
262 263
		break;

264
	default:
265
		g_warning ("do_gnm_expr_unref error.");
266
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
267
	}
268

269
	g_free ((gpointer)expr);
270 271
}

Morten Welinder's avatar
Morten Welinder committed
272
/*
273 274
 * gnm_expr_unref:
 * Decrements the ref_count for part of a expression.  (All trees are expected
Morten Welinder's avatar
Morten Welinder committed
275 276 277
 * to have been created with a ref-count of one, so when we hit zero, we
 * go down over the tree and unref the tree and its leaves stuff.)
 */
278
void
279
gnm_expr_unref (GnmExpr const *expr)
280
{
281 282
	g_return_if_fail (expr != NULL);
	g_return_if_fail (expr->any.ref_count > 0);
283

284
	if (expr->any.ref_count == 1)
285
		do_gnm_expr_unref (expr);
286
	else
287
		((GnmExpr *)expr)->any.ref_count--;
288 289
}

Jody Goldberg's avatar
Jody Goldberg committed
290
/**
291
 * gnm_expr_is_shared : Returns TRUE if the reference count
Jody Goldberg's avatar
Jody Goldberg committed
292 293 294
 *   for the supplied expression is > 1
 */
gboolean
295
gnm_expr_is_shared (GnmExpr const *expr)
Jody Goldberg's avatar
Jody Goldberg committed
296
{
297
	g_return_val_if_fail (expr != NULL, FALSE);
Jody Goldberg's avatar
Jody Goldberg committed
298

299
	return (expr->any.ref_count > 1);
Jody Goldberg's avatar
Jody Goldberg committed
300 301
}

Jody Goldberg's avatar
Jody Goldberg committed
302
/**
303
 * gnm_expr_equal : Returns TRUE if the supplied expressions are exactly the
Jody Goldberg's avatar
Jody Goldberg committed
304 305 306 307 308
 *   same.  No eval position is used to see if they are effectively the same.
 *   Named expressions must refer the the same name, having equivalent names is
 *   insufficeient.
 */
gboolean
309
gnm_expr_equal (GnmExpr const *a, GnmExpr const *b)
Jody Goldberg's avatar
Jody Goldberg committed
310 311 312 313 314 315 316 317 318 319 320
{
	if (a == b)
		return TRUE;

	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);

	if (a->any.oper != b->any.oper)
		return FALSE;

	switch (a->any.oper) {
321 322 323
	case GNM_EXPR_OP_ANY_BINARY:
		return	gnm_expr_equal (a->binary.value_a, b->binary.value_a) &&
			gnm_expr_equal (a->binary.value_b, b->binary.value_b);
Jody Goldberg's avatar
Jody Goldberg committed
324

325 326
	case GNM_EXPR_OP_ANY_UNARY:
		return gnm_expr_equal (a->unary.value, b->unary.value);
Jody Goldberg's avatar
Jody Goldberg committed
327

328
	case GNM_EXPR_OP_FUNCALL:
329
		return (a->func.func == b->func.func) &&
330
			gnm_expr_list_equal (a->func.arg_list, b->func.arg_list);
Jody Goldberg's avatar
Jody Goldberg committed
331

332
	case GNM_EXPR_OP_NAME:
Jody Goldberg's avatar
Jody Goldberg committed
333 334
		return a->name.name == b->name.name;

335 336
	case GNM_EXPR_OP_CELLREF:
		return cellref_equal (&a->cellref.ref, &b->cellref.ref);
Jody Goldberg's avatar
Jody Goldberg committed
337

338
	case GNM_EXPR_OP_CONSTANT: {
Jody Goldberg's avatar
Jody Goldberg committed
339 340 341 342 343 344 345 346 347 348 349 350 351
		Value const *va = a->constant.value;
		Value const *vb = b->constant.value;

		if (va->type != vb->type)
			return FALSE;

		if (va->type == VALUE_CELLRANGE)
			return	cellref_equal (&va->v_range.cell.a, &vb->v_range.cell.a) &&
				cellref_equal (&va->v_range.cell.b, &vb->v_range.cell.b);

		return value_compare (va, vb, TRUE) == IS_EQUAL;
	}

352 353 354
	case GNM_EXPR_OP_ARRAY: {
		GnmExprArray const *aa = &a->array;
		GnmExprArray const *ab = &b->array;
Jody Goldberg's avatar
Jody Goldberg committed
355 356 357 358 359

		return	aa->cols == ab->cols &&
			aa->rows == ab->rows &&
			aa->x == ab->x &&
			aa->y == ab->y &&
360
			gnm_expr_equal (aa->corner.expr, ab->corner.expr);
Jody Goldberg's avatar
Jody Goldberg committed
361 362
	}

363 364
	case GNM_EXPR_OP_SET:
		return gnm_expr_list_equal (a->set.set, b->set.set);
365

Jody Goldberg's avatar
Jody Goldberg committed
366 367 368 369 370 371 372
	default :
		g_assert_not_reached ();
	}

	return FALSE;
}

Jody Goldberg's avatar
Jody Goldberg committed
373
/**
374
 * gnm_expr_implicit_intersection :
Jody Goldberg's avatar
Jody Goldberg committed
375 376
 * @ei: EvalInfo containing valid fd!
 * @v: a VALUE_CELLRANGE
377
 *
378 379 380 381 382
 * Handle the implicit union of a single row or column with the eval position.
 *
 * NOTE : We do not need to know if this is expression is being evaluated as an
 * array or not because we can differentiate based on the required type for the
 * argument.
Jody Goldberg's avatar
Jody Goldberg committed
383 384 385
 *
 * Always release the value passed in.
 *
386
 * Return value:
Jody Goldberg's avatar
Jody Goldberg committed
387 388 389 390
 *     If the intersection succeeded return a duplicate of the value
 *     at the intersection point.  This value needs to be freed.
 **/
Value *
391
gnm_expr_implicit_intersection (EvalPos const *pos, Value *v)
Jody Goldberg's avatar
Jody Goldberg committed
392 393
{
	Value *res = NULL;
394 395 396 397
	Range rng;
	Sheet *start_sheet, *end_sheet;

	/* handle inverted ranges */
Jody Goldberg's avatar
Jody Goldberg committed
398
	value_cellrange_normalize (pos, v, &start_sheet, &end_sheet, &rng);
399 400 401

	if (start_sheet == end_sheet) {
		if (rng.start.row == rng.end.row) {
Jody Goldberg's avatar
Jody Goldberg committed
402
			int const c = pos->eval.col;
Jody Goldberg's avatar
Jody Goldberg committed
403 404 405 406 407 408
			if (rng.start.col <= c && c <= rng.end.col) {
				Value const *tmp = value_area_get_x_y (pos, v,
					c - rng.start.col, 0);
				if (tmp != NULL)
					res = value_duplicate (tmp);
			}
Jody Goldberg's avatar
Jody Goldberg committed
409 410
		}

411
		if (rng.start.col == rng.end.col) {
Jody Goldberg's avatar
Jody Goldberg committed
412
			int const r = pos->eval.row;
Jody Goldberg's avatar
Jody Goldberg committed
413 414 415 416 417 418
			if (rng.start.row <= r && r <= rng.end.row) {
				Value const *tmp = value_area_get_x_y (pos, v,
					0, r - rng.start.row);
				if (tmp != NULL)
					res = value_duplicate (tmp);
			}
Jody Goldberg's avatar
Jody Goldberg committed
419 420 421 422 423 424
		}
	}
	value_release (v);
	return res;
}

425
/**
426
 * gnm_expr_array_intersection :
427 428 429 430 431 432 433 434 435 436 437 438 439
 * @v: a VALUE_ARRAY
 *
 * Returns the upper left corner of an array.
 *
 * Always release the value passed in.
 *
 * FIXME FIXME FIXME : This will need to be reworked
 * cellrange for array expressions
 *
 * Return value:
 *     duplicate of the value in the upper left of the array
 **/
Value *
440
gnm_expr_array_intersection (Value *a)
441 442 443 444 445 446
{
	Value *tmp = value_duplicate (a->v_array.vals [0][0]);
	value_release (a);
	return tmp;
}

Jody Goldberg's avatar
Jody Goldberg committed
447 448
static Value *
cb_range_eval (Sheet *sheet, int col, int row, Cell *cell, void *ignore)
449
{
Jody Goldberg's avatar
Jody Goldberg committed
450 451
	cell_eval (cell);
	return NULL;
452 453
}

454
static Value *
455 456
expr_eval_real (GnmExpr const *expr, EvalPos const *pos,
		GnmExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
457
{
458
	Value *res = NULL, *a = NULL, *b = NULL;
459

460
	g_return_val_if_fail (expr != NULL, NULL);
461
	g_return_val_if_fail (pos != NULL, NULL);
462

463
	switch (expr->any.oper){
464 465 466 467 468 469
	case GNM_EXPR_OP_EQUAL:
	case GNM_EXPR_OP_NOT_EQUAL:
	case GNM_EXPR_OP_GT:
	case GNM_EXPR_OP_GTE:
	case GNM_EXPR_OP_LT:
	case GNM_EXPR_OP_LTE: {
470
		ValueCompare comp;
471

472
		a = expr_eval_real (expr->binary.value_a, pos, flags);
Jody Goldberg's avatar
Jody Goldberg committed
473 474
		if (a != NULL) {
			if (a->type == VALUE_CELLRANGE) {
475
				a = gnm_expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
476
				if (a == NULL)
477
					return value_new_error (pos, gnumeric_err_VALUE);
478
			} else if (a->type == VALUE_ARRAY) {
479
				a = gnm_expr_array_intersection (a);
480 481
				if (a == NULL)
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
482 483 484
			} else if (a->type == VALUE_ERROR)
				return a;
		}
Morten Welinder's avatar
Morten Welinder committed
485

486
		b = expr_eval_real (expr->binary.value_b, pos, flags);
Jody Goldberg's avatar
Jody Goldberg committed
487 488 489
		if (b != NULL) {
			Value *res = NULL;
			if (b->type == VALUE_CELLRANGE) {
490
				b = gnm_expr_implicit_intersection (pos, b);
Jody Goldberg's avatar
Jody Goldberg committed
491
				if (b == NULL)
492
					res = value_new_error (pos, gnumeric_err_VALUE);
493
			} else if (b->type == VALUE_ARRAY) {
494
				b = gnm_expr_array_intersection (b);
495 496
				if (b == NULL)
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
497 498 499 500 501 502 503 504
			} else if (b->type == VALUE_ERROR)
				res = b;

			if (res != NULL) {
				if (a != NULL)
					value_release (a);
				return res;
			}
Morten Welinder's avatar
Morten Welinder committed
505
		}
506

JP Rosevear's avatar
JP Rosevear committed
507
		comp = value_compare (a, b, FALSE);
Arturo Espinosa's avatar
Arturo Espinosa committed
508

509 510 511 512
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
513

Michael Meeks's avatar
Michael Meeks committed
514
		if (comp == TYPE_MISMATCH) {
515 516 517 518
			/* TODO TODO TODO : Make error more informative
			 *    regarding what is comparing to what
			 */
			/* For equality comparisons even errors are ok */
519
			if (expr->any.oper == GNM_EXPR_OP_EQUAL)
520
				return value_new_bool (FALSE);
521
			if (expr->any.oper == GNM_EXPR_OP_NOT_EQUAL)
522 523
				return value_new_bool (TRUE);

524
			return value_new_error (pos, gnumeric_err_VALUE);
525
		}
526

527
		switch (expr->any.oper) {
528
		case GNM_EXPR_OP_EQUAL:
529
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
530 531
			break;

532
		case GNM_EXPR_OP_GT:
533
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
534 535
			break;

536
		case GNM_EXPR_OP_LT:
537
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
538 539
			break;

540
		case GNM_EXPR_OP_NOT_EQUAL:
541
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
542 543
			break;

544
		case GNM_EXPR_OP_LTE:
545
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
546 547
			break;

548
		case GNM_EXPR_OP_GTE:
549
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
550
			break;
551

Arturo Espinosa's avatar
Arturo Espinosa committed
552
		default:
553
			g_assert_not_reached ();
554
			res = value_new_error (pos,
555
						_("Internal type error"));
Arturo Espinosa's avatar
Arturo Espinosa committed
556
		}
Morten Welinder's avatar
Morten Welinder committed
557
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
558
	}
559

560 561 562 563 564
	case GNM_EXPR_OP_ADD:
	case GNM_EXPR_OP_SUB:
	case GNM_EXPR_OP_MULT:
	case GNM_EXPR_OP_DIV:
	case GNM_EXPR_OP_EXP:
565 566 567 568 569 570 571 572 573
		/*
		 * Priority
		 * 1) Error from A
		 * 2) #!VALUE error if A is not a number
		 * 3) Error from B
		 * 4) #!VALUE error if B is not a number
		 * 5) result of operation, or error specific to the operation
		 */

574
	        /* Guarantees a != NULL */
575 576
		a = gnm_expr_eval (expr->binary.value_a, pos,
			       flags & (~GNM_EXPR_EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
577 578 579

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
580
			a = gnm_expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
581
			if (a == NULL)
582
				return value_new_error (pos, gnumeric_err_VALUE);
583
		} else if (a->type == VALUE_ARRAY) {
584
			a = gnm_expr_array_intersection (a);
585 586
			if (a == NULL)
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
587 588
		}

589 590
		/* 1) Error from A */
		if (a->type == VALUE_ERROR)
591
			return value_error_set_pos (&a->v_err, pos);
592

593
		/* 2) #!VALUE error if A is not a number */
594
		if (a->type == VALUE_STRING) {
595
			Value *tmp = format_match_number (a->v_str.val->str, NULL);
596 597 598 599 600 601

			value_release (a);
			if (tmp == NULL)
				return value_new_error (pos, gnumeric_err_VALUE);
			a = tmp;
		} else if (!VALUE_IS_NUMBER (a)) {
602
			value_release (a);
603
			return value_new_error (pos, gnumeric_err_VALUE);
604 605
		}

606
	        /* Guarantees that b != NULL */
607 608
		b = gnm_expr_eval (expr->binary.value_b, pos,
			       flags & (~GNM_EXPR_EVAL_PERMIT_EMPTY));
Arturo Espinosa's avatar
Arturo Espinosa committed
609

Jody Goldberg's avatar
Jody Goldberg committed
610 611
		/* Handle implicit intersection */
		if (b->type == VALUE_CELLRANGE) {
612
			b = gnm_expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
613
			if (b == NULL)
614
				return value_new_error (pos, gnumeric_err_VALUE);
615
		} else if (b->type == VALUE_ARRAY) {
616
			b = gnm_expr_array_intersection (b);
617 618
			if (b == NULL)
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
619 620
		}

621 622
		/* 3) Error from B */
		if (b->type == VALUE_ERROR) {
623
			value_release (a);
624
			return value_error_set_pos (&b->v_err, pos);
Arturo Espinosa's avatar
Arturo Espinosa committed
625
		}
626

627
		/* 4) #!VALUE error if B is not a number */
628
		if (b->type == VALUE_STRING) {
629
			Value *tmp = format_match_number (b->v_str.val->str, NULL);
630 631 632 633 634 635 636 637

			value_release (b);
			if (tmp == NULL) {
				value_release (a);
				return value_new_error (pos, gnumeric_err_VALUE);
			}
			b = tmp;
		} else if (!VALUE_IS_NUMBER (b)) {
638 639
			value_release (a);
			value_release (b);
640
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
641
		}
642

643
		if (a->type != VALUE_FLOAT && b->type != VALUE_FLOAT){
Morten Welinder's avatar
Morten Welinder committed
644
			int ia = value_get_as_int (a);
645
			int ib = value_get_as_int (b);
646
			gnum_float dres;
647 648
			int ires;

Morten Welinder's avatar
Morten Welinder committed
649 650
			value_release (a);
			value_release (b);
651

652 653
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
654
			switch (expr->any.oper){
655
			case GNM_EXPR_OP_ADD:
656
				dres = (gnum_float)ia + (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
657
				break;
658

659
			case GNM_EXPR_OP_SUB:
660
				dres = (gnum_float)ia - (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
661
				break;
662

663
			case GNM_EXPR_OP_MULT:
664
				dres = (gnum_float)ia * (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
665
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
666

667
			case GNM_EXPR_OP_DIV:
668
				if (ib == 0)
669
					return value_new_error (pos, gnumeric_err_DIV0);
670
				dres = (gnum_float)ia / (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
671
				break;
672

673
			case GNM_EXPR_OP_EXP:
674
				if (ia == 0 && ib <= 0)
675
					return value_new_error (pos, gnumeric_err_NUM);
676
				dres = powgnum ((gnum_float)ia, (gnum_float)ib);
677 678
				if (!finitegnum (dres))
					return value_new_error (pos, gnumeric_err_NUM);
Morten Welinder's avatar
Morten Welinder committed
679
				break;
680

Arturo Espinosa's avatar
Arturo Espinosa committed
681
			default:
682
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
683
			}
Morten Welinder's avatar
Morten Welinder committed
684 685 686 687 688 689

			ires = (int)dres;
			if (dres == ires)
				return value_new_int (ires);
			else
				return value_new_float (dres);
Arturo Espinosa's avatar
Arturo Espinosa committed
690
		} else {
691 692
			gnum_float const va = value_get_as_float (a);
			gnum_float const vb = value_get_as_float (b);
693 694
			value_release (a);
			value_release (b);
695

696
			switch (expr->any.oper){
697
			case GNM_EXPR_OP_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
698
				return value_new_float (va + vb);
699

700
			case GNM_EXPR_OP_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
701
				return value_new_float (va - vb);
702

703
			case GNM_EXPR_OP_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
704
				return value_new_float (va * vb);
705

706
			case GNM_EXPR_OP_DIV:
707
				return (vb == 0.0)
708
				    ? value_new_error (pos,
709
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
710
				    : value_new_float (va / vb);
711

712 713
			case GNM_EXPR_OP_EXP: {
				gnum_float res;
714 715
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
716
					return value_new_error (pos, gnumeric_err_NUM);
717 718 719 720 721 722

				res = powgnum (va, vb);
				return finitegnum (res)
					? value_new_float (res)
					: value_new_error (pos, gnumeric_err_NUM);
			}
723

Arturo Espinosa's avatar
Arturo Espinosa committed
724
			default:
725
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
726 727
			}
		}
728
		return value_new_error (pos, _("Unknown operator"));
729

730 731 732
	case GNM_EXPR_OP_PERCENTAGE:
	case GNM_EXPR_OP_UNARY_NEG:
	case GNM_EXPR_OP_UNARY_PLUS:
733
	        /* Garantees that a != NULL */
734 735
		a = gnm_expr_eval (expr->unary.value, pos,
			flags & (~GNM_EXPR_EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
736 737 738

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
739
			a = gnm_expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
740
			if (a == NULL)
741
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
742
		} else if (a->type == VALUE_ARRAY) {
743
			a = gnm_expr_array_intersection (a);
744 745
			if (a == NULL)
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
746 747
		}

748 749
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
750

751
		if (expr->any.oper == GNM_EXPR_OP_UNARY_PLUS)
Jody Goldberg's avatar
Jody Goldberg committed
752 753
			return a;

754 755
		if (!VALUE_IS_NUMBER (a)){
			value_release (a);
756
			return value_new_error (pos, gnumeric_err_VALUE);
757
		}
758
		if (expr->any.oper == GNM_EXPR_OP_UNARY_NEG) {
Jody Goldberg's avatar
Jody Goldberg committed
759
			if (a->type == VALUE_INTEGER)
760
				res = value_new_int (-a->v_int.val);
Jody Goldberg's avatar
Jody Goldberg committed
761
			else if (a->type == VALUE_FLOAT)
762
				res = value_new_float (-a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
763
			else
764
				res = value_new_bool (!a->v_float.val);
765 766 767 768 769
			if (VALUE_FMT (a) != NULL) {
				VALUE_FMT (res) = VALUE_FMT (a);
				style_format_ref (VALUE_FMT (res));
			}
		} else {
Morten Welinder's avatar
Morten Welinder committed
770
			res = value_new_float (value_get_as_float (a) / 100);
771 772 773
			VALUE_FMT (res) = style_format_default_percentage ();
			style_format_ref (VALUE_FMT (res));
		}
774
		value_release (a);
Morten Welinder's avatar
Morten Welinder committed
775
		return res;
776

777
	case GNM_EXPR_OP_CAT:
778
		a = expr_eval_real (expr->binary.value_a, pos, flags);
779
		if (a != NULL && a->type == VALUE_ERROR)
780
			return a;
781
		b = expr_eval_real (expr->binary.value_b, pos, flags);
782 783 784
		if (b != NULL && b->type == VALUE_ERROR) {
			if (a != NULL)
				value_release (a);
785
			return b;
786 787
		}

788 789 790 791 792 793 794 795 796 797 798 799 800 801
		if (a == NULL) {
			if (b != NULL) {
				res = value_new_string (value_peek_string (b));
				value_release (b);
			} else
				res = value_new_string ("");
		} else if (b == NULL) {
			res = value_new_string (value_peek_string (a));
			value_release (a);
		} else {
			char *tmp = g_strconcat (value_peek_string (a),
						 value_peek_string (b), NULL);
			res = value_new_string (tmp);
			g_free (tmp);
Morten Welinder's avatar
Morten Welinder committed
802 803
			value_release (a);
			value_release (b);
804 805
		}

Morten Welinder's avatar
Morten Welinder committed
806
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
807

808
	case GNM_EXPR_OP_FUNCALL: {
809 810
		FunctionEvalInfo ei;
		ei.pos = pos;
811
		ei.func_call = (GnmExprFunction const *)expr;
812

813
		/*if (flags & GNM_EXPR_EVAL_PERMIT_NON_SCALAR)*/
814 815
		return function_call_with_list (&ei, expr->func.arg_list);
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
816

817
	case GNM_EXPR_OP_NAME:
818 819 820
		if (expr->name.name->active)
			return expr_name_eval (expr->name.name, pos, flags);
		return value_new_error (pos, gnumeric_err_REF);
Michael Meeks's avatar
Michael Meeks committed
821

822 823
	case GNM_EXPR_OP_CELLREF: {
		CellRef const * const ref = &expr->cellref.ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
824
		Cell *cell;
Jody Goldberg's avatar