expr.c 39.4 KB
Newer Older
Miguel de Icaza's avatar
Miguel de Icaza committed
1 2 3 4 5 6
/*
 * expr.c: Expression evaluation in Gnumeriuc
 *
 * 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>
Arturo Espinosa's avatar
Arturo Espinosa committed
11
#include "gnumeric.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
12
#include "expr.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
13
#include "eval.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
14
#include "format.h"
15
#include "func.h"
16
#include "utils.h"
17

18 19
Value *value_zero = NULL;

20
ExprTree *
21 22
expr_parse_string (const char *expr, Sheet *sheet, int col, int row,
		   const char **desired_format, char **error_msg)
23
{
24
	ExprTree *tree;
25
	g_return_val_if_fail (expr != NULL, NULL);
26 27

	switch (gnumeric_expr_parser (expr, sheet, col, row, desired_format, &tree)) {
28 29
	case PARSE_OK:
		*error_msg = NULL;
30 31
		tree->ref_count = 1;
		return tree;
32

Arturo Espinosa's avatar
Arturo Espinosa committed
33 34 35
	case PARSE_ERR_SYNTAX:
		*error_msg = _("Syntax error");
		break;
36

37 38 39
	case PARSE_ERR_NO_QUOTE:
		*error_msg = _("Missing quote");
		break;
40
	default:
Arturo Espinosa's avatar
Arturo Espinosa committed
41 42 43
		g_assert_not_reached ();
		*error_msg = _("Impossible!");
		break;
44
	}
45 46 47
	return NULL;
}

48

49
ExprTree *
Morten Welinder's avatar
Morten Welinder committed
50
expr_tree_new_constant (Value *v)
51
{
52 53 54
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
Morten Welinder's avatar
Morten Welinder committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
	if (ans) {
		ans->ref_count = 1;
		ans->oper = OPER_CONSTANT;
		ans->u.constant = v;
	}
	return ans;
}

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

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = op;
		ans->u.value = e;
	}
	return ans;
}


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

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = op;
		ans->u.binary.value_a = l;
		ans->u.binary.value_b = r;
	}
	return ans;
}

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

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = OPER_FUNCALL;
		ans->u.function.symbol = sym;;
		ans->u.function.arg_list = args;
	}
	return ans;
}

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

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = OPER_VAR;
		ans->u.ref = *cr;
	}
120 121 122
	return ans;
}

Morten Welinder's avatar
Morten Welinder committed
123 124 125 126
ExprTree *
expr_tree_new_error (const char *txt)
{
	Symbol *func;
Morten Welinder's avatar
Morten Welinder committed
127 128 129 130 131 132 133 134 135
	GList *args = NULL;

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

	symbol_ref (func);
Morten Welinder's avatar
Morten Welinder committed
138
	return expr_tree_new_funcall (func, args);
Morten Welinder's avatar
Morten Welinder committed
139 140 141
}


Arturo Espinosa's avatar
Arturo Espinosa committed
142 143 144 145
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
146 147 148 149 150 151
void
expr_tree_ref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Morten Welinder's avatar
Morten Welinder committed
152
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
153 154 155 156 157
}

static void
do_expr_tree_unref (ExprTree *tree)
{
Morten Welinder's avatar
Morten Welinder committed
158 159 160
	if (--tree->ref_count > 0)
		return;

Arturo Espinosa's avatar
Arturo Espinosa committed
161
	switch (tree->oper){
162
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
163
		break;
164

165
	case OPER_CONSTANT:
Morten Welinder's avatar
Morten Welinder committed
166
		value_release (tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
167
		break;
168

Morten Welinder's avatar
Morten Welinder committed
169 170 171 172 173 174 175
	case OPER_FUNCALL: {
		GList *l;

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

179
	case OPER_ANY_BINARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
180 181 182 183
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

184
	case OPER_ANY_UNARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
185 186
		do_expr_tree_unref (tree->u.value);
		break;
187 188 189
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
190
	}
191

Morten Welinder's avatar
Morten Welinder committed
192
	g_free (tree);
193 194
}

Morten Welinder's avatar
Morten Welinder committed
195 196 197 198 199 200
/*
 * 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.)
 */
