expr.c 53.5 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
/*
3
 * expr.c : Expression evaluation in Gnumeric
Miguel de Icaza's avatar
Miguel de Icaza committed
4
 *
5
 * Copyright (C) 2001-2002 Jody Goldberg (jody@gnome.org)
6
 * Copyright (C) 1998-2000 Miguel de Icaza (miguel@gnu.org)
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
Miguel de Icaza's avatar
Miguel de Icaza committed
21
 */
22
#include <gnumeric-config.h>
Zbigniew Chyla's avatar
New  
Zbigniew Chyla committed
23
#include <gnumeric-i18n.h>
24
#include "gnumeric.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
25
#include "expr.h"
26

27
#include "expr-impl.h"
28
#include "expr-name.h"
29
#include "dependent.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
30
#include "format.h"
31
#include "func.h"
Jody Goldberg's avatar
Jody Goldberg committed
32
#include "cell.h"
Jody Goldberg's avatar
Jody Goldberg committed
33 34
#include "sheet.h"
#include "str.h"
35
#include "value.h"
36
#include "parse-util.h"
37
#include "ranges.h"
38
#include "number-match.h"
39
#include "workbook.h"
Jeffrey Stedfast's avatar
Jeffrey Stedfast committed
40
#include "gutils.h"
41
#include "parse-util.h"
42
#include "mathfunc.h"
43

44 45
#include <math.h>
#include <string.h>
Jody Goldberg's avatar
Jody Goldberg committed
46
#include <stdlib.h>
47

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/*
 * 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

66 67
/***************************************************************************/

Jody Goldberg's avatar
Jody Goldberg committed
68 69 70 71 72 73 74 75 76 77 78 79
#if 0
static guint
gnm_expr_constant_hash (GnmExprConstant const *expr)
{
	return value_hash (expr->value);
}
static gboolean
gnm_expr_constant_eq (GnmExprConstant const *a,
		      GnmExprConstant const *b)
{
}
#endif
80 81
GnmExpr const *
gnm_expr_new_constant (Value *v)
82
{
83
	GnmExprConstant *ans;
84

85
	ans = CHUNK_ALLOC (GnmExprConstant, expression_pool);
86 87
	if (!ans)
		return NULL;
88
	gnm_expr_constant_init (ans, v);
89

90
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
91 92
}

Jody Goldberg's avatar
Jody Goldberg committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
/***************************************************************************/

#if 0
static guint
gnm_expr_function_hash (GnmExprFunction const *expr)
{
	guint h = expr->oper;
	GnmExprList *l;
	for (l = expr->arg_list; l; l = l->next)
		h = (h * 3) ^ (GPOINTER_TO_INT (l->data));
	return h;
}
static gboolean
gnm_expr_function_eq (GnmExprFunction const *a,
		      GnmExprFunction const *b)
{
}
#endif

112 113
GnmExpr const *
gnm_expr_new_funcall (FunctionDefinition *func, GnmExprList *args)
114
{
115
	GnmExprFunction *ans;
Jody Goldberg's avatar
Jody Goldberg committed
116
	g_return_val_if_fail (func, NULL);
117

118
	ans = CHUNK_ALLOC (GnmExprFunction, expression_pool);
119 120
	if (!ans)
		return NULL;
121

122
	ans->ref_count = 1;
123
	ans->oper = GNM_EXPR_OP_FUNCALL;
Jody Goldberg's avatar
Jody Goldberg committed
124
	func_ref (func);
Jody Goldberg's avatar
Jody Goldberg committed
125
	ans->func = func;;
126 127
	ans->arg_list = args;

128
	return (GnmExpr *)ans;
129
}
130

Jody Goldberg's avatar
Jody Goldberg committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
/***************************************************************************/

#if 0
static guint
gnm_expr_unary_hash (GnmExprUnary const *expr)
{
	return  (GPOINTER_TO_INT (expr->value) * 7) ^
		(guint)(expr->oper);
}
static gboolean
gnm_expr_unary_eq (GnmExprUnary const *a,
		   GnmExprUnary const *b)
{
	return  a->oper == b->oper && a->value == b->value;
}
#endif

