expr.c 49.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
/*
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-name.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
13
#include "eval.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
14
#include "format.h"
15
#include "func.h"
Jody Goldberg's avatar
Jody Goldberg committed
16
#include "cell.h"
Jody Goldberg's avatar
Jody Goldberg committed
17 18
#include "sheet.h"
#include "str.h"
19
#include "value.h"
20
#include "parse-util.h"
21
#include "ranges.h"
22
#include "number-match.h"
23
#include "workbook.h"
Jeffrey Stedfast's avatar
Jeffrey Stedfast committed
24
#include "gutils.h"
25
#include "parse-util.h"
26

27 28
#include <math.h>
#include <string.h>
29
#include <libgnome/gnome-i18n.h>
30

31 32
/***************************************************************************/

33
ExprTree *
Morten Welinder's avatar
Morten Welinder committed
34
expr_tree_new_constant (Value *v)
35
{
36
	ExprConstant *ans;
37

38
	ans = g_new (ExprConstant, 1);
39 40
	if (!ans)
		return NULL;
41

42
	ans->ref_count = 1;
Jody Goldberg's avatar
Jody Goldberg committed
43
	*((Operation *)&(ans->oper)) = OPER_CONSTANT;
44
	ans->value = v;
45

46
	return (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
47 48
}

49 50 51
ExprTree *
expr_tree_new_error (char const *txt)
{
Jody Goldberg's avatar
Jody Goldberg committed
52
	FunctionDefinition *func;
53
	ExprList *args = NULL;
54

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

Jody Goldberg's avatar
Jody Goldberg committed
62
	func_ref (func);
63 64 65 66
	return expr_tree_new_funcall (func, args);
}

ExprTree *
67
expr_tree_new_funcall (FunctionDefinition *func, ExprList *args)
68 69
{
	ExprFunction *ans;
Jody Goldberg's avatar
Jody Goldberg committed
70
	g_return_val_if_fail (func, NULL);
71 72 73 74

	ans = g_new (ExprFunction, 1);
	if (!ans)
		return NULL;
75

76 77
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_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 82 83
	ans->arg_list = args;

	return (ExprTree *)ans;
}
84

Morten Welinder's avatar
Morten Welinder committed
85 86 87
ExprTree *
expr_tree_new_unary  (Operation op, ExprTree *e)
{
88
	ExprUnary *ans;
Morten Welinder's avatar
Morten Welinder committed
89

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

	ans->ref_count = 1;
Jody Goldberg's avatar
Jody Goldberg committed
95
	*((Operation *)&(ans->oper)) = op;
96
	ans->value = e;
97

98
	return (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
99 100 101 102 103 104
}


ExprTree *
expr_tree_new_binary (ExprTree *l, Operation op, ExprTree *r)
{
105
	ExprBinary *ans;
Morten Welinder's avatar
Morten Welinder committed
106

107
	ans = g_new (ExprBinary, 1);
108 109
	if (!ans)
		return NULL;
110

111
	ans->ref_count = 1;
Jody Goldberg's avatar
Jody Goldberg committed
112
	*((Operation *)&(ans->oper)) = op;
113 114
	ans->value_a = l;
	ans->value_b = r;
115

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

ExprTree *
120 121
expr_tree_new_name (NamedExpression *name,
		    Sheet *optional_scope, Workbook *optional_wb_scope)
Morten Welinder's avatar
Morten Welinder committed
122
{
123
	ExprName *ans;
Morten Welinder's avatar
Morten Welinder committed
124

125
	ans = g_new (ExprName, 1);
126 127
	if (!ans)
		return NULL;
128

129
	ans->ref_count = 1;
130 131
	*((Operation *)&(ans->oper)) = OPER_NAME;
	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 (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
138
}
139 140 141 142 143 144 145 146 147

ExprTree *
expr_tree_new_var (CellRef const *cr)
{
	ExprVar *ans;

	ans = g_new (ExprVar, 1);
	if (!ans)
		return NULL;
148

149 150 151 152 153 154 155 156
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_VAR;
	ans->ref = *cr;

	return (ExprTree *)ans;
}

ExprTree *
157
expr_tree_new_array (int x, int y, int cols, int rows)
158 159 160 161 162 163
{
	ExprArray *ans;

	ans = g_new (ExprArray, 1);
	if (ans == NULL)
		return NULL;
164

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

176
ExprTree *
177
expr_tree_new_set (ExprList *set)
178
{
179
	ExprSet *ans;
180

181 182 183
	ans = g_new (ExprSet, 1);
	if (!ans)
		return NULL;
184

185 186 187
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_SET;
	ans->set = set;
188

189
	return (ExprTree *)ans;
190 191
}

192 193 194
static Cell *
expr_tree_array_corner (ExprTree const *expr,
			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 203 204 205
	g_return_val_if_fail (corner->base.expression != (void *)0xdeadbeef, NULL);
	g_return_val_if_fail (corner->base.expression->any.oper == OPER_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);
206

207
	return corner;
208 209
}

Arturo Espinosa's avatar
Arturo Espinosa committed
210 211 212 213
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
214
void
215
expr_tree_ref (ExprTree *expr)
216
{
217 218
	g_return_if_fail (expr != NULL);
	g_return_if_fail (expr->any.ref_count > 0);
219

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

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

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

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

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

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

246
	case OPER_ANY_BINARY:
247 248
		do_expr_tree_unref (expr->binary.value_a);
		do_expr_tree_unref (expr->binary.value_b);
Arturo Espinosa's avatar
Arturo Espinosa committed
249 250
		break;

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

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

270
	g_free (expr);
271 272
}

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

285
	do_expr_tree_unref (expr);
286 287
}

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

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

Jody Goldberg's avatar
Jody Goldberg committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
/**
 * expr_tree_equal : Returns TRUE if the supplied expressions are exactly the
 *   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
expr_tree_equal (ExprTree const *a, ExprTree const *b)
{
	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) {
	case OPER_ANY_BINARY:
		return	expr_tree_equal (a->binary.value_a, b->binary.value_a) &&
			expr_tree_equal (a->binary.value_b, b->binary.value_b);

	case OPER_ANY_UNARY:
		return expr_tree_equal (a->unary.value, b->unary.value);

326 327 328
	case OPER_FUNCALL:
		return (a->func.func == b->func.func) &&
			expr_list_equal (a->func.arg_list, b->func.arg_list);
Jody Goldberg's avatar
Jody Goldberg committed
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360

	case OPER_NAME:
		return a->name.name == b->name.name;

	case OPER_VAR:
		return cellref_equal (&a->var.ref, &b->var.ref);

	case OPER_CONSTANT: {
		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;
	}

	case OPER_ARRAY: {
		ExprArray const *aa = &a->array;
		ExprArray const *ab = &b->array;

		return	aa->cols == ab->cols &&
			aa->rows == ab->rows &&
			aa->x == ab->x &&
			aa->y == ab->y &&
			expr_tree_equal (aa->corner.expr, ab->corner.expr);
	}

361 362 363
	case OPER_SET:
		return expr_list_equal (a->set.set, b->set.set);

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

	return FALSE;
}

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

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

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

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

423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
/**
 * expr_array_intersection :
 * @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 *
expr_array_intersection (Value *a)
{
	Value *tmp = value_duplicate (a->v_array.vals [0][0]);
	value_release (a);
	return tmp;
}

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

452
static Value *
453
expr_eval_real (ExprTree const *expr, EvalPos const *pos,
454
		ExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
455
{
456
	Value *res = NULL, *a = NULL, *b = NULL;
457

458
	g_return_val_if_fail (expr != NULL, NULL);
459
	g_return_val_if_fail (pos != NULL, NULL);
460

461
	switch (expr->any.oper){
462 463 464 465 466 467
	case OPER_EQUAL:
	case OPER_NOT_EQUAL:
	case OPER_GT:
	case OPER_GTE:
	case OPER_LT:
	case OPER_LTE: {
468
		ValueCompare comp;
469

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

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

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

507 508 509 510
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
511

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

522
			return value_new_error (pos, gnumeric_err_VALUE);
523
		}
524

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

530
		case OPER_GT:
531
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
532 533
			break;

534
		case OPER_LT:
535
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
536 537
			break;

538 539
		case OPER_NOT_EQUAL:
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
540 541
			break;

542 543
		case OPER_LTE:
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
544 545
			break;

546 547
		case OPER_GTE:
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
548
			break;
549

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

558 559 560 561 562
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
563 564 565 566 567 568 569 570 571
		/*
		 * 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
		 */

572
	        /* Guarantees a != NULL */
573
		a = expr_eval (expr->binary.value_a, pos,
574
			       flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
575 576 577

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

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

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

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

604
	        /* Guarantees that b != NULL */
605
		b = expr_eval (expr->binary.value_b, pos,
606
			       flags & (~EVAL_PERMIT_EMPTY));
Arturo Espinosa's avatar
Arturo Espinosa committed
607

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

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

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

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

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

Morten Welinder's avatar
Morten Welinder committed
647 648
			value_release (a);
			value_release (b);
649

650 651
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
652
			switch (expr->any.oper){
653
			case OPER_ADD:
654
				dres = (gnum_float)ia + (gnum_float)ib;
655 656 657 658
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
659
					return value_new_float ((gnum_float) dres);
660

661
			case OPER_SUB:
662
				dres = (gnum_float)ia - (gnum_float)ib;
663 664 665 666
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
667
					return value_new_float ((gnum_float) dres);
668

669
			case OPER_MULT:
670
				dres = (gnum_float)ia * (gnum_float)ib;
671 672 673 674
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
675
					return value_new_float ((gnum_float) dres);
Arturo Espinosa's avatar
Arturo Espinosa committed
676

677
			case OPER_DIV:
678
				if (ib == 0)
679
					return value_new_error (pos, gnumeric_err_DIV0);
680
				dres = (gnum_float)ia / (gnum_float)ib;
681 682 683 684
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
685
					return value_new_float ((gnum_float) dres);
686 687

			case OPER_EXP:
688
				if (ia == 0 && ib <= 0)
689
					return value_new_error (pos, gnumeric_err_NUM);
690
				dres = powgnum ((gnum_float)ia, (gnum_float)ib);
691 692 693 694
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
695
					return value_new_float ((gnum_float) dres);
696

Arturo Espinosa's avatar
Arturo Espinosa committed
697
			default:
698
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
699 700
			}
		} else {
701 702
			gnum_float const va = value_get_as_float (a);
			gnum_float const vb = value_get_as_float (b);
703 704
			value_release (a);
			value_release (b);
705

706
			switch (expr->any.oper){
707
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
708
				return value_new_float (va + vb);
709

710
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
711
				return value_new_float (va - vb);
712

713
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
714
				return value_new_float (va * vb);
715

716
			case OPER_DIV:
717
				return (vb == 0.0)
718
				    ? value_new_error (pos,
719
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
720
				    : value_new_float (va / vb);
721

722
			case OPER_EXP:
723 724
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
725
					return value_new_error (pos, gnumeric_err_NUM);
726
				return value_new_float (powgnum (va, vb));
727

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

Jody Goldberg's avatar
Jody Goldberg committed
734
	case OPER_PERCENT:
Jody Goldberg's avatar
Jody Goldberg committed
735 736
	case OPER_UNARY_NEG:
	case OPER_UNARY_PLUS:
737
	        /* Garantees that a != NULL */
738 739
		a = expr_eval (expr->unary.value, pos,
			flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
740 741 742

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
743
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
744
			if (a == NULL)
745
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
746
		} else if (a->type == VALUE_ARRAY) {
747 748 749
			a = expr_array_intersection (a);
			if (a == NULL)
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
750 751
		}

752 753
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
754

755
		if (expr->any.oper == OPER_UNARY_PLUS)
Jody Goldberg's avatar
Jody Goldberg committed
756 757
			return a;

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

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

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

Morten Welinder's avatar
Morten Welinder committed
810
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
811

812 813 814
	case OPER_FUNCALL: {
		FunctionEvalInfo ei;
		ei.pos = pos;
815
		ei.func_call = (ExprFunction const *)expr;
816 817 818 819

		/*if (flags & EVAL_PERMIT_NON_SCALAR)*/
		return function_call_with_list (&ei, expr->func.arg_list);
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
820

Michael Meeks's avatar
Michael Meeks committed
821
	case OPER_NAME:
822 823 824
		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
825

826
	case OPER_VAR: {
827
		CellRef const * const ref = &expr->var.ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
828
		Cell *cell;
829
		CellPos dest;
830

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

833 834
		cell = sheet_cell_get (eval_sheet (ref->sheet, pos->sheet),
			dest.col, dest.row);
835 836
		if (cell == NULL)
			return NULL;
837

Jody Goldberg's avatar
Jody Goldberg committed
838
		cell_eval (cell);
839

840
		return value_duplicate (cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
841
	}
842

843
	case OPER_CONSTANT:
844
		res = expr->constant.value;
845 846
		if (res->type != VALUE_CELLRANGE)
			return value_duplicate (res);
847
		if (flags & EVAL_PERMIT_NON_SCALAR) {
Jody Goldberg's avatar
Jody Goldberg committed
848 849
			workbook_foreach_cell_in_range (pos, res, TRUE,
							cb_range_eval, NULL);
850 851 852 853 854 855 856 857 858
			return value_duplicate (res);
		} else {
			/*
			 * 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.
			 */
859 860
			CellRef const * const ref_a = & res->v_range.cell.a;
			CellRef const * const ref_b = & res->v_range.cell.b;
861 862
			gboolean found = FALSE;

863 864
			if (ref_a->sheet == ref_b->sheet) {
				CellPos a, b;
865 866 867
				int c = pos->eval.col;
				int r = pos->eval.row;

868 869 870 871 872
				cellref_get_abs_pos (ref_a, &pos->eval, &a);
				cellref_get_abs_pos (ref_b, &pos->eval, &b);
				if (a.row == b.row) {
					if (a.col <= c && c <= b.col) {
						r = a.row;
873 874
						found = TRUE;
					}
875 876 877
				} else if (a.col == b.col) {
					if (a.row <= r && r <= b.row) {
						c = a.col;
878 879 880 881 882 883 884 885
						found = TRUE;
					}
				}
				if (found) {
					Cell * cell = sheet_cell_get (pos->sheet, c, r);
					if (cell == NULL)
						return NULL;

Jody Goldberg's avatar
Jody Goldberg committed
886
					cell_eval (cell);
887 888 889 890 891 892

					return value_duplicate (cell->value);
				}
			}
			return value_new_error (pos, gnumeric_err_VALUE);
		}
893

894 895 896
	case OPER_ARRAY:
	{
		/* The upper left corner manages the recalc of the expr */
897 898
		int x = expr->array.x;
		int y = expr->array.y;
899
		if (x == 0 && y == 0){
900
			/* Release old value if necessary */
901
			a = expr->array.corner.value;
902 903 904
			if (a != NULL)
				value_release (a);

905 906 907 908
			/*
			 * FIXME : Call a wrapper routine that will iterate
			 * over the the array and evaluate the expression for
			 * all elements
Jody Goldberg's avatar
Jody Goldberg committed
909
			 *
910 911
			 * Figure out when to iterate and when to do array
			 * operations.
Jody Goldberg's avatar
Jody Goldberg committed
912
			 * ie
913 914
			 * 	A1:A3 = '=B1:B3^2'
			 * Will iterate over all the elements and re-evaluate.
Jody Goldberg's avatar
Jody Goldberg committed
915
			 * whereas
916 917
			 *	 A1:A3 = '=bob(B1:B3)'
			 * Will call bob once if it returns an array.
Jody Goldberg's avatar
Jody Goldberg committed
918
			 *
919 920 921 922
			 * This may be as simple as evaluating the corner.  If
			 * that is is an array return the result, else build an
			 * array and iterate over the elements, but that theory
			 * needs validation.
Jody Goldberg's avatar
Jody Goldberg committed
923
			 */
924
			a = expr_eval_real (expr->array.corner.expr, pos,
Jody Goldberg's avatar
Jody Goldberg committed
925
					    EVAL_PERMIT_NON_SCALAR);