expr.c 37.6 KB
Newer Older
Miguel de Icaza's avatar
Miguel de Icaza committed
1
/*
Morten Welinder's avatar
Morten Welinder committed
2
 * expr.c: Expression evaluation in Gnumeric
Miguel de Icaza's avatar
Miguel de Icaza committed
3 4 5 6
 *
 * Author:
 *   Miguel de Icaza (miguel@gnu.org).
 */
7
#include <config.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
8
#include <gnome.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
9
#include <math.h>
10
#include <string.h>
11
#include <locale.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
12
#include "gnumeric.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
13
#include "expr.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
14
#include "eval.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
15
#include "format.h"
16
#include "func.h"
17
#include "utils.h"
18
#include "ranges.h"
19

20
EvalPosition *
21
eval_pos_init (EvalPosition *eval_pos, Sheet *sheet, int col, int row)
22
{
23 24 25 26 27
	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (eval_pos != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);

	eval_pos->sheet = sheet;
Jody Goldberg's avatar
Jody Goldberg committed
28 29
	eval_pos->eval.col = col;
	eval_pos->eval.row = row;
30

31
	return eval_pos;
32
}
33

34 35 36 37 38 39 40 41 42 43 44 45 46
ParsePosition *
parse_pos_init (ParsePosition *pp, Workbook *wb, int col, int row)
{
	g_return_val_if_fail (wb != NULL, NULL);
	g_return_val_if_fail (pp != NULL, NULL);

	pp->wb  = wb;
	pp->col = col;
	pp->row = row;

	return pp;
}

47
EvalPosition *
48
eval_pos_cell (EvalPosition *eval_pos, Cell *cell)
49
{
50 51 52
	g_return_val_if_fail (eval_pos != NULL, NULL);
	g_return_val_if_fail (cell != NULL, NULL);
	g_return_val_if_fail (cell->sheet != NULL, NULL);
53 54
	g_return_val_if_fail (IS_SHEET (cell->sheet), NULL);

55 56 57 58 59
	return eval_pos_init (
		eval_pos,
		cell->sheet,
		cell->col->pos,
		cell->row->pos);
60
}
61

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
ParsePosition *
parse_pos_cell (ParsePosition *pp, Cell *cell)
{
	g_return_val_if_fail (pp != NULL, NULL);
	g_return_val_if_fail (cell != NULL, NULL);
	g_return_val_if_fail (cell->sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (cell->sheet), NULL);
	g_return_val_if_fail (cell->sheet->workbook != NULL, NULL);

	return parse_pos_init (
		pp,
		cell->sheet->workbook,
		cell->col->pos,
		cell->row->pos);
}

78
ExprTree *
Morten Welinder's avatar
Morten Welinder committed
79
expr_tree_new_constant (Value *v)
80
{
81 82 83
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
84 85 86 87 88 89 90
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_CONSTANT;
	ans->u.constant = v;

Morten Welinder's avatar
Morten Welinder committed
91 92 93 94 95 96 97 98 99
	return ans;
}

ExprTree *
expr_tree_new_unary  (Operation op, ExprTree *e)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
100 101 102 103 104 105 106
	if (!ans)
		return NULL;

	ans->ref_count = 1;
	ans->oper = op;
	ans->u.value = e;

Morten Welinder's avatar
Morten Welinder committed
107 108 109 110 111 112 113 114 115 116
	return ans;
}


ExprTree *
expr_tree_new_binary (ExprTree *l, Operation op, ExprTree *r)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
117 118 119 120 121 122 123 124
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = op;
	ans->u.binary.value_a = l;
	ans->u.binary.value_b = r;

Morten Welinder's avatar
Morten Welinder committed
125 126 127 128 129 130 131 132 133 134
	return ans;
}

ExprTree *
expr_tree_new_funcall (Symbol *sym, GList *args)
{
	ExprTree *ans;
	g_return_val_if_fail (sym, NULL);

	ans = g_new (ExprTree, 1);
135 136 137 138 139 140 141 142
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_FUNCALL;
	ans->u.function.symbol = sym;;
	ans->u.function.arg_list = args;

Morten Welinder's avatar
Morten Welinder committed
143 144
	return ans;
}
145
       
