expr.c 39.7 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 32 33
	if (!ans)
		return NULL;
	
	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 67 68 69 70 71 72 73 74 75
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;
	
	ans->ref_count = 1;
	*((Operation *)&(ans->oper)) = OPER_FUNCALL;
	ans->symbol = sym;;
	ans->arg_list = args;

	return (ExprTree *)ans;
}
       
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 101 102
	if (!ans)
		return NULL;
	
	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 118 119
	if (!ans)
		return NULL;
	
	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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

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

	ans = g_new (ExprVar, 1);
	if (!ans)
		return NULL;
	
	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;
	
	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,
Morten Welinder's avatar
Morten Welinder committed
187
		   char **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 361
/**
 * expr_implicit_intersection :
 * @ei: EvalInfo containing valid fd!
 * @v: a VALUE_CELLRANGE
 * 
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 370 371 372 373 374
 *
 * 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 *
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
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
408 409
	IS_EQUAL,
	IS_LESS,
410
	IS_GREATER,
411
	TYPE_MISMATCH
412 413 414
} compare_t;

static compare_t
415
compare_bool_bool (Value const *va, Value const *vb)
416
{
417 418 419 420 421 422 423 424 425
	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
426
compare_int_int (Value const *va, Value const *vb)
427 428 429
{
	int const a = value_get_as_int (va);
	int const b = value_get_as_int (vb);
430 431 432 433 434 435 436 437 438
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}

static compare_t
439
compare_float_float (Value const *va, Value const *vb)
440
{
441 442
	float_t const a = value_get_as_float (va);
	float_t const b = value_get_as_float (vb);
443 444 445 446 447 448 449
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}
Arturo Espinosa's avatar
Arturo Espinosa committed
450

451 452
/*
 * Compares two (Value *) and returns one of compare_t
Jody Goldberg's avatar
Jody Goldberg committed
453 454 455
 *
 * if pos is non null it will perform implict intersection for
 * cellranges.
456 457
 */
static compare_t
458
compare (Value const *a, Value const *b)
Arturo Espinosa's avatar
Arturo Espinosa committed
459
{
460 461
	ValueType ta, tb;

462 463 464 465
	/* Handle trivial and double NULL case */
	if (a == b)
		return IS_EQUAL;

466 467
	ta = value_is_empty_cell (a) ? VALUE_EMPTY : a->type;
	tb = value_is_empty_cell (b) ? VALUE_EMPTY : b->type;
468

469 470 471 472 473 474
	/* 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;
475

476 477 478
		/* Strings are < FALSE ?? */
		case VALUE_BOOLEAN :
			return IS_LESS;
479

480 481 482
		/* If both are strings compare as string */
		case VALUE_STRING :
		{
483
			int const t = g_strcasecmp (a->v_str.val->str, b->v_str.val->str);
484 485 486 487 488 489 490 491
			if (t == 0)
				return IS_EQUAL;
			else if (t > 0)
				return IS_GREATER;
			else
				return IS_LESS;
		}
		default :
492
			return TYPE_MISMATCH;
493
		}
494 495 496 497 498
	} else if (tb == VALUE_STRING) {
		switch (ta) {
		/* (empty, or number) < String */
		case VALUE_EMPTY : case VALUE_INTEGER : case VALUE_FLOAT :
			return IS_LESS;
499

500 501 502
		/* Strings are < FALSE ?? */
		case VALUE_BOOLEAN :
			return IS_GREATER;
503

504
		default :
505
			return TYPE_MISMATCH;
506 507 508
		}
	}

509 510 511 512 513 514
	/* 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;

515 516 517
	switch ((ta > tb) ? ta : tb) {
	case VALUE_EMPTY:	/* Empty Empty compare */
		return IS_EQUAL;
518

519 520
	case VALUE_BOOLEAN:
		return compare_bool_bool (a, b);
521

522 523 524 525 526 527 528 529
	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
530 531
}

532 533 534 535 536
/*
 * Utility routine to ensure that all elements of a range are recalced as
 * necessary.
 */
