expr.c 19.8 KB
Newer Older
1
#include <config.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
2
#include <gnome.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
3
#include <math.h>
4
#include <string.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
5
#include "gnumeric.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
6
#include "expr.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
7
#include "eval.h"
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
8
#include "format.h"
9
#include "func.h"
10

Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
11
12
13
14
15
16
17
18
19
20
21
22
/* 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 */
23
ExprTree *parser_result;
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
24
25
26

/*        Location where the parsing is taking place */
int       parser_col, parser_row;
27

28
ExprTree *
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
29
expr_parse_string (char *expr, int col, int row, char **desired_format, char **error_msg)
30
31
{
	parser_expr = expr;
32
	parser_error = PARSE_OK;
33
34
	parser_col = col;
	parser_row = row;
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
35
36
	parser_desired_format = NULL;
	
37
	yyparse ();
38
39
40
	switch (parser_error){
	case PARSE_OK:
		*error_msg = NULL;
Miguel de Icaza's avatar
New:    
Miguel de Icaza committed
41
42
		if (desired_format)
			*desired_format = parser_desired_format;
43
		parser_result->ref_count = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
44
		return parser_result;
45

Arturo Espinosa's avatar
Arturo Espinosa committed
46
47
48
49
	case PARSE_ERR_SYNTAX:
		*error_msg = _("Syntax error");
		break;
			
50
51
52
53
	case PARSE_ERR_NO_QUOTE:
		*error_msg = _("Missing quote");
		break;
	}
54
55
56
	return NULL;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
57
58
static void
do_expr_tree_ref (ExprTree *tree)
59
{
60
	g_return_if_fail (tree != NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
61
62
63
	g_return_if_fail (tree->ref_count > 0);

	tree->ref_count++;
64
	switch (tree->oper){
65
	case OP_VAR:
66
	case OP_CONSTANT:
67
68
69
	case OP_FUNCALL:
		break;

70
71
72
73
74
75
	case OP_EQUAL:
	case OP_GT:
	case OP_LT:
	case OP_GTE:
	case OP_LTE:
	case OP_NOT_EQUAL:
76
77
78
79
80
81
	case OP_ADD:
	case OP_SUB:
	case OP_MULT:
	case OP_DIV:
	case OP_EXP:
	case OP_CONCAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
82
83
		do_expr_tree_ref (tree->u.binary.value_a);
		do_expr_tree_ref (tree->u.binary.value_b);
84
85
86
		break;

	case OP_NEG:
Arturo Espinosa's avatar
Arturo Espinosa committed
87
		do_expr_tree_ref (tree->u.value);
88
89
90
91
		break;
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
92
93
94
95
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
96
97
98
99
100
101
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
	do_expr_tree_ref (tree);
}

static void
do_expr_tree_unref (ExprTree *tree)
{
	tree->ref_count--;
	switch (tree->oper){
	case OP_VAR:
		break;
		
	case OP_CONSTANT:
		if (tree->ref_count == 0)
			value_release (tree->u.constant);
		break;
		
	case OP_FUNCALL:
		if (tree->ref_count == 0)
			symbol_unref (tree->u.function.symbol);
		break;

	case OP_EQUAL:
	case OP_GT:
	case OP_LT:
	case OP_GTE:
	case OP_LTE:
	case OP_NOT_EQUAL:
	case OP_ADD:
	case OP_SUB:
	case OP_MULT:
	case OP_DIV:
	case OP_EXP:
	case OP_CONCAT:
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

	case OP_NEG:
		do_expr_tree_unref (tree->u.value);
		break;
	}
	
	if (tree->ref_count == 0)
		g_free (tree);
146
147
148
149
150
151
152
153
}

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
154
	do_expr_tree_unref (tree);
155
156
}

Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
157
158
159
160
161
162
/*
 * simplistic value rendering
 */
char *
value_string (Value *value)
{
163
	char buffer [40];
Miguel de Icaza's avatar
Today:    
Miguel de Icaza committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
		
	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);
}

187
188
189
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
190
191
	g_return_if_fail (value != NULL);
	
192
193
194
195
196
197
198
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
199
200
		break;
		
201
202
203
204
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

Arturo Espinosa's avatar
Arturo Espinosa committed
205
206
207
208
209
210
211
212
213
214
215
	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;
		
216
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
217
	g_free (value);
218
}
219