148 149
GnmExpr const *
gnm_expr_new_unary  (GnmExprOp op, GnmExpr const *e)
Morten Welinder's avatar
Morten Welinder committed
150
{
151
	GnmExprUnary *ans;
Morten Welinder's avatar
Morten Welinder committed
152

153
	ans = CHUNK_ALLOC (GnmExprUnary, expression_pool);
154 155 156 157
	if (!ans)
		return NULL;

	ans->ref_count = 1;
158
	ans->oper = op;
159
	ans->value = e;
160

161
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
162 163
}

Jody Goldberg's avatar
Jody Goldberg committed
164 165 166 167 168 169 170 171 172 173 174
/***************************************************************************/

#if 0
static guint
gnm_expr_binary_hash (GnmExprBinary const *expr)
{
	return  (GPOINTER_TO_INT (expr->value_a) * 7) ^
		(GPOINTER_TO_INT (expr->value_b) * 3) ^
		(guint)(expr->oper);
}
#endif
Morten Welinder's avatar
Morten Welinder committed
175

176 177
GnmExpr const *
gnm_expr_new_binary (GnmExpr const *l, GnmExprOp op, GnmExpr const *r)
Morten Welinder's avatar
Morten Welinder committed
178
{
179
	GnmExprBinary *ans;
Morten Welinder's avatar
Morten Welinder committed
180

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

185
	ans->ref_count = 1;
186
	ans->oper = op;
187 188
	ans->value_a = l;
	ans->value_b = r;
189

190
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
191 192
}

Jody Goldberg's avatar
Jody Goldberg committed
193 194 195 196 197 198 199 200 201 202
/***************************************************************************/

#if 0
static guint
gnm_expr_name_hash (GnmExprName const *expr)
{
	return GPOINTER_TO_INT (expr->name);
}
#endif

203 204
GnmExpr const *
gnm_expr_new_name (GnmNamedExpr *name,
205
		   Sheet *optional_scope, Workbook *optional_wb_scope)
Morten Welinder's avatar
Morten Welinder committed
206
{
207
	GnmExprName *ans;
Morten Welinder's avatar
Morten Welinder committed
208

209
	ans = CHUNK_ALLOC (GnmExprName, expression_pool);
210 211
	if (!ans)
		return NULL;
212

213
	ans->ref_count = 1;
214
	ans->oper = GNM_EXPR_OP_NAME;
215
	ans->name = name;
216
	expr_name_ref (name);
217

218 219 220
	ans->optional_scope = optional_scope;
	ans->optional_wb_scope = optional_wb_scope;

221
	return (GnmExpr *)ans;
Morten Welinder's avatar
Morten Welinder committed
222
}
223

Jody Goldberg's avatar
Jody Goldberg committed
224 225 226 227 228 229 230 231 232
/***************************************************************************/

#if 0
static guint
gnm_expr_cellref_hash (GnmExprCellRef const *expr)
{
}
#endif

233 234
GnmExpr const *
gnm_expr_new_cellref (CellRef const *cr)
235
{
236
	GnmExprCellRef *ans;
237

238
	ans = CHUNK_ALLOC (GnmExprCellRef, expression_pool);
239 240
	if (!ans)
		return NULL;
241

242
	ans->ref_count = 1;
243
	ans->oper = GNM_EXPR_OP_CELLREF;
244 245
	ans->ref = *cr;

246
	return (GnmExpr *)ans;
247 248
}

Jody Goldberg's avatar
Jody Goldberg committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
/***************************************************************************/

#if 0
static guint
gnm_expr_array_hash (GnmExprArray const *expr)
{
}
#endif

/**
 * gnm_expr_new_array :
 * @x :
 * @y :
 * @cols :
 * @rows :
 * @expr : optionally NULL.
 *
 * Absorb a referernce to @expr if it is non NULL.
 **/
