1169 // void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c |
1166 // void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c |
1170 |
1167 |
1171 /* global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */ |
1168 /* global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */ |
1172 //SYM_REF2(external_declaration_c, global_var_name, specification) |
1169 //SYM_REF2(external_declaration_c, global_var_name, specification) |
1173 void *constant_folding_c::visit(external_declaration_c *symbol) { |
1170 void *constant_folding_c::visit(external_declaration_c *symbol) { |
1174 // Note that specification->const_value will have been set by handle_var_extern_global_pair, which is called from declaration_check_c |
1171 // Note that specification->const_value will have been set by handle_var_extern_global_pair(), which is called from declaration_check_c |
1175 symbol->global_var_name->const_value = symbol->specification->const_value; |
1172 symbol->global_var_name->const_value = symbol->specification->const_value; |
1176 if (fixed_init_value_) { |
1173 if (fixed_init_value_) { |
1177 std::string varName = get_var_name_c::get_name(symbol->global_var_name)->value; |
1174 std::string varName = get_var_name_c::get_name(symbol->global_var_name)->value; |
1178 values[varName] = symbol->specification->const_value; |
1175 values[varName] = symbol->specification->const_value; |
1179 } |
1176 } |
1180 // 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) |
1177 // 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) |
1181 symbol->specification->accept(*this); // should never get to change the const_value of the symbol->specification symbol (only its children!). |
1178 symbol->specification->accept(*this); // should never get to change the const_value of the symbol->specification symbol (only its children!). |
1182 return NULL; |
1179 return NULL; |
1183 } |
1180 } |
1184 |
1181 |
1185 /* Visitors related to GLOBAL variables are not really needed, |
1182 /* NOTE that the constant folding of GLOBAL variables is already handled by handle_var_extern_global_pair, which |
1186 * as they are already handled by handle_var_extern_global_pair, which is called from declaration_check_c |
1183 * is called from declaration_check_c, |
1187 * |
|
1188 * This is done like this because we need to know the pairing of external<->global variables to get the cvalue |
1184 * This is done like this because we need to know the pairing of external<->global variables to get the cvalue |
1189 * from the global variable. Since the external<->global pairing information is available in the declaration_check_c, |
1185 * from the global variable. Since the external<->global pairing information is available in the declaration_check_c, |
1190 * we have that class call the constant_folding_c::handle_var_extern_global_pair(), which will actually do the |
1186 * we have that class call the constant_folding_c::handle_var_extern_global_pair(), which will actually do the |
1191 * constant folding of the global and the external variable declarations! |
1187 * constant folding of the global and the external variable declarations! |
1192 */ |
1188 */ |
|
1189 /* NOTE: The constant propagation portion of this algorithm must still be done here!! |
|
1190 * Even though the constant folding of GLOBAL variables are already handled by handle_var_extern_global_pair(), |
|
1191 * we must still visit them here, since when doing constant propagation of a Configuration or a Resource we need the |
|
1192 * values of constant variables to be placed in the values[] map, as these same variables may be used to declare |
|
1193 * arrays of a variable size |
|
1194 * VAR_GLOBAL CONSTANT max : INT := 42; END_VAR |
|
1195 * VAR_GLOBAL array_v : ARRAY [1..max] of INT; END_VAR <---- NOTE the use of 'max' in the subrange! |
|
1196 */ |
1193 /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */ |
1197 /*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */ |
1194 /* option -> may be NULL ! */ |
1198 /* option -> may be NULL ! */ |
1195 // SYM_REF2(global_var_declarations_c, option, global_var_decl_list) |
1199 // SYM_REF2(global_var_declarations_c, option, global_var_decl_list) |
|
1200 /* Note that calling handle_var_decl() will result in doing constant folding of literals (of datatype initial values) |
|
1201 * that were already constant folded by the method handle_var_extern_global_pair() |
|
1202 * Nevertheless, since constant folding is idem-potent, it is simpler to just call handle_var_decl() instead |
|
1203 * of writing some code specific for this situation! |
|
1204 */ |
|
1205 void *constant_folding_c::visit(global_var_declarations_c *symbol) {return handle_var_decl(symbol->global_var_decl_list, is_constant(symbol->option));} |
|
1206 |
|
1207 |
1196 /* helper symbol for global_var_declarations */ |
1208 /* helper symbol for global_var_declarations */ |
1197 /*| global_var_decl_list global_var_decl ';' */ |
1209 /*| global_var_decl_list global_var_decl ';' */ |
1198 // SYM_LIST(global_var_decl_list_c) |
1210 // SYM_LIST(global_var_decl_list_c) |
|
1211 // void *constant_folding_c::visit(global_var_decl_list_c *symbol) {} // Not needed: we inherit from iterator_c |
|
1212 |
1199 /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */ |
1213 /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */ |
1200 /* type_specification ->may be NULL ! */ |
1214 /* type_specification ->may be NULL ! */ |
1201 //SYM_REF2(global_var_decl_c, global_var_spec, type_specification) |
1215 //SYM_REF2(global_var_decl_c, global_var_spec, type_specification) |
|
1216 void *constant_folding_c::visit(global_var_decl_c *symbol) { |
|
1217 /* global_var_spec may be either a global_var_spec_c or a global_var_list_c. |
|
1218 * Since we already have a nice method that handles var lists (handle_var_list_decl() ) |
|
1219 * if it is a global_var_spec_c we will create a temporary list so we can call that method! |
|
1220 */ |
|
1221 global_var_spec_c *var_spec = dynamic_cast<global_var_spec_c *>(symbol->global_var_spec); |
|
1222 if (NULL == var_spec) { |
|
1223 // global_var_spec is a global_var_list_c |
|
1224 return handle_var_list_decl(symbol->global_var_spec, symbol->type_specification); |
|
1225 } else { |
|
1226 global_var_list_c var_list; |
|
1227 var_list.add_element(var_spec->global_var_name); |
|
1228 return handle_var_list_decl(&var_list, symbol->type_specification); |
|
1229 } |
|
1230 } |
|
1231 |
|
1232 |
1202 /*| global_var_name location */ |
1233 /*| global_var_name location */ |
1203 //SYM_REF2(global_var_spec_c, global_var_name, location) |
1234 //SYM_REF2(global_var_spec_c, global_var_name, location) // Not needed! |
|
1235 |
1204 /* AT direct_variable */ |
1236 /* AT direct_variable */ |
1205 //SYM_REF1(location_c, direct_variable) |
1237 //SYM_REF1(location_c, direct_variable) // Not needed! |
|
1238 |
1206 /*| global_var_list ',' global_var_name */ |
1239 /*| global_var_list ',' global_var_name */ |
1207 //SYM_LIST(global_var_list_c) |
1240 //SYM_LIST(global_var_list_c) // Not needed! |
1208 |
1241 |
1209 |
1242 |
1210 #if 0 |
1243 #if 0 |
1211 // TODO |
1244 // TODO |
|
1245 // We do not do constant folding of strings yet, so there is no need to implement this now! |
1212 /* var1_list ':' single_byte_string_spec */ |
1246 /* var1_list ':' single_byte_string_spec */ |
1213 SYM_REF2(single_byte_string_var_declaration_c, var1_list, single_byte_string_spec) |
1247 SYM_REF2(single_byte_string_var_declaration_c, var1_list, single_byte_string_spec) |
1214 /* STRING ['[' integer ']'] [ASSIGN single_byte_character_string] */ |
1248 /* STRING ['[' integer ']'] [ASSIGN single_byte_character_string] */ |
1215 /* integer ->may be NULL ! */ |
1249 /* integer ->may be NULL ! */ |
1216 /* single_byte_character_string ->may be NULL ! */ |
1250 /* single_byte_character_string ->may be NULL ! */ |
1318 symbol->function_block_body->accept(*this); |
1352 symbol->function_block_body->accept(*this); |
1319 return NULL; |
1353 return NULL; |
1320 } |
1354 } |
1321 |
1355 |
1322 |
1356 |
|
1357 /********************************/ |
|
1358 /* B 1.7 Configuration elements */ |
|
1359 /********************************/ |
|
1360 |
|
1361 /* |
|
1362 CONFIGURATION configuration_name |
|
1363 optional_global_var_declarations |
|
1364 (resource_declaration_list | single_resource_declaration) |
|
1365 optional_access_declarations |
|
1366 optional_instance_specific_initializations |
|
1367 END_CONFIGURATION |
|
1368 */ |
|
1369 /* 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 */ |
|
1370 // SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, |
|
1371 // enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;) |
|
1372 void *constant_folding_c::visit(configuration_declaration_c *symbol) { |
|
1373 values.clear(); /* Clear global map */ |
|
1374 /* Add initial value of all declared variables into Values map. */ |
|
1375 function_pou_ = false; |
|
1376 return iterator_visitor_c::visit(symbol); // let the base iterator class handle the rest (basically iterate through the whole configuration and do the constant folding! |
|
1377 } |
|
1378 |
|
1379 |
|
1380 /* helper symbol for configuration_declaration */ |
|
1381 // SYM_LIST(resource_declaration_list_c) // Not needed: we inherit from iterator_c |
|
1382 |
|
1383 /* |
|
1384 RESOURCE resource_name ON resource_type_name |
|
1385 optional_global_var_declarations |
|
1386 single_resource_declaration |
|
1387 END_RESOURCE |
|
1388 */ |
|
1389 /* 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 */ |
|
1390 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, |
|
1391 // enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;) |
|
1392 void *constant_folding_c::visit(resource_declaration_c *symbol) { |
|
1393 values.clear(); /* Clear global map */ |
|
1394 /* Add initial value of all declared variables into Values map. */ |
|
1395 function_pou_ = false; |
|
1396 return iterator_visitor_c::visit(symbol); // let the base iterator class handle the rest (basically iterate through the whole configuration and do the constant folding! |
|
1397 } |
|
1398 |
|
1399 |
|
1400 |
|
1401 /* task_configuration_list program_configuration_list */ |
|
1402 // SYM_REF2(single_resource_declaration_c, task_configuration_list, program_configuration_list) |
|
1403 /* helper symbol for single_resource_declaration */ |
|
1404 // SYM_LIST(task_configuration_list_c) |
|
1405 /* helper symbol for single_resource_declaration */ |
|
1406 // SYM_LIST(program_configuration_list_c) |
|
1407 /* helper symbol for: (access_path, instance_specific_init) */ |
|
1408 // SYM_LIST(any_fb_name_list_c) |
|
1409 /* [resource_name '.'] global_var_name ['.' structure_element_name] */ |
|
1410 // SYM_REF3(global_var_reference_c, resource_name, global_var_name, structure_element_name) |
|
1411 /* prev_declared_program_name '.' symbolic_variable */ |
|
1412 // SYM_REF2(program_output_reference_c, program_name, symbolic_variable) |
|
1413 /* TASK task_name task_initialization */ |
|
1414 // SYM_REF2(task_configuration_c, task_name, task_initialization) |
|
1415 /* '(' [SINGLE ASSIGN data_source ','] [INTERVAL ASSIGN data_source ','] PRIORITY ASSIGN integer ')' */ |
|
1416 // SYM_REF3(task_initialization_c, single_data_source, interval_data_source, priority_data_source) |
|
1417 /* PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */ |
|
1418 /* NOTE: The parameter 'called_prog_declaration'is used to pass data between stage 3 and stage4 */ |
|
1419 // SYM_REF5(program_configuration_c, retain_option, program_name, task_name, program_type_name, prog_conf_elements, |
|
1420 // symbol_c *called_prog_declaration;) |
|
1421 /* prog_conf_elements ',' prog_conf_element */ |
|
1422 // SYM_LIST(prog_conf_elements_c) |
|
1423 /* fb_name WITH task_name */ |
|
1424 // SYM_REF2(fb_task_c, fb_name, task_name) |
|
1425 /* any_symbolic_variable ASSIGN prog_data_source */ |
|
1426 // SYM_REF2(prog_cnxn_assign_c, symbolic_variable, prog_data_source) |
|
1427 /* any_symbolic_variable SENDTO data_sink */ |
|
1428 // SYM_REF2(prog_cnxn_sendto_c, symbolic_variable, data_sink) |
|
1429 /* VAR_CONFIG instance_specific_init_list END_VAR */ |
|
1430 // SYM_REF1(instance_specific_initializations_c, instance_specific_init_list) |
|
1431 /* helper symbol for instance_specific_initializations */ |
|
1432 // SYM_LIST(instance_specific_init_list_c) |
|
1433 /* resource_name '.' program_name '.' {fb_name '.'} |
|
1434 ((variable_name [location] ':' located_var_spec_init) | (fb_name ':' fb_initialization)) |
|
1435 */ |
|
1436 // SYM_REF6(instance_specific_init_c, resource_name, program_name, any_fb_name_list, variable_name, location, initialization) |
|
1437 /* helper symbol for instance_specific_init */ |
|
1438 /* function_block_type_name ':=' structure_initialization */ |
|
1439 // SYM_REF2(fb_initialization_c, function_block_type_name, structure_initialization) |
|
1440 |
|
1441 |
|
1442 |
|
1443 |
1323 /****************************************/ |
1444 /****************************************/ |
1324 /* B.2 - Language IL (Instruction List) */ |
1445 /* B.2 - Language IL (Instruction List) */ |
1325 /****************************************/ |
1446 /****************************************/ |
1326 /***********************************/ |
1447 /***********************************/ |
1327 /* B 2.1 Instructions and Operands */ |
1448 /* B 2.1 Instructions and Operands */ |