Arturo Espinosa's avatar
Arturo Espinosa committed
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*
 * 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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
	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
261
262
263
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/*
 * 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;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
279
280
281
282
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
283
Value *
284
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
285
286
287
288
289
290
291
292
293
294
295
{
	Value *newv;
	
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

	if (v->type == VALUE_FLOAT)
		return v;
	
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
296
	value_release (v);
Arturo Espinosa's avatar
Arturo Espinosa committed
297
298
299
300
	
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
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
343
344
345
	if (v->type == VALUE_ARRAY)
		return 0.0;
	
Arturo Espinosa's avatar
Arturo Espinosa committed
346
	return (float_t) v->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
347
348
}

Arturo Espinosa's avatar
Arturo Espinosa committed
349
350
static Value *
eval_cell_value (Sheet *sheet, Value *value)
351
{
Arturo Espinosa's avatar
Arturo Espinosa committed
352
	Value *res;
353

Arturo Espinosa's avatar
Arturo Espinosa committed
354
355
356
357
358
359
	res = g_new (Value, 1);
	res->type = value->type;
	
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
360
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
361
362
363
		break;
		
	case VALUE_INTEGER:
364
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
365
366
367
		break;
		
	case VALUE_FLOAT:
368
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
369
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
370
371
372
373
374
375
376

	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
377
378
379
380
381
382
383
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
	}
	return res;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
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;
		}
427
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
428
429
430
431
432
433
434
435
436
437

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

438
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
482
483
484
485
486
487
488
489
490
491
492
493
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++){
				tree [i].oper = OP_CONSTANT;
				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);

	sym = symbol_lookup (name);
494
495
496
497
	if (sym == NULL){
		*error_string = "Function does not exist";
		return NULL;
	}
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
	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;
}

513
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
514
515
	IS_EQUAL,
	IS_LESS,
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
	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
541

542
543
544
545
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
Arturo Espinosa's avatar
Arturo Espinosa committed
546
547
compare (Value *a, Value *b)
{
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
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
596
597
598
	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
599
600
}

Arturo Espinosa's avatar
Arturo Espinosa committed
601
Value *
602
eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
603
604
605
{
	Value *a, *b, *res;
	Sheet *sheet = asheet;
Arturo Espinosa's avatar
Arturo Espinosa committed
606
607
608
609
610

	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
611
	
612
	switch (tree->oper){
Arturo Espinosa's avatar
Arturo Espinosa committed
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	case OP_EQUAL:
	case OP_NOT_EQUAL:
	case OP_GT:
	case OP_GTE:
	case OP_LT:
	case OP_LTE: {
		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);

637
638
639
640
641
642
643
		if (comp == TYPE_ERROR){
			value_release (a);
			value_release (b);
			*error_string = _("Type error");
			return NULL;
		}
		
Arturo Espinosa's avatar
Arturo Espinosa committed
644
645
646
647
648
649
		switch (tree->oper){
		case OP_EQUAL:
			res->v.v_int = comp == IS_EQUAL;
			break;

		case OP_GT:
650
			res->v.v_int = comp == IS_GREATER;
Arturo Espinosa's avatar
Arturo Espinosa committed
651
652
653
654
655
656
657
658
659
660
661
			break;

		case OP_LT:
			res->v.v_int = comp == IS_LESS;
			break;

		case OP_LTE:
			res->v.v_int = (comp == IS_EQUAL || comp == IS_LESS);
			break;

		case OP_GTE:
662
			res->v.v_int = (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
663
664
665
666
667
668
669
670
671
672
673
674
675
676
			break;

		case OP_NOT_EQUAL:
			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;
	}
	
Arturo Espinosa's avatar
Arturo Espinosa committed
677
678
679
680
681
	case OP_ADD:
	case OP_SUB:
	case OP_MULT:
	case OP_DIV:
	case OP_EXP:
682
683
684
685
		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
686
687
688

		if (!(a && b)){
			if (a)
689
				value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
690
			if (b)
691
				value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
692
693
694
695
			return NULL;
		}
		
		if (!VALUE_IS_NUMBER (a) || !VALUE_IS_NUMBER (b)){
696
697
			value_release (a);
			value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
698
699
700
701
702
703
704
705
			*error_string = _("Type mismatch");
			return NULL;
		}
		
		res = g_new (Value, 1);
		if (a->type == VALUE_INTEGER && b->type == VALUE_INTEGER){
			res->type = VALUE_INTEGER;
			
706
			switch (tree->oper){
Arturo Espinosa's avatar
Arturo Espinosa committed
707
			case OP_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
708
				res->v.v_int = a->v.v_int + b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
709
710
711
				break;
				
			case OP_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
712
				res->v.v_int = a->v.v_int - b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
713
714
715
				break;
				
			case OP_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
716
				res->v.v_int = a->v.v_int * b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
717
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
718

Arturo Espinosa's avatar
Arturo Espinosa committed
719
			case OP_DIV:
Arturo Espinosa's avatar
Arturo Espinosa committed
720
				if (b->v.v_int == 0){
721
722
723
					value_release (a);
					value_release (b);
					value_release (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
724
725
726
					*error_string = _("Division by zero");
					return NULL;
				}
727
728
				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
729
730
				break;
				
Arturo Espinosa's avatar
Arturo Espinosa committed
731
732
			case OP_EXP: 
				res->v.v_int = pow (a->v.v_int, b->v.v_int);
Arturo Espinosa's avatar
Arturo Espinosa committed
733
734
735
736
737
				break;
			default:
			}
		} else {
			res->type = VALUE_FLOAT;
Arturo Espinosa's avatar
Arturo Espinosa committed
738
			res->v.v_float = 0.0;
739
740
			a = value_cast_to_float (a);
			b = value_cast_to_float (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
741
			
742
			switch (tree->oper){
Arturo Espinosa's avatar
Arturo Espinosa committed
743
			case OP_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
744
				res->v.v_float = a->v.v_float + b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
745
746
747
				break;
				
			case OP_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
748
				res->v.v_float = a->v.v_float - b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
749
750
751
				break;
				
			case OP_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
752
				res->v.v_float = a->v.v_float * b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
753
754
755
				break;
				
			case OP_DIV:
Arturo Espinosa's avatar
Arturo Espinosa committed
756
				if (b->v.v_float == 0.0){
757
758
759
					value_release (a);
					value_release (b);
					value_release (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
760
761
762
					*error_string = _("Division by zero");
					return NULL;
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
763
764

				res->v.v_float = a->v.v_float / b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
765
766
767
				break;
				
			case OP_EXP:
Arturo Espinosa's avatar
Arturo Espinosa committed
768
				res->v.v_float = pow (a->v.v_float, b->v.v_float);
Arturo Espinosa's avatar
Arturo Espinosa committed
769
770
771
772
				break;
			default:
			}
		}
773
774
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
775
776
		return res;
		
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
	case OP_CONCAT: {
		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
806
807

	case OP_FUNCALL:
Arturo Espinosa's avatar
Arturo Espinosa committed
808
		return eval_funcall (sheet, tree, eval_col, eval_row, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
809
810

	case OP_CONSTANT:
811
		return eval_cell_value (sheet, tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
812
813

	case OP_VAR:{
814
		CellRef *ref;
Arturo Espinosa's avatar
Arturo Espinosa committed
815
816
817
818
819
820
821
822
823
824
825
826
827
		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;
		}

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

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

Arturo Espinosa's avatar
Arturo Espinosa committed
833
		if (cell){
834
			if (cell->generation != sheet->workbook->generation){
835
				cell->generation = sheet->workbook->generation;
836
837
838
839
840

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

841
842
			if (cell->value)
				return eval_cell_value (sheet, cell->value);
Arturo Espinosa's avatar
Arturo Espinosa committed
843
		}
844
845
846
847
		res = g_new (Value, 1);
			
		res->type = VALUE_INTEGER;
		res->v.v_int = 0;
Arturo Espinosa's avatar
Arturo Espinosa committed
848
849
850
		return res;
	}
	case OP_NEG:
851
852
		a = eval_expr (sheet, tree->u.value,
			       eval_col, eval_row, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
853
854
855
856
		if (!a)
			return NULL;
		if (!VALUE_IS_NUMBER (a)){
			*error_string = _("Type mismatch");
857
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
858
859
860
			return NULL;
		}
		res = g_new (Value, 1);
861
		res->type = a->type;
Arturo Espinosa's avatar
Arturo Espinosa committed
862
		if (a->type == VALUE_INTEGER){
Arturo Espinosa's avatar
Arturo Espinosa committed
863
			res->v.v_int = -a->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
864
		} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
865
			res->v.v_float = -a->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
866
		}
867
		value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
868
		return res;
869
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
870
871
872
	
	*error_string = _("Unknown evaluation error");
	return NULL;
873
}
Arturo Espinosa's avatar
Arturo Espinosa committed
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890

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;
}

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
static int
evaluate_level (Operation x)
{
	if (x == OP_EXP)
		return 3;
	if ((x==OP_MULT) || (x==OP_DIV))
		return 2;
	if ((x==OP_ADD)  || (x==OP_SUB)   || (x==OP_CONCAT))
		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;
}

914
915
916
917
918
919
920
921
922
/*
 * 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.
 */
