expr.c 51.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 37 38 39 40 41 42 43 44 45 46 47 48 49 50
/*
 * Using pools here probably does not save anything, but it's a darn
 * good debugging tool.
 */
#ifndef USE_EXPR_POOLS
#define USE_EXPR_POOLS 1
#endif

#if USE_EXPR_POOLS
/* Memory pool for expressions.  */
static gnm_mem_chunk *expression_pool;
#define CHUNK_ALLOC(T,p) ((T*)gnm_mem_chunk_alloc (p))
#define CHUNK_FREE(p,v) gnm_mem_chunk_free ((p), (v))
#else
#define CHUNK_ALLOC(T,c) g_new (T,1)
#define CHUNK_FREE(p,v) g_free ((v))
#endif

51 52
/***************************************************************************/

53 54
GnmExpr const *
gnm_expr_new_constant (Value *v)
55
{
56
	GnmExprConstant *ans;
57

58
	ans = CHUNK_ALLOC (GnmExprConstant, expression_pool);
59 60
	if (!ans)
		return NULL;
61
	gnm_expr_constant_init (ans, v);
62

63
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
64 65
}

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

72
	ans = CHUNK_ALLOC (GnmExprFunction, expression_pool);
73 74
	if (!ans)
		return NULL;
75

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

82
	return (GnmExpr *)ans;
83
}
84

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

90
	ans = CHUNK_ALLOC (GnmExprUnary, expression_pool);
91 92 93 94
	if (!ans)
		return NULL;

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

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


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

107
	ans = CHUNK_ALLOC (GnmExprBinary, expression_pool);
108 109
	if (!ans)
		return NULL;
110

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

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

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

125
	ans = CHUNK_ALLOC (GnmExprName, expression_pool);
126 127
	if (!ans)
		return NULL;
128

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

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

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

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

145
	ans = CHUNK_ALLOC (GnmExprCellRef, expression_pool);
146 147
	if (!ans)
		return NULL;
148

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

153
	return (GnmExpr *)ans;
154 155
}

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

161
	ans = CHUNK_ALLOC (GnmExprArray, expression_pool);
162 163
	if (ans == NULL)
		return NULL;
164

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

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

181
	ans = CHUNK_ALLOC (GnmExprSet, expression_pool);
182 183
	if (!ans)
		return NULL;
184

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

189
	return (GnmExpr *)ans;
190 191
}

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

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

207
	return corner;
208 209
}

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

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

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

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

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

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

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

246 247 248
	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
249 250
		break;

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

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

270
	CHUNK_FREE (expression_pool, (gpointer)expr);
271 272
}

Morten Welinder's avatar
Morten Welinder committed
273
/*
274 275
 * gnm_expr_unref:
 * Decrements the ref_count for part of a expression.  (All trees are expected
Morten Welinder's avatar
Morten Welinder committed
276 277 278
 * 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.)
 */
279
void
280
gnm_expr_unref (GnmExpr const *expr)
281
{
282 283
	g_return_if_fail (expr != NULL);
	g_return_if_fail (expr->any.ref_count > 0);
284

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

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

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

Jody Goldberg's avatar
Jody Goldberg committed
303
/**
304
 * gnm_expr_equal : Returns TRUE if the supplied expressions are exactly the
Jody Goldberg's avatar
Jody Goldberg committed
305 306 307 308 309
 *   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
310
gnm_expr_equal (GnmExpr const *a, GnmExpr const *b)
Jody Goldberg's avatar
Jody Goldberg committed
311 312 313 314 315 316 317 318 319 320 321
{
	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) {
322 323 324
	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
325

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

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

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

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

339
	case GNM_EXPR_OP_CONSTANT: {
Jody Goldberg's avatar
Jody Goldberg committed
340 341 342 343 344 345 346 347 348 349 350 351 352
		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;
	}

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

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

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

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

	return FALSE;
}

Jody Goldberg's avatar
Jody Goldberg committed
374
/**
375
 * gnm_expr_implicit_intersection :
Jody Goldberg's avatar
Jody Goldberg committed
376 377
 * @ei: EvalInfo containing valid fd!
 * @v: a VALUE_CELLRANGE
378
 *
379 380 381 382 383
 * 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
384 385 386
 *
 * Always release the value passed in.
 *
387
 * Return value:
Jody Goldberg's avatar
Jody Goldberg committed
388 389 390 391
 *     If the intersection succeeded return a duplicate of the value
 *     at the intersection point.  This value needs to be freed.
 **/
Value *
392
gnm_expr_implicit_intersection (EvalPos const *pos, Value *v)
Jody Goldberg's avatar
Jody Goldberg committed
393 394
{
	Value *res = NULL;
395 396 397 398
	Range rng;
	Sheet *start_sheet, *end_sheet;

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

	if (start_sheet == end_sheet) {
		if (rng.start.row == rng.end.row) {
Jody Goldberg's avatar
Jody Goldberg committed
403
			int const c = pos->eval.col;
Jody Goldberg's avatar
Jody Goldberg committed
404 405 406 407 408 409
			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
410 411
		}

412
		if (rng.start.col == rng.end.col) {
Jody Goldberg's avatar
Jody Goldberg committed
413
			int const r = pos->eval.row;
Jody Goldberg's avatar
Jody Goldberg committed
414 415 416 417 418 419
			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
420 421 422 423 424 425
		}
	}
	value_release (v);
	return res;
}

426
/**
427
 * gnm_expr_array_intersection :
428 429 430 431 432 433 434 435 436 437 438 439 440
 * @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 *
441
gnm_expr_array_intersection (Value *a)
442
{
Morten Welinder's avatar
Typo.  
Morten Welinder committed
443
	Value *tmp = value_duplicate (a->v_array.vals[0][0]);
444 445 446 447
	value_release (a);
	return tmp;
}

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

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

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

464
	switch (expr->any.oper){
465 466 467 468 469 470
	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: {
471
		ValueCompare comp;
472

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

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

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

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

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

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

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

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

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

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

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

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

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

561 562 563 564 565
	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:
566 567 568 569 570 571 572 573 574
		/*
		 * 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
		 */

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

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

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

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

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

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

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

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

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

			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)) {
639 640
			value_release (a);
			value_release (b);
641
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
642
		}
643

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

789 790 791 792 793 794 795 796 797 798 799 800 801 802
		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
803 804
			value_release (a);
			value_release (b);
805 806
		}

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

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

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

818
	case GNM_EXPR_OP_NAME:
819 820 821
		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
822

823 824
	case GNM_EXPR_OP_CELLREF: {
		CellRef const * const ref = &expr->cellref.ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
825
		Cell *cell;
826
		CellPos dest;
827

828
		cellref_get_abs_pos (ref, &pos->eval, &dest);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
829

830 831
		cell = sheet_cell_get (eval_sheet (ref->sheet, pos->sheet),
			dest.col, dest.row);
832 833
		if (cell == NULL)
			return NULL;
834