stage3/constant_folding.cc
changeset 967 544ff4dff04f
parent 965 c9eeb67ba939
child 968 649e03abbfc1
equal deleted inserted replaced
966:cd7fa00ad774 967:544ff4dff04f
   804 #endif
   804 #endif
   805 
   805 
   806 
   806 
   807 
   807 
   808 constant_folding_c::constant_folding_c(symbol_c *symbol) {
   808 constant_folding_c::constant_folding_c(symbol_c *symbol) {
       
   809     fixed_init_value_ = false;
       
   810     function_pou_ = false;
   809     error_count = 0;
   811     error_count = 0;
   810     warning_found = false;
   812     warning_found = false;
   811     current_display_error_level = 0;
   813     current_display_error_level = 0;
   812     il_operand = NULL;
   814     il_operand = NULL;
   813     search_varfb_instance_type = NULL;
   815     search_varfb_instance_type = NULL;
   987 }
   989 }
   988 
   990 
   989 /*********************/
   991 /*********************/
   990 /* B 1.4 - Variables */
   992 /* B 1.4 - Variables */
   991 /*********************/
   993 /*********************/
   992 #if DO_CONSTANT_PROPAGATION__
   994 // #if DO_CONSTANT_PROPAGATION__
   993 void *constant_folding_c::visit(symbolic_variable_c *symbol) {
   995 void *constant_folding_c::visit(symbolic_variable_c *symbol) {
   994 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
   996 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
   995 	if (values.count(varName) > 0) 
   997 	if (values.count(varName) > 0) 
   996 		symbol->const_value = values[varName];
   998 		symbol->const_value = values[varName];
   997 	return NULL;
   999 	return NULL;
   998 }
  1000 }
   999 #endif  // DO_CONSTANT_PROPAGATION__
  1001 // #endif  // DO_CONSTANT_PROPAGATION__
  1000 
  1002 
  1001 void *constant_folding_c::visit(symbolic_constant_c *symbol) {
  1003 void *constant_folding_c::visit(symbolic_constant_c *symbol) {
  1002 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
  1004 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
  1003 	if (values.count(varName) > 0) 
  1005 	if (values.count(varName) > 0) 
  1004 		symbol->const_value = values[varName];
  1006 		symbol->const_value = values[varName];
  1033   if (NULL != global_var_decl) global_var_decl->const_value = init_value->const_value;  // Note that each external variable declaration has its own datatype specification, so we can set this symbol's const_value too!
  1035   if (NULL != global_var_decl) global_var_decl->const_value = init_value->const_value;  // Note that each external variable declaration has its own datatype specification, so we can set this symbol's const_value too!
  1034   return 0;
  1036   return 0;
  1035 }
  1037 }
  1036 
  1038 
  1037 
  1039 
       
  1040   
       
  1041 void *constant_folding_c::handle_var_decl(symbol_c *var_list, bool fixed_init_value) {
       
  1042   fixed_init_value_ = fixed_init_value;
       
  1043   var_list->accept(*this); 
       
  1044   fixed_init_value_ = false; 
       
  1045   return NULL;
       
  1046 }
       
  1047 
  1038 void *constant_folding_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl) {
  1048 void *constant_folding_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl) {
  1039   type_decl->accept(*this);  // Do constant folding of the initial value, and literals in subranges! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
  1049   type_decl->accept(*this);  // Do constant folding of the initial value, and literals in subranges! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
  1040   symbol_c *init_value = type_initial_value_c::get(type_decl);  
  1050   symbol_c *init_value = type_initial_value_c::get(type_decl);  
  1041   if (NULL == init_value)   return NULL; // this is probably a FB datatype, for which no initial value exists! Do nothing and return.
  1051   if (NULL == init_value)   return NULL; // this is probably a FB datatype, for which no initial value exists! Do nothing and return.
  1042 
  1052 
  1045   for (int i = 0; i < list->n; i++) {
  1055   for (int i = 0; i < list->n; i++) {
  1046     token_c *var_name = dynamic_cast<token_c *>(list->elements[i]);
  1056     token_c *var_name = dynamic_cast<token_c *>(list->elements[i]);
  1047     if (NULL == var_name) {
  1057     if (NULL == var_name) {
  1048       if (NULL != dynamic_cast<extensible_input_parameter_c *>(list->elements[i]))
  1058       if (NULL != dynamic_cast<extensible_input_parameter_c *>(list->elements[i]))
  1049         continue; // this is an extensible standard function. Ignore this variable, and continue!
  1059         continue; // this is an extensible standard function. Ignore this variable, and continue!
  1050       debug_c::print(list->elements[i]);
  1060       // debug_c::print(list->elements[i]);
  1051       ERROR;
  1061       ERROR;
  1052     }
  1062     }
  1053     std::string varName = var_name->value;
       
  1054     values[varName] = init_value->const_value;
       
  1055     list->elements[i]->const_value = init_value->const_value;
  1063     list->elements[i]->const_value = init_value->const_value;
       
  1064     if (fixed_init_value_) {
       
  1065       std::string varName = var_name->value;
       
  1066       values[varName] = init_value->const_value;
       
  1067     }
  1056   }
  1068   }
  1057   return NULL;
  1069   return NULL;
  1058 }
  1070 }
  1059 
  1071 
  1060 /* | var1_list ',' variable_name */
       
  1061 //SYM_LIST(var1_list_c)           // Not needed!
       
  1062 //SYM_REF0(constant_option_c)     // Not needed!
  1072 //SYM_REF0(constant_option_c)     // Not needed!
  1063 //SYM_REF0(retain_option_c)       // Not needed!
  1073 //SYM_REF0(retain_option_c)       // Not needed!
  1064 //SYM_REF0(non_retain_option_c)   // Not needed!
  1074 //SYM_REF0(non_retain_option_c)   // Not needed!
  1065 
  1075 bool constant_folding_c::is_constant(symbol_c *option) {return (NULL != dynamic_cast<constant_option_c *>(option));}
       
  1076 bool constant_folding_c::is_retain  (symbol_c *option) {return (NULL != dynamic_cast<  retain_option_c *>(option));}
       
  1077 
       
  1078 /* | var1_list ',' variable_name */
       
  1079 //SYM_LIST(var1_list_c)           // Not needed!
  1066 
  1080 
  1067 /* spec_init is one of the following...
  1081 /* spec_init is one of the following...
  1068  *    simple_spec_init_c *
  1082  *    simple_spec_init_c *
  1069  *    subrange_spec_init_c *
  1083  *    subrange_spec_init_c *
  1070  *    enumerated_spec_init_c *
  1084  *    enumerated_spec_init_c *
  1073 void *constant_folding_c::visit(var1_init_decl_c *symbol) {return handle_var_list_decl(symbol->var1_list, symbol->spec_init);}
  1087 void *constant_folding_c::visit(var1_init_decl_c *symbol) {return handle_var_list_decl(symbol->var1_list, symbol->spec_init);}
  1074 
  1088 
  1075 /* | [var1_list ','] variable_name integer '..' */
  1089 /* | [var1_list ','] variable_name integer '..' */
  1076 /* NOTE: This is an extension to the standard!!! */
  1090 /* NOTE: This is an extension to the standard!!! */
  1077 //SYM_REF2(extensible_input_parameter_c, var_name, first_index)          // Not needed!
  1091 //SYM_REF2(extensible_input_parameter_c, var_name, first_index)          // Not needed!
       
  1092 
  1078 /* var1_list ':' array_spec_init */
  1093 /* var1_list ':' array_spec_init */
  1079 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)            // We do not yet handle arrays!
  1094 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)            // We do not yet handle arrays!
       
  1095 
  1080 /*  var1_list ':' initialized_structure */
  1096 /*  var1_list ':' initialized_structure */
  1081 //SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) // We do not yet handle structures!
  1097 //SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) // We do not yet handle structures!
       
  1098 
  1082 /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
  1099 /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
  1083 //SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init)                   // We do not yet handle FBs!
  1100 //SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init)                   // We do not yet handle FBs!
       
  1101 
  1084 /* fb_name_list ',' fb_name */
  1102 /* fb_name_list ',' fb_name */
  1085 //SYM_LIST(fb_name_list_c)                                               // Not needed!
  1103 //SYM_LIST(fb_name_list_c)                                               // Not needed!
       
  1104 
  1086 /* VAR_INPUT [option] input_declaration_list END_VAR */
  1105 /* VAR_INPUT [option] input_declaration_list END_VAR */
  1087 /* option -> the RETAIN/NON_RETAIN/<NULL> directive... */
  1106 /* option -> the RETAIN/NON_RETAIN/<NULL> directive... */
  1088 //SYM_REF3(input_declarations_c, option, input_declaration_list, method) // Not needed since we inherit from iterator_visitor_c!
  1107 //SYM_REF3(input_declarations_c, option, input_declaration_list, method) // Not needed since we inherit from iterator_visitor_c!
  1089 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we do NOT call handle_var_list_decl() !!!
  1108 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1090 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1109 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
       
  1110 void *constant_folding_c::visit(input_declarations_c *symbol) {return handle_var_decl(symbol->input_declaration_list, false);}
       
  1111 
  1091 /* helper symbol for input_declarations */
  1112 /* helper symbol for input_declarations */
  1092 //SYM_LIST(input_declaration_list_c)                                     // Not needed!
  1113 //SYM_LIST(input_declaration_list_c)                                     // Not needed!
       
  1114 
  1093 /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
  1115 /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
  1094 /* option -> may be NULL ! */
  1116 /* option -> may be NULL ! */
  1095 //SYM_REF3(output_declarations_c, option, var_init_decl_list, method)    // Not needed since we inherit from iterator_visitor_c!
  1117 //SYM_REF3(output_declarations_c, option, var_init_decl_list, method) 
       
  1118 void *constant_folding_c::visit(output_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, !is_retain(symbol->option) && function_pou_);}
  1096 
  1119 
  1097 /*  VAR_IN_OUT var_declaration_list END_VAR */
  1120 /*  VAR_IN_OUT var_declaration_list END_VAR */
  1098 //SYM_REF1(input_output_declarations_c, var_declaration_list)            // Not needed since we inherit from iterator_visitor_c!
  1121 //SYM_REF1(input_output_declarations_c, var_declaration_list)
  1099 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we do NOT call handle_var_list_decl() !!!
  1122 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1100 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1123 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
       
  1124 void *constant_folding_c::visit(input_output_declarations_c *symbol) {return handle_var_decl(symbol->var_declaration_list, false);}
       
  1125 
  1101 /* helper symbol for input_output_declarations */
  1126 /* helper symbol for input_output_declarations */
  1102 /* var_declaration_list var_declaration ';' */
  1127 /* var_declaration_list var_declaration ';' */
  1103 //SYM_LIST(var_declaration_list_c)                                       // Not needed since we inherit from iterator_visitor_c!
  1128 //SYM_LIST(var_declaration_list_c)                                       // Not needed since we inherit from iterator_visitor_c!
       
  1129 
  1104 /*  var1_list ':' array_specification */
  1130 /*  var1_list ':' array_specification */
  1105 //SYM_REF2(array_var_declaration_c, var1_list, array_specification)      // We do not yet handle arrays! 
  1131 //SYM_REF2(array_var_declaration_c, var1_list, array_specification)      // We do not yet handle arrays! 
       
  1132 
  1106 /*  var1_list ':' structure_type_name */
  1133 /*  var1_list ':' structure_type_name */
  1107 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) // We do not yet handle structures!
  1134 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) // We do not yet handle structures!
       
  1135 
  1108 /* VAR [CONSTANT] var_init_decl_list END_VAR */
  1136 /* VAR [CONSTANT] var_init_decl_list END_VAR */
  1109 /* option -> may be NULL ! */
  1137 /* option -> may be NULL ! */
  1110 //SYM_REF2(var_declarations_c, option, var_init_decl_list)               // Not needed: we inherit from iterator_c
  1138 //SYM_REF2(var_declarations_c, option, var_init_decl_list)
       
  1139 void *constant_folding_c::visit(var_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, false);}
  1111 
  1140 
  1112 /*  VAR RETAIN var_init_decl_list END_VAR */
  1141 /*  VAR RETAIN var_init_decl_list END_VAR */
  1113 //SYM_REF1(retentive_var_declarations_c, var_init_decl_list)             // Not needed since we inherit from iterator_visitor_c!
  1142 //SYM_REF1(retentive_var_declarations_c, var_init_decl_list)             // Not needed since we inherit from iterator_visitor_c!
  1114 // NOTE: Retentive variables can take any initial value, so we can not set the const_value annotation => we do NOT call handle_var_list_decl() !!!
  1143 // NOTE: Retentive variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1115 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1144 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
       
  1145 void *constant_folding_c::visit(retentive_var_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, false);}
       
  1146 
       
  1147 #if 0  
       
  1148 // TODO
  1116 /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
  1149 /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
  1117 /* option -> may be NULL ! */
  1150 /* option -> may be NULL ! */
  1118 
       
  1119 #if 0  
       
  1120 // TODO
       
  1121 SYM_REF2(located_var_declarations_c, option, located_var_decl_list)
  1151 SYM_REF2(located_var_declarations_c, option, located_var_decl_list)
  1122 /* helper symbol for located_var_declarations */
  1152 /* helper symbol for located_var_declarations */
  1123 /* located_var_decl_list located_var_decl ';' */
  1153 /* located_var_decl_list located_var_decl ';' */
  1124 SYM_LIST(located_var_decl_list_c)
  1154 SYM_LIST(located_var_decl_list_c)
  1125 /*  [variable_name] location ':' located_var_spec_init */
  1155 /*  [variable_name] location ':' located_var_spec_init */
  1128 #endif
  1158 #endif
  1129 
  1159 
  1130 /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
  1160 /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
  1131 /* option -> may be NULL ! */
  1161 /* option -> may be NULL ! */
  1132 // SYM_REF2(external_var_declarations_c, option, external_declaration_list)
  1162 // SYM_REF2(external_var_declarations_c, option, external_declaration_list)
  1133 // void *constant_folding_c::visit(external_var_declarations_c *symbol) {} // Not needed: we inherit from iterator_c
  1163 void *constant_folding_c::visit(external_var_declarations_c *symbol) {return handle_var_decl(symbol->external_declaration_list, is_constant(symbol->option));}
  1134 
  1164 
  1135 /* helper symbol for external_var_declarations */
  1165 /* helper symbol for external_var_declarations */
  1136 /*| external_declaration_list external_declaration';' */
  1166 /*| external_declaration_list external_declaration';' */
  1137 // SYM_LIST(external_declaration_list_c)
  1167 // SYM_LIST(external_declaration_list_c)
  1138 // void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c
  1168 // void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c
  1140 /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
  1170 /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
  1141 //SYM_REF2(external_declaration_c, global_var_name, specification)
  1171 //SYM_REF2(external_declaration_c, global_var_name, specification)
  1142 void *constant_folding_c::visit(external_declaration_c *symbol) {
  1172 void *constant_folding_c::visit(external_declaration_c *symbol) {
  1143   // Note that specification->const_value will have been set by handle_var_extern_global_pair, which is called from declaration_check_c
  1173   // Note that specification->const_value will have been set by handle_var_extern_global_pair, which is called from declaration_check_c
  1144   symbol->global_var_name->const_value = symbol->specification->const_value;
  1174   symbol->global_var_name->const_value = symbol->specification->const_value;
  1145   std::string varName = get_var_name_c::get_name(symbol->global_var_name)->value;
  1175   if (fixed_init_value_) {
  1146   values[varName] = symbol->specification->const_value;
  1176     std::string varName = get_var_name_c::get_name(symbol->global_var_name)->value;
  1147   // If the datatype specification is a subrange or array, do constant folding of all the literals in that type declaration...
  1177     values[varName] = symbol->specification->const_value;
       
  1178   }
       
  1179   // If the datatype specification is a subrange or array, do constant folding of all the literals in that type declaration... (ex: literals in array subrange limits)
  1148   symbol->specification->accept(*this);  // should never get to change the const_value of the symbol->specification symbol (only its children!).
  1180   symbol->specification->accept(*this);  // should never get to change the const_value of the symbol->specification symbol (only its children!).
  1149   return NULL;
  1181   return NULL;
  1150 }
  1182 }
  1151 
  1183 
  1152 /* Visitors related to GLOBAL variables are not really needed, 
  1184 /* Visitors related to GLOBAL variables are not really needed, 
  1218 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1250 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1219 //SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;)
  1251 //SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;)
  1220 void *constant_folding_c::visit(function_declaration_c *symbol) {
  1252 void *constant_folding_c::visit(function_declaration_c *symbol) {
  1221 	values.clear(); /* Clear global map */
  1253 	values.clear(); /* Clear global map */
  1222 	/* Add initial value of all declared variables into Values map. */
  1254 	/* Add initial value of all declared variables into Values map. */
       
  1255 	function_pou_ = true;
  1223 	symbol->var_declarations_list->accept(*this);
  1256 	symbol->var_declarations_list->accept(*this);
       
  1257 	function_pou_ = false;
  1224 	symbol->function_body->accept(*this);
  1258 	symbol->function_body->accept(*this);
  1225 	return NULL;
  1259 	return NULL;
  1226 }
  1260 }
       
  1261 
       
  1262 
       
  1263 /* intermediate helper symbol for
       
  1264  * - function_declaration
       
  1265  * - function_block_declaration
       
  1266  * - program_declaration
       
  1267  */
       
  1268 // SYM_LIST(var_declarations_list_c) // Not needed since we inherit from iterator_c
       
  1269 
       
  1270 /* option -> storage method, CONSTANT or <null> */
       
  1271 // SYM_REF2(function_var_decls_c, option, decl_list)
       
  1272 // NOTE: function_var_decls_c is only used inside Functions, so it is safe to call with fixed_init_value_ = true 
       
  1273 void *constant_folding_c::visit(function_var_decls_c *symbol) {return handle_var_decl(symbol->decl_list, true);}
       
  1274 
       
  1275 /* intermediate helper symbol for function_var_decls */
       
  1276 // SYM_LIST(var2_init_decl_list_c) // Not needed since we inherit from iterator_c
  1227 
  1277 
  1228 
  1278 
  1229 /*****************************/
  1279 /*****************************/
  1230 /* B 1.5.2 - Function Blocks */
  1280 /* B 1.5.2 - Function Blocks */
  1231 /*****************************/
  1281 /*****************************/
  1233 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1283 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1234 //SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;)
  1284 //SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;)
  1235 void *constant_folding_c::visit(function_block_declaration_c *symbol) {
  1285 void *constant_folding_c::visit(function_block_declaration_c *symbol) {
  1236 	values.clear(); /* Clear global map */
  1286 	values.clear(); /* Clear global map */
  1237 	/* Add initial value of all declared variables into Values map. */
  1287 	/* Add initial value of all declared variables into Values map. */
       
  1288 	function_pou_ = false;
  1238 	symbol->var_declarations->accept(*this);
  1289 	symbol->var_declarations->accept(*this);
  1239 	symbol->fblock_body->accept(*this);
  1290 	symbol->fblock_body->accept(*this);
  1240 	return NULL;
  1291 	return NULL;
  1241 }
  1292 }
       
  1293 
       
  1294 /*  VAR_TEMP temp_var_decl_list END_VAR */
       
  1295 // SYM_REF1(temp_var_decls_c, var_decl_list)
       
  1296 void *constant_folding_c::visit(temp_var_decls_c *symbol) {debug_c::print(symbol); return handle_var_decl(symbol->var_decl_list, true);}
       
  1297 
       
  1298 /* intermediate helper symbol for temp_var_decls */
       
  1299 // SYM_LIST(temp_var_decls_list_c)
       
  1300 
       
  1301 /*  VAR NON_RETAIN var_init_decl_list END_VAR */
       
  1302 // SYM_REF1(non_retentive_var_decls_c, var_decl_list)
       
  1303 // NOTE: non_retentive_var_decls_c is only used inside FBs and Programs, so it is safe to call with fixed_init_value_ = false 
       
  1304 void *constant_folding_c::visit(non_retentive_var_decls_c *symbol) {debug_c::print(symbol); return handle_var_decl(symbol->var_decl_list, false);}
  1242 
  1305 
  1243 
  1306 
  1244 /**********************/
  1307 /**********************/
  1245 /* B 1.5.3 - Programs */
  1308 /* B 1.5.3 - Programs */
  1246 /**********************/
  1309 /**********************/
  1247 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
  1310 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
  1248 //SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;)
  1311 //SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;)
  1249 void *constant_folding_c::visit(program_declaration_c *symbol) {
  1312 void *constant_folding_c::visit(program_declaration_c *symbol) {
  1250 	values.clear(); /* Clear global map */
  1313 	values.clear(); /* Clear global map */
  1251 	/* Add initial value of all declared variables into Values map. */
  1314 	/* Add initial value of all declared variables into Values map. */
       
  1315 	function_pou_ = false;
  1252 	symbol->var_declarations->accept(*this);
  1316 	symbol->var_declarations->accept(*this);
  1253 	symbol->function_block_body->accept(*this);
  1317 	symbol->function_block_body->accept(*this);
  1254 	return NULL;
  1318 	return NULL;
  1255 }
  1319 }
  1256 
  1320 
  1523 /* TODO: handle function invocations... */
  1587 /* TODO: handle function invocations... */
  1524 // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {}
  1588 // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {}
  1525 
  1589 
  1526 
  1590 
  1527 
  1591 
  1528 #if DO_CONSTANT_PROPAGATION__
       
  1529 /*********************************/
  1592 /*********************************/
  1530 /* B 3.2.1 Assignment Statements */
  1593 /* B 3.2.1 Assignment Statements */
  1531 /*********************************/
  1594 /*********************************/
  1532 void *constant_folding_c::visit(assignment_statement_c *symbol) {
  1595 void *constant_folding_c::visit(assignment_statement_c *symbol) {
  1533 	std::string varName;
  1596 	std::string varName;
  1534 
  1597 
  1535 	symbol->r_exp->accept(*this);
  1598 	symbol->r_exp->accept(*this);
       
  1599 	symbol->l_exp->accept(*this); // if the lvalue has an array, do contant folding of the array indexes!
  1536 	symbol->l_exp->const_value = symbol->r_exp->const_value;
  1600 	symbol->l_exp->const_value = symbol->r_exp->const_value;
  1537 	varName = get_var_name_c::get_name(symbol->l_exp)->value;
  1601 	varName = get_var_name_c::get_name(symbol->l_exp)->value;
  1538 	values[varName] = symbol->l_exp->const_value;
  1602 	values[varName] = symbol->l_exp->const_value;
  1539 
  1603 	return NULL;
  1540 	return NULL;
  1604 }
  1541 }
  1605 
  1542 
  1606 #if DO_CONSTANT_PROPAGATION__
  1543 /********************************/
  1607 /********************************/
  1544 /* B 3.2.3 Selection Statements */
  1608 /* B 3.2.3 Selection Statements */
  1545 /********************************/
  1609 /********************************/
  1546 void *constant_folding_c::visit(if_statement_c *symbol) {
  1610 void *constant_folding_c::visit(if_statement_c *symbol) {
  1547 	map_values_t values_incoming;
  1611 	map_values_t values_incoming;