268
GnmExpr const *
Jody Goldberg's avatar
Jody Goldberg committed
269
gnm_expr_new_array (int x, int y, int cols, int rows, GnmExpr const *expr)
270
{
271
	GnmExprArray *ans;
272

273
	ans = CHUNK_ALLOC (GnmExprArray, expression_pool);
274 275
	if (ans == NULL)
		return NULL;
276

277
	ans->ref_count = 1;
278
	ans->oper = GNM_EXPR_OP_ARRAY;
279 280 281 282
	ans->x = x;
	ans->y = y;
	ans->rows = rows;
	ans->cols = cols;
283
	ans->corner.value = NULL;
Jody Goldberg's avatar
Jody Goldberg committed
284
	ans->corner.expr = expr;
285
	return (GnmExpr *)ans;
286 287
}

Jody Goldberg's avatar
Jody Goldberg committed
288 289 290 291 292 293 294 295 296 297 298 299 300 301
/***************************************************************************/

#if 0
static guint
gnm_expr_set_hash (GnmExprSet const *expr)
{
	guint h = expr->oper;
	GnmExprList *l;
	for (l = expr->set; l; l = l->next)
		h = (h * 3) ^ (GPOINTER_TO_INT (l->data));
	return h;
}
#endif

302 303
GnmExpr const *
gnm_expr_new_set (GnmExprList *set)
304
{
305
	GnmExprSet *ans;
306

307
	ans = CHUNK_ALLOC (GnmExprSet, expression_pool);
308 309
	if (!ans)
		return NULL;
310

311
	ans->ref_count = 1;
312
	ans->oper = GNM_EXPR_OP_SET;
313
	ans->set = set;
314

315
	return (GnmExpr *)ans;
316 317
}

Jody Goldberg's avatar
Jody Goldberg committed
318 319
/***************************************************************************/

320 321 322
/**
 * gnm_expr_ref:
 * Increments the ref_count for an expression node.
Arturo Espinosa's avatar
Arturo Espinosa committed
323
 */
324
void
325
gnm_expr_ref (GnmExpr const *expr)
326
{
327 328
	g_return_if_fail (expr != NULL);
	g_return_if_fail (expr->any.ref_count > 0);
329

330
	((GnmExpr *)expr)->any.ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
331 332 333
}

static void
334
do_gnm_expr_unref (GnmExpr const *expr)
Arturo Espinosa's avatar
Arturo Espinosa committed
335
{
336
	if (--((GnmExpr *)expr)->any.ref_count > 0)
Morten Welinder's avatar
Morten Welinder committed
337 338
		return;

339
	switch (expr->any.oper) {
340 341 342 343
	case GNM_EXPR_OP_RANGE_CTOR:
	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
344
		break;
345

346 347
	case GNM_EXPR_OP_FUNCALL:
		gnm_expr_list_unref (expr->func.arg_list);
348
		func_unref (expr->func.func);
Arturo Espinosa's avatar
Arturo Espinosa committed
349 350
		break;

351
	case GNM_EXPR_OP_NAME:
352
		expr_name_unref (expr->name.name);
Michael Meeks's avatar
Michael Meeks committed
353 354
		break;

355 356 357 358 359
	case GNM_EXPR_OP_CONSTANT:
		value_release ((Value *)expr->constant.value);
		break;

	case GNM_EXPR_OP_CELLREF:
Arturo Espinosa's avatar
Arturo Espinosa committed
360 361
		break;

362 363
	case GNM_EXPR_OP_ANY_UNARY:
		do_gnm_expr_unref (expr->unary.value);
Arturo Espinosa's avatar
Arturo Espinosa committed
364
		break;
365

366
	case GNM_EXPR_OP_ARRAY:
367 368 369
		if (expr->array.x == 0 && expr->array.y == 0) {
			if (expr->array.corner.value)
				value_release (expr->array.corner.value);
370
			do_gnm_expr_unref (expr->array.corner.expr);
371
		}
Jody Goldberg's avatar
Jody Goldberg committed
372
		break;
373

374 375
	case GNM_EXPR_OP_SET:
		gnm_expr_list_unref (expr->set.set);
376
		break;
377
	default:
378
		g_warning ("do_gnm_expr_unref error.");
379
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
380
	}
381

382
	CHUNK_FREE (expression_pool, (gpointer)expr);
383 384
}

