GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

expr.c 36.5 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
ExprTree *
expr_tree_new_error (char const *txt)
{
	Symbol *func;
	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)));
	}

	symbol_ref (func);
	return expr_tree_new_funcall (func, args);
}

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

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

68 69 70 71 72 73 74
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_FUNCALL;
	ans->symbol = sym;;
	ans->arg_list = args;

	return (ExprTree *)ans;
}
75

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

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

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

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


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

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

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

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

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

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

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

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

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

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

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	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;
150

151 152 153 154 155 156 157 158 159 160 161 162
	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;
}

163
int
164
expr_tree_get_const_int (ExprTree const *expr)
165 166
{
	g_return_val_if_fail (expr != NULL, 0);
167 168 169
	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);
170

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

174
char const *
175
expr_tree_get_const_str (ExprTree const *expr)
176 177
{
	g_return_val_if_fail (expr != NULL, NULL);
178 179 180
	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);
181

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

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

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

212 213

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

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

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

	/* Sanity check incase the corner gets removed for some reason */
233
	g_return_val_if_fail (corner->u.expression != (void *)0xdeadbeef, NULL);
234 235 236
	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);
237

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

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

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

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

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

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

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

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

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

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

286
	case OPER_ANY_UNARY:
287
		do_expr_tree_unref (tree->unary.value);
Arturo Espinosa's avatar
Arturo Espinosa committed
288
		break;
289
	case OPER_ARRAY:
290 291 292 293
		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);
294
		}
295
		break;
296 297 298
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
299
	}
300

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

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

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

Jody Goldberg's avatar
Jody Goldberg committed
319 320 321 322 323 324 325 326 327 328 329 330
/**
 * 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);
}

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

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

343
	sym = tree->func.symbol;
344 345

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

348
	fd = (FunctionDefinition *)sym->data;
349 350
	ei.func_def = fd;
	ei.pos = pos;
351
	args = tree->func.arg_list;
352

Jody Goldberg's avatar
Jody Goldberg committed
353
	/*if (flags & EVAL_PERMIT_NON_SCALAR)*/
354
	return function_call_with_list (&ei, args);
Arturo Espinosa's avatar
Arturo Espinosa committed
355 356
}

Jody Goldberg's avatar
Jody Goldberg committed
357 358 359 360
/**
 * expr_implicit_intersection :
 * @ei: EvalInfo containing valid fd!
 * @v: a VALUE_CELLRANGE
361
 *
362 363 364 365 366
 * 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
367 368 369
 *
 * Always release the value passed in.
 *
370
 * Return value:
Jody Goldberg's avatar
Jody Goldberg committed
371 372 373 374
 *     If the intersection succeeded return a duplicate of the value
 *     at the intersection point.  This value needs to be freed.
 **/
Value *
375
expr_implicit_intersection (EvalPos const *pos,
376
			    Value *v)
Jody Goldberg's avatar
Jody Goldberg committed
377 378
{
	Value *res = NULL;
379 380 381 382 383 384 385 386
	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
387
			int const c = pos->eval.col;
388 389 390 391 392
			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
393 394
		}

395
		if (rng.start.col == rng.end.col) {
Jody Goldberg's avatar
Jody Goldberg committed
396
			int const r = pos->eval.row;
397 398 399 400
			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
401 402 403 404 405 406
		}
	}
	value_release (v);
	return res;
}

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

422 423
	cell_get_abs_col_row (a, &pos->eval, &start_col, &start_row);
	cell_get_abs_col_row (b, &pos->eval, &end_col, &end_row);
424

Michael Meeks's avatar
Michael Meeks committed
425
	if (b->sheet && a->sheet != b->sheet) {
426 427 428 429 430 431 432 433 434
		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;
435 436
			if (cell->generation != gen)
				cell_eval (cell);
437 438 439
		}
}

