204 {SET_OVFLOW(dtype, symbol);} \ |
204 {SET_OVFLOW(dtype, symbol);} \ |
205 else if (IS_NONCONST (dtype, operand)) \ |
205 else if (IS_NONCONST (dtype, operand)) \ |
206 {SET_NONCONST(dtype, symbol);} \ |
206 {SET_NONCONST(dtype, symbol);} \ |
207 } |
207 } |
208 |
208 |
209 |
209 /* Meet rules |
210 |
210 * - any * T = any |
|
211 * - any * B = B |
|
212 * - constant * constant = constant (if equal) |
|
213 * - constant * constant = B (if not equal) |
|
214 */ |
|
215 #define COMPUTE_MEET_SEMILATTICE(dtype, c1, c2, resValue) {\ |
|
216 if ((c1._##dtype.value != c2._##dtype.value && c2._##dtype.status == symbol_c::cs_const_value && c1._##dtype.status == symbol_c::cs_const_value) ||\ |
|
217 ( c1._##dtype.status == symbol_c::cs_non_const && c2._##dtype.status == symbol_c::cs_const_value ) ||\ |
|
218 ( c2._##dtype.status == symbol_c::cs_non_const && c1._##dtype.status == symbol_c::cs_const_value )) {\ |
|
219 resValue._##dtype.status = symbol_c::cs_non_const;\ |
|
220 } else {\ |
|
221 resValue._##dtype.status = symbol_c::cs_const_value;\ |
|
222 resValue._##dtype.value = c1._##dtype.value;\ |
|
223 }\ |
|
224 } |
|
225 |
|
226 |
|
227 static std::map <std::string, symbol_c::const_value_t> values; |
211 |
228 |
212 |
229 |
213 /***********************************************************************/ |
230 /***********************************************************************/ |
214 /***********************************************************************/ |
231 /***********************************************************************/ |
215 /***********************************************************************/ |
232 /***********************************************************************/ |
914 SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow)); |
931 SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow)); |
915 if (overflow) SET_OVFLOW(real64, symbol); |
932 if (overflow) SET_OVFLOW(real64, symbol); |
916 return NULL; |
933 return NULL; |
917 } |
934 } |
918 |
935 |
|
936 /*********************/ |
|
937 /* B 1.4 - Variables */ |
|
938 /*********************/ |
|
939 void *constant_folding_c::visit(symbolic_variable_c *symbol) { |
|
940 std::string varName; |
|
941 |
|
942 varName = convert.toString(symbol->var_name); |
|
943 if (values.count(varName) > 0) { |
|
944 symbol->const_value = values[varName]; |
|
945 } |
|
946 return NULL; |
|
947 } |
|
948 |
|
949 /**********************/ |
|
950 /* B 1.5.3 - Programs */ |
|
951 /**********************/ |
|
952 void *constant_folding_c::visit(program_declaration_c *symbol) { |
|
953 symbol_c *var_name; |
|
954 |
|
955 values.clear(); /* Clear global map */ |
|
956 search_var_instance_decl_c search_var_instance_decl(symbol); |
|
957 function_param_iterator_c fpi(symbol); |
|
958 while((var_name = fpi.next()) != NULL) { |
|
959 std::string varName = convert.toString(var_name); |
|
960 symbol_c *varDecl = search_var_instance_decl.get_decl(var_name); |
|
961 values[varName] = varDecl->const_value; |
|
962 } |
|
963 /* Add all variables declared into Values map and put them to initial value */ |
|
964 symbol->function_block_body->accept(*this); |
|
965 return NULL; |
|
966 } |
919 |
967 |
920 |
968 |
921 /****************************************/ |
969 /****************************************/ |
922 /* B.2 - Language IL (Instruction List) */ |
970 /* B.2 - Language IL (Instruction List) */ |
923 /****************************************/ |
971 /****************************************/ |
1183 void *constant_folding_c::visit( neg_expression_c *symbol) {symbol-> exp->accept(*this); return handle_neg(symbol, symbol->exp);} |
1231 void *constant_folding_c::visit( neg_expression_c *symbol) {symbol-> exp->accept(*this); return handle_neg(symbol, symbol->exp);} |
1184 void *constant_folding_c::visit( not_expression_c *symbol) {symbol-> exp->accept(*this); return handle_not(symbol, symbol->exp);} |
1232 void *constant_folding_c::visit( not_expression_c *symbol) {symbol-> exp->accept(*this); return handle_not(symbol, symbol->exp);} |
1185 |
1233 |
1186 /* TODO: handle function invocations... */ |
1234 /* TODO: handle function invocations... */ |
1187 // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {} |
1235 // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {} |
|
1236 |
|
1237 |
|
1238 |
|
1239 |
|
1240 /*********************************/ |
|
1241 /* B 3.2.1 Assignment Statements */ |
|
1242 /*********************************/ |
|
1243 void *constant_folding_c::visit(assignment_statement_c *symbol) { |
|
1244 std::string varName; |
|
1245 |
|
1246 symbol->r_exp->accept(*this); |
|
1247 symbol->l_exp->const_value = symbol->r_exp->const_value; |
|
1248 varName = convert.toString(symbol->l_exp); |
|
1249 values[varName] = symbol->l_exp->const_value; |
|
1250 return NULL; |
|
1251 } |
|
1252 |
|
1253 /********************************/ |
|
1254 /* B 3.2.3 Selection Statements */ |
|
1255 /********************************/ |
|
1256 void *constant_folding_c::visit(if_statement_c *symbol) { |
|
1257 std::map <std::string, symbol_c::const_value_t> values_incoming; |
|
1258 std::map <std::string, symbol_c::const_value_t> values_statement_result; |
|
1259 std::map <std::string, symbol_c::const_value_t> values_elsestatement_result; |
|
1260 std::map <std::string, symbol_c::const_value_t>::iterator itr; |
|
1261 values_incoming = values; /* save incoming status */ |
|
1262 |
|
1263 symbol->statement_list->accept(*this); |
|
1264 values_statement_result = values; |
|
1265 if (NULL != symbol->else_statement_list) { |
|
1266 values = values_incoming; |
|
1267 symbol->else_statement_list->accept(*this); |
|
1268 values_elsestatement_result = values; |
|
1269 } else |
|
1270 values_elsestatement_result = values_incoming; |
|
1271 values.clear(); |
|
1272 itr = values_statement_result.begin(); |
|
1273 for ( ; itr != values_statement_result.end(); ++itr) { |
|
1274 std::string name = itr->first; |
|
1275 symbol_c::const_value_t value; |
|
1276 |
|
1277 if (values_elsestatement_result.count(name) > 0) { |
|
1278 symbol_c::const_value_t c1 = itr->second; |
|
1279 symbol_c::const_value_t c2 = values_elsestatement_result[name]; |
|
1280 COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value); |
|
1281 COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value); |
|
1282 COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value); |
|
1283 COMPUTE_MEET_SEMILATTICE ( bool, c1, c2, value); |
|
1284 } else |
|
1285 value = values_statement_result[name]; |
|
1286 values[name] = value; |
|
1287 } |
|
1288 return NULL; |
|
1289 } |
|
1290 |
|
1291 |
|
1292 |