-
Notifications
You must be signed in to change notification settings - Fork 0
/
ast-evaluate.cc
217 lines (185 loc) · 6.02 KB
/
ast-evaluate.cc
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*********************************************************************************************
cfglp : A CFG Language Processor
--------------------------------
About:
Implemented by Uday Khedker (http://www.cse.iitb.ac.in/~uday) for
the courses cs302+cs306: Language Processors (theory and lab) at
IIT Bombay. Release date Jan 6, 2013. Copyrights reserved by Uday
Khedker. This implemenation has been made available purely for
academic purposes without any warranty of any kind.
Please see the README file for some details. A doxygen generated
documentation can be found at http://www.cse.iitb.ac.in/~uday/cfglp
***********************************************************************************************/
#include <iostream>
#include <ostream>
#include <sstream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
#include "common-classes.hh"
#include "evaluate.hh"
#include "reg-alloc.hh"
#include "symtab.hh"
#include "ast.hh"
#include "program.hh"
#include "support.hh"
#include "options.hh"
eval_Result asgn_Ast::evaluate()
{
CHECK_INVARIANT (right != NULL, "Right child of an assignment tree node cannot be NULL")
eval_Result res = right->evaluate();
CHECK_INVARIANT (left != NULL, "Left child of an assignment tree node cannot be NULL")
CHECK_INVARIANT (left->get_Tree_Op() == name_Leaf, "LHS of an assignment should be a name")
left->set_Value_of_Evaluation(res);
/*
Here we really do not need to return the result but since
the type of the evaluate function has to remain identical
across all derived classes, we return a dummy object which
has been declared globally.
*/
print_Eval_Result(this);
return dummy_result;
}
eval_Result name_Ast::evaluate()
{
CHECK_INVARIANT (sym_entry != NULL, "Left child of an assignment tree node cannot be NULL")
return this->get_Value_of_Evaluation();
}
eval_Result int_num_Ast::evaluate()
{
eval_Result res(num, NULL, int_Res);
return res;
}
eval_Result num_Ast::evaluate()
{
CHECK_INVARIANT (false, "evaluate cannot be called for num_Ast")
}
eval_Result ret_Ast::evaluate()
{
/*
In this version, we have void procedures only
hence we return the dummy value which is void.
*/
return dummy_result;
}
eval_Result name_Ast::get_Value_of_Evaluation()
{
CHECK_INVARIANT(sym_entry, "Sym entry of symbol cannot be NULL")
return sym_entry->get_Value_of_Evaluation();
}
void name_Ast::set_Value_of_Evaluation(eval_Result res)
{
CHECK_INVARIANT(sym_entry, "Sym entry of symbol cannot be NULL")
sym_entry->set_Value_of_Evaluation(res);
}
eval_Result ast_Node::get_Value_of_Evaluation()
{
CHECK_INVARIANT(SHOULD_NOT_REACH, "get_Value_of_Evaluation cannot be called on a non-name-Ast")
}
void ast_Node::set_Value_of_Evaluation(eval_Result res)
{
CHECK_INVARIANT(SHOULD_NOT_REACH, "set_Value_of_Evaluation cannot be called on a non-name-Ast")
}
eval_Result arith_Ast::evaluate()
{
CHECK_INVARIANT(false, "should not be called for arith_Ast class")
}
eval_Result exp_var_Ast::evaluate()
{
CHECK_INVARIANT(SHOULD_NOT_REACH, "evaluate for exp var called")
return dummy_result;
}
eval_Result float_num_Ast::evaluate()
{
eval_Result res(num, NULL, float_Res);
return res;
}
eval_Result mult_Ast::evaluate()
{
eval_Result l_eval = left->evaluate();
eval_Result r_eval = right->evaluate();
CHECK_INVARIANT(l_eval.which_Result() == r_eval.which_Result(), "Type mismatch in * expression")
res_Type r = l_eval.which_Result();
float d_num;
int i_num;
if(r == float_Res) {
d_num = l_eval.get_Float_Val() * r_eval.get_Float_Val();
eval_Result res(d_num, NULL, float_Res);
return res;
} else {
i_num = l_eval.get_Int_Val() * r_eval.get_Int_Val();
eval_Result res(i_num, NULL, int_Res);
return res;
}
}
eval_Result plus_Ast::evaluate()
{
eval_Result l_eval = left->evaluate();
eval_Result r_eval = right->evaluate();
CHECK_INVARIANT(l_eval.which_Result() == r_eval.which_Result(), "Type mismatch in * expression")
res_Type r= l_eval.which_Result();
float d_num;
int i_num;
if(r == float_Res) {
d_num = l_eval.get_Float_Val() + r_eval.get_Float_Val();
eval_Result res(d_num, NULL, float_Res);
return res;
} else {
i_num = l_eval.get_Int_Val() + r_eval.get_Int_Val();
eval_Result res(i_num, NULL, int_Res);
return res;
}
}
eval_Result minus_Ast::evaluate()
{
eval_Result l_eval = left->evaluate();
eval_Result r_eval = right->evaluate();
CHECK_INVARIANT(l_eval.which_Result() == r_eval.which_Result(), "Type mismatch in * expression")
res_Type r = l_eval.which_Result();
float d_num;
int i_num;
if(r == float_Res) {
d_num = l_eval.get_Float_Val() - r_eval.get_Float_Val();
eval_Result res(d_num, NULL, float_Res);
return res;
} else {
i_num = l_eval.get_Int_Val() - r_eval.get_Int_Val();
eval_Result res(i_num, NULL, int_Res);
return res;
}
}
eval_Result div_Ast::evaluate()
{
eval_Result l_eval = left->evaluate();
eval_Result r_eval = right->evaluate();
CHECK_INVARIANT(l_eval.which_Result() == r_eval.which_Result(), "Type mismatch in * expression")
res_Type r= l_eval.which_Result();
float d_num;
int i_num;
if(r == float_Res) {
d_num = l_eval.get_Float_Val() / r_eval.get_Float_Val();
eval_Result res(d_num, NULL, float_Res);
return res;
} else {
i_num = l_eval.get_Int_Val() / r_eval.get_Int_Val();
eval_Result res(i_num, NULL, int_Res);
return res;
}
}
eval_Result uminus_Ast::evaluate()
{
eval_Result l_eval = left->evaluate();
res_Type r = l_eval.which_Result();
float d_num;
int i_num;
if(r == float_Res) {
d_num = -1.0 * l_eval.get_Float_Val();
eval_Result res(d_num, NULL, float_Res);
return res;
} else {
i_num = -1 * l_eval.get_Int_Val();
eval_Result res(i_num, NULL, int_Res);
return res;
}
}