Morten Welinder's avatar
Morten Welinder committed
385
/*
386 387
 * gnm_expr_unref:
 * Decrements the ref_count for part of a expression.  (All trees are expected
Morten Welinder's avatar
Morten Welinder committed
388 389 390
 * 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.)
 */
391
void
392
gnm_expr_unref (GnmExpr const *expr)
393
{
394 395
	g_return_if_fail (expr != NULL);
	g_return_if_fail (expr->any.ref_count > 0);
396

397
	if (expr->any.ref_count == 1)
398
		do_gnm_expr_unref (expr);
399
	else
400
		((GnmExpr *)expr)->any.ref_count--;
401 402
}

Jody Goldberg's avatar
Jody Goldberg committed
403
/**
404
 * gnm_expr_is_shared : Returns TRUE if the reference count
Jody Goldberg's avatar
Jody Goldberg committed
405 406 407
 *   for the supplied expression is > 1
 */
gboolean
408
gnm_expr_is_shared (GnmExpr const *expr)
Jody Goldberg's avatar
Jody Goldberg committed
409
{
410
	g_return_val_if_fail (expr != NULL, FALSE);
Jody Goldberg's avatar
Jody Goldberg committed
411

412
	return (expr->any.ref_count > 1);
Jody Goldberg's avatar
Jody Goldberg committed
413 414
}