146 147 148 149 150 151 152 153 154 155 156
int
expr_tree_get_const_int (ExprTree const * const expr)
{
	g_return_val_if_fail (expr != NULL, 0);
	g_return_val_if_fail (expr->oper == OPER_CONSTANT, 0);
	g_return_val_if_fail (expr->u.constant, 0);
	g_return_val_if_fail (expr->u.constant->type == VALUE_INTEGER, 0);

	return expr->u.constant->v.v_int;
}

157 158 159 160 161 162 163 164 165 166 167
char const *
expr_tree_get_const_str (ExprTree const *const expr)
{
	g_return_val_if_fail (expr != NULL, NULL);
	g_return_val_if_fail (expr->oper == OPER_CONSTANT, NULL);
	g_return_val_if_fail (expr->u.constant, NULL);
	g_return_val_if_fail (expr->u.constant->type == VALUE_STRING, NULL);

	return expr->u.constant->v.str->str;
}

168
ExprTree *
169
expr_parse_string (const char *expr, const ParsePosition *pp,
170 171 172 173 174
		   const char **desired_format, char **error_msg)
{
	ExprTree *tree;
	g_return_val_if_fail (expr != NULL, NULL);

175
	switch (gnumeric_expr_parser (expr, pp, desired_format, &tree)) {
176 177
	case PARSE_OK:
		*error_msg = NULL;
178 179
		/* What kind of joke is this?  -- MW.  */
		/* tree->ref_count = 1; */
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
		return tree;

	case PARSE_ERR_SYNTAX:
		*error_msg = _("Syntax error");
		break;

	case PARSE_ERR_NO_QUOTE:
		*error_msg = _("Missing quote");
		break;
	default:
		g_assert_not_reached ();
		*error_msg = _("Impossible!");
		break;
	}
	return NULL;
}

Michael Meeks's avatar
Michael Meeks committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
ExprTree *
expr_tree_new_name (const ExprName *name)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_NAME;
	ans->u.name = name;

	return ans;
}
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

/*ExprTree *
expr_tree_new (void)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_CONSTANT;
	ans->u.constant = NULL;
	return ans;
}*/
Morten Welinder's avatar
Morten Welinder committed
227 228 229 230 231 232 233

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

	ans = g_new (ExprTree, 1);
234 235 236 237 238 239 240
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_VAR;
	ans->u.ref = *cr;

241 242 243
	return ans;
}

Morten Welinder's avatar
Morten Welinder committed
244 245 246 247
ExprTree *
expr_tree_new_error (const char *txt)
{
	Symbol *func;
Morten Welinder's avatar
Morten Welinder committed
248 249 250 251 252 253 254 255 256
	GList *args = NULL;

	if (strcmp (txt, gnumeric_err_NA) == 0) {
		func = symbol_lookup (global_symbol_table, "NA");
	} else {
		func = symbol_lookup (global_symbol_table, "ERROR");
		args = g_list_prepend (NULL,
				       expr_tree_new_constant (value_new_string (txt)));
	}
Morten Welinder's avatar
Morten Welinder committed
257 258

	symbol_ref (func);
Morten Welinder's avatar
Morten Welinder committed
259
	return expr_tree_new_funcall (func, args);
Morten Welinder's avatar
Morten Welinder committed
260 261
}

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
ExprTree *
expr_tree_array_formula (int const x, int const y, int const rows, int const cols)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (ans == NULL)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_ARRAY;
	ans->u.array.x = x;
	ans->u.array.y = y;
	ans->u.array.rows = rows;
	ans->u.array.cols = cols;
	ans->u.array.corner.func.value = NULL;
	ans->u.array.corner.func.expr = NULL;
	ans->u.array.corner.cell = NULL;
	return ans;
}


static ExprTree *
285
expr_tree_array_formula_corner (ExprTree const *expr, EvalPosition const *pos)
286
{
287
	Cell * corner = expr->u.array.corner.cell;
288

289 290 291 292 293 294
	/* Attempt to set the corner if it is not already set */
	if (corner == NULL) {
		g_return_val_if_fail (pos != NULL, NULL);
		g_return_val_if_fail (pos->sheet != NULL, NULL);

		corner = sheet_cell_get (pos->sheet,
Jody Goldberg's avatar
Jody Goldberg committed
295 296
					 pos->eval.col - expr->u.array.x,
					 pos->eval.row - expr->u.array.y);
297 298 299 300
		((ExprTree *)expr)->u.array.corner.cell = corner;
	}

	g_return_val_if_fail (corner != NULL, NULL);
301 302 303 304 305
	g_return_val_if_fail (corner->parsed_node != NULL, NULL);

	/* Sanity check incase the corner gets removed for some reason */
	g_return_val_if_fail (corner->parsed_node != (void *)0xdeadbeef, NULL);
	g_return_val_if_fail (corner->parsed_node->oper == OPER_ARRAY, NULL);
306 307
	g_return_val_if_fail (corner->parsed_node->u.array.x == 0, NULL);
	g_return_val_if_fail (corner->parsed_node->u.array.y == 0, NULL);
308 309 310 311

	return corner->parsed_node;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
312 313 314 315
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
316 317 318 319 320 321
void
expr_tree_ref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Morten Welinder's avatar
Morten Welinder committed
322
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
323 324 325 326 327
}

