stage3/constant_folding.cc
changeset 963 e3d4dca7520b
parent 945 477393b00f95
child 964 5f4dfe6670da
equal deleted inserted replaced
962:98e7a0d3af21 963:e3d4dca7520b
   990 /*********************/
   990 /*********************/
   991 /* B 1.4 - Variables */
   991 /* B 1.4 - Variables */
   992 /*********************/
   992 /*********************/
   993 #if DO_CONSTANT_PROPAGATION__
   993 #if DO_CONSTANT_PROPAGATION__
   994 void *constant_folding_c::visit(symbolic_variable_c *symbol) {
   994 void *constant_folding_c::visit(symbolic_variable_c *symbol) {
   995 	std::string varName;
   995 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
   996 
   996 	if (values.count(varName) > 0) 
   997 	varName = get_var_name_c::get_name(symbol->var_name)->value;
       
   998 	if (values.count(varName) > 0) {
       
   999 		symbol->const_value = values[varName];
   997 		symbol->const_value = values[varName];
  1000 	}
       
  1001 	return NULL;
   998 	return NULL;
  1002 }
   999 }
  1003 #endif  // DO_CONSTANT_PROPAGATION__
  1000 #endif  // DO_CONSTANT_PROPAGATION__
       
  1001 
       
  1002 void *constant_folding_c::visit(symbolic_constant_c *symbol) {
       
  1003 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
       
  1004 	if (values.count(varName) > 0) 
       
  1005 		symbol->const_value = values[varName];
       
  1006 	return NULL;
       
  1007 }
       
  1008 
       
  1009 
       
  1010 /******************************************/
       
  1011 /* B 1.4.3 - Declaration & Initialisation */
       
  1012 /******************************************/
       
  1013 
       
  1014 /* Do the constant folding for VAR_EXTERNAL and VAR_GLOBAL pairs.
       
  1015  *  This function is called from the declaration_check_c, since it has easy access to the extern<->global pairing information
       
  1016  *  needed for this function to work.
       
  1017  */
       
  1018 int constant_folding_c::handle_var_extern_global_pair(symbol_c *extern_var_name, symbol_c *extern_var_decl, symbol_c *global_var_name, symbol_c *global_var_decl) {  
       
  1019   // the minimum infor we must get to make sense
       
  1020   if (NULL == global_var_decl) ERROR;
       
  1021   if (NULL == extern_var_name) ERROR;
       
  1022   
       
  1023   symbol_c *init_value = type_initial_value_c::get(global_var_decl);  
       
  1024   if (NULL == init_value)   return 0; // this is probably a FB datatype, for which no initial value exists! Do nothing and return.
       
  1025   
       
  1026   // Do constant folding of the initial value!
       
  1027   //   This is required since this function may be called before we do the iterative constant folding of the complete library!
       
  1028   init_value->accept(*this);  
       
  1029   
       
  1030   if (NULL != extern_var_name) extern_var_name->const_value = init_value->const_value;
       
  1031   if (NULL != extern_var_decl) extern_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!
       
  1032   // we could leave the constant folding of the global variable itself for later, when we iteratively visit the whole library, but there is nor harm in doing it now!
       
  1033   if (NULL != global_var_name) global_var_name->const_value = init_value->const_value;
       
  1034   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   return 0;
       
  1036 }
       
  1037 
       
  1038 
       
  1039 void *constant_folding_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl) {
       
  1040   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.
       
  1042   init_value->accept(*this);  // Do constant folding of the initial value! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
       
  1043 
       
  1044   list_c *list = dynamic_cast<list_c *>(var_list);
       
  1045   if (NULL == list) ERROR;
       
  1046   for (int i = 0; i < list->n; i++) {
       
  1047     token_c *var_name = dynamic_cast<token_c *>(list->elements[i]);
       
  1048     if (NULL == var_name) {
       
  1049       if (NULL != dynamic_cast<extensible_input_parameter_c *>(list->elements[i]))
       
  1050         continue; // this is an extensible standard function. Ignore this variable, and continue!
       
  1051       debug_c::print(list->elements[i]);
       
  1052       ERROR;
       
  1053     }
       
  1054     std::string varName = var_name->value;
       
  1055     values[varName] = init_value->const_value;
       
  1056     list->elements[i]->const_value = init_value->const_value;
       
  1057   }
       
  1058   return NULL;
       
  1059 }
       
  1060 
       
  1061 /* | var1_list ',' variable_name */
       
  1062 //SYM_LIST(var1_list_c)           // Not needed!
       
  1063 //SYM_REF0(constant_option_c)     // Not needed!
       
  1064 //SYM_REF0(retain_option_c)       // Not needed!
       
  1065 //SYM_REF0(non_retain_option_c)   // Not needed!
       
  1066 
       
  1067 
       
  1068 /* spec_init is one of the following...
       
  1069  *    simple_spec_init_c *
       
  1070  *    subrange_spec_init_c *
       
  1071  *    enumerated_spec_init_c *
       
  1072  */
       
  1073 // SYM_REF2(var1_init_decl_c, var1_list, spec_init)
       
  1074 void *constant_folding_c::visit(var1_init_decl_c *symbol) {return handle_var_list_decl(symbol->var1_list, symbol->spec_init);}
       
  1075 
       
  1076 /* | [var1_list ','] variable_name integer '..' */
       
  1077 /* NOTE: This is an extension to the standard!!! */
       
  1078 //SYM_REF2(extensible_input_parameter_c, var_name, first_index)          // Not needed!
       
  1079 /* var1_list ':' array_spec_init */
       
  1080 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)            // We do not yet handle arrays!
       
  1081 /*  var1_list ':' initialized_structure */
       
  1082 //SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) // We do not yet handle structures!
       
  1083 /* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
       
  1084 //SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init)                   // We do not yet handle FBs!
       
  1085 /* fb_name_list ',' fb_name */
       
  1086 //SYM_LIST(fb_name_list_c)                                               // Not needed!
       
  1087 /* VAR_INPUT [option] input_declaration_list END_VAR */
       
  1088 /* option -> the RETAIN/NON_RETAIN/<NULL> directive... */
       
  1089 //SYM_REF3(input_declarations_c, option, input_declaration_list, method)
       
  1090 void *constant_folding_c::visit(input_declarations_c *symbol) {return NULL;}  // Input variables can take any initial value, so we can not set the const_value annotation!
       
  1091 
       
  1092 /* helper symbol for input_declarations */
       
  1093 //SYM_LIST(input_declaration_list_c)                                     // Not needed!
       
  1094 /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
       
  1095 /* option -> may be NULL ! */
       
  1096 //SYM_REF3(output_declarations_c, option, var_init_decl_list, method)    // Not needed since we inherit from iterator_visitor_c!
       
  1097 
       
  1098 /*  VAR_IN_OUT var_declaration_list END_VAR */
       
  1099 //SYM_REF1(input_output_declarations_c, var_declaration_list)
       
  1100 void *constant_folding_c::visit(input_output_declarations_c *symbol) {return NULL;}  // Input variables can take any initial value, so we can not set the const_value annotation!
       
  1101 /* helper symbol for input_output_declarations */
       
  1102 /* var_declaration_list var_declaration ';' */
       
  1103 //SYM_LIST(var_declaration_list_c)                                       // Not needed since we inherit from iterator_visitor_c!
       
  1104 /*  var1_list ':' array_specification */
       
  1105 //SYM_REF2(array_var_declaration_c, var1_list, array_specification)      // We do not yet handle arrays! 
       
  1106 /*  var1_list ':' structure_type_name */
       
  1107 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) // We do not yet handle structures!
       
  1108 /* VAR [CONSTANT] var_init_decl_list END_VAR */
       
  1109 /* option -> may be NULL ! */
       
  1110 //SYM_REF2(var_declarations_c, option, var_init_decl_list)               // Not needed: we inherit from iterator_c
       
  1111 
       
  1112 /*  VAR RETAIN var_init_decl_list END_VAR */
       
  1113 //SYM_REF1(retentive_var_declarations_c, var_init_decl_list)
       
  1114 void *constant_folding_c::visit(retentive_var_declarations_c *symbol) {return NULL;}  // Retentive variables can take any initial value, so we can not set the const_value annotation!
       
  1115 /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
       
  1116 /* option -> may be NULL ! */
       
  1117 
       
  1118 #if 0  
       
  1119 // TODO
       
  1120 SYM_REF2(located_var_declarations_c, option, located_var_decl_list)
       
  1121 /* helper symbol for located_var_declarations */
       
  1122 /* located_var_decl_list located_var_decl ';' */
       
  1123 SYM_LIST(located_var_decl_list_c)
       
  1124 /*  [variable_name] location ':' located_var_spec_init */
       
  1125 /* variable_name -> may be NULL ! */
       
  1126 SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init)
       
  1127 #endif
       
  1128 
       
  1129 /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
       
  1130 /* option -> may be NULL ! */
       
  1131 // SYM_REF2(external_var_declarations_c, option, external_declaration_list)
       
  1132 // void *constant_folding_c::visit(external_var_declarations_c *symbol) {} // Not needed: we inherit from iterator_c
       
  1133 
       
  1134 /* helper symbol for external_var_declarations */
       
  1135 /*| external_declaration_list external_declaration';' */
       
  1136 // SYM_LIST(external_declaration_list_c)
       
  1137 // void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c
       
  1138 
       
  1139 /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
       
  1140 //SYM_REF2(external_declaration_c, global_var_name, specification)
       
  1141 void *constant_folding_c::visit(external_declaration_c *symbol) {
       
  1142   // Note that specification->const_value will have been set by handle_var_extern_global_pair, which is called from declaration_check_c
       
  1143   symbol->global_var_name->const_value = symbol->specification->const_value;
       
  1144   std::string varName = get_var_name_c::get_name(symbol->global_var_name)->value;
       
  1145   values[varName] = symbol->specification->const_value;
       
  1146   return NULL;
       
  1147 }
       
  1148 
       
  1149 /* Visitors related to GLOBAL variables are not really needed, 
       
  1150  * as they are already handled by handle_var_extern_global_pair, which is called from declaration_check_c 
       
  1151  * 
       
  1152  * This is done like this because we need to know the pairing of external<->global variables to get the cvalue
       
  1153  * from the global variable. Since the external<->global pairing information is available in the declaration_check_c,
       
  1154  * we have that class call the constant_folding_c::handle_var_extern_global_pair(), which will actually do the 
       
  1155  * constant folding of the global and the external variable declarations!
       
  1156  */
       
  1157 /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */
       
  1158 /* option -> may be NULL ! */
       
  1159 // SYM_REF2(global_var_declarations_c, option, global_var_decl_list)
       
  1160 /* helper symbol for global_var_declarations */
       
  1161 /*| global_var_decl_list global_var_decl ';' */
       
  1162 // SYM_LIST(global_var_decl_list_c)
       
  1163 /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
       
  1164 /* type_specification ->may be NULL ! */
       
  1165 //SYM_REF2(global_var_decl_c, global_var_spec, type_specification)
       
  1166 /*| global_var_name location */
       
  1167 //SYM_REF2(global_var_spec_c, global_var_name, location)
       
  1168 /*  AT direct_variable */
       
  1169 //SYM_REF1(location_c, direct_variable)
       
  1170 /*| global_var_list ',' global_var_name */
       
  1171 //SYM_LIST(global_var_list_c)
       
  1172 
       
  1173 
       
  1174 #if 0  
       
  1175 // TODO
       
  1176 /*  var1_list ':' single_byte_string_spec */
       
  1177 SYM_REF2(single_byte_string_var_declaration_c, var1_list, single_byte_string_spec)
       
  1178 /*  STRING ['[' integer ']'] [ASSIGN single_byte_character_string] */
       
  1179 /* integer ->may be NULL ! */
       
  1180 /* single_byte_character_string ->may be NULL ! */
       
  1181 SYM_REF2(single_byte_string_spec_c, string_spec, single_byte_character_string)
       
  1182 /*   STRING ['[' integer ']'] */
       
  1183 /* integer ->may be NULL ! */
       
  1184 SYM_REF2(single_byte_limited_len_string_spec_c, string_type_name, character_string_len)
       
  1185 /*  WSTRING ['[' integer ']'] */
       
  1186 /* integer ->may be NULL ! */
       
  1187 SYM_REF2(double_byte_limited_len_string_spec_c, string_type_name, character_string_len)
       
  1188 /*  var1_list ':' double_byte_string_spec */
       
  1189 SYM_REF2(double_byte_string_var_declaration_c, var1_list, double_byte_string_spec)
       
  1190 /*  WSTRING ['[' integer ']'] [ASSIGN double_byte_character_string] */
       
  1191 /* integer ->may be NULL ! */
       
  1192 /* double_byte_character_string ->may be NULL ! */
       
  1193 SYM_REF2(double_byte_string_spec_c, string_spec, double_byte_character_string)
       
  1194 /*| VAR [RETAIN|NON_RETAIN] incompl_located_var_decl_list END_VAR */
       
  1195 /* option ->may be NULL ! */
       
  1196 SYM_REF2(incompl_located_var_declarations_c, option, incompl_located_var_decl_list)
       
  1197 /* helper symbol for incompl_located_var_declarations */
       
  1198 /*| incompl_located_var_decl_list incompl_located_var_decl ';' */
       
  1199 SYM_LIST(incompl_located_var_decl_list_c)
       
  1200 /*  variable_name incompl_location ':' var_spec */
       
  1201 SYM_REF3(incompl_located_var_decl_c, variable_name, incompl_location, var_spec)
       
  1202 /*  AT incompl_location_token */
       
  1203 SYM_TOKEN(incompl_location_c)
       
  1204 /* intermediate helper symbol for:
       
  1205  *  - non_retentive_var_decls
       
  1206  *  - output_declarations
       
  1207  */
       
  1208 SYM_LIST(var_init_decl_list_c)
       
  1209 #endif
       
  1210 
       
  1211 
       
  1212 /***********************/
       
  1213 /* B 1.5.1 - Functions */
       
  1214 /***********************/
       
  1215 /* 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 */
       
  1216 //SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;)
       
  1217 void *constant_folding_c::visit(function_declaration_c *symbol) {
       
  1218 	values.clear(); /* Clear global map */
       
  1219 	/* Add initial value of all declared variables into Values map. */
       
  1220 	symbol->var_declarations_list->accept(*this);
       
  1221 	symbol->function_body->accept(*this);
       
  1222 	return NULL;
       
  1223 }
       
  1224 
       
  1225 
       
  1226 /*****************************/
       
  1227 /* B 1.5.2 - Function Blocks */
       
  1228 /*****************************/
       
  1229 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
       
  1230 /* 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 */
       
  1231 //SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;)
       
  1232 void *constant_folding_c::visit(function_block_declaration_c *symbol) {
       
  1233 	values.clear(); /* Clear global map */
       
  1234 	/* Add initial value of all declared variables into Values map. */
       
  1235 	symbol->var_declarations->accept(*this);
       
  1236 	symbol->fblock_body->accept(*this);
       
  1237 	return NULL;
       
  1238 }
  1004 
  1239 
  1005 
  1240 
  1006 /**********************/
  1241 /**********************/
  1007 /* B 1.5.3 - Programs */
  1242 /* B 1.5.3 - Programs */
  1008 /**********************/
  1243 /**********************/
  1009 #if DO_CONSTANT_PROPAGATION__
  1244 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
       
  1245 //SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;)
  1010 void *constant_folding_c::visit(program_declaration_c *symbol) {
  1246 void *constant_folding_c::visit(program_declaration_c *symbol) {
  1011 	symbol_c *var_name;
  1247 	values.clear(); /* Clear global map */
  1012 
  1248 	/* Add initial value of all declared variables into Values map. */
  1013 	symbol->var_declarations->accept(*this);
  1249 	symbol->var_declarations->accept(*this);
  1014 	values.clear(); /* Clear global map */
       
  1015 	search_var_instance_decl_c search_var_instance_decl(symbol);
       
  1016 	function_param_iterator_c fpi(symbol);
       
  1017 	while((var_name = fpi.next()) != NULL) {
       
  1018 		std::string varName = get_var_name_c::get_name(var_name)->value;
       
  1019 		symbol_c   *varDecl = search_var_instance_decl.get_decl(var_name);
       
  1020 		values[varName] = varDecl->const_value;
       
  1021 	}
       
  1022 	/* Add all variables declared into Values map and put them to initial value */
       
  1023 	symbol->function_block_body->accept(*this);
  1250 	symbol->function_block_body->accept(*this);
  1024 	return NULL;
  1251 	return NULL;
  1025 }
  1252 }
  1026 #endif  // DO_CONSTANT_PROPAGATION__
       
  1027 
  1253 
  1028 
  1254 
  1029 /****************************************/
  1255 /****************************************/
  1030 /* B.2 - Language IL (Instruction List) */
  1256 /* B.2 - Language IL (Instruction List) */
  1031 /****************************************/
  1257 /****************************************/
  1417 }
  1643 }
  1418 
  1644 
  1419 #endif  // DO_CONSTANT_PROPAGATION__
  1645 #endif  // DO_CONSTANT_PROPAGATION__
  1420 
  1646 
  1421 
  1647 
       
  1648 
       
  1649 
       
  1650 
       
  1651