expr.c 36.4 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"
14
#include "expr-name.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
15
#include "eval.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
16
#include "format.h"
17
#include "func.h"
18
#include "parse-util.h"
19
#include "ranges.h"
20
#include "workbook.h"
21

22 23
/***************************************************************************/

24
ExprTree *
Morten Welinder's avatar
Morten Welinder committed
25
expr_tree_new_constant (Value *v)
26
{
27
	ExprConstant *ans;
28

29
	ans = g_new (ExprConstant, 1);
30 31
	if (!ans)
		return NULL;
32

33
	ans->ref_count = 1;
Jody Goldberg's avatar
Jody Goldberg committed
34
	*((Operation *)&(ans->oper)) = OPER_CONSTANT;
35
	ans->value = v;
36

37
	return (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
38 39
}

40 41 42
ExprTree *
expr_tree_new_error (char const *txt)
{
Jody Goldberg's avatar
Jody Goldberg committed
43
	FunctionDefinition *func;
44 45
	GList *args = NULL;

Jody Goldberg's avatar
Jody Goldberg committed
46 47
	if (strcmp (txt, gnumeric_err_NA) != 0) {
		func = func_lookup_by_name ("ERROR", NULL);
48 49
		args = g_list_prepend (NULL,
				       expr_tree_new_constant (value_new_string (txt)));
Jody Goldberg's avatar
Jody Goldberg committed
50 51
	} else
		func = func_lookup_by_name ("NA", NULL);
52

Jody Goldberg's avatar
Jody Goldberg committed
53
	func_ref (func);
54 55 56 57
	return expr_tree_new_funcall (func, args);
}

ExprTree *
Jody Goldberg's avatar
Jody Goldberg committed
58
expr_tree_new_funcall (FunctionDefinition *func, GList *args)
59 60
{
	ExprFunction *ans;
Jody Goldberg's avatar
Jody Goldberg committed
61
	g_return_val_if_fail (func, NULL);
62 63 64 65

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

67 68
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_FUNCALL;
Jody Goldberg's avatar
Jody Goldberg committed
69
	ans->func = func;;
70 71 72 73
	ans->arg_list = args;

	return (ExprTree *)ans;
}
74

Morten Welinder's avatar
Morten Welinder committed
75 76 77
ExprTree *
expr_tree_new_unary  (Operation op, ExprTree *e)
{
78
	ExprUnary *ans;
Morten Welinder's avatar
Morten Welinder committed
79

80
	ans = g_new (ExprUnary, 1);
81 82 83 84
	if (!ans)
		return NULL;

	ans->ref_count = 1;
Jody Goldberg's avatar
Jody Goldberg committed
85
	*((Operation *)&(ans->oper)) = op;
86
	ans->value = e;
87

88
	return (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
89 90 91 92 93 94
}


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

97
	ans = g_new (ExprBinary, 1);
98 99
	if (!ans)
		return NULL;
100

101
	ans->ref_count = 1;
Jody Goldberg's avatar
Jody Goldberg committed
102
	*((Operation *)&(ans->oper)) = op;
103 104
	ans->value_a = l;
	ans->value_b = r;
105

106
	return (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
107 108 109
}

ExprTree *
110
expr_tree_new_name (NamedExpression const *name)
Morten Welinder's avatar
Morten Welinder committed
111
{
112
	ExprName *ans;
Morten Welinder's avatar
Morten Welinder committed
113

114
	ans = g_new (ExprName, 1);
115 116
	if (!ans)
		return NULL;
117

118
	ans->ref_count = 1;
119 120
	*((Operation *)&(ans->oper)) = OPER_NAME;
	ans->name = name;
121

122
	return (ExprTree *)ans;
Morten Welinder's avatar
Morten Welinder committed
123
}
124 125 126 127 128 129 130 131 132

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

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

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_VAR;
	ans->ref = *cr;

	return (ExprTree *)ans;
}

ExprTree *
expr_tree_new_array (int x, int y, int rows, int cols)
{
	ExprArray *ans;

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

150 151 152 153 154 155 156 157 158 159 160 161
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_ARRAY;
	ans->x = x;
	ans->y = y;
	ans->rows = rows;
	ans->cols = cols;
	ans->corner.func.value = NULL;
	ans->corner.func.expr = NULL;
	ans->corner.cell = NULL;
	return (ExprTree *)ans;
}

162
int
163
expr_tree_get_const_int (ExprTree const *expr)
164 165
{
	g_return_val_if_fail (expr != NULL, 0);
166 167 168
	g_return_val_if_fail (expr->any.oper == OPER_CONSTANT, 0);
	g_return_val_if_fail (expr->constant.value, 0);
	g_return_val_if_fail (expr->constant.value->type == VALUE_INTEGER, 0);
169

170
	return expr->constant.value->v_int.val;
171 172
}

173
char const *
174
expr_tree_get_const_str (ExprTree const *expr)
175 176
{
	g_return_val_if_fail (expr != NULL, NULL);
177 178 179
	g_return_val_if_fail (expr->any.oper == OPER_CONSTANT, NULL);
	g_return_val_if_fail (expr->constant.value, NULL);
	g_return_val_if_fail (expr->constant.value->type == VALUE_STRING, NULL);
180

181
	return expr->constant.value->v_str.val->str;
182 183
}

184
ExprTree *
185
expr_parse_string (char const *expr, ParsePos const *pp,
186
		   StyleFormat **desired_format, char **error_msg)
187 188 189 190
{
	ExprTree *tree;
	g_return_val_if_fail (expr != NULL, NULL);

191
	switch (gnumeric_expr_parser (expr, pp, TRUE, desired_format, &tree)) {
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
	case PARSE_OK:
		*error_msg = NULL;
		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;
}

211 212

static ExprTree *
213
expr_tree_array_formula_corner (ExprTree const *expr, EvalPos const *pos)
214
{
215
	Cell * corner = expr->array.corner.cell;
216

217 218 219 220 221 222
	/* 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,
223 224 225
					 pos->eval.col - expr->array.x,
					 pos->eval.row - expr->array.y);
		((ExprTree *)expr)->array.corner.cell = corner;
226 227 228
	}

	g_return_val_if_fail (corner != NULL, NULL);
229
	g_return_val_if_fail (cell_has_expr (corner), NULL);
230 231

	/* Sanity check incase the corner gets removed for some reason */
232
	g_return_val_if_fail (corner->u.expression != (void *)0xdeadbeef, NULL);
233 234 235
	g_return_val_if_fail (corner->u.expression->any.oper == OPER_ARRAY, NULL);
	g_return_val_if_fail (corner->u.expression->array.x == 0, NULL);
	g_return_val_if_fail (corner->u.expression->array.y == 0, NULL);
236

237
	return corner->u.expression;
238 239
}

Arturo Espinosa's avatar
Arturo Espinosa committed
240 241 242 243
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
244 245 246 247
void
expr_tree_ref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
248
	g_return_if_fail (tree->any.ref_count > 0);
249

250
	tree->any.ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
251 252 253 254 255
}

static void
do_expr_tree_unref (ExprTree *tree)
{
256
	if (--tree->any.ref_count > 0)
Morten Welinder's avatar
Morten Welinder committed
257 258
		return;

259
	switch (tree->any.oper){
260
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
261
		break;
262

263
	case OPER_CONSTANT:
264
		value_release (tree->constant.value);
Arturo Espinosa's avatar
Arturo Espinosa committed
265
		break;
266

Morten Welinder's avatar
Morten Welinder committed
267 268 269
	case OPER_FUNCALL: {
		GList *l;

270
		for (l = tree->func.arg_list; l; l = l->next)
Morten Welinder's avatar
Morten Welinder committed
271
			do_expr_tree_unref (l->data);
272
		g_list_free (tree->func.arg_list);
Jody Goldberg's avatar
Jody Goldberg committed
273
		func_unref (tree->func.func);
Arturo Espinosa's avatar
Arturo Espinosa committed
274
		break;
Morten Welinder's avatar
Morten Welinder committed
275
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
276

Michael Meeks's avatar
Michael Meeks committed
277 278 279
	case OPER_NAME:
		break;

280
	case OPER_ANY_BINARY:
281 282
		do_expr_tree_unref (tree->binary.value_a);
		do_expr_tree_unref (tree->binary.value_b);
Arturo Espinosa's avatar
Arturo Espinosa committed
283 284
		break;

285
	case OPER_ANY_UNARY:
286
		do_expr_tree_unref (tree->unary.value);
Arturo Espinosa's avatar
Arturo Espinosa committed
287
		break;
288
	case OPER_ARRAY:
289 290 291 292
		if (tree->array.x == 0 && tree->array.y == 0) {
			if (tree->array.corner.func.value)
				value_release (tree->array.corner.func.value);
			do_expr_tree_unref (tree->array.corner.func.expr);
293
		}
294
		break;
295 296 297
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
298
	}
299

Morten Welinder's avatar
Morten Welinder committed
300
	g_free (tree);
301 302
}

Morten Welinder's avatar
Morten Welinder committed
303 304 305 306 307 308
/*
 * 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.)
 */
309 310 311 312
void
expr_tree_unref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
313
	g_return_if_fail (tree->any.ref_count > 0);
314

Arturo Espinosa's avatar
Arturo Espinosa committed
315
	do_expr_tree_unref (tree);
316 317
}

Jody Goldberg's avatar
Jody Goldberg committed
318 319 320 321 322 323 324 325 326 327 328 329
/**
 * expr_tree_shared : Returns TRUE if the reference count
 *   for the supplied expression is > 1
 */
gboolean
expr_tree_shared (ExprTree const *tree)
{
	g_return_val_if_fail (tree != NULL, FALSE);

	return (tree->any.ref_count > 1);
}

330
static Value *
Jody Goldberg's avatar
Jody Goldberg committed
331 332
eval_funcall (EvalPos const *pos, ExprTree const *tree,
	      ExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
333
{
334
	FunctionEvalInfo ei;
Arturo Espinosa's avatar
Arturo Espinosa committed
335
	FunctionDefinition *fd;
Michael Meeks's avatar
Michael Meeks committed
336
	GList *args;
337

338
	g_return_val_if_fail (pos != NULL, NULL);
Michael Meeks's avatar
Michael Meeks committed
339
	g_return_val_if_fail (tree != NULL, NULL);
340

Jody Goldberg's avatar
Jody Goldberg committed
341
	fd = tree->func.func;
342 343
	ei.func_def = fd;
	ei.pos = pos;
344
	args = tree->func.arg_list;
345

Jody Goldberg's avatar
Jody Goldberg committed
346
	/*if (flags & EVAL_PERMIT_NON_SCALAR)*/
347
	return function_call_with_list (&ei, args);
Arturo Espinosa's avatar
Arturo Espinosa committed
348 349
}

Jody Goldberg's avatar
Jody Goldberg committed
350 351 352 353
/**
 * expr_implicit_intersection :
 * @ei: EvalInfo containing valid fd!
 * @v: a VALUE_CELLRANGE
354
 *
355 356 357 358 359
 * 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
360 361 362
 *
 * Always release the value passed in.
 *
363
 * Return value:
Jody Goldberg's avatar
Jody Goldberg committed
364 365 366 367
 *     If the intersection succeeded return a duplicate of the value
 *     at the intersection point.  This value needs to be freed.
 **/
Value *
368
expr_implicit_intersection (EvalPos const *pos,
369
			    Value *v)
Jody Goldberg's avatar
Jody Goldberg committed
370 371
{
	Value *res = NULL;
372 373 374 375 376 377 378 379
	Range rng;
	Sheet *start_sheet, *end_sheet;

	/* handle inverted ranges */
	range_ref_normalize  (&rng, &start_sheet, &end_sheet, v, pos);

	if (start_sheet == end_sheet) {
		if (rng.start.row == rng.end.row) {
Jody Goldberg's avatar
Jody Goldberg committed
380
			int const c = pos->eval.col;
381 382 383 384 385
			if (rng.start.col <= c && c <= rng.end.col)
				res = value_duplicate (
					value_area_get_x_y (pos, v,
							    c - rng.start.col,
							    0));
Jody Goldberg's avatar
Jody Goldberg committed
386 387
		}

388
		if (rng.start.col == rng.end.col) {
Jody Goldberg's avatar
Jody Goldberg committed
389
			int const r = pos->eval.row;
390 391 392 393
			if (rng.start.row <= r && r <= rng.end.row)
				res = value_duplicate (
					value_area_get_x_y (pos, v, 0,
							    r - rng.start.row));
Jody Goldberg's avatar
Jody Goldberg committed
394 395 396 397 398 399
		}
	}
	value_release (v);
	return res;
}

400 401 402 403 404
/*
 * Utility routine to ensure that all elements of a range are recalced as
 * necessary.
 */
static void
405
eval_range (EvalPos const *pos, Value *v)
406 407
{
	int start_col, start_row, end_col, end_row;
408 409
	CellRef * a = &v->v_range.cell.a;
	CellRef * b = &v->v_range.cell.b;
410
	Sheet * sheet = a->sheet ? a->sheet : pos->sheet;
411 412
	Cell * cell;
	int r, c;
413
	int const gen = pos->sheet->workbook->generation;
414

415 416
	cell_get_abs_col_row (a, &pos->eval, &start_col, &start_row);
	cell_get_abs_col_row (b, &pos->eval, &end_col, &end_row);
417

Michael Meeks's avatar
Michael Meeks committed
418
	if (b->sheet && a->sheet != b->sheet) {
419 420 421 422 423 424 425 426 427
		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;
428 429
			if (cell->generation != gen)
				cell_eval (cell);
430 431 432
		}
}

433
static Value *
434
eval_expr_real (EvalPos const *pos, ExprTree const *tree,
435
		ExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
436
{
437
	Value *res = NULL, *a = NULL, *b = NULL;
438

Arturo Espinosa's avatar
Arturo Espinosa committed
439
	g_return_val_if_fail (tree != NULL, NULL);
440
	g_return_val_if_fail (pos != NULL, NULL);
441

442
	switch (tree->any.oper){
443 444 445 446 447 448
	case OPER_EQUAL:
	case OPER_NOT_EQUAL:
	case OPER_GT:
	case OPER_GTE:
	case OPER_LT:
	case OPER_LTE: {
449
		ValueCompare comp;
450

451
		a = eval_expr_real (pos, tree->binary.value_a, flags);
Jody Goldberg's avatar
Jody Goldberg committed
452 453
		if (a != NULL) {
			if (a->type == VALUE_CELLRANGE) {
454
				a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
455
				if (a == NULL)
456
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
457 458 459
			} else if (a->type == VALUE_ERROR)
				return a;
		}
Morten Welinder's avatar
Morten Welinder committed
460

461
		b = eval_expr_real (pos, tree->binary.value_b, flags);
Jody Goldberg's avatar
Jody Goldberg committed
462 463 464
		if (b != NULL) {
			Value *res = NULL;
			if (b->type == VALUE_CELLRANGE) {
465
				b = expr_implicit_intersection (pos, b);
Jody Goldberg's avatar
Jody Goldberg committed
466
				if (b == NULL)
467
					res = value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
468 469 470 471 472 473 474 475
			} 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
476
		}
477

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

480 481 482 483
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
484

Michael Meeks's avatar
Michael Meeks committed
485
		if (comp == TYPE_MISMATCH) {
486 487 488 489
			/* TODO TODO TODO : Make error more informative
			 *    regarding what is comparing to what
			 */
			/* For equality comparisons even errors are ok */
490
			if (tree->any.oper == OPER_EQUAL)
491
				return value_new_bool (FALSE);
492
			if (tree->any.oper == OPER_NOT_EQUAL)
493 494
				return value_new_bool (TRUE);

495
			return value_new_error (pos, gnumeric_err_VALUE);
496
		}
497

498
		switch (tree->any.oper) {
499
		case OPER_EQUAL:
500
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
501 502
			break;

503
		case OPER_GT:
504
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
505 506
			break;

507
		case OPER_LT:
508
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
509 510
			break;

511 512
		case OPER_NOT_EQUAL:
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
513 514
			break;

515 516
		case OPER_LTE:
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
517 518
			break;

519 520
		case OPER_GTE:
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
521
			break;
522

Arturo Espinosa's avatar
Arturo Espinosa committed
523
		default:
524
			g_assert_not_reached ();
525
			res = value_new_error (pos,
526
						_("Internal type error"));
Arturo Espinosa's avatar
Arturo Espinosa committed
527
		}
Morten Welinder's avatar
Morten Welinder committed
528
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
529
	}
530

531 532 533 534 535
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
536 537 538 539 540 541 542 543 544
		/*
		 * 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
		 */

545
	        /* Ensure a != NULL */
546
		a = eval_expr (pos, tree->binary.value_a,
547
			       flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
548 549 550

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
551
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
552
			if (a == NULL)
553
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
554 555
		}

556 557
		/* 1) Error from A */
		if (a->type == VALUE_ERROR)
558
			return a;
559

560 561 562
		/* 2) #!VALUE error if A is not a number */
		if (!VALUE_IS_NUMBER (a)) {
			value_release (a);
563
			return value_new_error (pos, gnumeric_err_VALUE);
564 565 566
		}

	        /* Garantees that b != NULL */
567
		b = eval_expr (pos, tree->binary.value_b,
568
			       flags & (~EVAL_PERMIT_EMPTY));
Arturo Espinosa's avatar
Arturo Espinosa committed
569

Jody Goldberg's avatar
Jody Goldberg committed
570 571
		/* Handle implicit intersection */
		if (b->type == VALUE_CELLRANGE) {
572
			b = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
573
			if (b == NULL)
574
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
575 576
		}

577 578
		/* 3) Error from B */
		if (b->type == VALUE_ERROR) {
579
			value_release (a);
580
			return b;
Arturo Espinosa's avatar
Arturo Espinosa committed
581
		}
582

583 584
		/* 4) #!VALUE error if B is not a number */
		if (!VALUE_IS_NUMBER (b)) {
585 586
			value_release (a);
			value_release (b);
587
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
588
		}
589

590
		if (a->type != VALUE_FLOAT && b->type != VALUE_FLOAT){
Morten Welinder's avatar
Morten Welinder committed
591
			int ia = value_get_as_int (a);
592
			int ib = value_get_as_int (b);
593 594 595
			double dres;
			int ires;

Morten Welinder's avatar
Morten Welinder committed
596 597
			value_release (a);
			value_release (b);
598

599 600
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
601
			switch (tree->any.oper){
602 603 604 605 606 607 608 609
			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);

610
			case OPER_SUB:
611 612 613 614 615 616
				dres = (double)ia - (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
617

618
			case OPER_MULT:
619 620 621 622 623 624
				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
625

626
			case OPER_DIV:
627
				if (ib == 0)
628
					return value_new_error (pos, gnumeric_err_DIV0);
629 630 631 632 633 634
				dres = (double)ia / (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
635 636

			case OPER_EXP:
637
				if (ia == 0 && ib <= 0)
638
					return value_new_error (pos, gnumeric_err_NUM);
639 640 641 642 643 644 645
				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
646
			default:
647
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
648 649
			}
		} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
650 651
			float_t const va = value_get_as_float (a);
			float_t const vb = value_get_as_float (b);
652 653
			value_release (a);
			value_release (b);
654

655
			switch (tree->any.oper){
656
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
657
				return value_new_float (va + vb);
658

659
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
660
				return value_new_float (va - vb);
661

662
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
663
				return value_new_float (va * vb);
664

665
			case OPER_DIV:
666
				return (vb == 0.0)
667
				    ? value_new_error (pos,
668
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
669
				    : value_new_float (va / vb);
670

671
			case OPER_EXP:
672 673
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
674
					return value_new_error (pos, gnumeric_err_NUM);
Arturo Espinosa's avatar
Arturo Espinosa committed
675
				return value_new_float (pow (va, vb));
676

Arturo Espinosa's avatar
Arturo Espinosa committed
677
			default:
678
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
679 680
			}
		}
681
		return value_new_error (pos, _("Unknown operator"));
682

Jody Goldberg's avatar
Jody Goldberg committed
683
	case OPER_PERCENT:
Jody Goldberg's avatar
Jody Goldberg committed
684 685
	case OPER_UNARY_NEG:
	case OPER_UNARY_PLUS:
686
	        /* Garantees that a != NULL */
687
		a = eval_expr (pos, tree->unary.value, flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
688 689 690

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
691
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
692
			if (a == NULL)
693
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
694 695
		}

696 697
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
698

699
		if (tree->any.oper == OPER_UNARY_PLUS)
Jody Goldberg's avatar
Jody Goldberg committed
700 701
			return a;

702 703
		if (!VALUE_IS_NUMBER (a)){
			value_release (a);
704
			return value_new_error (pos, gnumeric_err_VALUE);
705
		}
706
		if (tree->any.oper == OPER_UNARY_NEG) {
Jody Goldberg's avatar
Jody Goldberg committed
707
			if (a->type == VALUE_INTEGER)
708
				res = value_new_int (-a->v_int.val);
Jody Goldberg's avatar
Jody Goldberg committed
709
			else if (a->type == VALUE_FLOAT)
710
				res = value_new_float (-a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
711
			else
712
				res = value_new_bool (!a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
713 714
		} else
			res = value_new_float (value_get_as_float (a) * .01);
715
		value_release (a);
Morten Welinder's avatar
Morten Welinder committed
716
		return res;
717

718
	case OPER_CONCAT: {
719 720
		char *sa, *sb, *tmp;

721
		a = eval_expr_real (pos, tree->binary.value_a, flags);
722
		if (a != NULL && a->type == VALUE_ERROR)
723
			return a;
724
		b = eval_expr_real (pos, tree->binary.value_b, flags);
725 726 727
		if (b != NULL && b->type == VALUE_ERROR) {
			if (a != NULL)
				value_release (a);
728
			return b;
729 730
		}

Michael Meeks's avatar
Michael Meeks committed
731 732
		sa = value_get_as_string (a);
		sb = value_get_as_string (b);
Jeff Garzik's avatar
Jeff Garzik committed
733
		tmp = g_strconcat (sa, sb, NULL);
Morten Welinder's avatar
Morten Welinder committed
734 735
		res = value_new_string (tmp);

736 737 738 739
		g_free (sa);
		g_free (sb);
		g_free (tmp);

740
		if (a != NULL)
741
		value_release (a);
742
		if (b != NULL)
743
		value_release (b);
Morten Welinder's avatar
Morten Welinder committed
744
		return res;
745
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
746

747
	case OPER_FUNCALL:
Jody Goldberg's avatar
Jody Goldberg committed
748
		return eval_funcall (pos, tree, flags);
Arturo Espinosa's avatar
Arturo Espinosa committed
749

Michael Meeks's avatar
Michael Meeks committed
750
	case OPER_NAME:
751
		return eval_expr_name (pos, tree->name.name, flags);
Michael Meeks's avatar
Michael Meeks committed
752

753
	case OPER_VAR: {
754
		Sheet *cell_sheet;
755
		CellRef const *ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
756 757
		Cell *cell;
		int col, row;
758

759
		if (pos->sheet == NULL) {
Arturo Espinosa's avatar
Arturo Espinosa committed
760
			/* Only the test program requests this */
Morten Welinder's avatar
Morten Welinder committed
761
			return value_new_float (3.14);
Arturo Espinosa's avatar
Arturo Espinosa committed
762 763
		}

764
		ref = &tree->var.ref;
765
		cell_get_abs_col_row (ref, &pos->eval, &col, &row);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
766

767
		cell_sheet = eval_sheet (ref->sheet, pos->sheet);
768
		cell = sheet_cell_get (cell_sheet, col, row);
769 770
		if (cell == NULL)
			return NULL;
771

772
		if (cell->generation != pos->sheet->workbook->generation)
773
			cell_eval (cell);
774

775
		return value_duplicate (cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
776
	}
777

778
	case OPER_CONSTANT:
779
		res = tree->constant.value;
780 781
		if (res->type != VALUE_CELLRANGE)
			return value_duplicate (res);
782
		if (flags & EVAL_PERMIT_NON_SCALAR) {
783
			eval_range (pos, res);
784 785 786 787 788 789 790 791 792
			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.
			 */
793 794
			CellRef const * const a = & res->v_range.cell.a;
			CellRef const * const b = & res->v_range.cell.b;
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
			gboolean found = FALSE;

			if (a->sheet == b->sheet) {
				int a_col, a_row, b_col, b_row;
				int c = pos->eval.col;
				int r = pos->eval.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) {
					if (a_col <= c && c <= b_col) {
						r = a_row;
						found = TRUE;
					}
				} else if (a_col == b_col) {
					if (a_row <= r && r <= b_row) {
						c = a_col;
						found = TRUE;
					}
				}
				if (found) {
					Cell * cell = sheet_cell_get (pos->sheet, c, r);
					if (cell == NULL)
						return NULL;

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

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

829 830 831
	case OPER_ARRAY:
	{
		/* The upper left corner manages the recalc of the expr */
832 833
		int x = tree->array.x;
		int y = tree->array.y;
834
		if (x == 0 && y == 0){
835
			/* Release old value if necessary */
836
			a = tree->array.corner.func.value;
837 838 839
			if (a != NULL)
				value_release (a);

840 841 842 843
			/*
			 * 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
844
			 *
845 846
			 * Figure out when to iterate and when to do array
			 * operations.
Jody Goldberg's avatar
Jody Goldberg committed
847
			 * ie
848 849
			 * 	A1:A3 = '=B1:B3^2'
			 * Will iterate over all the elements and re-evaluate.
Jody Goldberg's avatar
Jody Goldberg committed
850
			 * whereas
851 852
			 *	 A1:A3 = '=bob(B1:B3)'
			 * Will call bob once if it returns an array.
Jody Goldberg's avatar
Jody Goldberg committed
853
			 *
854 855 856 857
			 * 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
858
			 */
859
			a = eval_expr_real (pos, tree->array.corner.func.expr,
Jody Goldberg's avatar
Jody Goldberg committed
860
					    EVAL_PERMIT_NON_SCALAR);
861 862

			/* Store real result (cast away const)*/
863
			*((Value **)&(tree->array.corner.func.value)) = a;
864
		} else {
865
			ExprTree const * const array =
866
			    expr_tree_array_formula_corner (tree, pos);
867
			if (array)
868
				a = array->array.corner.func.value;
869 870
			else
				a = NULL;
871
		}
872

873 874
		if (a != NULL &&
		    (a->type == VALUE_CELLRANGE || a->type == VALUE_ARRAY)) {
875 876
			int const num_x = value_area_get_width (pos, a);
			int const num_y = value_area_get_height (pos, a);
877

878
			/* Evaluate relative to the upper left corner */
879
			EvalPos tmp_ep = *pos;
Jody Goldberg's avatar
Jody Goldberg committed
880 881
			tmp_ep.eval.col -= x;
			tmp_ep.eval.row -= y;
882 883 884 885 886 887 888

			/* If the src array is 1 element wide or tall we wrap */
			if (x >= 1 && num_x == 1)
				x = 0;
			if (y >= 1 && num_y == 1)
				y = 0;
			if (x >= num_x || y >= num_y)
889
				return value_new_error (pos, gnumeric_err_NA);
890 891 892

			a = (Value *)value_area_get_x_y (&tmp_ep, a, x, y);
		}
893 894 895

		if (a == NULL)
			return NULL;
896 897
		return value_duplicate (a);
	}
898
	}
899

900
	return value_new_error (pos, _("Unknown evaluation error"));
901 902 903
}