expr.c 40 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
Value *
Michael Meeks's avatar
Michael Meeks committed
306
value_new_string (const char *str)
307 308 309 310 311 312 313 314 315
{
	Value *v = g_new (Value, 1);

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

	return v;
}

316
Value *
Michael Meeks's avatar
Michael Meeks committed
317
value_new_cellrange (const CellRef *a, const CellRef *b)
318 319
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
320

321
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
322 323 324
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

325 326 327
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
328 329 330 331
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
332
Value *
333
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
334 335
{
	Value *newv;
336

Arturo Espinosa's avatar
Arturo Espinosa committed
337 338 339 340
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

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

Arturo Espinosa's avatar
Arturo Espinosa committed
342 343 344
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
345
	value_release (v);
346

Arturo Espinosa's avatar
Arturo Espinosa committed
347 348 349
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
350
int
Michael Meeks's avatar
Michael Meeks committed
351
value_get_as_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
352 353 354
{
	*err = 0;

355 356
	switch (v->type) {
	case VALUE_STRING:
Morten Welinder's avatar
Morten Welinder committed
357 358
		/* FIXME FIXME FIXME */
		/* Use locale to support TRUE, FALSE */
Arturo Espinosa's avatar
Arturo Espinosa committed
359 360
		return atoi (v->v.str->str);

361
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
362 363
		*err = 1;
		return 0;
364 365
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
366 367
		return v->v.v_int != 0;

368
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
369 370
		return v->v.v_float != 0.0;

371
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
372
		return 0;
373 374 375 376
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
377 378 379
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
380
float_t
Michael Meeks's avatar
Michael Meeks committed
381
value_get_as_float (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
382
{
383 384 385
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
386 387
		return atof (v->v.str->str);

388
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
389 390 391
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

392
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
393
		return (float_t) v->v.v_int;
394 395
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
396
		return 0.0;
397

398 399 400
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
Michael Meeks's avatar
Michael Meeks committed
401
		g_warning ("value_get_as_float type error\n");
402 403 404
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
405 406
}

407
int
408
value_get_as_int (const Value *v)
409
{
410 411 412
	switch (v->type)
	{
	case VALUE_STRING:
413 414
		return atoi (v->v.str->str);

415
	case VALUE_CELLRANGE:
Morten Welinder's avatar
Morten Welinder committed
416
		g_warning ("Getting range as a int: what to do?");
417
		return 0;
418

419
	case VALUE_INTEGER:
420 421
		return v->v.v_int;

422
	case VALUE_ARRAY:
423
		return 0;
424

425 426 427 428
	case VALUE_FLOAT:
		return (int) v->v.v_float;
	default:
		g_warning ("value_get_as_int unknown type\n");
429
		return 0;
430
	}
Michael Meeks's avatar
Michael Meeks committed
431
	return 0.0;
432 433
}

434 435 436
Value *
value_array_new (guint width, guint height)
{
437
	int x, y;
438 439 440 441 442

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
443
	v->v.array.vals = g_new (Value **, width);
444 445

	for (x = 0; x < width; x++){
446 447 448
		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);
449 450 451 452
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
453 454 455 456
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
457
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
458 459
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
460 461
	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
462

463 464 465
	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
466 467
}

468 469 470
void
value_array_resize (Value *v, guint width, guint height)
{
471
	int x, y, xcpy, ycpy;
472
	Value *newval;
473
	Value ***tmp;
474

Michael Meeks's avatar
Michael Meeks committed
475
	g_warning ("Totally untested");
476 477 478 479 480 481 482 483
	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
484
		xcpy = width;
485 486 487 488 489 490

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

491 492 493 494 495
	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;
496
	v->v.array.vals = newval->v.array.vals;
497
	newval->v.array.vals = tmp;
498 499
	value_release (newval);

500 501 502 503 504 505 506
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
507
	int x, y;
508 509 510 511 512

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

515 516 517 518
	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]);
519 520 521 522 523 524 525 526 527
	}
}

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

529 530
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
531 532 533 534 535 536 537 538
	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;
	}
539 540 541 542 543 544 545 546
}

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

548 549
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
550 551 552 553 554 555 556 557
	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;
	}
558 559 560 561 562 563 564 565
}

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
566
			     value_new_int (0));