static void
537
eval_range (EvalPos const *pos, Value *v)
538 539
{
	int start_col, start_row, end_col, end_row;
540 541
	CellRef * a = &v->v_range.cell.a;
	CellRef * b = &v->v_range.cell.b;
542
	Sheet * sheet = a->sheet ? a->sheet : pos->sheet;
543 544
	Cell * cell;
	int r, c;
545
	int const gen = pos->sheet->workbook->generation;
546

547 548
	cell_get_abs_col_row (a, &pos->eval, &start_col, &start_row);
	cell_get_abs_col_row (b, &pos->eval, &end_col, &end_row);
549

Michael Meeks's avatar
Michael Meeks committed
550
	if (b->sheet && a->sheet != b->sheet) {
551 552 553 554 555 556 557 558 559
		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;
560 561
			if (cell->generation != gen)
				cell_eval (cell);
562 563 564
		}
}

565
static Value *
566
eval_expr_real (EvalPos const *pos, ExprTree const *tree,
567
		ExprEvalFlags flags)
Arturo Espinosa's avatar
Arturo Espinosa committed
568
{
569
	Value *res = NULL, *a = NULL, *b = NULL;
570
	
Arturo Espinosa's avatar
Arturo Espinosa committed
571
	g_return_val_if_fail (tree != NULL, NULL);
572
	g_return_val_if_fail (pos != NULL, NULL);
573

574
	switch (tree->any.oper){
575 576 577 578 579 580
	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
581
		int comp;
582

583
		a = eval_expr_real (pos, tree->binary.value_a, flags);
Jody Goldberg's avatar
Jody Goldberg committed
584 585
		if (a != NULL) {
			if (a->type == VALUE_CELLRANGE) {
586
				a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
587
				if (a == NULL)
588
					return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
589 590 591
			} else if (a->type == VALUE_ERROR)
				return a;
		}
Morten Welinder's avatar
Morten Welinder committed
592

593
		b = eval_expr_real (pos, tree->binary.value_b, flags);
Jody Goldberg's avatar
Jody Goldberg committed
594 595 596
		if (b != NULL) {
			Value *res = NULL;
			if (b->type == VALUE_CELLRANGE) {
597
				b = expr_implicit_intersection (pos, b);
Jody Goldberg's avatar
Jody Goldberg committed
598
				if (b == NULL)
599
					res = value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
600 601 602 603 604 605 606 607
			} 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
608
		}
609

Arturo Espinosa's avatar
Arturo Espinosa committed
610 611
		comp = compare (a, b);

612 613 614 615
		if (a != NULL)
			value_release (a);
		if (b != NULL)
			value_release (b);
616

Michael Meeks's avatar
Michael Meeks committed
617
		if (comp == TYPE_MISMATCH) {
618 619 620 621
			/* TODO TODO TODO : Make error more informative
			 *    regarding what is comparing to what
			 */
			/* For equality comparisons even errors are ok */
622
			if (tree->any.oper == OPER_EQUAL)
623
				return value_new_bool (FALSE);
624
			if (tree->any.oper == OPER_NOT_EQUAL)
625 626
				return value_new_bool (TRUE);

627
			return value_new_error (pos, gnumeric_err_VALUE);
628
		}
629

630
		switch (tree->any.oper) {
631
		case OPER_EQUAL:
632
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
633 634
			break;

635
		case OPER_GT:
636
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
637 638
			break;

639
		case OPER_LT:
640
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
641 642
			break;

643 644
		case OPER_NOT_EQUAL:
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
645 646
			break;

647 648
		case OPER_LTE:
			res = value_new_bool (comp != IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
649 650
			break;

651 652
		case OPER_GTE:
			res = value_new_bool (comp != IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
653
			break;
654

Arturo Espinosa's avatar
Arturo Espinosa committed
655
		default:
656
			g_assert_not_reached ();
657
			res = value_new_error (pos,
658
						_("Internal type error"));
Arturo Espinosa's avatar
Arturo Espinosa committed
659
		}
Morten Welinder's avatar
Morten Welinder committed
660
		return res;
Arturo Espinosa's avatar
Arturo Espinosa committed
661
	}
662

663 664 665 666 667
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
668 669 670 671 672 673 674 675 676
		/*
		 * 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
		 */

677
	        /* Ensure a != NULL */
678
		a = eval_expr (pos, tree->binary.value_a,
679
			       flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
680 681 682

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
683
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
684
			if (a == NULL)
685
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
686 687
		}

688 689
		/* 1) Error from A */
		if (a->type == VALUE_ERROR)
690
			return a;
691

692 693 694
		/* 2) #!VALUE error if A is not a number */
		if (!VALUE_IS_NUMBER (a)) {
			value_release (a);
695
			return value_new_error (pos, gnumeric_err_VALUE);
696 697 698
		}

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

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

709 710
		/* 3) Error from B */
		if (b->type == VALUE_ERROR) {
711
			value_release (a);
712
			return b;
Arturo Espinosa's avatar
Arturo Espinosa committed
713
		}
714

715 716
		/* 4) #!VALUE error if B is not a number */
		if (!VALUE_IS_NUMBER (b)) {
717 718
			value_release (a);
			value_release (b);
719
			return value_new_error (pos, gnumeric_err_VALUE);
Arturo Espinosa's avatar
Arturo Espinosa committed
720
		}
721

722
		if (a->type != VALUE_FLOAT && b->type != VALUE_FLOAT){
Morten Welinder's avatar
Morten Welinder committed
723
			int ia = value_get_as_int (a);
724
			int ib = value_get_as_int (b);
725 726 727
			double dres;
			int ires;

Morten Welinder's avatar
Morten Welinder committed
728 729
			value_release (a);
			value_release (b);
730

731 732
			/* FIXME: we could use simple (cheap) heuristics to
			   catch most cases where overflow will not happen.  */
733
			switch (tree->any.oper){
734 735 736 737 738 739 740 741
			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);

742
			case OPER_SUB:
743 744 745 746 747 748
				dres = (double)ia - (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
749

750
			case OPER_MULT:
751 752 753 754 755 756
				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
757

758
			case OPER_DIV:
759
				if (ib == 0)
760
					return value_new_error (pos, gnumeric_err_DIV0);
761 762 763 764 765 766
				dres = (double)ia / (double)ib;
				ires = (int)dres;
				if (dres == ires)
					return value_new_int (ires);
				else
					return value_new_float ((float_t) dres);
767 768

			case OPER_EXP:
769
				if (ia == 0 && ib <= 0)
770
					return value_new_error (pos, gnumeric_err_NUM);
771 772 773 774 775 776 777
				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
778
			default:
779
				abort ();
Arturo Espinosa's avatar
Arturo Espinosa committed
780 781
			}
		} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
782 783
			float_t const va = value_get_as_float (a);
			float_t const vb = value_get_as_float (b);
784 785
			value_release (a);
			value_release (b);
786

787
			switch (tree->any.oper){
788
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
789
				return value_new_float (va + vb);
790

791
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
792
				return value_new_float (va - vb);
793

794
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
795
				return value_new_float (va * vb);
796

797
			case OPER_DIV:
798
				return (vb == 0.0)
799
				    ? value_new_error (pos,
800
						       gnumeric_err_DIV0)
Arturo Espinosa's avatar
Arturo Espinosa committed
801
				    : value_new_float (va / vb);
802

803
			case OPER_EXP:
804 805
				if ((va == 0 && vb <= 0) ||
				    (va < 0 && vb != (int)vb))
806
					return value_new_error (pos, gnumeric_err_NUM);
Arturo Espinosa's avatar
Arturo Espinosa committed
807
				return value_new_float (pow (va, vb));
808

Arturo Espinosa's avatar
Arturo Espinosa committed
809
			default:
810
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
811 812
			}
		}
813
		return value_new_error (pos, _("Unknown operator"));
814

Jody Goldberg's avatar
Jody Goldberg committed
815
	case OPER_PERCENT:
Jody Goldberg's avatar
Jody Goldberg committed
816 817
	case OPER_UNARY_NEG:
	case OPER_UNARY_PLUS:
818
	        /* Garantees that a != NULL */
819
		a = eval_expr (pos, tree->unary.value, flags & (~EVAL_PERMIT_EMPTY));
Jody Goldberg's avatar
Jody Goldberg committed
820 821 822

		/* Handle implicit intersection */
		if (a->type == VALUE_CELLRANGE) {
823
			a = expr_implicit_intersection (pos, a);
Jody Goldberg's avatar
Jody Goldberg committed
824
			if (a == NULL)
825
				return value_new_error (pos, gnumeric_err_VALUE);
Jody Goldberg's avatar
Jody Goldberg committed
826 827
		}

828 829
		if (a->type == VALUE_ERROR)
			return a;
Jody Goldberg's avatar
Jody Goldberg committed
830

831
		if (tree->any.oper == OPER_UNARY_PLUS)
Jody Goldberg's avatar
Jody Goldberg committed
832 833
			return a;

834 835
		if (!VALUE_IS_NUMBER (a)){
			value_release (a);
836
			return value_new_error (pos, gnumeric_err_VALUE);
837
		}
838
		if (tree->any.oper == OPER_UNARY_NEG) {
Jody Goldberg's avatar
Jody Goldberg committed
839
			if (a->type == VALUE_INTEGER)
840
				res = value_new_int (-a->v_int.val);
Jody Goldberg's avatar
Jody Goldberg committed
841
			else if (a->type == VALUE_FLOAT)
842
				res = value_new_float (-a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
843
			else
844
				res = value_new_bool (!a->v_float.val);
Jody Goldberg's avatar
Jody Goldberg committed
845 846
		} else
			res = value_new_float (value_get_as_float (a) * .01);
847
		value_release (a);
Morten Welinder's avatar
Morten Welinder committed
848
		return res;
849

850
	case OPER_CONCAT: {
851 852
		char *sa, *sb, *tmp;

853
		a = eval_expr_real (pos, tree->binary.value_a, flags);
854
		if (a != NULL && a->type == VALUE_ERROR)
855
			return a;
856
		b = eval_expr_real (pos, tree->binary.value_b, flags);
857 858 859
		if (b != NULL && b->type == VALUE_ERROR) {
			if (a != NULL)
				value_release (a);
860
			return b;
861 862
		}

Michael Meeks's avatar
Michael Meeks committed
863 864
		sa = value_get_as_string (a);
		sb = value_get_as_string (b);
Jeff Garzik's avatar
Jeff Garzik committed
865
		tmp = g_strconcat (sa, sb, NULL);
Morten Welinder's avatar
Morten Welinder committed
866 867
		res = value_new_string (tmp);

868 869 870 871
		g_free (sa);
		g_free (sb);
		g_free (tmp);

872
		if (a != NULL)
873
		value_release (a);
874
		if (b != NULL)
875
		value_release (b);
Morten Welinder's avatar
Morten Welinder committed
876
		return res;
877
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
878

879
	case OPER_FUNCALL:
Jody Goldberg's avatar
Jody Goldberg committed
880
		return eval_funcall (pos, tree, flags);
Arturo Espinosa's avatar
Arturo Espinosa committed
881

Michael Meeks's avatar
Michael Meeks committed
882
	case OPER_NAME:
883
		return eval_expr_name (pos, tree->name.name, flags);
Michael Meeks's avatar
Michael Meeks committed
884

885
	case OPER_VAR: {
886
		Sheet *cell_sheet;
887
		CellRef const *ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
888 889
		Cell *cell;
		int col, row;
890

891
		if (pos->sheet == NULL) {
Arturo Espinosa's avatar
Arturo Espinosa committed
892
			/* Only the test program requests this */
Morten Welinder's avatar
Morten Welinder committed
893
			return value_new_float (3.14);
Arturo Espinosa's avatar
Arturo Espinosa committed
894 895
		}

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

899
		cell_sheet = eval_sheet (ref->sheet, pos->sheet);
900
		cell = sheet_cell_get (cell_sheet, col, row);
901 902
		if (cell == NULL)
			return NULL;
903

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

907
		return value_duplicate (cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
908
	}
909

910
	case OPER_CONSTANT:
911
		res = tree->constant.value;
912 913
		if (res->type != VALUE_CELLRANGE)
			return value_duplicate (res);
914
		if (flags & EVAL_PERMIT_NON_SCALAR) {
915
			eval_range (pos, res);
916 917 918 919 920 921 922 923 924
			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.
			 */
925 926
			CellRef const * const a = & res->v_range.cell.a;
			CellRef const * const b = & res->v_range.cell.b;
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
			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);
		}
960

961 962 963
	case OPER_ARRAY:
	{
		/* The upper left corner manages the recalc of the expr */
964 965
		int x = tree->array.x;
		int y = tree->array.y;
966
		if (x == 0 && y == 0){
967
			/* Release old value if necessary */
968
			a = tree->array.corner.func.value;
969 970 971
			if (a != NULL)
				value_release (a);

972 973 974 975