expr.c 20.9 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

Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
17
18
19
20
21
22
23
24
25
26
27
28
/* Shared variables with parser.y */

/*       The expression being parsed */
char     *parser_expr;

/*        The suggested format to use for this expression */
char     *parser_desired_format;

/*        The error returned from the */
ParseErr  parser_error;

/*        The expression tree returned from the parser */
29
ExprTree *parser_result;
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
30

31
32
33
/*        The sheet where the parsing takes place */
void     *parser_sheet;

Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
34
35
/*        Location where the parsing is taking place */
int       parser_col, parser_row;
36

37
ExprTree *
38
expr_parse_string (char *expr, void *sheet, int col, int row, char **desired_format, char **error_msg)
39
{
40
41
42
	g_return_val_if_fail (expr != NULL, NULL);
	
	parser_expr  = expr;
43
	parser_error = PARSE_OK;
44
45
46
	parser_col   = col;
	parser_row   = row;
	parser_sheet = sheet;
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
47
48
	parser_desired_format = NULL;
	
49
	yyparse ();
50
51
52
	switch (parser_error){
	case PARSE_OK:
		*error_msg = NULL;
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
53
54
		if (desired_format)
			*desired_format = parser_desired_format;
55
		parser_result->ref_count = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
56
		return parser_result;
57

Arturo Espinosa's avatar
Arturo Espinosa committed
58
59
60
61
	case PARSE_ERR_SYNTAX:
		*error_msg = _("Syntax error");
		break;
			
62
63
64
65
	case PARSE_ERR_NO_QUOTE:
		*error_msg = _("Missing quote");
		break;
	}
66
67
68
	return NULL;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
69
70
static void
do_expr_tree_ref (ExprTree *tree)
71
{
72
	g_return_if_fail (tree != NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
73
74
75
	g_return_if_fail (tree->ref_count > 0);

	tree->ref_count++;
76
	switch (tree->oper){
77
78
79
	case OPER_VAR:
	case OPER_CONSTANT:
	case OPER_FUNCALL:
80
81
		break;

82
83
84
85
86
87
88
89
90
91
92
93
	case OPER_EQUAL:
	case OPER_GT:
	case OPER_LT:
	case OPER_GTE:
	case OPER_LTE:
	case OPER_NOT_EQUAL:
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
	case OPER_CONCAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
94
95
		do_expr_tree_ref (tree->u.binary.value_a);
		do_expr_tree_ref (tree->u.binary.value_b);
96
97
		break;

98
	case OPER_NEG:
Arturo Espinosa's avatar
Arturo Espinosa committed
99
		do_expr_tree_ref (tree->u.value);
100
101
102
103
		break;
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
104
105
106
107
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
108
109
110
111
112
113
void
expr_tree_ref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Arturo Espinosa's avatar
Arturo Espinosa committed
114
115
116
117
118
119
120
121
	do_expr_tree_ref (tree);
}

static void
do_expr_tree_unref (ExprTree *tree)
{
	tree->ref_count--;
	switch (tree->oper){
122
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
123
124
		break;
		
125
	case OPER_CONSTANT:
Arturo Espinosa's avatar
Arturo Espinosa committed
126
127
128
129
		if (tree->ref_count == 0)
			value_release (tree->u.constant);
		break;
		
130
	case OPER_FUNCALL:
Arturo Espinosa's avatar
Arturo Espinosa committed
131
132
133
134
		if (tree->ref_count == 0)
			symbol_unref (tree->u.function.symbol);
		break;

135
136
137
138
139
140
141
142
143
144
145
146
	case OPER_EQUAL:
	case OPER_GT:
	case OPER_LT:
	case OPER_GTE:
	case OPER_LTE:
	case OPER_NOT_EQUAL:
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
	case OPER_CONCAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
147
148
149
150
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

151
	case OPER_NEG:
Arturo Espinosa's avatar
Arturo Espinosa committed
152
153
154
155
156
157
		do_expr_tree_unref (tree->u.value);
		break;
	}
	
	if (tree->ref_count == 0)
		g_free (tree);
158
159
160
161
162
163
164
165
}

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
166
	do_expr_tree_unref (tree);
167
168
}

Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
169
170
171
172
173
174
/*
 * simplistic value rendering
 */
char *
value_string (Value *value)
{
175
	char buffer [40];
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
		
	switch (value->type){
	case VALUE_STRING:
		return g_strdup (value->v.str->str);

	case VALUE_INTEGER:
		snprintf (buffer, sizeof (buffer)-1, "%d", value->v.v_int);
		break;

	case VALUE_FLOAT:
		snprintf (buffer, sizeof (buffer)-1, "%g", value->v.v_float);
		break;

	case VALUE_ARRAY:
		snprintf (buffer, sizeof (buffer)-1, "ARRAY");
		break;
		
	case VALUE_CELLRANGE:
		return g_strdup ("Internal problem");
	}
	return g_strdup (buffer);
}

199
200
201
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
202
203
	g_return_if_fail (value != NULL);
	
204
205
206
207
208
209
210
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
211
212
		break;
		
213
214
215
216
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

Arturo Espinosa's avatar
Arturo Espinosa committed
217
218
219
220
221
222
223
224
225
226
227
	case VALUE_ARRAY: {
		GList *l;

		for (l = value->v.array; l; l = l->next)
			value_release (l->data);
		g_list_free (l);
	}
	
	case VALUE_CELLRANGE:
		break;
		
228
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
229
	g_free (value);
230
}
231

Arturo Espinosa's avatar
Arturo Espinosa committed
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*
 * Copies a Value.
 */
void
value_copy_to (Value *dest, Value *source)
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
	
	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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
	case VALUE_ARRAY: {
		GList *l, *new = NULL;

		for (l = source->v.array; l; l = l->next){
			Value *copy;

			copy = value_duplicate (l->data);
			
			new = g_list_append (new, copy);
		}
		dest->v.array = new;
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
273
274
275
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/*
 * Makes a copy of a Value
 */
Value *
value_duplicate (Value *value)
{
	Value *new_value;

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

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
Value *
value_float (float_t f)
{
	Value *v = g_new (Value, 1);

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

	return v;
}

Value *
value_int (int i)
{
	Value *v = g_new (Value, 1);

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

	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
313
314
315
316
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
317
Value *
318
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
319
320
321
322
323
324
325
{
	Value *newv;
	
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

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

Arturo Espinosa's avatar
Arturo Espinosa committed
327
328
329
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
330
	value_release (v);
Arturo Espinosa's avatar
Arturo Espinosa committed
331
332
333
334
	
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
int
value_get_bool (Value *v, int *err)
{
	*err = 0;

	if (v->type == VALUE_STRING)
		return atoi (v->v.str->str);

	if (v->type == VALUE_CELLRANGE){
		*err = 1;
		return 0;
	}

	if (v->type == VALUE_INTEGER)
		return v->v.v_int != 0;

	if (v->type == VALUE_FLOAT)
		return v->v.v_float != 0.0;

	if (v->type == VALUE_ARRAY)
		return 0;
	
	g_warning ("Unhandled value in value_get_boolean");

	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
float_t
value_get_as_double (Value *v)
{
	if (v->type == VALUE_STRING){
		return atof (v->v.str->str);
	}

	if (v->type == VALUE_CELLRANGE){
		g_warning ("Getting range as a double: what to do?");
		return 0.0;
	}

	if (v->type == VALUE_INTEGER)
		return (float_t) v->v.v_int;

Arturo Espinosa's avatar
Arturo Espinosa committed
377
378
379
	if (v->type == VALUE_ARRAY)
		return 0.0;
	
Arturo Espinosa's avatar
Arturo Espinosa committed
380
	return (float_t) v->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
381
382
}

383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
int
value_get_as_int (Value *v)
{
	if (v->type == VALUE_STRING){
		return atoi (v->v.str->str);
	}

	if (v->type == VALUE_CELLRANGE){
		g_warning ("Getting range as a double: what to do?");
		return 0.0;
	}

	if (v->type == VALUE_INTEGER)
		return v->v.v_int;

	if (v->type == VALUE_ARRAY)
		return 0.0;
	
	return (int) v->v.v_float;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
404
405
static Value *
eval_cell_value (Sheet *sheet, Value *value)
406
{
Arturo Espinosa's avatar
Arturo Espinosa committed
407
	Value *res;
408

Arturo Espinosa's avatar
Arturo Espinosa committed
409
410
411
412
413
414
	res = g_new (Value, 1);
	res->type = value->type;
	
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
415
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
416
417
418
		break;
		
	case VALUE_INTEGER:
419
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
420
421
422
		break;
		
	case VALUE_FLOAT:
423
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
424
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
425
426
427
428
429
430
431

	case VALUE_ARRAY:
		g_warning ("VALUE_ARRAY not handled in eval_cell_value\n");
		res->type = VALUE_INTEGER;
		res->v.v_int = 0;
		break;
			
Arturo Espinosa's avatar
Arturo Espinosa committed
432
433
434
435
436
437
438
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
	}
	return res;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
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;
	Value *v;
	
	fd = (FunctionDefinition *) tree->u.function.symbol->data;
	
	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;
		int fn_argc;
		char *arg_type = fd->args;
		
		fn_argc = strlen (fd->args);
		
		if (fn_argc != argc){
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

		values = g_new (Value *, argc);
		
		for (arg = 0; l; l = l->next, arg++, arg_type++){
			ExprTree *t = (ExprTree *) l->data;
			
			v = eval_expr (sheet, t, eval_col, eval_row, error_string);
			if (v == NULL)
				goto free_list;
			
			values [arg] = v;
		}
482
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
483
484
485
486
487
488
489
490
491
492

	free_list:
		for (i = 0; i < arg; i++)
			value_release (values [i]);
		g_free (values);
		return v;
	}
	return v;
}

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
	
	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);
		
			for (i = 0; i < argc; i++){
512
				tree [i].oper = OPER_CONSTANT;
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
				
				l = g_list_append (l, &(tree[i]));
			}
		}
		
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

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

	} else 
		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 *
function_call_with_values (Sheet *sheet, char *name, int argc, Value *values[], char **error_string)
{
	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
548
	sym = symbol_lookup (global_symbol_table, name);
549
550
551
552
	if (sym == NULL){
		*error_string = "Function does not exist";
		return NULL;
	}
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
	if (sym->type != SYMBOL_FUNCTION){
		*error_string = "Calling non-function";
		return NULL;
	}
	
	fd = sym->data;

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

	symbol_unref (sym);

	return retval;
}

568
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
569
570
	IS_EQUAL,
	IS_LESS,
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
	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
596

597
598
599
600
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
Arturo Espinosa's avatar
Arturo Espinosa committed
601
602
compare (Value *a, Value *b)
{
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
	if (a->type == VALUE_INTEGER){
		int f;
		
		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:
			f = value_get_as_double (b);
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
	
	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:
			f = value_get_as_double (b);
			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
654
655
}

Arturo Espinosa's avatar
Arturo Espinosa committed
656
Value *
657
eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
658
659
660
{
	Value *a, *b, *res;
	Sheet *sheet = asheet;
Arturo Espinosa's avatar
Arturo Espinosa committed
661
662
663
664
665

	g_return_val_if_fail (tree != NULL, NULL);
	g_return_val_if_fail (asheet != NULL, NULL);
	g_return_val_if_fail (error_string != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (asheet), NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
666
	
667
	switch (tree->oper){
668
669
670
671
672
673
	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
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
		int comp;
		
		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;
		}
		res = g_new (Value, 1);
		res->type = VALUE_INTEGER;

		comp = compare (a, b);

692
693
694
695
696
697
698
		if (comp == TYPE_ERROR){
			value_release (a);
			value_release (b);
			*error_string = _("Type error");
			return NULL;
		}
		
Arturo Espinosa's avatar
Arturo Espinosa committed
699
		switch (tree->oper){
700
		case OPER_EQUAL:
Arturo Espinosa's avatar
Arturo Espinosa committed
701
702
703
			res->v.v_int = comp == IS_EQUAL;
			break;

704
		case OPER_GT:
705
			res->v.v_int = comp == IS_GREATER;
Arturo Espinosa's avatar
Arturo Espinosa committed
706
707
			break;

708
		case OPER_LT:
Arturo Espinosa's avatar
Arturo Espinosa committed
709
710
711
			res->v.v_int = comp == IS_LESS;
			break;

712
		case OPER_LTE:
Arturo Espinosa's avatar
Arturo Espinosa committed
713
714
715
			res->v.v_int = (comp == IS_EQUAL || comp == IS_LESS);
			break;

716
		case OPER_GTE:
717
			res->v.v_int = (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
718
719
			break;

720
		case OPER_NOT_EQUAL:
Arturo Espinosa's avatar
Arturo Espinosa committed
721
722
723
724
725
726
727
728
729
730
731
			res->v.v_int = comp != IS_EQUAL;
			break;
			
		default:
			g_warning ("This should never be reached: comparission ops\n");
		}
		value_release (a);
		value_release (b);
		return res;
	}
	
732
733
734
735
736
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
737
738
739
740
		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);
Arturo Espinosa's avatar
Arturo Espinosa committed
741
742
743

		if (!(a && b)){
			if (a)
744
				value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
745
			if (b)
746
				value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
747
748
749
750
			return NULL;
		}
		
		if (!VALUE_IS_NUMBER (a) || !VALUE_IS_NUMBER (b)){
751
752
			value_release (a);
			value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
753
754
755
756
757
758
759
760
			*error_string = _("Type mismatch");
			return NULL;
		}
		
		res = g_new (Value, 1);
		if (a->type == VALUE_INTEGER && b->type == VALUE_INTEGER){
			res->type = VALUE_INTEGER;
			
761
			switch (tree->oper){
762
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
763
				res->v.v_int = a->v.v_int + b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
764
765
				break;
				
766
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
767
				res->v.v_int = a->v.v_int - b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
768
769
				break;
				
770
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
771
				res->v.v_int = a->v.v_int * b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
772
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
773

774
			case OPER_DIV:
Arturo Espinosa's avatar
Arturo Espinosa committed
775
				if (b->v.v_int == 0){
776
777
778
					value_release (a);
					value_release (b);
					value_release (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
779
780
781
					*error_string = _("Division by zero");
					return NULL;
				}
782
783
				res->type = VALUE_FLOAT;
				res->v.v_float =  a->v.v_int / (float_t)b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
784
785
				break;
				
786
			case OPER_EXP: 
Arturo Espinosa's avatar
Arturo Espinosa committed
787
				res->v.v_int = pow (a->v.v_int, b->v.v_int);
Arturo Espinosa's avatar
Arturo Espinosa committed
788
789
790
791
792
				break;
			default:
			}
		} else {
			res->type = VALUE_FLOAT;
Arturo Espinosa's avatar
Arturo Espinosa committed
793
			res->v.v_float = 0.0;
794
795
			a = value_cast_to_float (a);
			b = value_cast_to_float (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
796
			
797
			switch (tree->oper){
798
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
799
				res->v.v_float = a->v.v_float + b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
800
801
				break;
				
802
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
803
				res->v.v_float = a->v.v_float - b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
804
805
				break;
				
806
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
807
				res->v.v_float = a->v.v_float * b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
808
809
				break;
				
810
			case OPER_DIV:
Arturo Espinosa's avatar
Arturo Espinosa committed
811
				if (b->v.v_float == 0.0){
812
813
814
					value_release (a);
					value_release (b);
					value_release (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
815
816
817
					*error_string = _("Division by zero");
					return NULL;
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
818
819

				res->v.v_float = a->v.v_float / b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
820
821
				break;
				
822
			case OPER_EXP:
Arturo Espinosa's avatar
Arturo Espinosa committed
823
				res->v.v_float = pow (a->v.v_float, b->v.v_float);
Arturo Espinosa's avatar
Arturo Espinosa committed
824
825
826
827
				break;
			default:
			}
		}
828
829
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
830
831
		return res;
		
832
	case OPER_CONCAT: {
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
		char *sa, *sb, *tmp;

		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
		if (!a)
			return NULL;
		b = eval_expr (sheet, tree->u.binary.value_b,
			       eval_col, eval_row, error_string);
		if (!b){
			value_release (a);
			return NULL;
		}

		res = g_new (Value, 1);
		res->type = VALUE_STRING;
		sa = value_string (a);
		sb = value_string (b);
		
		tmp = g_copy_strings (sa, sb, NULL);
		res->v.str = string_get (tmp);
		g_free (sa);
		g_free (sb);
		g_free (tmp);

		value_release (a);
		value_release (b);
		return res;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
861

862
	case OPER_FUNCALL:
Arturo Espinosa's avatar
Arturo Espinosa committed
863
		return eval_funcall (sheet, tree, eval_col, eval_row, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
864

865
	case OPER_CONSTANT:
866
		return eval_cell_value (sheet, tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
867

868
	case OPER_VAR:{
869
		CellRef *ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
870
871
872
873
874
875
876
877
878
879
880
881
882
		Cell *cell;
		int col, row;
		
		if (sheet == NULL){
			/* Only the test program requests this */
			res = g_new (Value, 1);

			res->type = VALUE_FLOAT;
			res->v.v_float = 3.14;
			
			return res;
		}

883
		ref = &tree->u.constant->v.cell;
Arturo Espinosa's avatar
Arturo Espinosa committed
884
		cell_get_abs_col_row (&tree->u.constant->v.cell, eval_col, eval_row, &col, &row);
Arturo Espinosa's avatar
Today:    
Arturo Espinosa committed
885

Arturo Espinosa's avatar
Arturo Espinosa committed
886
		cell = sheet_cell_get (sheet, col, row);
887

Arturo Espinosa's avatar
Arturo Espinosa committed
888
		if (cell){
889
			if (cell->generation != sheet->workbook->generation){
890
				cell->generation = sheet->workbook->generation;
891
892
893
894
895

				if (cell->parsed_node)
					cell_eval (cell);
			}

896
897
			if (cell->value)
				return eval_cell_value (sheet, cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
898
		}
899
900
901
902
		res = g_new (Value, 1);
			
		res->type = VALUE_INTEGER;
		res->v.v_int = 0;
Arturo Espinosa's avatar
Arturo Espinosa committed
903
904
		return res;
	}
905
	case OPER_NEG:
906
907
		a = eval_expr (sheet, tree->u.value,
			       eval_col, eval_row, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
908
909
910
911
		if (!a)
			return NULL;
		if (!VALUE_IS_NUMBER (a)){
			*error_string = _("Type mismatch");
912
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
913
914
915
			return NULL;
		}
		res = g_new (Value, 1);
916
		res->type = a->type;
Arturo Espinosa's avatar
Arturo Espinosa committed
917
		if (a->type == VALUE_INTEGER){
Arturo Espinosa's avatar
Arturo Espinosa committed
918
			res->v.v_int = -a->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
919
		} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
920
			res->v.v_float = -a->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
921
		}
922
		value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
923
		return res;
924
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
925
926
927
	
	*error_string = _("Unknown evaluation error");
	return NULL;
928
}
Arturo Espinosa's avatar
Arturo Espinosa committed
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945

void
cell_get_abs_col_row (CellRef *cell_ref, int eval_col, int eval_row, int *col, int *row)
{
	g_return_if_fail (cell_ref != NULL);

	if (cell_ref->col_relative)
		*col = eval_col + cell_ref->col;
	else
		*col = cell_ref->col;

	if (cell_ref->row_relative)
		*row = eval_row + cell_ref->row;
	else
		*row = cell_ref->row;
}

946
947
948
static int
evaluate_level (Operation x)
{
949
	if (x == OPER_EXP)
950
		return 3;
951
	if ((x==OPER_MULT) || (x==OPER_DIV))
952
		return 2;
953
	if ((x==OPER_ADD)  || (x==OPER_SUB)   || (x==OPER_CONCAT))
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
		return 1;
	return 0;
}

static int
bigger_prec (Operation parent, Operation this)
{
	int parent_level, this_level;

	parent_level = evaluate_level (parent);
	this_level   = evaluate_level (this);

	return parent_level > this_level;
}

969
970
971
972
973
974
975
976
977
/*
 * Converts a parsed tree into its string representation
 * assuming that we are evaluating at col, row (This is
 * only used during copying to "render" a new text
 * representation for a copied cell.
 *
 * This routine is pretty simple: it walks the ExprTree and
 * create a string representation.
 */
978
static char *
979
do_expr_decode_tree (ExprTree *tree, void *sheet, int col, int row, Operation parent_op)
980
981
982
983
984
985
986
987
988
{
	static const char *binary_operation_names [] = {
		"=", ">", "<", ">=", "<=", "<>",
		"+", "-", "*", "/",  "^",  "&"
	};

	switch (tree->oper){

		/* The binary operations */
989
990
991
992
993
994
995
996
997
998
999
1000
	case OPER_EQUAL:
	case OPER_NOT_EQUAL:
	case OPER_GT:
	case OPER_GTE:
	case OPER_LT:
	case OPER_LTE:
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
	case OPER_CONCAT: {	
1001
1002
1003
		char *a, *b, *res;
		char const *op;
		
1004
1005
		a = do_expr_decode_tree (tree->u.binary.value_a, sheet, col, row, tree->oper);
		b = do_expr_decode_tree (tree->u.binary.value_b, sheet, col, row, tree->oper);
1006
		op = binary_operation_names [tree->oper];
1007
1008
1009
1010
1011
1012

		if (bigger_prec (parent_op, tree->oper))
			res = g_copy_strings ("(", a, op, b, ")", NULL);
		else
			res = g_copy_strings (a, op, b, NULL);
		
1013
1014
1015
1016
1017
		g_free (a);
		g_free (b);
		return res;
	}
	
1018
	case OPER_NEG: {
1019
1020
		char *res, *a;

1021
		a = do_expr_decode_tree (tree->u.value, sheet, col, row, tree->oper);
1022
1023
1024
1025
1026
		res = g_copy_strings ("-", a);
		g_free (a);
		return res;
	}
	
1027
	case OPER_FUNCALL: {
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
		FunctionDefinition *fd;
		GList *arg_list, *l;
		char *res, *sum;
		char **args;
		int  argc;

		fd = tree->u.function.symbol->data;
		arg_list = tree->u.function.arg_list;
		argc = g_list_length (arg_list);

		if (argc){
			int i, len = 0;
			args = g_malloc (sizeof (char *) * argc);

			i = 0;
1043
			for (l = arg_list; l; l = l->next, i++){
1044
1045
				ExprTree *t = l->data;
				
1046
				args [i] = do_expr_decode_tree (t, sheet, col, row, OPER_CONSTANT);
1047
1048
1049
				len += strlen (args [i]) + 1;
			}
			len++;
1050
			sum = g_malloc (len + 2);
1051
1052
1053
			
			i = 0;
			sum [0] = 0;
1054
			for (l = arg_list; l; l = l->next, i++){
1055
				strcat (sum, args [i]);
1056
1057
1058
1059
				if (l->next)
					strcat (sum, ",");
			}
			
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
			res = g_copy_strings (
				fd->name, "(", sum, ")", NULL);

			for (i = 0; i < argc; i++)
				g_free (args [i]);
			g_free (args);

			return res;
		} else
			return g_copy_strings (fd->name, "()", NULL);
	}
	
1072
	case OPER_CONSTANT: {
1073
1074
1075
		Value *v = tree->u.constant;

		if (v->type == VALUE_CELLRANGE){
1076
1077
1078
1079
			char *a, *b, *res;

			a = cellref_name (&v->v.cell_range.cell_a, sheet, col, row);
			b = cellref_name (&v->v.cell_range.cell_b, sheet, col, row);
1080

1081
			res = g_copy_strings (a, ":", b, NULL);
1082

1083
1084
1085
1086
			g_free (a);
			g_free (b);
			
			return res;
1087
1088
1089
1090
1091
1092
		} else {
			if (v->type == VALUE_STRING){
				return g_copy_strings ("\"", v->v.str->str, "\"", NULL);
			} else
				return value_string (v);
		}
1093
1094
	}
	
1095
	case OPER_VAR: {
1096
1097
1098
		CellRef *cell_ref;

		cell_ref = &tree->u.constant->v.cell;
1099
		return cellref_name (cell_ref, sheet, col, row);
1100
1101
1102
1103
1104
1105
1106
	}
	}

	g_warning ("ExprTree: This should not happen\n");
	return g_strdup ("0");
}

1107
char *
1108
expr_decode_tree (ExprTree *tree, void *sheet, int col, int row)
1109
1110
{
	g_return_val_if_fail (tree != NULL, NULL);
1111
1112
1113
1114
	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
	
	return do_expr_decode_tree (tree, sheet, col, row, OPER_CONSTANT);
1115
}
1116