567 568

	if (v->type == VALUE_ARRAY){
569
		g_return_val_if_fail (v->v.array.x < x &&
570
				      v->v.array.y < y,
Michael Meeks's avatar
Michael Meeks committed
571
				     value_new_int (0));
572
		return v->v.array.vals [x][y];
573 574 575
	} else {
		CellRef *a, *b;
		Cell *cell;
576

577 578
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
579 580 581 582 583 584
		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
585
		g_return_val_if_fail (a->sheet,       value_zero);
586 587 588 589 590

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

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

594 595 596
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
597
	
598
	return value_zero;
599 600
}

601 602 603 604 605 606
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)
607
		cell_ref->col = eval_col + cell_ref->col;
608 609 610

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

Arturo Espinosa's avatar
Arturo Espinosa committed
612 613
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
614 615
}

616 617 618 619 620 621 622 623 624 625 626 627 628 629
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;
	}
}

630
#if 0
Arturo Espinosa's avatar
Arturo Espinosa committed
631 632
static Value *
eval_cell_value (Sheet *sheet, Value *value)
633
{
Arturo Espinosa's avatar
Arturo Espinosa committed
634
	Value *res;
635

Arturo Espinosa's avatar
Arturo Espinosa committed
636 637
	res = g_new (Value, 1);
	res->type = value->type;
638

Arturo Espinosa's avatar
Arturo Espinosa committed
639 640 641
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
642
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
643
		break;
644

Arturo Espinosa's avatar
Arturo Espinosa committed
645
	case VALUE_INTEGER:
646
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
647
		break;
648

Arturo Espinosa's avatar
Arturo Espinosa committed
649
	case VALUE_FLOAT:
650
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
651
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
652 653

	case VALUE_ARRAY:
Michael Meeks's avatar
Michael Meeks committed
654
		res = value_duplicate (value);
Arturo Espinosa's avatar
Arturo Espinosa committed
655
		break;
656

Arturo Espinosa's avatar
Arturo Espinosa committed
657 658 659
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
660 661 662
	default:
		g_warning ("eval_cell_value error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
663 664 665
	}
	return res;
}
666
#endif
Arturo Espinosa's avatar
Arturo Espinosa committed
667

668 669 670 671
static void
free_values (Value **values, int top)
{
	int i;
672

673
	for (i = 0; i < top; i++)
674 675
		if (values[i])
			value_release (values [i]);
676 677 678
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
679 680 681 682 683 684
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;
685
	Value *v = NULL;
686

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

Arturo Espinosa's avatar
Arturo Espinosa committed
689 690 691 692 693 694 695 696 697 698 699 700
	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
701 702 703
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
		char *arg_type = fd->args;
		char *argptr = fd->args;
704

705
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
706 707 708 709
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
710 711
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
712 713
				fn_argc_min++;
			fn_argc_max++;
714
		}
715

Arturo Espinosa's avatar
Arturo Espinosa committed
716
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
717 718 719 720
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

721
		values = g_new (Value *, fn_argc_max);
722

723
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
724
			ExprTree *t = (ExprTree *) l->data;
725
			int type_mismatch = 0;
726
			Value *v;
727

Arturo Espinosa's avatar
Arturo Espinosa committed
728 729
			if (*arg_type=='|')
				arg_type++;
730 731 732 733 734 735 736 737 738

			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
739 740
				v =value_new_cellrange (&t->u.ref,
							 &t->u.ref);
741 742 743 744 745
				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;
			}
746

Arturo Espinosa's avatar
Arturo Espinosa committed
747
			switch (*arg_type){
748
			case 'f':
749

750 751 752 753
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
754
			case 's':
755 756
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
757
				break;
758
			case 'r':
759 760 761 762 763
				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);
764
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
765
				break;
766 767 768 769 770 771 772 773
			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
774 775 776 777 778

				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);
				}
779 780
				break;
			}
781
			values [arg] = v;
782
			if (type_mismatch){
783
				free_values (values, arg + 1);
784 785
				*error_string = _("Type mismatch");
				return NULL;
786
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
787
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
788 789
		while (arg < fn_argc_max)
			values [arg++] = NULL;
790
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
791 792

	free_list:
793
		free_values (values, arg);
Arturo Espinosa's avatar
Arturo Espinosa committed
794 795 796 797
	}
	return v;
}

798 799 800 801 802
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
803

804 805 806 807 808 809 810 811 812 813 814
	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);
815

816
			for (i = 0; i < argc; i++){
817
				tree [i].oper = OPER_CONSTANT;
818 819
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
820

821 822 823
				l = g_list_append (l, &(tree[i]));
			}
		}
