-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc.c
112 lines (105 loc) · 3.64 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
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "calc.h"
#include "y.tab.h"
int fn_id_i;
struct NodeStruct fn_body;
typedef struct fn {
bool is_set;
struct NodeStruct body;
} fn;
struct fn functions[256];
void deepCopyNodeStruct(struct NodeStruct* dest, struct NodeStruct* src) {
dest->type = src->type;
switch (src->type) {
case typeCon:
dest->con.value = src->con.value;
break;
case typeId:
dest->id.i = src->id.i;
break;
case typeStr:
dest->snode.str = malloc(sizeof(char) * (strlen(src->snode.str) + 1));
strcpy(dest->snode.str, src->snode.str);
break;
case typeOpr:
dest->opr.oper = src->opr.oper;
dest->opr.nops = src->opr.nops;
for (int i = 0; i < src->opr.nops; i++) {
dest->opr.op[i] = malloc(sizeof(struct NodeStruct));
deepCopyNodeStruct(dest->opr.op[i], src->opr.op[i]);
}
break;
}
}
int strsize(char *str) {
int i = 1;
while(str[i++] != '"') { }
return i;
}
int evaluate(Node* p) {
struct NodeStruct* fn_body = NULL;
if (!p)
return 0;
switch (p->type) {
case typeCon:
return p->con.value;
case typeId:
return sym[p->id.i];
case typeStr:
return 0;
case typeOpr:
switch (p->opr.oper) {
case FNCALL:
if (functions[p->opr.op[0]->id.i].is_set) {
return evaluate(&functions[p->opr.op[0]->id.i].body);
} else {
fprintf(stderr, "Error: function %c not found\n", p->opr.op[0]->id.i);
return 0;
}
case FNDEF:
deepCopyNodeStruct(&functions[p->opr.op[0]->id.i].body, p->opr.op[1]);
functions[p->opr.op[0]->id.i].is_set = true;
return 0;
case WHILE:
while (evaluate(p->opr.op[0]))
evaluate(p->opr.op[1]);
return 0;
case IF:
if (evaluate(p->opr.op[0]))
evaluate(p->opr.op[1]);
return 0;
case PRINT:
if (p->opr.op[0]->type == typeStr) {
printf("%s\n", p->opr.op[0]->snode.str);
return 0;
}
printf("%d\n", evaluate(p->opr.op[0]));
return 0;
case COMB:
evaluate(p->opr.op[0]);
return evaluate(p->opr.op[1]);
case SET:
return sym[p->opr.op[0]->id.i] = evaluate(p->opr.op[1]);
case ADD:
return evaluate(p->opr.op[0]) + evaluate(p->opr.op[1]);
case SUB:
return evaluate(p->opr.op[0]) - evaluate(p->opr.op[1]);
case MUL:
return evaluate(p->opr.op[0]) * evaluate(p->opr.op[1]);
case DIV:
return evaluate(p->opr.op[0]) / evaluate(p->opr.op[1]);
case LT:
return evaluate(p->opr.op[0]) < evaluate(p->opr.op[1]);
case GT:
return evaluate(p->opr.op[0]) > evaluate(p->opr.op[1]);
case EQ:
return evaluate(p->opr.op[0]) == evaluate(p->opr.op[1]);
case NEQ:
return evaluate(p->opr.op[0]) != evaluate(p->opr.op[1]);
}
}
return 0;
}