201 202 203 204 205 206
void
expr_tree_unref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Arturo Espinosa's avatar
Arturo Espinosa committed
207
	do_expr_tree_unref (tree);
208 209
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
210 211 212 213
/*
 * simplistic value rendering
 */
char *
Michael Meeks's avatar
Michael Meeks committed
214
value_get_as_string (const Value *value)
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
215 216 217 218 219 220
{
	switch (value->type){
	case VALUE_STRING:
		return g_strdup (value->v.str->str);

	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
221
		return g_strdup_printf ("%d", value->v.v_int);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
222 223

	case VALUE_FLOAT:
Morten Welinder's avatar
Morten Welinder committed
224
		return g_strdup_printf ("%.*g", DBL_DIG, value->v.v_float);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
225

226 227 228 229 230
	case VALUE_ARRAY: {
		GString *str = g_string_new ("{");
		guint lpx, lpy;
		char *ans;

231 232 233 234
		for (lpy = 0; lpy < value->v.array.y; lpy++){
			for (lpx = 0; lpx < value->v.array.x; lpx++){
				const Value *v = value->v.array.vals [lpx][lpy];

235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
				g_return_val_if_fail (v->type == VALUE_STRING ||
						      v->type == VALUE_FLOAT ||
						      v->type == VALUE_INTEGER,
						      "Duff Array contents");
				if (lpx)
					g_string_sprintfa (str, ",");
				if (v->type == VALUE_STRING)
					g_string_sprintfa (str, "\"%s\"",
							   v->v.str->str);
				else
					g_string_sprintfa (str, "%g",
							   value_get_as_float (v));
			}
			if (lpy<value->v.array.y-1)
				g_string_sprintfa (str, ";");
		}
		g_string_sprintfa (str, "}");
		ans = str->str;
		g_string_free (str, FALSE);
		return ans;
	}
256

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
257
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
258
		break;
259 260 261
	default:
		g_warning ("value_string problem\n");
		break;
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
262
	}
263

Arturo Espinosa's avatar
Arturo Espinosa committed
264
	return g_strdup ("Internal problem");
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
265 266
}

267 268 269
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
270
	g_return_if_fail (value != NULL);
271

272 273 274 275 276 277 278
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
279
		break;
280

281 282 283 284
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

285
	case VALUE_ARRAY:{
286
		guint lpx, lpy;
287

288
		for (lpx = 0; lpx < value->v.array.x; lpx++){
289
			for (lpy = 0; lpy < value->v.array.y; lpy++)
290
				value_release (value->v.array.vals [lpx][lpy]);
291 292
			g_free (value->v.array.vals [lpx]);
		}
293

294
		g_free (value->v.array.vals);
Morten Welinder's avatar
Morten Welinder committed
295
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
296
	}
297

Arturo Espinosa's avatar
Arturo Espinosa committed
298 299
	case VALUE_CELLRANGE:
		break;
300

301 302 303
	default:
		g_warning ("value_release problem\n");
		break;
304
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
305
	g_free (value);
306
}
307

Arturo Espinosa's avatar
Arturo Espinosa committed
308 309 310 311
/*
 * Copies a Value.
 */
void
312
value_copy_to (Value *dest, const Value *source)
Arturo Espinosa's avatar
Arturo Espinosa committed
313 314 315 316 317
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
318