Jody Goldberg's avatar
Jody Goldberg committed
415
/**
416
 * gnm_expr_equal : Returns TRUE if the supplied expressions are exactly the
Jody Goldberg's avatar
Jody Goldberg committed
417 418 419 420 421
 *   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
422
gnm_expr_equal (GnmExpr const *a, GnmExpr const *b)
Jody Goldberg's avatar
Jody Goldberg committed
423 424 425 426 427 428 429 430 431 432 433
{
	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) {
434
	case GNM_EXPR_OP_RANGE_CTOR:
435 436 437
	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
438

439 440
	case GNM_EXPR_OP_ANY_UNARY:
		return gnm_expr_equal (a->unary.value, b->unary.value);
Jody Goldberg's avatar
Jody Goldberg committed
441

442
	case GNM_EXPR_OP_FUNCALL:
443
		return (a->func.func == b->func.func) &&
444
			gnm_expr_list_equal (a->func.arg_list, b->func.arg_list);
Jody Goldberg's avatar
Jody Goldberg committed
445

446
	case GNM_EXPR_OP_NAME:
Jody Goldberg's avatar
Jody Goldberg committed
447 448
		return a->name.name == b->name.name;

449 450
	case GNM_EXPR_OP_CELLREF:
		return cellref_equal (&a->cellref.ref, &b->cellref.ref);
Jody Goldberg's avatar
Jody Goldberg committed
451

452
	case GNM_EXPR_OP_CONSTANT: {
Jody Goldberg's avatar
Jody Goldberg committed
453 454 455 456 457 458 459 460 461 462 463 464 465
		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;
	}

466 467 468
	case GNM_EXPR_OP_ARRAY: {
		GnmExprArray const *aa = &a->array;
		GnmExprArray const *ab = &b->array;
Jody Goldberg's avatar
Jody Goldberg committed
469 470 471 472 473

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

477 478
	case GNM_EXPR_OP_SET:
		return gnm_expr_list_equal (a->set.set, b->set.set);
479

Jody Goldberg's avatar
Jody Goldberg committed
480 481 482 483 484 485 486
	default :
		g_assert_not_reached ();
	}

	return FALSE;
}

Jody Goldberg's avatar
Jody Goldberg committed
487 488
static Value *
cb_range_eval (Sheet *sheet, int col, int row, Cell *cell, void *ignore)
489
{
Jody Goldberg's avatar
Jody Goldberg committed
490 491
	cell_eval (cell);
	return NULL;
492 493
}

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
static Cell *
expr_array_corner (GnmExpr const *expr,
			Sheet const *sheet, CellPos const *pos)
{
	Cell *corner = sheet_cell_get (sheet,
		pos->col - expr->array.x, pos->row - expr->array.y);

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

	return corner;
}

static gboolean
513 514
gnm_expr_extract_ref (CellRef *res, GnmExpr const *expr,
		      EvalPos const *pos, GnmExprEvalFlags flags)
515 516 517 518 519 520 521 522 523
{
	switch (expr->any.oper) {
	case GNM_EXPR_OP_FUNCALL : {
		gboolean failed = TRUE;
		Value *v;
		FunctionEvalInfo ei;
		ei.pos = pos;
		ei.func_call = (GnmExprFunction const *)expr;

524
		v = function_call_with_list (&ei, expr->func.arg_list, flags);
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
		if (v != NULL) {
			if (v->type == VALUE_CELLRANGE &&
			    cellref_equal (&v->v_range.cell.a, &v->v_range.cell.b)) {
				*res = v->v_range.cell.a;
				failed = FALSE;
			}
			value_release (v);
		}
		return failed;
	}

	case GNM_EXPR_OP_CELLREF :
		*res = expr->cellref.ref;
		return FALSE;

	case GNM_EXPR_OP_CONSTANT: {
		Value const *v = expr->constant.value;
		if (v->type == VALUE_CELLRANGE &&
		    cellref_equal (&v->v_range.cell.a, &v->v_range.cell.b)) {
			*res = v->v_range.cell.a;
			return FALSE;
		}
		return TRUE;
	}

	case GNM_EXPR_OP_NAME:
		if (!expr->name.name->active || expr->name.name->builtin)
			return TRUE;
553
		return gnm_expr_extract_ref (res, expr->name.name->t.expr_tree, pos, flags);
554 555 556 557 558 559
	default :
		break;
	}
	return TRUE;
}

560
static Value *
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
handle_empty (Value *res, GnmExprEvalFlags flags)
{
	if (res == NULL)
		return (flags & GNM_EXPR_EVAL_PERMIT_EMPTY)
		    ? NULL : value_new_int (0);

	if (res->type == VALUE_EMPTY) {
		value_release (res);
		return (flags & GNM_EXPR_EVAL_PERMIT_EMPTY)
		    ? NULL : value_new_int (0);
	}
	return res;
}

/**
 * gnm_expr_eval :
 * @expr :
 * @ep   :
 * @flags:
 *
 * if GNM_EXPR_EVAL_PERMIT_EMPTY is not set then return int(0) if the
 * expression returns empty, or the  value of an unused cell.
 */