824

825 826 827 828 829 830 831
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

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

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

863 864 865 866 867 868 869 870 871 872
	fd = sym->data;

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

	symbol_unref (sym);

	return retval;
}

873
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
874 875
	IS_EQUAL,
	IS_LESS,
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
	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
901

902 903 904 905
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
906
compare (const Value *a, const Value *b)
Arturo Espinosa's avatar
Arturo Espinosa committed
907
{
908 909
	if (a->type == VALUE_INTEGER){
		int f;
910

911 912 913 914 915 916 917 918
		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:
919
			f = value_get_as_float (b);
920 921 922 923 924 925
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
926

927 928 929 930 931 932 933 934 935 936 937
	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:
938
			f = value_get_as_float (b);
939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
			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
959 960
}

Arturo Espinosa's avatar
Arturo Espinosa committed
961
Value *
962
eval_expr (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
963 964
{
	Value *a, *b, *res;
Arturo Espinosa's avatar
Arturo Espinosa committed
965 966

	g_return_val_if_fail (tree != NULL, NULL);
967
	g_return_val_if_fail (sheet != NULL, NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
968
	g_return_val_if_fail (error_string != NULL, NULL);
969
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
970

971
	switch (tree->oper){
972 973 974 975 976 977
	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
978
		int comp;
979

Arturo Espinosa's avatar
Arturo Espinosa committed
980 981 982 983 984 985 986 987 988 989 990 991
		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);
992 993
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
994

995 996 997 998
		if (comp == TYPE_ERROR){
			*error_string = _("Type error");
			return NULL;
		}
999

Arturo Espinosa's avatar
Arturo Espinosa committed
1000
		switch (tree->oper){
1001
		case OPER_EQUAL:
1002
			res = value_new_int (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1003 1004
			break;

1005
		case OPER_GT:
1006
			res = value_new_int (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1007 1008
			break;

1009
		case OPER_LT:
1010
			res = value_new_int (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1011 1012
			break;

1013
		case OPER_LTE:
1014
			res = value_new_int (comp == IS_EQUAL || comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1015 1016
			break;

1017
		case OPER_GTE:
1018
			res = value_new_int (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1019 1020
			break;

1021
		case OPER_NOT_EQUAL:
1022
			res = value_new_int (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1023
			break;
1024

Arturo Espinosa's avatar
Arturo Espinosa committed
1025
		default:
1026 1027 1028
			g_assert_not_reached ();
			*error_string = "Internal error";
			res = NULL;
Arturo Espinosa's avatar
Arturo Espinosa committed
1029 1030 1031
		}
		return res;
	}
1032

1033 1034 1035 1036 1037
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
1038 1039
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
1040 1041 1042

		if (!a)
			return NULL;
1043

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

1047 1048
		if (!b){
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
1049 1050
			return NULL;
		}
1051

Arturo Espinosa's avatar
Arturo Espinosa committed
1052
		if (!VALUE_IS_NUMBER (a) || !VALUE_IS_NUMBER (b)){
1053 1054
			value_release (a);
			value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1055 1056 1057
			*error_string = _("Type mismatch");
			return NULL;
		}
1058

Arturo Espinosa's avatar
Arturo Espinosa committed
1059 1060
		res = g_new (Value, 1);
		if (a->type == VALUE_INTEGER && b->type == VALUE_INTEGER){
1061 1062
			int ia = a->v.v_int;
			int ib = b->v.v_int;
1063

Arturo Espinosa's avatar
Arturo Espinosa committed
1064
			res->type = VALUE_INTEGER;
1065

1066
			switch (tree->oper){
1067
			case OPER_SUB:
1068 1069 1070 1071
			case OPER_ADD: {
				int sum;

				if (tree->oper == OPER_SUB){
Arturo Espinosa's avatar
0.20  
Arturo Espinosa committed
1072
					ib = -ib;
1073 1074 1075
				}

				sum = ia + ib;
1076

1077
				if ((ia > 0) && (ib > 0)){
1078

1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
					if (sum < ia){
						res->type = VALUE_FLOAT;
						res->v.v_float = ((double)ia) + ib;
					} else
						res->v.v_int = sum;
				} else if ((ia < 0) && (ib < 0)){
					if (sum > ia){
						res->type = VALUE_FLOAT;
						res->v.v_float = ((double)ia) + ib;
					} else
						res->v.v_int = sum;
				} else
					res->v.v_int = sum;