expr.c 40.2 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 (void)
51
{
52 53 54 55 56 57
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (!ans)
		return NULL;
	
58 59 60 61 62 63
	ans->ref_count = 1;
	ans->oper = OPER_CONSTANT;
	ans->u.constant = NULL;
	return ans;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
64 65 66 67
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
68 69 70 71 72 73
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
74
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
75 76 77 78 79
}

static void
do_expr_tree_unref (ExprTree *tree)
{
Morten Welinder's avatar
Morten Welinder committed
80 81 82
	if (--tree->ref_count > 0)
		return;

Arturo Espinosa's avatar
Arturo Espinosa committed
83
	switch (tree->oper){
84
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
85
		break;
86

87
	case OPER_CONSTANT:
Morten Welinder's avatar
Morten Welinder committed
88
		value_release (tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
89
		break;
90

Morten Welinder's avatar
Morten Welinder committed
91 92 93 94 95 96 97
	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
98
		break;
Morten Welinder's avatar
Morten Welinder committed
99
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
100

101
	case OPER_ANY_BINARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
102 103 104 105
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

106
	case OPER_ANY_UNARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
107 108
		do_expr_tree_unref (tree->u.value);
		break;
109 110 111
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
112
	}
113

Morten Welinder's avatar
Morten Welinder committed
114
	g_free (tree);
115 116
}

Morten Welinder's avatar
Morten Welinder committed
117 118 119 120 121 122
/*
 * 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.)
 */
123 124 125 126 127 128
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
129
	do_expr_tree_unref (tree);
130 131
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
132 133 134 135
/*
 * simplistic value rendering
 */
char *
Michael Meeks's avatar
Michael Meeks committed
136
value_get_as_string (const Value *value)
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
137 138 139 140 141 142
{
	switch (value->type){
	case VALUE_STRING:
		return g_strdup (value->v.str->str);

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

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

148 149 150 151 152
	case VALUE_ARRAY: {
		GString *str = g_string_new ("{");
		guint lpx, lpy;
		char *ans;

153 154 155 156
		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];

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
				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;
	}
178

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
179
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
180
		break;
181 182 183
	default:
		g_warning ("value_string problem\n");
		break;
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
184
	}
185

Arturo Espinosa's avatar
Arturo Espinosa committed
186
	return g_strdup ("Internal problem");
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
187 188
}

189 190 191
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
192
	g_return_if_fail (value != NULL);
193

194 195 196 197 198 199 200
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
201
		break;
202

203 204 205 206
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

207
	case VALUE_ARRAY:{
208
		guint lpx, lpy;
209

210
		for (lpx = 0; lpx < value->v.array.x; lpx++){
211
			for (lpy = 0; lpy < value->v.array.y; lpy++)
212
				value_release (value->v.array.vals [lpx][lpy]);
213 214
			g_free (value->v.array.vals [lpx]);
		}
215

216
		g_free (value->v.array.vals);
Morten Welinder's avatar
Morten Welinder committed
217
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
218
	}
219

Arturo Espinosa's avatar
Arturo Espinosa committed
220 221
	case VALUE_CELLRANGE:
		break;
222

223 224 225
	default:
		g_warning ("value_release problem\n");
		break;
226
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
227
	g_free (value);
228
}
229

Arturo Espinosa's avatar
Arturo Espinosa committed
230 231 232 233
/*
 * Copies a Value.
 */
void
234
value_copy_to (Value *dest, const Value *source)
Arturo Espinosa's avatar
Arturo Espinosa committed
235 236 237 238 239
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
240

Arturo Espinosa's avatar
Arturo Espinosa committed
241 242 243 244 245 246 247 248 249 250 251 252 253 254
	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
255
	case VALUE_ARRAY: {
256
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
257 258 259 260 261
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
262 263 264
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
265 266 267
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
268 269 270 271
/*
 * Makes a copy of a Value
 */
Value *
272
value_duplicate (const Value *value)
Arturo Espinosa's avatar
Arturo Espinosa committed
273 274 275 276 277 278
{
	Value *new_value;

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

Arturo Espinosa's avatar
Arturo Espinosa committed
280 281 282
	return new_value;
}

283
Value *
Michael Meeks's avatar
Michael Meeks committed
284
value_new_float (float_t f)
285 286 287 288 289 290 291 292 293 294
{
	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
295
value_new_int (int i)
296 297 298 299 300 301 302 303 304
{
	Value *v = g_new (Value, 1);

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

	return v;
}

305 306 307 308 309 310 311 312
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);
}

313
Value *
Michael Meeks's avatar
Michael Meeks committed
314
value_new_string (const char *str)
315 316 317 318 319 320 321 322 323
{
	Value *v = g_new (Value, 1);

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

	return v;
}