static void
do_expr_tree_unref (ExprTree *tree)
{
Morten Welinder's avatar
Morten Welinder committed
328 329 330
	if (--tree->ref_count > 0)
		return;

Arturo Espinosa's avatar
Arturo Espinosa committed
331
	switch (tree->oper){
332
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
333
		break;
334

335
	case OPER_CONSTANT:
Morten Welinder's avatar
Morten Welinder committed
336
		value_release (tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
337
		break;
338

Morten Welinder's avatar
Morten Welinder committed
339 340 341 342 343 344 345
	case OPER_FUNCALL: {
		GList *l;

		for (l = tree->u.function.arg_list; l; l = l->next)
			do_expr_tree_unref (l->data);
		g_list_free (tree->u.function.arg_list);
		symbol_unref (tree->u.function.symbol);
Arturo Espinosa's avatar
Arturo Espinosa committed
346
		break;
Morten Welinder's avatar
Morten Welinder committed
347
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
348

Michael Meeks's avatar
Michael Meeks committed
349 350 351
	case OPER_NAME:
		break;

352
	case OPER_ANY_BINARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
353 354 355 356
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

357
	case OPER_ANY_UNARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
358 359
		do_expr_tree_unref (tree->u.value);
		break;
360
	case OPER_ARRAY:
361 362 363
		if (tree->u.array.x == 0 && tree->u.array.y == 0) {
			if (tree->u.array.corner.func.value)
				value_release (tree->u.array.corner.func.value);
364
			do_expr_tree_unref (tree->u.array.corner.func.expr);
365
		}
366
		break;
367 368 369
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
370
	}
371

Morten Welinder's avatar
Morten Welinder committed
372
	g_free (tree);
373 374
}

Morten Welinder's avatar
Morten Welinder committed
375 376 377 378 379 380
/*
 * 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.)
 */
381 382 383 384 385 386
void
expr_tree_unref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Arturo Espinosa's avatar
Arturo Espinosa committed
387
	do_expr_tree_unref (tree);
388 389
}

390
static Value *
391
eval_funcall (EvalPosition const * const pos, ExprTree const *tree)
Arturo Espinosa's avatar
Arturo Espinosa committed
392
{
393
	FunctionEvalInfo ei;
394
	const Symbol *sym;
Arturo Espinosa's avatar
Arturo Espinosa committed
395
	FunctionDefinition *fd;
Michael Meeks's avatar
Michael Meeks committed
396
	GList *args;
397

398
	g_return_val_if_fail (pos != NULL, NULL);
Michael Meeks's avatar
Michael Meeks committed
399
	g_return_val_if_fail (tree != NULL, NULL);
400

401
	sym = tree->u.function.symbol;
402 403

	if (sym->type != SYMBOL_FUNCTION)
404
		return value_new_error (pos, _("Internal error"));
405

406
	fd = (FunctionDefinition *)sym->data;
407 408
	ei.func_def = fd;
	ei.pos = pos;
Michael Meeks's avatar
Michael Meeks committed
409
	args = tree->u.function.arg_list;
410

411
	return function_call_with_list (&ei, args);
Arturo Espinosa's avatar
Arturo Espinosa committed
412 413
}

Jody Goldberg's avatar
Jody Goldberg committed
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
/**
 * expr_implicit_intersection :
 * @ei: EvalInfo containing valid fd!
 * @v: a VALUE_CELLRANGE
 * 
 * Attempt to find the intersection between the calling cell and
 * some element of the 1 one unit wide or tall range.
 *
 * Always release the value passed in.
 *
 * Return value: 
 *     If the intersection succeeded return a duplicate of the value
 *     at the intersection point.  This value needs to be freed.
 **/
Value *
expr_implicit_intersection (EvalPosition const * const pos,
			    Value * const v)
{
	/*
	 * 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.
	 */
	Value *res = NULL;
	CellRef const * const a = & v->v.cell_range.cell_a;
	CellRef const * const b = & v->v.cell_range.cell_b;

	if (a->sheet == b->sheet) {
		int a_col, a_row, b_col, b_row;
		cell_get_abs_col_row (a, &pos->eval, &a_col, &a_row);
		cell_get_abs_col_row (b, &pos->eval, &b_col, &b_row);
		if (a_row == b_row) {
			int const c = pos->eval.col;
			if (a_col <= c && c <= b_col)
				res = value_duplicate (value_area_get_x_y (pos, v, c - a_col, 0));
		}

		if (a_col == b_col) {
			int const r = pos->eval.row;
			if (a_row <= r && r <= b_row)
				res = value_duplicate (value_area_get_x_y (pos, v, 0, r - a_row));
		}
	}
	value_release (v);
	return res;
}

463
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
464 465
	IS_EQUAL,
	IS_LESS,
466
	IS_GREATER,
467
	TYPE_MISMATCH
468 469 470
} compare_t;