Arturo Espinosa's avatar
Arturo Espinosa committed
319 320 321 322 323 324 325 326 327 328 329 330 331 332
	switch (source->type){
	case VALUE_STRING:
		dest->v.str = source->v.str;
		string_ref (dest->v.str);
		break;

	case VALUE_INTEGER:
		dest->v.v_int = source->v.v_int;
		break;

	case VALUE_FLOAT:
		dest->v.v_float = source->v.v_float;
		break;

Arturo Espinosa's avatar
Arturo Espinosa committed
333
	case VALUE_ARRAY: {
334
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
335 336 337 338 339
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
340 341 342
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
343 344 345
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
346 347 348 349
/*
 * Makes a copy of a Value
 */
Value *
350
value_duplicate (const Value *value)
Arturo Espinosa's avatar
Arturo Espinosa committed
351 352 353 354 355 356
{
	Value *new_value;

	g_return_val_if_fail (value != NULL, NULL);
	new_value = g_new (Value, 1);
	value_copy_to (new_value, value);
357

Arturo Espinosa's avatar
Arturo Espinosa committed
358 359 360
	return new_value;
}

361
Value *
Michael Meeks's avatar
Michael Meeks committed
362
value_new_float (float_t f)
363 364 365 366 367 368 369 370 371 372
{
	Value *v = g_new (Value, 1);

	v->type = VALUE_FLOAT;
	v->v.v_float = f;

	return v;
}

Value *
Michael Meeks's avatar
Michael Meeks committed
373
value_new_int (int i)
374 375 376 377 378 379 380 381 382
{
	Value *v = g_new (Value, 1);

	v->type = VALUE_INTEGER;
	v->v.v_int = i;

	return v;
}

383 384 385 386 387 388 389 390
Value *
value_new_bool (gboolean b)
{
	/* Currently our booleans are really just ints.  This will have to
	   change if we want Excel's ISLOGICAL.  */
	return value_new_int (b ? 1 : 0);
}

391
Value *
Michael Meeks's avatar
Michael Meeks committed
392
value_new_string (const char *str)
393 394 395 396 397 398 399 400 401
{
	Value *v = g_new (Value, 1);

	v->type = VALUE_STRING;
	v->v.str = string_get (str);

	return v;
}

402
Value *
Michael Meeks's avatar
Michael Meeks committed
403
value_new_cellrange (const CellRef *a, const CellRef *b)
404 405
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
406

407
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
408 409 410
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

411 412 413
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
414 415 416 417
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
418
Value *
419
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
420 421
{
	Value *newv;
422

Arturo Espinosa's avatar
Arturo Espinosa committed
423 424 425 426
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

	if (v->type == VALUE_FLOAT)
		return v;
427

Arturo Espinosa's avatar
Arturo Espinosa committed
428 429 430
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
431
	value_release (v);
432

Arturo Espinosa's avatar
Arturo Espinosa committed
433 434 435
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
436
int
Michael Meeks's avatar
Michael Meeks committed
437
value_get_as_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
438 439 440
{
	*err = 0;

441 442
	switch (v->type) {
	case VALUE_STRING:
Morten Welinder's avatar
Morten Welinder committed
443 444
		/* FIXME FIXME FIXME */
		/* Use locale to support TRUE, FALSE */
Arturo Espinosa's avatar
Arturo Espinosa committed
445 446
		return atoi (v->v.str->str);

447
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
448 449
		*err = 1;
		return 0;
450 451
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
452 453
		return v->v.v_int != 0;

454
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
455 456
		return v->v.v_float != 0.0;

457
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
458
		return 0;
459 460 461 462
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
463 464 465
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
466
float_t
Michael Meeks's avatar
Michael Meeks committed
467
value_get_as_float (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
468
{
469 470 471
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
472 473
		return atof (v->v.str->str);

474
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
475 476 477
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

478
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
479
		return (float_t) v->v.v_int;
480 481
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
482
		return 0.0;
483

484 485 486
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
Michael Meeks's avatar
Michael Meeks committed
487
		g_warning ("value_get_as_float type error\n");
488 489 490
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
491 492
}

493
int
494
value_get_as_int (const Value *v)
495
{
496 497 498
	switch (v->type)
	{
	case VALUE_STRING:
499 500
		return atoi (v->v.str->str);

501
	case VALUE_CELLRANGE:
Morten Welinder's avatar
Morten Welinder committed
502
		g_warning ("Getting range as a int: what to do?");
503
		return 0;
504

505
	case VALUE_INTEGER:
506 507
		return v->v.v_int;

508
	case VALUE_ARRAY:
509
		return 0;
510

511 512 513 514
	case VALUE_FLOAT:
		return (int) v->v.v_float;
	default:
		g_warning ("value_get_as_int unknown type\n");
515
		return 0;
516
	}
Michael Meeks's avatar
Michael Meeks committed
517
	return 0.0;
518 519
}

520 521 522
Value *
value_array_new (guint width, guint height)
{
523
	int x, y;
524 525 526 527 528

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
529
	v->v.array.vals = g_new (Value **, width);
530 531

	for (x = 0; x < width; x++){
532 533 534
		v->v.array.vals [x] = g_new (Value *, height);
		for (y = 0; y < height; y++)
			v->v.array.vals[x][y] = value_new_int (0);
535 536 537 538
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
539 540 541 542
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
543
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
544 545
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
546 547
	g_return_if_fail (array->v.array.y > row);
	g_return_if_fail (array->v.array.x > col);
Michael Meeks's avatar
Michael Meeks committed
548

549 550 551
	if (array->v.array.vals[col][row])
		value_release (array->v.array.vals[col][row]);
	array->v.array.vals[col][row] = v;
Michael Meeks's avatar
Michael Meeks committed
552 553
}

554 555 556
void
value_array_resize (Value *v, guint width, guint height)
{
557
	int x, y, xcpy, ycpy;
558
	Value *newval;
559
	Value ***tmp;
560

Michael Meeks's avatar
Michael Meeks committed
561
	g_warning ("Totally untested");
562 563 564 565 566 567 568 569
	g_return_if_fail (v);
	g_return_if_fail (v->type == VALUE_ARRAY);

	newval = value_array_new (width, height);

	if (width>v->v.array.x)
		xcpy = v->v.array.x;
	else
570
		xcpy = width;
571 572 573 574 575 576

	if (height>v->v.array.y)
		ycpy = v->v.array.y;
	else
		ycpy = height;

577 578 579 580 581
	for (x = 0; x < xcpy; x++)
		for (y = 0; y < ycpy; y++)
			value_array_set (newval, x, y, v->v.array.vals[x][y]);

	tmp = v->v.array.vals;
582
	v->v.array.vals = newval->v.array.vals;
583
	newval->v.array.vals = tmp;
584 585
	value_release (newval);

586 587 588 589 590 591 592
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
593
	int x, y;
594 595 596 597 598

	g_return_if_fail (src->type == VALUE_ARRAY);
	v->type = VALUE_ARRAY;
	v->v.array.x = src->v.array.x;
	v->v.array.y = src->v.array.y;
599
	v->v.array.vals = g_new (Value **, v->v.array.x);
600

601 602 603 604
	for (x = 0; x < v->v.array.x; x++) {
		v->v.array.vals [x] = g_new (Value *, v->v.array.y);
		for (y = 0; y < v->v.array.y; y++)
			v->v.array.vals [x][y] = value_duplicate (src->v.array.vals [x][y]);
605 606 607 608 609 610 611 612 613
	}
}

guint
value_area_get_width (Value *v)
{
	g_return_val_if_fail (v, 0);
	g_return_val_if_fail (v->type == VALUE_ARRAY ||
			      v->type == VALUE_CELLRANGE, 1);
614

615 616
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
617 618 619 620 621 622 623 624
	else {
		guint ans = v->v.cell_range.cell_b.col -
			    v->v.cell_range.cell_a.col + 1;
		if (v->v.cell_range.cell_a.sheet && 
		    v->v.cell_range.cell_a.sheet->max_col_used < ans)
			ans = v->v.cell_range.cell_a.sheet->max_col_used+1;
		return ans;
	}
625 626 627 628 629 630 631 632
}

guint
value_area_get_height (Value *v)
{
	g_return_val_if_fail (v, 0);
	g_return_val_if_fail (v->type == VALUE_ARRAY ||
			      v->type == VALUE_CELLRANGE, 1);
633

634 635
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
636 637 638 639 640 641 642 643
	else {
		guint ans = v->v.cell_range.cell_b.row -
		            v->v.cell_range.cell_a.row + 1;
		if (v->v.cell_range.cell_a.sheet && 
		    v->v.cell_range.cell_a.sheet->max_row_used < ans)
			ans = v->v.cell_range.cell_a.sheet->max_row_used+1;
		return ans;
	}
644 645 646 647 648 649 650 651
}

const Value *
value_area_get_at_x_y (Value *v, guint x, guint y)
{
	g_return_val_if_fail (v, 0);
	g_return_val_if_fail (v->type == VALUE_ARRAY ||
			      v->type == VALUE_CELLRANGE,
Michael Meeks's avatar
Michael Meeks committed
652
			     value_new_int (0));
653 654

	if (v->type == VALUE_ARRAY){
655
		g_return_val_if_fail (v->v.array.x < x &&
656
				      v->v.array.y < y,
Michael Meeks's avatar
Michael Meeks committed
657
				     value_new_int (0));
658
		return v->v.array.vals [x][y];
659 660 661
	} else {
		CellRef *a, *b;
		Cell *cell;
662

663 664
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
665 666 667 668 669 670
		g_return_val_if_fail (!a->col_relative, value_zero);
		g_return_val_if_fail (!b->col_relative, value_zero);
		g_return_val_if_fail (!a->row_relative, value_zero);
		g_return_val_if_fail (!b->row_relative, value_zero);
		g_return_val_if_fail (a->col<=b->col, value_zero);
		g_return_val_if_fail (a->row<=b->row, value_zero);
Michael Meeks's avatar
Michael Meeks committed
671
		g_return_val_if_fail (a->sheet,       value_zero);
672 673 674 675 676

		/* Speedup */
		if (a->sheet->max_col_used < a->col+x ||
		    a->sheet->max_row_used < a->row+y)
			return value_zero;
677

678
		cell = sheet_cell_get (a->sheet, a->col+x, a->row+y);
679

680 681 682
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
683
	
684
	return value_zero;
685 686
}

687 688 689 690 691 692
static void
cell_ref_make_absolute (CellRef *cell_ref, int eval_col, int eval_row)
{
	g_return_if_fail (cell_ref != NULL);

	if (cell_ref->col_relative)
693
		cell_ref->col = eval_col + cell_ref->col;
694 695 696

	if (cell_ref->row_relative)
		cell_ref->row = eval_row + cell_ref->row;
697

Arturo Espinosa's avatar
Arturo Espinosa committed
698 699
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
700 701
}

702 703 704 705 706 707 708 709 710 711 712 713 714 715
static void
cell_ref_restore_absolute (CellRef *cell_ref, const CellRef *orig, int eval_col, int eval_row)
{
	if (orig->col_relative) {
		cell_ref->col -= eval_col;
		cell_ref->col_relative = 1;
	}

	if (orig->row_relative) {
		cell_ref->row -= eval_row;
		cell_ref->row_relative = 1;
	}
}

716 717 718 719
static void
free_values (Value **values, int top)
{
	int i;
720

721
	for (i = 0; i < top; i++)
722 723
		if (values[i])
			value_release (values [i]);
724 725 726
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
727 728 729
static Value *
eval_funcall (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
{
730
	const Symbol *sym;
Arturo Espinosa's avatar
Arturo Espinosa committed
731 732 733
	FunctionDefinition *fd;
	GList *l;
	int argc, arg, i;
734
	Value *v = NULL;
735

736
	sym = tree->u.function.symbol;
Arturo Espinosa's avatar
Arturo Espinosa committed
737 738 739
	l = tree->u.function.arg_list;
	argc = g_list_length (l);

Morten Welinder's avatar
Morten Welinder committed
740
	if (sym->type != SYMBOL_FUNCTION) {
741 742 743 744 745
		*error_string = _("Internal error");
		return NULL;
	}
	fd = (FunctionDefinition *)sym->data;

Arturo Espinosa's avatar
Arturo Espinosa committed
746 747 748 749 750 751 752 753 754
	if (fd->expr_fn)
	{
		/* Functions that deal with ExprNodes */
		v = fd->expr_fn (sheet, l, eval_col, eval_row, error_string);
	}
	else
	{
		/* Functions that take pre-computed Values */
		Value **values;
Arturo Espinosa's avatar
Arturo Espinosa committed
755
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
756 757
		const char *arg_type = fd->args;
		const char *argptr = fd->args;
758

759
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
760 761 762 763
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
764 765
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
766 767
				fn_argc_min++;
			fn_argc_max++;
768
		}
769

Arturo Espinosa's avatar
Arturo Espinosa committed
770
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
771 772 773 774
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

775
		values = g_new (Value *, fn_argc_max);
776

777
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
778
			ExprTree *t = (ExprTree *) l->data;
779
			int type_mismatch = 0;
780
			Value *v;
781

Arturo Espinosa's avatar
Arturo Espinosa committed
782 783
			if (*arg_type=='|')
				arg_type++;
784 785 786 787 788 789 790 791 792

			if ((*arg_type != 'A' &&          /* This is so a cell reference */
			     *arg_type != 'r') ||         /* can be converted to a cell range */
			    !t || (t->oper != OPER_VAR)) { /* without being evaluated */
				if ((v = eval_expr (sheet, t, eval_col,
						    eval_row, error_string))==NULL)
					goto free_list;
			} else {
				g_assert (t->oper == OPER_VAR);
Michael Meeks's avatar
Michael Meeks committed
793 794
				v =value_new_cellrange (&t->u.ref,
							 &t->u.ref);
795 796 797 798 799
				if (!v->v.cell_range.cell_a.sheet)
					v->v.cell_range.cell_a.sheet = sheet;
				if (!v->v.cell_range.cell_b.sheet)
					v->v.cell_range.cell_b.sheet = sheet;
			}
800

Arturo Espinosa's avatar
Arturo Espinosa committed
801
			switch (*arg_type){
802
			case 'f':
803

804 805 806 807
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
808
			case 's':
809 810
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
811
				break;
812
			case 'r':
813 814 815 816 817
				if (v->type != VALUE_CELLRANGE)
					type_mismatch = 1;
				else {
					cell_ref_make_absolute (&v->v.cell_range.cell_a, eval_col, eval_row);
					cell_ref_make_absolute (&v->v.cell_range.cell_b, eval_col, eval_row);
818
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
819
				break;
820 821 822 823 824 825 826 827
			case 'a':
				if (v->type != VALUE_ARRAY)
					type_mismatch = 1;
				break;
			case 'A':
				if (v->type != VALUE_ARRAY &&
				    v->type != VALUE_CELLRANGE)
					type_mismatch = 1;
Michael Meeks's avatar
Michael Meeks committed
828 829 830 831 832

				if (v->type == VALUE_CELLRANGE) {
					cell_ref_make_absolute (&v->v.cell_range.cell_a, eval_col, eval_row);
					cell_ref_make_absolute (&v->v.cell_range.cell_b, eval_col, eval_row);
				}
833 834
				break;
			}
835
			values [arg] = v;
836
			if (type_mismatch){
837
				free_values (values, arg + 1);
838 839
				*error_string = _("Type mismatch");
				return NULL;
840
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
841
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
842 843
		while (arg < fn_argc_max)
			values [arg++] = NULL;
844
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
845 846

	free_list:
847
		free_values (values, arg);
Arturo Espinosa's avatar
Arturo Espinosa committed
848 849 850 851
	}
	return v;
}

852 853 854 855 856
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
857

858 859 860 861 862 863 864 865 866 867 868
	if (fd->expr_fn){
		/*
		 * If function deals with ExprNodes, create some
		 * temporary ExprNodes with constants.
		 */
		ExprTree *tree = NULL;
		GList *l = NULL;
		int i;

		if (argc){
			tree = g_new (ExprTree, argc);
869

870
			for (i = 0; i < argc; i++){
871
				tree [i].oper = OPER_CONSTANT;
872 873
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
874

875 876 877
				l = g_list_append (l, &(tree[i]));
			}
		}
878

879 880 881 882 883 884 885
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

		if (tree){
			g_free (tree);
			g_list_free (l);
		}

886
	} else
887 888 889 890 891 892 893 894 895 896
		retval = fd->fn (fd, values, error_string);

	return retval;
}

/*
 * Use this to invoke a register function: the only drawback is that
 * you have to compute/expand all of the values to use this
 */
Value *
897
function_call_with_values (Sheet *sheet, const char *name, int argc, Value *values[], char **error_string)
898 899 900 901 902 903 904 905 906
{
	FunctionDefinition *fd;
	Value *retval;
	Symbol *sym;

	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
	g_return_val_if_fail (name != NULL, NULL);

Miguel de Icaza's avatar
Miguel de Icaza committed
907
	sym = symbol_lookup (global_symbol_table, name);
908
	if (sym == NULL){
909
		*error_string = _("Function does not exist");
910 911
		return NULL;
	}
912
	if (sym->type != SYMBOL_FUNCTION){
913
		*error_string = _("Calling non-function");
914 915
		return NULL;
	}
916

917 918 919 920 921 922 923 924 925 926
	fd = sym->data;

	symbol_ref (sym);
	retval = function_def_call_with_values (sheet, fd, argc, values, error_string);

	symbol_unref (sym);

	return retval;
}

927
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
928 929
	IS_EQUAL,
	IS_LESS,
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
	IS_GREATER,
	TYPE_ERROR
} compare_t;

static compare_t
compare_int_int (int a, int b)
{
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}

static compare_t
compare_float_float (float_t a, float_t b)
{
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}
Arturo Espinosa's avatar
Arturo Espinosa committed
955

956 957 958 959
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
960
compare (const Value *a, const Value *b)
Arturo Espinosa's avatar
Arturo Espinosa committed
961
{
962 963
	if (a->type == VALUE_INTEGER){
		int f;
964

965 966 967 968 969 970 971 972
		switch (b->type){
		case VALUE_INTEGER:
			return compare_int_int (a->v.v_int, b->v.v_int);

		case VALUE_FLOAT:
			return compare_float_float (a->v.v_int, b->v.v_float);

		case VALUE_STRING:
973
			f = value_get_as_float (b);
974 975 976 977 978 979
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
980

981 982 983 984 985 986 987 988 989 990 991
	if (a->type == VALUE_FLOAT){
		float_t f;

		switch (b->type){
		case VALUE_INTEGER:
			return compare_float_float (a->v.v_float, b->v.v_int);

		case VALUE_FLOAT:
			return compare_float_float (a->v.v_float, b->v.v_float);

		case VALUE_STRING:
992
			f = value_get_as_float (b);
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
			return compare_float_float (a->v.v_float, f);

		default:
			return TYPE_ERROR;
		}
	}

	if (a->type == VALUE_STRING && b->type == VALUE_STRING){
		int t;

		t = strcasecmp (a->v.str->str, b->v.str->str);
		if (t == 0)
			return IS_EQUAL;
		else if (t > 0)
			return IS_GREATER;
		else
			return IS_LESS;
	}

	return TYPE_ERROR;
Arturo Espinosa's avatar
Arturo Espinosa committed
1013 1014
}

Arturo Espinosa's avatar
Arturo Espinosa committed
1015
Value *
1016
eval_expr (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
1017 1018
{
	Value *a, *b, *res;
Arturo Espinosa's avatar
Arturo Espinosa committed
1019 1020

	g_return_val_if_fail (tree != NULL, NULL);
1021
	g_return_val_if_fail (sheet != NULL, NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1022
	g_return_val_if_fail (error_string != NULL, NULL);
1023
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
1024

1025
	switch (tree->oper){
1026 1027 1028 1029 1030 1031
	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
1032
		int comp;
1033

Arturo Espinosa's avatar
Arturo Espinosa committed
1034 1035
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
1036 1037 1038
		if (!a)
			return NULL;

Arturo Espinosa's avatar
Arturo Espinosa committed
1039 1040
		b = eval_expr (sheet, tree->u.binary.value_b,
			       eval_col, eval_row, error_string);
1041 1042
		if (!b) {
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
1043 1044 1045
			return NULL;
		}
		comp = compare (a, b);
1046 1047
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1048

1049 1050 1051 1052
		if (comp == TYPE_ERROR){
			*error_string = _("Type error");
			return NULL;
		}
1053

Arturo Espinosa's avatar
Arturo Espinosa committed
1054
		switch (tree->oper){
1055
		case OPER_EQUAL:
1056
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1057 1058
			break;

1059
		case OPER_GT:
1060
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1061 1062
			break;

1063
		case OPER_LT:
1064
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1065 1066
			break;

1067
		case OPER_LTE:
1068
			res = value_new_bool (comp == IS_EQUAL || comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1069 1070
			break;

1071
		case OPER_GTE:
1072
			res = value_new_bool (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1073 1074
			break;

1075
		case OPER_NOT_EQUAL:
1076
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1077
			break;
1078

Arturo Espinosa's avatar
Arturo Espinosa committed
1079
		default:
1080 1081 1082
			g_assert_not_reached ();
			*error_string = "Internal error";
			res = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
1083 1084 1085
		}
		return res;
	}
1086

1087 1088 1089 1090 1091
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
1092 1093
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
1094 1095 1096

		if (!a)
			return NULL;
1097

1098 1099
		b = eval_expr (sheet, tree->u.binary.value_b,
			       eval_col, eval_row, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
1100

1101 1102
		if (!b){
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
1103 1104
			return NULL;
		}
1105

Arturo Espinosa's avatar
Arturo Espinosa committed
1106
		if (!VALUE_IS_NUMBER (a) || !VALUE_IS_NUMBER (b)){
1107 1108
			value_release (a);
			value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1109 1110 1111
			*error_string = _("Type mismatch");
			return NULL;
		}
1112

Arturo Espinosa's avatar
Arturo Espinosa committed
1113 1114
		res = g_new (Value, 1);
		if (a->type == VALUE_INTEGER && b->type == VALUE_INTEGER){
1115 1116
			int ia = a->v.v_int;
			int ib = b->v.v_int;
1117

Arturo Espinosa's avatar
Arturo Espinosa committed
1118
			res->type = VALUE_INTEGER;
1119

1120
			switch (tree->oper){
1121
			case OPER_SUB:
1122 1123 1124 1125
			case OPER_ADD: {
				int sum;

				if (tree->oper == OPER_SUB){
Arturo Espinosa's avatar
0.20  
Arturo Espinosa committed
1126
					ib = -ib;
1127 1128 1129
				}

				sum = ia + ib;
1130

1131
				if ((ia > 0) && (ib > 0)){
1132

1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
					if (sum < ia){
						res->type = VALUE_FLOAT;