-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc.c
129 lines (110 loc) · 4.45 KB
/
calc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <math.h>
#include "rpsc.h"
#include "Parser.h"
#include "Lexer.h"
SExpression * getAST(const char * expr, struct roman * p) {
SExpression *expression = 0;
yyscan_t scanner;
YY_BUFFER_STATE state;
if (yylex_init(&scanner)) {
// couldn't initialize
return NULL;
}
// printf("PARSING: [%s]\n",expr);
state = yy_scan_string(expr, scanner);
if (yyparse(&expression, scanner,p)) {
// error parsing
printf(" %s \n", expr);
return NULL;
}
yy_delete_buffer(state, scanner);
yylex_destroy(scanner);
return expression;
}
double eval(struct roman *pp, SExpression *s, struct Ent *p) {
double (*func)(struct roman *,int, char **);
double (*funct)(double);
switch (s->type) {
case eVALUE: return s->value;
case ePLUS: return eval(pp,s->left,p)+eval(pp,s->right,p); break;
case eMINUS: return eval(pp,s->left,p)-eval(pp,s->right,p); break;
case eMULTIPLY: return eval(pp,s->left,p)*eval(pp,s->right,p); break;
case eDIVIDE: return eval(pp,s->left,p)/eval(pp,s->right,p); break;
case '>': return (eval(pp,s->left,p)>eval(pp,s->right,p)); break;
case '<': return (eval(pp,s->left,p)<eval(pp,s->right,p)); break;
case '=': return eval(pp,s->left,p)==eval(pp,s->right,p); break;
case '^': return pow(eval(pp,s->left,p),eval(pp,s->right,p)); break;
case eIF: return eval(pp,s->left,p)?eval(pp,s->if_t->next,p):eval(pp,s->if_t->next->next,p); break;
case 's':
{
char * str = (char *) s->right;
struct Ent * rp = s->left->ptr;
if (rp->label == 0) return 0;
return strcmp(rp->label, str) ? 0 : 1;
}
break;
case 'f':
func = s->ptr;
return func(pp, s->next->ptr, s->next->next->ptr);
break;
case'm':
funct = s->ptr;
return funct(eval(pp, s->next, p));
break;
case eENT:
{
struct Ent * ppd = (struct Ent *) s->ptr;
if (ppd == p ) {
//printf("Recurssion detected\n");
return p->val;
}
/*
if ((pp)->exp != 0 )
return eval((pp)->exp,pp);
else */
return ppd->val;
}
break;
}
}
void recalc(struct roman * p) {
register struct Ent ** pp;
int x, y;
int a=0;
if (p->cache_nr !=0) {
for(a=0; a < p->cache_nr; a++) {
p->cache[a]->val = eval(p, (p->cache[a])->exp, p->cache[a]);
}
}
else{
for(p->cur_sh = p->first_sh; p->cur_sh != 0; p->cur_sh = p->cur_sh->next) {
for(x=0; x <= p->cur_sh->col; x++)
for(y=0; y <= p->cur_sh->row; y++) {
pp = ATBL(p->cur_sh,p->cur_sh->tbl, y, x);
if((pp != 0) && (*pp != 0)) {
//printf("%s1 %s %d %d %x val : %f\n",__FUNCTION__,p->cur_sh->name,x,y,(*pp)->flag, (*pp)->val);
if (((*pp)->flag & RP_FORMULA) == RP_FORMULA) {
int sz=0;
char *ptr=(*pp)->formula;
if ((*pp)->exp !=0 ) {
struct Ent *pt;
(*pp)->val=eval(p,(*pp)->exp, *pp);
// printf("%s2 %s %d %d val : %f\n",__FUNCTION__,p->cur_sh->name,x,y,(*pp)->val);
pt=(*pp);
sz=sizeof(struct Ent *);
//printf("%s %d %p\n",__FUNCTION__,sz*a,p->cache);
if((sz*a) < 4096) sz=4096;
p->cache=realloc((void *)p->cache,sz);
//printf("%s1 %d %p\n",__FUNCTION__,sz*a,p->cache);
p->cache[a]=pt;
a++;
}
}
}
}
//printf("%s %d\n",__FUNCTION__,a);
}
p->cache_nr=a;
}
p->cur_sh=p->first_sh;
}