static compare_t
471
compare_bool_bool (Value const * const va, Value const * const vb)
472
{
473 474 475 476 477 478 479 480 481 482 483 484 485
	gboolean err; /* Ignored */
	gboolean const a = value_get_as_bool (va, &err);
	gboolean const b = value_get_as_bool (vb, &err);
	if (a)
		return b ? IS_EQUAL : IS_GREATER;
	return b ? IS_LESS : IS_EQUAL;
}

static compare_t
compare_int_int (Value const * const va, Value const * const vb)
{
	int const a = value_get_as_int (va);
	int const b = value_get_as_int (vb);
486 487 488 489 490 491 492 493 494
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}

static compare_t
495
compare_float_float (Value const * const va, Value const * const vb)
496
{
497 498
	float_t const a = value_get_as_float (va);
	float_t const b = value_get_as_float (vb);
499 500 501 502 503 504 505
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}
Arturo Espinosa's avatar
Arturo Espinosa committed
506

507 508
/*
 * Compares two (Value *) and returns one of compare_t
Jody Goldberg's avatar
Jody Goldberg committed
509 510 511
 *
 * if pos is non null it will perform implict intersection for
 * cellranges.
512 513
 */
static compare_t
Jody Goldberg's avatar
Jody Goldberg committed
514
compare (Value const * const a, Value const * const b)
Arturo Espinosa's avatar
Arturo Espinosa committed
515
{
516 517
	ValueType ta, tb;

518 519 520 521
	/* Handle trivial and double NULL case */
	if (a == b)
		return IS_EQUAL;

522 523
	ta = value_is_empty_cell (a) ? VALUE_EMPTY : a->type;
	tb = value_is_empty_cell (b) ? VALUE_EMPTY : b->type;
524

525 526 527 528 529 530
	/* string > empty */
	if (ta == VALUE_STRING) {
		switch (tb) {
		/* Strings are > (empty, or number) */
		case VALUE_EMPTY : case VALUE_INTEGER : case VALUE_FLOAT :
			return IS_GREATER;
531

532 533 534
		/* Strings are < FALSE ?? */
		case VALUE_BOOLEAN :
			return IS_LESS;
535

536 537 538 539 540 541 542 543 544 545 546 547
		/* If both are strings compare as string */
		case VALUE_STRING :
		{
			int const t = strcasecmp (a->v.str->str, b->v.str->str);
			if (t == 0)
				return IS_EQUAL;
			else if (t > 0)
				return IS_GREATER;
			else
				return IS_LESS;
		}
		default :
548
			return TYPE_MISMATCH;
549
		}
550 551 552 553 554
	} else if (tb == VALUE_STRING) {
		switch (ta) {
		/* (empty, or number) < String */
		case VALUE_EMPTY : case VALUE_INTEGER : case VALUE_FLOAT :
			return IS_LESS;
555

556 557 558
		/* Strings are < FALSE ?? */
		case VALUE_BOOLEAN :
			return IS_GREATER;
559

560
		default :
561
			return TYPE_MISMATCH;
562 563 564
		}
	}

565 566 567 568 569 570
	/* Booleans > all numbers (Why did excel do this ??) */
	if (ta == VALUE_BOOLEAN && (tb == VALUE_INTEGER || tb == VALUE_FLOAT))
		return IS_GREATER;
	if (tb == VALUE_BOOLEAN && (ta == VALUE_INTEGER || ta == VALUE_FLOAT))
		return IS_LESS;

571 572 573
	switch ((ta > tb) ? ta : tb) {
	case VALUE_EMPTY:	/* Empty Empty compare */
		return IS_EQUAL;
574

575 576
	case VALUE_BOOLEAN:
		return compare_bool_bool (a, b);
577

578 579 580 581 582 583 584 585
	case VALUE_INTEGER:
		return compare_int_int (a, b);

	case VALUE_FLOAT:
		return compare_float_float (a, b);
	default:
		return TYPE_MISMATCH;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
586 587
}

588 589 590 591 592
/*
 * Utility routine to ensure that all elements of a range are recalced as
 * necessary.
 */
static void
593
eval_range (EvalPosition const * const pos, Value *v)
594 595 596 597
{
	int start_col, start_row, end_col, end_row;
	CellRef * a = &v->v.cell_range.cell_a;
	CellRef * b = &v->v.cell_range.cell_b;
598
	Sheet * sheet = a->sheet ? a->sheet : pos->sheet;
599 600
	Cell * cell;
	int r, c;
601
	int const gen = pos->sheet->workbook->generation;
602

603 604
	cell_get_abs_col_row (a, &pos->eval, &start_col, &start_row);
	cell_get_abs_col_row (b, &pos->eval, &end_col, &end_row);
605

Michael Meeks's avatar
Michael Meeks committed
606
	if (b->sheet && a->sheet != b->sheet) {
607 608 609 610 611 612 613 614 615
		g_warning ("3D references not-fully supported.\n"
			   "Recalc may be incorrect");
		return;
	}

	for (r = start_row; r <= end_row; ++r)
		for (c = start_col; c <= end_col; ++c) {
			if ((cell = sheet_cell_get (sheet, c, r)) == NULL)
				continue;
616 617
			if (cell->generation != gen)
				cell_eval (cell);
618 619 620
		}
}

621
static Value *
622
eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
Arturo Espinosa's avatar
Arturo Espinosa committed
623
{
624
	Value *res = NULL, *a = NULL, *b = NULL;
625
	
Arturo Espinosa's avatar
Arturo Espinosa committed
626
	g_return_val_if_fail (tree != NULL, NULL);
627
	g_return_val_if_fail (pos != NULL, NULL);
628

629
	switch (tree->oper){
630 631 632 633 634 635
	case OPER_EQUAL:
	case OPER_NOT_EQUAL:
	case OPER_GT:
	case OPER_GTE:
	case OPER_LT:
	case OPER_LTE: {
Arturo Espinosa's avatar
Arturo Espinosa committed
636
		int comp;
637

638
		a = eval_expr_real (pos, tree->u.binary.value_a);
Jody Goldberg's avatar
Jody Goldberg committed
639 640
		if (a != NULL) {
			if (a->type == VALUE_CELLRANGE) {
641
				a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
642
				if (a == NULL)
643
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
644 645 646
			} else if (a->type == VALUE_ERROR)
				return a;
		}
Morten Welinder's avatar
Morten Welinder committed
647

648
		b = eval_expr_real (pos, tree->u.binary.value_b);
Jody Goldberg's avatar
Jody Goldberg committed
649 650 651
		if (b != NULL) {
			Value *res = NULL;
			if (b->type == VALUE_CELLRANGE) {
652
				b = expr_implicit_intersection (pos, b);
Jody Goldberg's avatar
Jody Goldberg committed
653
				if (b == NULL)
654
					res = value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
655 656 657 658 659 660 661 662
			} 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
663
		}
664

Arturo Espinosa's avatar
Arturo Espinosa committed
665 666
		comp = compare (a, b);

667 668 669 670
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
671

Michael Meeks's avatar
Michael Meeks committed
672
		if (comp == TYPE_MISMATCH) {
673 674 675 676 677 678 679 680 681
			/* TODO TODO TODO : Make error more informative
			 *    regarding what is comparing to what
			 */
			/* For equality comparisons even errors are ok */
			if (tree->oper == OPER_EQUAL)
				return value_new_bool (FALSE);
			if (tree->oper == OPER_NOT_EQUAL)
				return value_new_bool (TRUE);

682
			return value_new_error (pos, gnumeric_err_VALUE);
683
		}
684

Michael Meeks's avatar
Michael Meeks committed
685
		switch (tree->oper) {
686
		case OPER_EQUAL:
687
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
688 689
			break;

690
		case OPER_GT:
691
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
692 693
			break;

694
		case OPER_LT:
695
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
696 697
			break;

698 699
		case OPER_NOT_EQUAL:
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
700 701
			break;

702 703
		case OPER_LTE:
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
704 705
			break;

706 707
		case OPER_GTE:
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
708
			break;
709

Arturo Espinosa's avatar
Arturo Espinosa committed
710
		default:
711
			g_assert_not_reached ();
712
			res = value_new_error (pos,
713
						_("Internal type error"));
Arturo Espinosa's avatar
Arturo Espinosa committed
714
		}
Morten Welinder's avatar
Morten Welinder committed
715
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
716
	}
717

718 719 720 721 722
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
723 724 725 726 727 728 729 730 731
		/*
		 * 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
		 */

Jody Goldberg's avatar
Jody Goldberg committed
732
	        /* Garantees that a != NULL */
733
		a = eval_expr (pos, tree->u.binary.value_a);
Jody Goldberg's avatar
Jody Goldberg committed
734 735 736

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
737
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
738
			if (a == NULL)
739
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
740 741
		}

742 743
		/* 1) Error from A */
		if (a->type == VALUE_ERROR)
744
			return a;
745

746 747 748
		/* 2) #!VALUE error if A is not a number */
		if (!VALUE_IS_NUMBER (a)) {
			value_release (a);
749
			return value_new_error (pos, gnumeric_err_VALUE);
750 751 752
		}

	        /* Garantees that b != NULL */
753
		b = eval_expr (pos, tree->u.binary.value_b);
Arturo Espinosa's avatar
Arturo Espinosa committed
754

Jody Goldberg's avatar
Jody Goldberg committed
755 756
		/* Handle implicit intersection */
		if (b->type == VALUE_CELLRANGE) {
757
			b = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
758
			if (b == NULL)
759
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
760 761
		}

762 763
		/* 3) Error from B */
		if (b->type == VALUE_ERROR) {
764
			value_release (a);
765
			return b;
Arturo Espinosa's avatar
Arturo Espinosa committed
766
		}
767

768 769
		/* 4) #!VALUE error if B is not a number */
		if (!VALUE_IS_NUMBER (b)) {
770 771
			value_release (a);
			value_release (b);
772
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
773
		}
774

775
		if (a->type != VALUE_FLOAT && b->type != VALUE_FLOAT){
Morten Welinder's avatar
Morten Welinder committed
776
			int ia = value_get_as_int (a);
777
			int ib = value_get_as_int (b);
778 779 780
			double dres;
			int ires;

Morten Welinder's avatar
Morten Welinder committed
781 782
			value_release (a);
			value_release (b);
783

784 785
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
786
			switch (tree->oper){
787 788 789 790 791 792 793 794
			case OPER_ADD:
				dres = (double)ia + (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);

795
			case OPER_SUB:
796 797 798 799 800 801
				dres = (double)ia - (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
802

803
			case OPER_MULT:
804 805 806 807 808 809
				dres = (double)ia * (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
Arturo Espinosa's avatar
Arturo Espinosa committed
810

811
			case OPER_DIV:
812
				if (ib == 0)
813
					return value_new_error (pos, gnumeric_err_DIV0);
814 815 816 817 818 819
				dres = (double)ia / (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
820 821

			case OPER_EXP:
822
				if (ia == 0 && ib <= 0)
823
					return value_new_error (pos, gnumeric_err_NUM);
824 825 826 827 828 829 830
				dres = pow ((double)ia, (double)ib);
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);

Arturo Espinosa's avatar
Arturo Espinosa committed
831
			default:
832
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
833 834
			}
		} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
835 836
			float_t const va = value_get_as_float (a);
			float_t const vb = value_get_as_float (b);
837 838
			value_release (a);
			value_release (b);
839

840
			switch (tree->oper){
841
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
842
				return value_new_float (va + vb);
843

844
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
845
				return value_new_float (va - vb);
846

847
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
848
				return value_new_float (va * vb);
849

850
			case OPER_DIV:
851
				return (vb == 0.0)
852
				    ? value_new_error (pos,
853
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
854
				    : value_new_float (va / vb);
855

856
			case OPER_EXP:
857 858
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
859
					return value_new_error (pos, gnumeric_err_NUM);
Arturo Espinosa's avatar
Arturo Espinosa committed
860
				return value_new_float (pow (va, vb));
861

Arturo Espinosa's avatar
Arturo Espinosa committed
862
			default:
863
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
864 865
			}
		}
866
		return value_new_error (pos, _("Unknown operator"));
867

Jody Goldberg's avatar
Jody Goldberg committed
868
	case OPER_PERCENT:
869 870
	case OPER_NEG:
	        /* Garantees that a != NULL */
871
		a = eval_expr (pos, tree->u.value);
Jody Goldberg's avatar
Jody Goldberg committed
872 873 874

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
875
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
876
			if (a == NULL)
877
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
878 879
		}

880 881
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
882

883 884
		if (!VALUE_IS_NUMBER (a)){
			value_release (a);
885
			return value_new_error (pos, gnumeric_err_VALUE);
886
		}
Jody Goldberg's avatar
Jody Goldberg committed
887 888 889 890 891 892 893 894 895
		if (tree->oper == OPER_NEG) {
			if (a->type == VALUE_INTEGER)
				res = value_new_int (-a->v.v_int);
			else if (a->type == VALUE_FLOAT)
				res = value_new_float (-a->v.v_float);
			else
				res = value_new_bool (!a->v.v_float);
		} else
			res = value_new_float (value_get_as_float (a) * .01);
896
		value_release (a);
Morten Welinder's avatar
Morten Welinder committed
897
		return res;
898

899
	case OPER_CONCAT: {
900 901
		char *sa, *sb, *tmp;

902
		a = eval_expr_real (pos, tree->u.binary.value_a);
903
		if (a != NULL && a->type == VALUE_ERROR)
904
			return a;
905
		b = eval_expr_real (pos, tree->u.binary.value_b);
906 907 908
		if (b != NULL && b->type == VALUE_ERROR) {
			if (a != NULL)
				value_release (a);
909
			return b;
910 911
		}

Michael Meeks's avatar
Michael Meeks committed
912 913
		sa = value_get_as_string (a);
		sb = value_get_as_string (b);
Jeff Garzik's avatar
Jeff Garzik committed
914
		tmp = g_strconcat (sa, sb, NULL);
Morten Welinder's avatar
Morten Welinder committed
915 916
		res = value_new_string (tmp);

917 918 919 920
		g_free (sa);
		g_free (sb);
		g_free (tmp);

921
		if (a != NULL)
922
		value_release (a);
923
		if (b != NULL)
924
		value_release (b);
Morten Welinder's avatar
Morten Welinder committed
925
		return res;
926
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
927

928
	case OPER_FUNCALL:
929
		return eval_funcall (pos, tree);
Arturo Espinosa's avatar
Arturo Espinosa committed
930

Michael Meeks's avatar
Michael Meeks committed
931
	case OPER_NAME:
932
		return eval_expr_name (pos, tree->u.name);
Michael Meeks's avatar
Michael Meeks committed
933

934
	case OPER_VAR: {
935
		Sheet *cell_sheet;
936
		CellRef const *ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
937 938
		Cell *cell;
		int col, row;
939

940
		if (pos->sheet == NULL) {
Arturo Espinosa's avatar
Arturo Espinosa committed
941
			/* Only the test program requests this */
Morten Welinder's avatar
Morten Welinder committed
942
			return value_new_float (3.14);
Arturo Espinosa's avatar
Arturo Espinosa committed
943 944
		}

945
		ref = &tree->u.ref;
946
		cell_get_abs_col_row (ref, &pos->eval, &col, &row);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
947

948
		cell_sheet = eval_sheet (ref->sheet, pos->sheet);
949
		cell = sheet_cell_get (cell_sheet, col, row);
950 951
		if (cell == NULL)
			return NULL;
952

953
		if (cell->generation != pos->sheet->workbook->generation)
954
			cell_eval (cell);
955

956
		return value_duplicate (cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
957
	}
958

959
	case OPER_CONSTANT:
960 961
		res = tree->u.constant;
		if (res->type == VALUE_CELLRANGE)
962
			eval_range (pos, res);
963
		return value_duplicate (res);
964

965 966 967
	case OPER_ARRAY:
	{
		/* The upper left corner manages the recalc of the expr */
968 969
		int x = tree->u.array.x;
		int y = tree->u.array.y;
970
		if (