440
static Value *
441
eval_expr_real (EvalPos const *pos, ExprTree const *tree,
442
		ExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
443
{
444
	Value *res = NULL, *a = NULL, *b = NULL;
445

Arturo Espinosa's avatar
Arturo Espinosa committed
446
	g_return_val_if_fail (tree != NULL, NULL);
447
	g_return_val_if_fail (pos != NULL, NULL);
448

449
	switch (tree->any.oper){
450 451 452 453 454 455
	case OPER_EQUAL:
	case OPER_NOT_EQUAL:
	case OPER_GT:
	case OPER_GTE:
	case OPER_LT:
	case OPER_LTE: {
456
		ValueCompare comp;
457

458
		a = eval_expr_real (pos, tree->binary.value_a, flags);
Jody Goldberg's avatar
Jody Goldberg committed
459 460
		if (a != NULL) {
			if (a->type == VALUE_CELLRANGE) {
461
				a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
462
				if (a == NULL)
463
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
464 465 466
			} else if (a->type == VALUE_ERROR)
				return a;
		}
Morten Welinder's avatar
Morten Welinder committed
467

468
		b = eval_expr_real (pos, tree->binary.value_b, flags);
Jody Goldberg's avatar
Jody Goldberg committed
469 470 471
		if (b != NULL) {
			Value *res = NULL;
			if (b->type == VALUE_CELLRANGE) {
472
				b = expr_implicit_intersection (pos, b);
Jody Goldberg's avatar
Jody Goldberg committed
473
				if (b == NULL)
474
					res = value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
475 476 477 478 479 480 481 482
			} 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
483
		}
484

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

487 488 489 490
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
491

Michael Meeks's avatar
Michael Meeks committed
492
		if (comp == TYPE_MISMATCH) {
493 494 495 496
			/* TODO TODO TODO : Make error more informative
			 *    regarding what is comparing to what
			 */
			/* For equality comparisons even errors are ok */
497
			if (tree->any.oper == OPER_EQUAL)
498
				return value_new_bool (FALSE);
499
			if (tree->any.oper == OPER_NOT_EQUAL)
500 501
				return value_new_bool (TRUE);

502
			return value_new_error (pos, gnumeric_err_VALUE);
503
		}
504

505
		switch (tree->any.oper) {
506
		case OPER_EQUAL:
507
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
508 509
			break;

510
		case OPER_GT:
511
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
512 513
			break;

514
		case OPER_LT:
515
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
516 517
			break;

518 519
		case OPER_NOT_EQUAL:
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
520 521
			break;

522 523
		case OPER_LTE:
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
524 525
			break;

526 527
		case OPER_GTE:
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
528
			break;
529

Arturo Espinosa's avatar
Arturo Espinosa committed
530
		default:
531
			g_assert_not_reached ();
532
			res = value_new_error (pos,
533
						_("Internal type error"));
Arturo Espinosa's avatar
Arturo Espinosa committed
534
		}
Morten Welinder's avatar
Morten Welinder committed
535
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
536
	}
537

538 539 540 541 542
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
543 544 545 546 547 548 549 550 551
		/*
		 * 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
		 */

552
	        /* Ensure a != NULL */
553
		a = eval_expr (pos, tree->binary.value_a,
554
			       flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
555 556 557

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
558
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
559
			if (a == NULL)
560
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
561 562
		}

563 564
		/* 1) Error from A */
		if (a->type == VALUE_ERROR)
565
			return a;
566

567 568 569
		/* 2) #!VALUE error if A is not a number */
		if (!VALUE_IS_NUMBER (a)) {
			value_release (a);
570
			return value_new_error (pos, gnumeric_err_VALUE);
571 572 573
		}

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

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

584 585
		/* 3) Error from B */
		if (b->type == VALUE_ERROR) {
586
			value_release (a);
587
			return b;
Arturo Espinosa's avatar
Arturo Espinosa committed
588
		}
589

590 591
		/* 4) #!VALUE error if B is not a number */
		if (!VALUE_IS_NUMBER (b)) {
592 593
			value_release (a);
			value_release (b);
594
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
595
		}
596

597
		if (a->type != VALUE_FLOAT && b->type != VALUE_FLOAT){
Morten Welinder's avatar
Morten Welinder committed
598
			int ia = value_get_as_int (a);
599
			int ib = value_get_as_int (b);
600 601 602
			double dres;
			int ires;

Morten Welinder's avatar
Morten Welinder committed
603 604
			value_release (a);
			value_release (b);
605

606 607
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
608
			switch (tree->any.oper){
609 610 611 612 613 614 615 616
			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);

617
			case OPER_SUB:
618 619 620 621 622 623
				dres = (double)ia - (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
624

625
			case OPER_MULT:
626 627 628 629 630 631
				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
632

633
			case OPER_DIV:
634
				if (ib == 0)
635
					return value_new_error (pos, gnumeric_err_DIV0);
636 637 638 639 640 641
				dres = (double)ia / (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
642 643

			case OPER_EXP:
644
				if (ia == 0 && ib <= 0)
645
					return value_new_error (pos, gnumeric_err_NUM);
646 647 648 649 650 651 652
				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
653
			default:
654
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
655 656
			}
		} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
657 658
			float_t const va = value_get_as_float (a);
			float_t const vb = value_get_as_float (b);
659 660
			value_release (a);
			value_release (b);
661

662
			switch (tree->any.oper){
663
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
664
				return value_new_float (va + vb);
665

666
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
667
				return value_new_float (va - vb);
668

669
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
670
				return value_new_float (va * vb);
671

672
			case OPER_DIV:
673
				return (vb == 0.0)
674
				    ? value_new_error (pos,
675
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
676
				    : value_new_float (va / vb);
677

678
			case OPER_EXP:
679 680
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
681
					return value_new_error (pos, gnumeric_err_NUM);
Arturo Espinosa's avatar
Arturo Espinosa committed
682
				return value_new_float (pow (va, vb));
683

Arturo Espinosa's avatar
Arturo Espinosa committed
684
			default:
685
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
686 687
			}
		}
688
		return value_new_error (pos, _("Unknown operator"));
689

Jody Goldberg's avatar
Jody Goldberg committed
690
	case OPER_PERCENT:
Jody Goldberg's avatar
Jody Goldberg committed
691 692
	case OPER_UNARY_NEG:
	case OPER_UNARY_PLUS:
693
	        /* Garantees that a != NULL */
694
		a = eval_expr (pos, tree->unary.value, flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
695 696 697

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
698
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
699
			if (a == NULL)
700
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
701 702
		}

703 704
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
705

706
		if (tree->any.oper == OPER_UNARY_PLUS)
Jody Goldberg's avatar
Jody Goldberg committed
707 708
			return a;

709 710
		if (!VALUE_IS_NUMBER (a)){
			value_release (a);
711
			return value_new_error (pos, gnumeric_err_VALUE);
712
		}
713
		if (tree->any.oper == OPER_UNARY_NEG) {
Jody Goldberg's avatar
Jody Goldberg committed
714
			if (a->type == VALUE_INTEGER)
715
				res = value_new_int (-a->v_int.val);
Jody Goldberg's avatar
Jody Goldberg committed
716
			else if (a->type == VALUE_FLOAT)
717
				res = value_new_float (-a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
718
			else
719
				res = value_new_bool (!a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
720 721
		} else
			res = value_new_float (value_get_as_float (a) * .01);
722
		value_release (a);
Morten Welinder's avatar
Morten Welinder committed
723
		return res;
724

725
	case OPER_CONCAT: {
726 727
		char *sa, *sb, *tmp;

728
		a = eval_expr_real (pos, tree->binary.value_a, flags);
729
		if (a != NULL && a->type == VALUE_ERROR)
730
			return a;
731
		b = eval_expr_real (pos, tree->binary.value_b, flags);
732 733 734
		if (b != NULL && b->type == VALUE_ERROR) {
			if (a != NULL)
				value_release (a);
735
			return b;
736 737
		}

Michael Meeks's avatar
Michael Meeks committed
738 739
		sa = value_get_as_string (a);
		sb = value_get_as_string (b);
Jeff Garzik's avatar
Jeff Garzik committed
740
		tmp = g_strconcat (sa, sb, NULL);
Morten Welinder's avatar
Morten Welinder committed
741 742
		res = value_new_string (tmp);

743 744 745 746
		g_free (sa);
		g_free (sb);
		g_free (tmp);

747
		if (a != NULL)
748
		value_release (a);
749
		if (b != NULL)
750
		value_release (b);
Morten Welinder's avatar
Morten Welinder committed
751
		return res;
752
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
753

754
	case OPER_FUNCALL:
Jody Goldberg's avatar
Jody Goldberg committed
755
		return eval_funcall (pos, tree, flags);
Arturo Espinosa's avatar
Arturo Espinosa committed
756

Michael Meeks's avatar
Michael Meeks committed
757
	case OPER_NAME:
758
		return eval_expr_name (pos, tree->name.name, flags);
Michael Meeks's avatar
Michael Meeks committed
759

760
	case OPER_VAR: {
761
		Sheet *cell_sheet;
762
		CellRef const *ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
763 764
		Cell *cell;
		int col, row;
765

766
		if (pos->sheet == NULL) {
Arturo Espinosa's avatar
Arturo Espinosa committed
767
			/* Only the test program requests this */
Morten Welinder's avatar
Morten Welinder committed
768
			return value_new_float (3.14);
Arturo Espinosa's avatar
Arturo Espinosa committed
769 770
		}

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

774
		cell_sheet = eval_sheet (ref->sheet, pos->sheet);
775
		cell = sheet_cell_get (cell_sheet, col, row);
776 777
		if (cell == NULL)
			return NULL;
778

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

782
		return value_duplicate (cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
783
	}
784

785
	case OPER_CONSTANT:
786
		res = tree->constant.value;
787 788
		if (res->type != VALUE_CELLRANGE)
			return value_duplicate (res);
789
		if (flags & EVAL_PERMIT_NON_SCALAR) {
790
			eval_range (pos, res);
791 792 793 794 795 796 797 798 799
			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.
			 */
800 801
			CellRef const * const a = & res->v_range.cell.a;
			CellRef const * const b = & res->v_range.cell.b;
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 828 829 830 831 832 833 834
			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);
		}
835

836 837 838
	case OPER_ARRAY:
	{
		/* The upper left corner manages the recalc of the expr */
839 840
		int x = tree->array.x;
		int y = tree->array.y;
841
		if (x == 0 && y == 0){
842
			/* Release old value if necessary */
843
			a = tree->array.corner.func.value;
844 845 846
			if (a != NULL)
				value_release (a);

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

			/* Store real result (cast away const)*/
870
			*((Value **)&(tree->array.corner.func.value)) = a;
871
		} else {
872
			ExprTree const * const array =
873
			    expr_tree_array_formula_corner (tree, pos);
874
			if (array)
875
				a = array->array.corner.func.value;
876 877
			else
				a = NULL;
878
		}
879

880 881
		if (a != NULL &&
		    (a->type == VALUE_CELLRANGE || a->type == VALUE_ARRAY)) {
882 883
			int const num_x = value_area_get_width (pos, a);
			int const num_y = value_area_get_height (pos, a);
884

885
			/* Evaluate relative to the upper left corner */
886
			EvalPos tmp_ep = *pos;
Jody Goldberg's avatar
Jody Goldberg committed
887 888
			tmp_ep.eval.col -= x;
			tmp_ep.eval.row -= y;
889 890 891 892 893 894 895

			/* 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)
896
				return value_new_error (pos, gnumeric_err_NA);
897 898 899

			a = (Value *)value_area_get_x_y (&tmp_ep, a, x, y);
		}
900 901 902

		if (a == NULL)
			return NULL;
903 904
		return value_duplicate (a);
	}
905
	}
906

907
	return value_new_error (pos, _("Unknown evaluation error"));
908 909 910
}

Value *
911
eval_expr (EvalPos const *pos, ExprTree const *tree,
912
	   ExprEvalFlags flags)
913
{
914 915
	Value * res = eval_expr_real (pos, tree, flags);

Jody Goldberg's avatar
Jody Goldberg committed
916 917 918
	if (res == NULL)
		return (flags & EVAL_PERMIT_EMPTY)
		    ? NULL : value_new_int (0);