Value *
gnm_expr_eval (GnmExpr const *expr, EvalPos const *pos,
	       GnmExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
587
{
588
	Value *res = NULL, *a = NULL, *b = NULL;
589

590 591
	g_return_val_if_fail (expr != NULL, handle_empty (NULL, flags));
	g_return_val_if_fail (pos != NULL, handle_empty (NULL, flags));
592

593
	switch (expr->any.oper){
594 595 596 597 598 599
	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: {
600
		ValueCompare comp;
601

602 603
		a = gnm_expr_eval (expr->binary.value_a, pos,
				   flags | GNM_EXPR_EVAL_PERMIT_EMPTY);
Jody Goldberg's avatar
Jody Goldberg committed
604
		if (a != NULL) {
605
			if (a->type == VALUE_CELLRANGE || a->type == VALUE_ARRAY) {
606
				a = value_intersection (a, pos);
Jody Goldberg's avatar
Jody Goldberg committed
607
				if (a == NULL)
608
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
609 610 611
			} else if (a->type == VALUE_ERROR)
				return a;
		}
Morten Welinder's avatar
Morten Welinder committed
612

613 614
		b = gnm_expr_eval (expr->binary.value_b, pos,
				   flags | GNM_EXPR_EVAL_PERMIT_EMPTY);
Jody Goldberg's avatar
Jody Goldberg committed
615 616
		if (b != NULL) {
			Value *res = NULL;
617
			if (b->type == VALUE_CELLRANGE || b->type == VALUE_ARRAY) {
618
				b = value_intersection (b, pos);
Jody Goldberg's avatar
Jody Goldberg committed
619
				if (b == NULL)
620
					res = value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
621 622 623 624 625 626
			} else if (b->type == VALUE_ERROR)
				res = b;

			if (res != NULL) {
				if (a != NULL)
					value_release (a);
627
				return handle_empty (res, flags);
Jody Goldberg's avatar
Jody Goldberg committed
628
			}
Morten Welinder's avatar
Morten Welinder committed
629
		}
630

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

633 634 635 636
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
637

Michael Meeks's avatar
Michael Meeks committed
638
		if (comp == TYPE_MISMATCH) {
639 640 641 642
			/* TODO TODO TODO : Make error more informative
			 *    regarding what is comparing to what
			 */
			/* For equality comparisons even errors are ok */
643
			if (expr->any.oper == GNM_EXPR_OP_EQUAL)
644
				return value_new_bool (FALSE);
645
			if (expr->any.oper == GNM_EXPR_OP_NOT_EQUAL)
646 647
				return value_new_bool (TRUE);

648
			return value_new_error (pos, gnumeric_err_VALUE);
649
		}
650

651
		switch (expr->any.oper) {
652
		case GNM_EXPR_OP_EQUAL:
653
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
654 655
			break;

656
		case GNM_EXPR_OP_GT:
657
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
658 659
			break;

660
		case GNM_EXPR_OP_LT:
661
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
662 663
			break;

664
		case GNM_EXPR_OP_NOT_EQUAL:
665
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
666 667
			break;

668
		case GNM_EXPR_OP_LTE:
669
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
670 671
			break;

672
		case GNM_EXPR_OP_GTE:
673
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
674
			break;
675

Arturo Espinosa's avatar
Arturo Espinosa committed
676
		default:
677
			g_assert_not_reached ();
678
			res = value_new_error (pos,
679
						_("Internal type error"));
Arturo Espinosa's avatar
Arturo Espinosa committed
680
		}
Morten Welinder's avatar
Morten Welinder committed
681
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
682
	}
683

684 685 686 687 688
	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:
689 690 691 692 693 694 695 696 697
		/*
		 * 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
		 */

698
	        /* Guarantees a != NULL */
699
		a = gnm_expr_eval (expr->binary.value_a, pos,
700
				   flags & (~GNM_EXPR_EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
701 702

		/* Handle implicit intersection */
703
		if (a->type == VALUE_CELLRANGE || a->type == VALUE_ARRAY) {
704
			a = value_intersection (a, pos);
Jody Goldberg's avatar
Jody Goldberg committed
705
			if (a == NULL)
706
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
707 708
		}

709 710
		/* 1) Error from A */
		if (a->type == VALUE_ERROR)
711
			return value_error_set_pos (&a->v_err, pos);
712

713
		/* 2) #!VALUE error if A is not a number */
714
		if (a->type == VALUE_STRING) {
715
			Value *tmp = format_match_number (a->v_str.val->str, NULL);
716 717 718 719 720 721

			value_release (a);
			if (tmp == NULL)
				return value_new_error (pos, gnumeric_err_VALUE);
			a = tmp;
		} else if (!VALUE_IS_NUMBER (a)) {
722
			value_release (a);
723
			return value_new_error (pos, gnumeric_err_VALUE);
724 725
		}

726
	        /* Guarantees that b != NULL */
727
		b = gnm_expr_eval (expr->binary.value_b, pos,
728
				   flags & (~GNM_EXPR_EVAL_PERMIT_EMPTY));
Arturo Espinosa's avatar
Arturo Espinosa committed
729

Jody Goldberg's avatar
Jody Goldberg committed
730
		/* Handle implicit intersection */
731
		if (b->type == VALUE_CELLRANGE || b->type == VALUE_ARRAY) {
732
			b = value_intersection (a, pos);
Jody Goldberg's avatar
Jody Goldberg committed
733
			if (b == NULL)
734
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
735 736
		}

737 738
		/* 3) Error from B */
		if (b->type == VALUE_ERROR) {
739
			value_release (a);
740
			return value_error_set_pos (&b->v_err, pos);
Arturo Espinosa's avatar
Arturo Espinosa committed
741
		}
742

743
		/* 4) #!VALUE error if B is not a number */
744
		if (b->type == VALUE_STRING) {
745
			Value *tmp = format_match_number (b->v_str.val->str, NULL);
746 747 748 749 750 751 752 753

			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)) {
754 755
			value_release (a);
			value_release (b);
756
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
757
		}
758

759
		if (a->type != VALUE_FLOAT && b->type != VALUE_FLOAT){
Morten Welinder's avatar
Morten Welinder committed
760
			int ia = value_get_as_int (a);
761
			int ib = value_get_as_int (b);
762
			gnum_float dres;
763 764
			int ires;

Morten Welinder's avatar
Morten Welinder committed
765 766
			value_release (a);
			value_release (b);
767

768 769
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
770
			switch (expr->any.oper){
771
			case GNM_EXPR_OP_ADD:
772
				dres = (gnum_float)ia + (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
773
				break;
774

775
			case GNM_EXPR_OP_SUB:
776
				dres = (gnum_float)ia - (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
777
				break;
778

779
			case GNM_EXPR_OP_MULT:
780
				dres = (gnum_float)ia * (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
781
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
782

783
			case GNM_EXPR_OP_DIV:
784
				if (ib == 0)
785
					return value_new_error (pos, gnumeric_err_DIV0);
786
				dres = (gnum_float)ia / (gnum_float)ib;
Morten Welinder's avatar
Morten Welinder committed
787
				break;
788

789
			case GNM_EXPR_OP_EXP:
790
				if (ia == 0 && ib <= 0)
791
					return value_new_error (pos, gnumeric_err_NUM);
792
				dres = powgnum ((gnum_float)ia, (gnum_float)ib);
793 794
				if (!finitegnum (dres))
					return value_new_error (pos, gnumeric_err_NUM);
Morten Welinder's avatar
Morten Welinder committed
795
				break;
796

Arturo Espinosa's avatar
Arturo Espinosa committed
797
			default:
798
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
799
			}
Morten Welinder's avatar
Morten Welinder committed
800 801 802 803 804 805

			ires = (int)dres;
			if (dres == ires)
				return value_new_int (ires);
			else
				return value_new_float (dres);
Arturo Espinosa's avatar
Arturo Espinosa committed
806
		} else {
807 808
			gnum_float const va = value_get_as_float (a);
			gnum_float const vb = value_get_as_float (b);
809 810
			value_release (a);
			value_release (b);
811

812
			switch (expr->any.oper){
813
			case GNM_EXPR_OP_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
814
				return value_new_float (va + vb);
815

816
			case GNM_EXPR_OP_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
817
				return value_new_float (va - vb);
818

819
			case GNM_EXPR_OP_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
820
				return value_new_float (va * vb);
821

822
			case GNM_EXPR_OP_DIV:
823
				return (vb == 0.0)
824
				    ? value_new_error (pos,
825
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
826
				    : value_new_float (va / vb);
827

828 829
			case GNM_EXPR_OP_EXP: {
				gnum_float res;
830 831
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
832
					return value_new_error (pos, gnumeric_err_NUM);
833 834 835 836 837 838

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

Arturo Espinosa's avatar
Arturo Espinosa committed
840
			default:
841
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
842 843
			}
		}
844
		return value_new_error (pos, _("Unknown operator"));
845

846 847 848
	case GNM_EXPR_OP_PERCENTAGE:
	case GNM_EXPR_OP_UNARY_NEG:
	case GNM_EXPR_OP_UNARY_PLUS:
849
	        /* Garantees that a != NULL */
850
		a = gnm_expr_eval (expr->unary.value, pos,
851
				   flags & (~GNM_EXPR_EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
852 853

		/* Handle implicit intersection */
854
		if (a->type == VALUE_CELLRANGE || a->type == VALUE_ARRAY) {
855
			a = value_intersection (a, pos);
Jody Goldberg's avatar
Jody Goldberg committed
856
			if (a == NULL)
857
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
858 859
		}

860 861
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
862

863
		if (expr->any.oper == GNM_EXPR_OP_UNARY_PLUS)
Jody Goldberg's avatar
Jody Goldberg committed
864 865
			return a;

866 867
		if (!VALUE_IS_NUMBER (a)){
			value_release (a);
868
			return value_new_error (pos, gnumeric_err_VALUE);
869
		}
870
		if (expr->any.oper == GNM_EXPR_OP_UNARY_NEG) {
Jody Goldberg's avatar
Jody Goldberg committed
871
			if (a->type == VALUE_INTEGER)
872
				res = value_new_int (-a->v_int.val);
Jody Goldberg's avatar
Jody Goldberg committed
873
			else if (a->type == VALUE_FLOAT)
874
				res = value_new_float (-a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
875
			else
876
				res = value_new_bool (!a->v_float.val);
877 878 879 880 881
			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
882
			res = value_new_float (value_get_as_float (a) / 100);
883 884 885
			VALUE_FMT (res) = style_format_default_percentage ();
			style_format_ref (VALUE_FMT (res));
		}
886
		value_release (a);
Morten Welinder's avatar
Morten Welinder committed
887
		return res;
888

889
	case GNM_EXPR_OP_CAT:
890 891 892
#warning BUG does not support intersection
		a = gnm_expr_eval (expr->binary.value_a, pos,
				   flags | GNM_EXPR_EVAL_PERMIT_EMPTY);
893
		if (a != NULL && a->type == VALUE_ERROR)
894
			return a;
895 896
		b = gnm_expr_eval (expr->binary.value_b, pos,
				   flags | GNM_EXPR_EVAL_PERMIT_EMPTY);
897 898 899
		if (b != NULL && b->type == VALUE_ERROR) {
			if (a != NULL)
				value_release (a);
900
			return b;
901 902
		}

903 904 905 906 907 908 909 910 911 912 913 914
		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);
915
			res = value_new_string_nocopy (tmp);
Morten Welinder's avatar
Morten Welinder committed
916 917
			value_release (a);
			value_release (b);
918 919
		}

Morten Welinder's avatar
Morten Welinder committed
920
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
921

922
	case GNM_EXPR_OP_FUNCALL: {
923 924
		FunctionEvalInfo ei;
		ei.pos = pos;
925
		ei.func_call = (GnmExprFunction const *)expr;
926
		return handle_empty (function_call_with_list (&ei, expr->func.arg_list, flags), flags);
927
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
928

929
	case GNM_EXPR_OP_NAME:
930
		if (expr->name.name->active)
931
			return handle_empty (expr_name_eval (expr->name.name, pos, flags), flags);
932
		return value_new_error (pos, gnumeric_err_REF);
Michael Meeks's avatar
Michael Meeks committed
933

934 935
	case GNM_EXPR_OP_CELLREF: {
		CellRef const * const ref = &expr->cellref.ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
936
		Cell *cell;
937
		CellPos dest;
938

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

941 942
		cell = sheet_cell_get (eval_sheet (ref->sheet, pos->sheet),
			dest.col, dest.row);
943
		if (cell == NULL)
944
			return handle_empty (NULL, flags);
945

Jody Goldberg's avatar
Jody Goldberg committed
946
		cell_eval (cell);