324
Value *
Michael Meeks's avatar
Michael Meeks committed
325
value_new_cellrange (const CellRef *a, const CellRef *b)
326 327
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
328

329
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
330 331 332
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

333 334 335
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
336 337 338 339
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
340
Value *
341
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
342 343
{
	Value *newv;
344

Arturo Espinosa's avatar
Arturo Espinosa committed
345 346 347 348
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

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

Arturo Espinosa's avatar
Arturo Espinosa committed
350 351 352
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
353
	value_release (v);
354

Arturo Espinosa's avatar
Arturo Espinosa committed
355 356 357
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
358
int
Michael Meeks's avatar
Michael Meeks committed
359
value_get_as_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
360 361 362
{
	*err = 0;

363 364
	switch (v->type) {
	case VALUE_STRING:
Morten Welinder's avatar
Morten Welinder committed
365 366
		/* FIXME FIXME FIXME */
		/* Use locale to support TRUE, FALSE */
Arturo Espinosa's avatar
Arturo Espinosa committed
367 368
		return atoi (v->v.str->str);

369
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
370 371
		*err = 1;
		return 0;
372 373
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
374 375
		return v->v.v_int != 0;

376
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
377 378
		return v->v.v_float != 0.0;

379
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
380
		return 0;
381 382 383 384
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
385 386 387
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
388
float_t
Michael Meeks's avatar
Michael Meeks committed
389
value_get_as_float (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
390
{
391 392 393
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
394 395
		return atof (v->v.str->str);

396
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
397 398 399
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

400
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
401
		return (float_t) v->v.v_int;
402 403
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
404
		return 0.0;
405

406 407 408
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
Michael Meeks's avatar
Michael Meeks committed
409
		g_warning ("value_get_as_float type error\n");
410 411 412
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
413 414
}

415
int
416
value_get_as_int (const Value *v)
417
{
418 419 420
	switch (v->type)
	{
	case VALUE_STRING:
421 422
		return atoi (v->v.str->str);

423
	case VALUE_CELLRANGE:
Morten Welinder's avatar
Morten Welinder committed
424
		g_warning ("Getting range as a int: what to do?");
425
		return 0;
426

427
	case VALUE_INTEGER:
428 429
		return v->v.v_int;

430
	case VALUE_ARRAY:
431
		return 0;
432

433 434 435 436
	case VALUE_FLOAT:
		return (int) v->v.v_float;
	default:
		g_warning ("value_get_as_int unknown type\n");
437
		return 0;
438
	}
Michael Meeks's avatar
Michael Meeks committed
439
	return 0.0;
440 441
}

442 443 444
Value *
value_array_new (guint width, guint height)
{
445
	int x, y;
446 447 448 449 450

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
451
	v->v.array.vals = g_new (Value **, width);
452 453

	for (x = 0; x < width; x++){
454 455 456
		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);
457 458 459 460
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
461 462 463 464
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
465
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
466 467
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
468 469
	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
470

471 472 473
	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
474 475
}

476 477 478
void
value_array_resize (Value *v, guint width, guint height)
{
479
	int x, y, xcpy, ycpy;
480
	Value *newval;
481
	Value ***tmp;
482

Michael Meeks's avatar
Michael Meeks committed
483
	g_warning ("Totally untested");
484 485 486 487 488 489 490 491
	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
492
		xcpy = width;
493 494 495 496 497 498

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

499 500 501 502 503
	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;
504
	v->v.array.vals = newval->v.array.vals;
505
	newval->v.array.vals = tmp;
506 507
	value_release (newval);

508 509 510 511 512 513 514
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
515
	int x, y;
516 517 518 519 520

	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;
521
	v->v.array.vals = g_new (Value **, v->v.array.x);
522

523 524 525 526
	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]);
527 528 529 530 531 532 533 534 535
	}
}

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);
536

537 538
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
539 540 541 542 543 544 545 546
	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;
	}
547 548 549 550 551 552 553 554
}

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);
555

556 557
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
558 559 560 561 562 563 564 565
	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;
	}
566 567 568 569 570 571 572 573
}

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
574
			     value_new_int (0));
575 576

	if (v->type == VALUE_ARRAY){
577
		g_return_val_if_fail (v->v.array.x < x &&
578
				      v->v.array.y < y,
Michael Meeks's avatar
Michael Meeks committed
579
				     value_new_int (0));
580
		return v->v.array.vals [x][y];
581 582 583
	} else {
		CellRef *a, *b;
		Cell *cell;
584

585 586
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
587 588 589 590 591 592
		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
593
		g_return_val_if_fail (a->sheet,       value_zero);
594 595 596 597 598

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

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

602 603 604
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
605
	
606
	return value_zero;
607 608
}