923
924
static char *
do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
{
	static const char *binary_operation_names [] = {
		"=", ">", "<", ">=", "<=", "<>",
		"+", "-", "*", "/",  "^",  "&"
	};

	switch (tree->oper){

		/* The binary operations */
	case OP_EQUAL:
	case OP_NOT_EQUAL:
	case OP_GT:
	case OP_GTE:
	case OP_LT:
	case OP_LTE:
	case OP_ADD:
	case OP_SUB:
	case OP_MULT:
	case OP_DIV:
	case OP_EXP:
	case OP_CONCAT: {	
		char *a, *b, *res;
		char const *op;
		
949
950
		a = do_expr_decode_tree (tree->u.binary.value_a, col, row, tree->oper);
		b = do_expr_decode_tree (tree->u.binary.value_b, col, row, tree->oper);
951
		op = binary_operation_names [tree->oper];
952
953
954
955
956
957

		if (bigger_prec (parent_op, tree->oper))
			res = g_copy_strings ("(", a, op, b, ")", NULL);
		else
			res = g_copy_strings (a, op, b, NULL);
		
958
959
960
961
962
963
964
965
		g_free (a);
		g_free (b);
		return res;
	}
	
	case OP_NEG: {
		char *res, *a;

966
		a = do_expr_decode_tree (tree->u.value, col, row, tree->oper);
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
		res = g_copy_strings ("-", a);
		g_free (a);
		return res;
	}
	
	case OP_FUNCALL: {
		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;
988
			for (l = arg_list; l; l = l->next, i++){
989
990
				ExprTree *t = l->data;
				
991
				args [i] = do_expr_decode_tree (t, col, row, OP_CONSTANT);
992
993
994
				len += strlen (args [i]) + 1;
			}
			len++;
995
			sum = g_malloc (len + 2);
996
997
998
			
			i = 0;
			sum [0] = 0;
999
			for (l = arg_list; l; l = l->next, i++){
1000
				strcat (sum, args [i]);