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 */ |
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; |