609 610 611 612 613 614
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)
615
		cell_ref->col = eval_col + cell_ref->col;
616 617 618

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

Arturo Espinosa's avatar
Arturo Espinosa committed
620 621
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
622 623
}

624 625 626 627 628 629 630 631 632 633 634 635 636 637
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;
	}
}

638
#if 0
Arturo Espinosa's avatar
Arturo Espinosa committed
639 640
static Value *
eval_cell_value (Sheet *sheet, Value *value)
641
{
Arturo Espinosa's avatar
Arturo Espinosa committed
642
	Value *res;
643

Arturo Espinosa's avatar
Arturo Espinosa committed
644 645
	res = g_new (Value, 1);
	res->type = value->type;
646

Arturo Espinosa's avatar
Arturo Espinosa committed
647 648 649
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
650
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
651
		break;
652

Arturo Espinosa's avatar
Arturo Espinosa committed
653
	case VALUE_INTEGER:
654
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
655
		break;
656

Arturo Espinosa's avatar
Arturo Espinosa committed
657
	case VALUE_FLOAT:
658
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
659
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
660 661

	case VALUE_ARRAY:
Michael Meeks's avatar
Michael Meeks committed
662
		res = value_duplicate (value);
Arturo Espinosa's avatar
Arturo Espinosa committed
663
		break;
664

Arturo Espinosa's avatar
Arturo Espinosa committed
665 666 667
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
668 669 670
	default:
		g_warning ("eval_cell_value error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
671 672 673
	}
	return res;
}
674
#endif
Arturo Espinosa's avatar
Arturo Espinosa committed
675

676 677 678 679
static void
free_values (Value **values, int top)
{
	int i;
680

681
	for (i = 0; i < top; i++)
682 683
		if (values[i])
			value_release (values [i]);
684 685 686
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
687 688 689 690 691 692
static Value *
eval_funcall (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
{
	FunctionDefinition *fd;
	GList *l;
	int argc, arg, i;
693
	Value *v = NULL;
694

Arturo Espinosa's avatar
Arturo Espinosa committed
695
	fd = (FunctionDefinition *) tree->u.function.symbol->data;
696

Arturo Espinosa's avatar
Arturo Espinosa committed
697 698 699 700 701 702 703 704 705 706 707 708
	l = tree->u.function.arg_list;
	argc = g_list_length (l);

	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
709 710 711
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
		char *arg_type = fd->args;
		char *argptr = fd->args;
712

713
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
714 715 716 717
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
718 719
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
720 721
				fn_argc_min++;
			fn_argc_max++;
722
		}
723

Arturo Espinosa's avatar
Arturo Espinosa committed
724
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
725 726 727 728
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

729
		values = g_new (Value *, fn_argc_max);
730

731
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
732
			ExprTree *t = (ExprTree *) l->data;
733
			int type_mismatch = 0;
734
			Value *v;
735

Arturo Espinosa's avatar
Arturo Espinosa committed
736 737
			if (*arg_type=='|')
				arg_type++;
738 739 740 741 742 743 744 745 746

			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
747 748
				v =value_new_cellrange (&t->u.ref,
							 &t->u.ref);
749 750 751 752 753
				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;
			}
754

Arturo Espinosa's avatar
Arturo Espinosa committed
755
			switch (*arg_type){
756
			case 'f':
757

758 759 760 761
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
762
			case 's':
763 764
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
765
				break;
766
			case 'r':
767 768 769 770 771
				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);
772
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
773
				break;
774 775 776 777 778 779 780 781
			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
782 783 784 785 786

				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);
				}
787 788
				break;
			}
789
			values [arg] = v;
790
			if (type_mismatch){
791
				free_values (values, arg + 1);
792 793
				*error_string = _("Type mismatch");
				return NULL;
794
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
795
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
796 797
		while (arg < fn_argc_max)
			values [arg++] = NULL;
798
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
799 800

	free_list:
801
		free_values (values, arg);
Arturo Espinosa's avatar
Arturo Espinosa committed
802 803 804 805
	}
	return v;
}

806 807 808 809 810
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
811

812 813 814 815 816 817 818 819 820 821 822
	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);
823

824
			for (i = 0; i < argc; i++){
825
				tree [i].oper = OPER_CONSTANT;
826 827
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
828

829 830 831
				l = g_list_append (l, &(tree[i]));
			}
		}
832

833 834 835 836 837 838 839
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

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

840
	} else
841 842 843 844 845 846 847 848 849 850
		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 *
851
function_call_with_values (Sheet *sheet, const char *name, int argc, Value *values[], char **error_string)
852 853 854 855 856 857 858 859 860
{
	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
861
	sym = symbol_lookup (global_symbol_table, name);
862
	if (sym == NULL){
863
		*error_string = _("Function does not exist");
864 865
		return NULL;
	}
866
	if (sym->type != SYMBOL_FUNCTION){
867
		*error_string = _("Calling non-function");
868 869
		return NULL;
	}
870

871 872 873 874 875 876 877 878 879 880
	fd = sym->data;

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

	symbol_unref (sym);

	return retval;
}

881
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
882 883
	IS_EQUAL,
	IS_LESS,
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
	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
909

910 911 912 913
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
914
compare (const Value *a, const Value *b)
Arturo Espinosa's avatar
Arturo Espinosa committed
915
{
916 917
	if (a->type == VALUE_INTEGER){
		int f;
918

919 920 921 922 923 924 925 926
		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:
927
			f = value_get_as_float (b);
928 929 930 931 932 933
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
934

935 936 937 938 939 940 941 942 943 944 945
	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:
946
			f = value_get_as_float (b);
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
			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
967 968
}

Arturo Espinosa's avatar
Arturo Espinosa committed
969
Value *
970
eval_expr (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
971 972
{
	Value *a, *b, *res;
Arturo Espinosa's avatar
Arturo Espinosa committed
973 974

	g_return_val_if_fail (tree != NULL, NULL);
975
	g_return_val_if_fail (sheet != NULL, NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
976
	g_return_val_if_fail (error_string != NULL, NULL);
977
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
978

979
	switch (tree->oper){
980 981 982 983 984 985
	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
986
		int comp;
987

Arturo Espinosa's avatar
Arturo Espinosa committed
988 989 990 991 992 993 994 995 996 997 998 999
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
		b = eval_expr (sheet, tree->u.binary.value_b,
			       eval_col, eval_row, error_string);
		if (!(a && b)){
			if (a)
				value_release (a);
			if (b)
				value_release (b);
			return NULL;
		}
		comp = compare (a, b);
1000 1001
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1002

1003 1004 1005 1006
		if (comp == TYPE_ERROR){
			*error_string = _("Type error");
			return NULL;
		}
1007

Arturo Espinosa's avatar
Arturo Espinosa committed
1008
		switch (tree->oper){
1009
		case OPER_EQUAL:
1010
			res = value_new_bool (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1011 1012
			break;

1013
		case OPER_GT:
1014
			res = value_new_bool (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1015 1016
			break;

1017
		case OPER_LT:
1018
			res = value_new_bool (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1019 1020
			break;

1021
		case OPER_LTE:
1022
			res = value_new_bool (comp == IS_EQUAL || comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1023 1024
			break;

1025
		case OPER_GTE:
1026
			res = value_new_bool (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1027 1028
			break;

1029
		case OPER_NOT_EQUAL:
1030
			res = value_new_bool (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1031
			break;
1032

Arturo Espinosa's avatar
Arturo Espinosa committed
1033
		default:
1034 1035 1036
			g_assert_not_reached ();
			*error_string = "Internal error";
			res = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
1037 1038 1039
		}
		return res;
	}
1040

1041 1042 1043 1044 1045
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
1046 1047
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
1048 1049 1050

		if (!a)
			return NULL;
1051

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

1055 1056
		if (!b){
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
1057 1058
			return NULL;
		}
1059

Arturo Espinosa's avatar
Arturo Espinosa committed
1060
		if (!VALUE_IS_NUMBER (a) || !VALUE_IS_NUMBER (b)){
1061 1062
			value_release (a);
			value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1063 1064 1065
			*error_string = _("Type mismatch");
			return NULL;
		}
1066

Arturo Espinosa's avatar
Arturo Espinosa committed
1067 1068
		res = g_new (Value, 1);
		if (a->type == VALUE_INTEGER && b->type == VALUE_INTEGER){
1069 1070
			int ia = a->v.v_int;
			int ib = b->v.v_int;
1071

Arturo Espinosa's avatar
Arturo Espinosa committed
1072
			res->type = VALUE_INTEGER;
1073

1074
			switch (tree->oper){
1075
			case OPER_SUB:
1076 1077 1078 1079
			case OPER_ADD: {
				int sum;

				if (tree->oper == OPER_SUB){
Arturo Espinosa's avatar
0.20  
Arturo Espinosa committed
1080
					ib = -ib;
1081 1082 1083
				}

				sum = ia + ib;
1084

1085
				if ((ia > 0) && (ib > 0)){
1086

1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
					if (sum < ia){
						res->type = VALUE_FLOAT;
						res->v.v_float = ((double)ia) + ib;
					} else
						res->v.v_int = sum</