1225 s4o.print(":\n"); |
1220 s4o.print(":\n"); |
1226 s4o.indent_right(); |
1221 s4o.indent_right(); |
1227 } |
1222 } |
1228 |
1223 |
1229 |
1224 |
1230 |
1225 /*************/ |
|
1226 /* Functions */ |
|
1227 /*************/ |
1231 public: |
1228 public: |
1232 /********************/ |
1229 /* NOTE: The following function will be called twice: |
1233 /* 2.1.6 - Pragmas */ |
1230 * 1st time: s4o will reference the .h file, and print_declaration=true |
1234 /********************/ |
1231 * Here, we generate the function prototypes... |
1235 void *visit(enable_code_generation_pragma_c * symbol) {s4o.enable_output(); return NULL;} |
1232 * 2nd time: s4o will reference the .c file, and print_declaration=false |
1236 void *visit(disable_code_generation_pragma_c * symbol) {s4o.disable_output(); return NULL;} |
1233 * Here we generate the source code! |
1237 |
1234 */ |
1238 /*************************/ |
1235 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
1239 /* B.1 - Common elements */ |
1236 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
1240 /*************************/ |
1237 static void handle_function(function_declaration_c *symbol, stage4out_c &s4o, bool print_declaration) { |
1241 /*******************************************/ |
1238 generate_c_vardecl_c *vardecl = NULL; |
1242 /* B 1.1 - Letters, digits and identifiers */ |
1239 generate_c_base_c print_base(&s4o); |
1243 /*******************************************/ |
1240 |
1244 /* done in base class(es) */ |
1241 TRACE("function_declaration_c"); |
1245 |
1242 |
1246 /*********************/ |
1243 /* (A) Function declaration... */ |
1247 /* B 1.2 - Constants */ |
1244 /* (A.1) Function return type */ |
1248 /*********************/ |
1245 s4o.print("// FUNCTION\n"); |
1249 /* originally empty... */ |
1246 symbol->type_name->accept(print_base); /* return type */ |
1250 |
1247 s4o.print(" "); |
1251 /******************************/ |
1248 /* (A.2) Function name */ |
1252 /* B 1.2.1 - Numeric Literals */ |
1249 symbol->derived_function_name->accept(print_base); |
1253 /******************************/ |
1250 s4o.print("("); |
1254 /* done in base class(es) */ |
1251 |
1255 |
1252 /* (A.3) Function parameters */ |
1256 /*******************************/ |
1253 s4o.indent_right(); |
1257 /* B.1.2.2 Character Strings */ |
1254 vardecl = new generate_c_vardecl_c(&s4o, |
1258 /*******************************/ |
1255 generate_c_vardecl_c::finterface_vf, |
1259 /* done in base class(es) */ |
1256 generate_c_vardecl_c::input_vt | |
1260 |
1257 generate_c_vardecl_c::output_vt | |
1261 /***************************/ |
1258 generate_c_vardecl_c::inoutput_vt | |
1262 /* B 1.2.3 - Time Literals */ |
1259 generate_c_vardecl_c::en_vt | |
1263 /***************************/ |
1260 generate_c_vardecl_c::eno_vt); |
1264 /************************/ |
1261 vardecl->print(symbol->var_declarations_list); |
1265 /* B 1.2.3.1 - Duration */ |
1262 delete vardecl; |
1266 /************************/ |
1263 |
1267 /* done in base class(es) */ |
1264 s4o.indent_left(); |
1268 |
1265 |
1269 /************************************/ |
1266 s4o.print(")"); |
1270 /* B 1.2.3.2 - Time of day and Date */ |
1267 |
1271 /************************************/ |
1268 /* If we only want the declaration/prototype, then return!! */ |
1272 /* done in base class(es) */ |
1269 if (print_declaration) |
1273 |
1270 {s4o.print(";\n"); return;} |
1274 /**********************/ |
1271 |
1275 /* B.1.3 - Data types */ |
1272 /* continue generating the function definition/code... */ |
1276 /**********************/ |
1273 s4o.print("\n" + s4o.indent_spaces + "{\n"); |
1277 /***********************************/ |
1274 |
1278 /* B 1.3.1 - Elementary Data Types */ |
1275 /* (B) Function local variable declaration */ |
1279 /***********************************/ |
1276 /* (B.1) Variables declared in ST source code */ |
1280 /* done in base class(es) */ |
1277 s4o.indent_right(); |
1281 |
1278 |
1282 /********************************/ |
1279 vardecl = new generate_c_vardecl_c(&s4o, |
1283 /* B.1.3.2 - Generic data types */ |
1280 generate_c_vardecl_c::localinit_vf, |
1284 /********************************/ |
1281 generate_c_vardecl_c::output_vt | |
1285 /* originally empty... */ |
1282 generate_c_vardecl_c::inoutput_vt | |
1286 |
1283 generate_c_vardecl_c::private_vt | |
1287 /********************************/ |
1284 generate_c_vardecl_c::eno_vt); |
1288 /* B 1.3.3 - Derived data types */ |
1285 vardecl->print(symbol->var_declarations_list); |
1289 /********************************/ |
1286 delete vardecl; |
1290 /* done in base class(es) */ |
1287 |
1291 |
1288 /* (B.2) Temporary variable for function's return value */ |
1292 /*********************/ |
1289 /* It will have the same name as the function itself! */ |
1293 /* B 1.4 - Variables */ |
1290 s4o.print(s4o.indent_spaces); |
1294 /*********************/ |
1291 symbol->type_name->accept(print_base); /* return type */ |
1295 /* done in base class(es) */ |
1292 s4o.print(" "); |
1296 |
1293 symbol->derived_function_name->accept(print_base); |
1297 /********************************************/ |
1294 s4o.print(" = "); |
1298 /* B.1.4.1 Directly Represented Variables */ |
1295 { |
1299 /********************************************/ |
1296 /* get the default value of this variable's type */ |
1300 /* done in base class(es) */ |
1297 symbol_c *default_value = type_initial_value_c::get(symbol->type_name); |
1301 |
1298 if (default_value == NULL) ERROR; |
1302 /*************************************/ |
1299 initialization_analyzer_c initialization_analyzer(default_value); |
1303 /* B.1.4.2 Multi-element Variables */ |
1300 switch (initialization_analyzer.get_initialization_type()) { |
1304 /*************************************/ |
1301 case initialization_analyzer_c::struct_it: |
1305 /* done in base class(es) */ |
1302 { |
1306 |
1303 generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o); |
1307 /******************************************/ |
1304 structure_initialization->init_structure_default(symbol->type_name); |
1308 /* B 1.4.3 - Declaration & Initialisation */ |
1305 structure_initialization->init_structure_values(default_value); |
1309 /******************************************/ |
1306 delete structure_initialization; |
1310 /* done in base class(es) */ |
1307 } |
1311 |
1308 break; |
1312 /**************************************/ |
1309 case initialization_analyzer_c::array_it: |
1313 /* B.1.5 - Program organization units */ |
1310 { |
1314 /**************************************/ |
1311 generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o); |
1315 /***********************/ |
1312 array_initialization->init_array_size(symbol->type_name); |
1316 /* B 1.5.1 - Functions */ |
1313 array_initialization->init_array_values(default_value); |
1317 /***********************/ |
1314 delete array_initialization; |
1318 |
1315 } |
1319 public: |
1316 break; |
1320 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
1317 default: |
1321 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
1318 default_value->accept(print_base); |
1322 void *visit(function_declaration_c *symbol) { |
1319 break; |
1323 generate_c_vardecl_c *vardecl; |
1320 } |
1324 TRACE("function_declaration_c"); |
1321 } |
1325 |
1322 s4o.print(";\n\n"); |
1326 /* (A) Function declaration... */ |
1323 |
1327 /* (A.1) Function return type */ |
1324 s4o.print(s4o.indent_spaces + "// Control execution\n"); |
1328 s4o.print("// FUNCTION\n"); |
1325 s4o.print(s4o.indent_spaces + "if (!EN) {\n"); |
1329 symbol->type_name->accept(*this); /* return type */ |
1326 s4o.indent_right(); |
1330 s4o.print(" "); |
1327 s4o.print(s4o.indent_spaces + "if (__ENO != NULL) {\n"); |
1331 /* (A.2) Function name */ |
1328 s4o.indent_right(); |
1332 symbol->derived_function_name->accept(*this); |
1329 s4o.print(s4o.indent_spaces + "*__ENO = __BOOL_LITERAL(FALSE);\n"); |
1333 s4o.print("("); |
1330 s4o.indent_left(); |
1334 |
1331 s4o.print(s4o.indent_spaces + "}\n"); |
1335 /* (A.3) Function parameters */ |
1332 s4o.print(s4o.indent_spaces + "return "); |
1336 s4o.indent_right(); |
1333 symbol->derived_function_name->accept(print_base); |
1337 vardecl = new generate_c_vardecl_c(&s4o, |
1334 s4o.print(";\n"); |
1338 generate_c_vardecl_c::finterface_vf, |
1335 s4o.indent_left(); |
1339 generate_c_vardecl_c::input_vt | |
1336 s4o.print(s4o.indent_spaces + "}\n"); |
1340 generate_c_vardecl_c::output_vt | |
1337 |
1341 generate_c_vardecl_c::inoutput_vt | |
1338 /* (C) Function body */ |
1342 generate_c_vardecl_c::en_vt | |
1339 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol); |
1343 generate_c_vardecl_c::eno_vt); |
1340 symbol->function_body->accept(generate_c_code); |
1344 vardecl->print(symbol->var_declarations_list); |
1341 |
1345 delete vardecl; |
1342 print_end_of_block_label(s4o); |
|
1343 |
|
1344 vardecl = new generate_c_vardecl_c(&s4o, |
|
1345 generate_c_vardecl_c::foutputassign_vf, |
|
1346 generate_c_vardecl_c::output_vt | |
|
1347 generate_c_vardecl_c::inoutput_vt | |
|
1348 generate_c_vardecl_c::eno_vt); |
|
1349 vardecl->print(symbol->var_declarations_list); |
|
1350 delete vardecl; |
|
1351 |
|
1352 s4o.print(s4o.indent_spaces + "return "); |
|
1353 symbol->derived_function_name->accept(print_base); |
|
1354 s4o.print(";\n"); |
|
1355 s4o.indent_left(); |
|
1356 s4o.print(s4o.indent_spaces + "}\n\n\n"); |
|
1357 |
|
1358 return; |
|
1359 } |
|
1360 |
|
1361 |
|
1362 /*******************/ |
|
1363 /* Function Blocks */ |
|
1364 /*******************/ |
|
1365 public: |
|
1366 /* NOTE: The following function will be called twice: |
|
1367 * 1st time: s4o will reference the .h file, and print_declaration=true |
|
1368 * Here, we generate the function prototypes... |
|
1369 * 2nd time: s4o will reference the .c file, and print_declaration=false |
|
1370 * Here we generate the source code! |
|
1371 */ |
|
1372 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
|
1373 //SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) |
|
1374 static void handle_function_block(function_block_declaration_c *symbol, stage4out_c &s4o, bool print_declaration) { |
|
1375 generate_c_vardecl_c *vardecl; |
|
1376 generate_c_sfcdecl_c *sfcdecl; |
|
1377 generate_c_base_c print_base(&s4o); |
|
1378 TRACE("function_block_declaration_c"); |
|
1379 |
|
1380 /* (A) Function Block data structure declaration... */ |
|
1381 if (print_declaration) { |
|
1382 /* (A.1) Data structure declaration */ |
|
1383 s4o.print("// FUNCTION_BLOCK "); |
|
1384 symbol->fblock_name->accept(print_base); |
|
1385 s4o.print("\n// Data part\n"); |
|
1386 s4o.print("typedef struct {\n"); |
|
1387 s4o.indent_right(); |
|
1388 |
|
1389 /* (A.2) Public variables: i.e. the function parameters... */ |
|
1390 s4o.print(s4o.indent_spaces + "// FB Interface - IN, OUT, IN_OUT variables\n"); |
|
1391 vardecl = new generate_c_vardecl_c(&s4o, |
|
1392 generate_c_vardecl_c::local_vf, |
|
1393 generate_c_vardecl_c::input_vt | |
|
1394 generate_c_vardecl_c::output_vt | |
|
1395 generate_c_vardecl_c::inoutput_vt | |
|
1396 generate_c_vardecl_c::en_vt | |
|
1397 generate_c_vardecl_c::eno_vt); |
|
1398 vardecl->print(symbol->var_declarations); |
|
1399 delete vardecl; |
|
1400 s4o.print("\n"); |
|
1401 |
|
1402 /* (A.3) Private internal variables */ |
|
1403 s4o.print(s4o.indent_spaces + "// FB private variables - TEMP, private and located variables\n"); |
|
1404 vardecl = new generate_c_vardecl_c(&s4o, |
|
1405 generate_c_vardecl_c::local_vf, |
|
1406 generate_c_vardecl_c::temp_vt | |
|
1407 generate_c_vardecl_c::private_vt | |
|
1408 generate_c_vardecl_c::located_vt | |
|
1409 generate_c_vardecl_c::external_vt); |
|
1410 vardecl->print(symbol->var_declarations); |
|
1411 delete vardecl; |
|
1412 |
|
1413 /* (A.4) Generate private internal variables for SFC */ |
|
1414 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol); |
|
1415 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::sfcdecl_sd); |
|
1416 delete sfcdecl; |
|
1417 s4o.print("\n"); |
|
1418 |
|
1419 /* (A.5) Function Block data structure type name. */ |
|
1420 s4o.indent_left(); |
|
1421 s4o.print("} "); |
|
1422 symbol->fblock_name->accept(print_base); |
|
1423 s4o.print(";\n\n"); |
|
1424 } |
|
1425 |
|
1426 if (!print_declaration) { |
|
1427 /* (A.6) Function Block inline function declaration for function invocation */ |
|
1428 generate_c_inlinefcall_c *inlinedecl = new generate_c_inlinefcall_c(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); |
|
1429 symbol->fblock_body->accept(*inlinedecl); |
|
1430 delete inlinedecl; |
|
1431 } |
|
1432 |
|
1433 /* (B) Constructor */ |
|
1434 /* (B.1) Constructor name... */ |
|
1435 s4o.print(s4o.indent_spaces + "void "); |
|
1436 symbol->fblock_name->accept(print_base); |
|
1437 s4o.print(FB_INIT_SUFFIX); |
|
1438 s4o.print("("); |
|
1439 |
|
1440 /* first and only parameter is a pointer to the data */ |
|
1441 symbol->fblock_name->accept(print_base); |
|
1442 s4o.print(" *"); |
|
1443 s4o.print(FB_FUNCTION_PARAM); |
|
1444 s4o.print(", BOOL retain)"); |
|
1445 |
|
1446 if (print_declaration) { |
|
1447 s4o.print(";\n"); |
|
1448 } else { |
|
1449 s4o.print(" {\n"); |
|
1450 s4o.indent_right(); |
|
1451 |
|
1452 /* (B.2) Member initializations... */ |
|
1453 s4o.print(s4o.indent_spaces); |
|
1454 vardecl = new generate_c_vardecl_c(&s4o, |
|
1455 generate_c_vardecl_c::constructorinit_vf, |
|
1456 generate_c_vardecl_c::input_vt | |
|
1457 generate_c_vardecl_c::output_vt | |
|
1458 generate_c_vardecl_c::inoutput_vt | |
|
1459 generate_c_vardecl_c::private_vt | |
|
1460 generate_c_vardecl_c::located_vt | |
|
1461 generate_c_vardecl_c::external_vt | |
|
1462 generate_c_vardecl_c::en_vt | |
|
1463 generate_c_vardecl_c::eno_vt); |
|
1464 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
|
1465 delete vardecl; |
|
1466 s4o.print("\n"); |
|
1467 |
|
1468 /* (B.3) Generate private internal variables for SFC */ |
|
1469 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
|
1470 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::sfcinit_sd); |
|
1471 delete sfcdecl; |
|
1472 |
|
1473 s4o.indent_left(); |
|
1474 s4o.print(s4o.indent_spaces + "}\n\n"); |
|
1475 } |
|
1476 |
|
1477 if (!print_declaration) { |
|
1478 /* (C) Function with FB body */ |
|
1479 /* (C.1) Step definitions */ |
|
1480 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
|
1481 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::stepdef_sd); |
|
1482 |
|
1483 /* (C.2) Action definitions */ |
|
1484 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::actiondef_sd); |
|
1485 delete sfcdecl; |
|
1486 } |
|
1487 |
|
1488 /* (C.3) Function declaration */ |
|
1489 s4o.print("// Code part\n"); |
|
1490 /* function interface */ |
|
1491 s4o.print("void "); |
|
1492 symbol->fblock_name->accept(print_base); |
|
1493 s4o.print(FB_FUNCTION_SUFFIX); |
|
1494 s4o.print("("); |
|
1495 /* first and only parameter is a pointer to the data */ |
|
1496 symbol->fblock_name->accept(print_base); |
|
1497 s4o.print(" *"); |
|
1498 s4o.print(FB_FUNCTION_PARAM); |
|
1499 s4o.print(")"); |
|
1500 |
|
1501 if (print_declaration) { |
|
1502 s4o.print(";\n"); |
|
1503 } else { |
|
1504 s4o.print(" {\n"); |
|
1505 s4o.indent_right(); |
|
1506 |
|
1507 s4o.print(s4o.indent_spaces + "// Control execution\n"); |
|
1508 s4o.print(s4o.indent_spaces + "if (!"); |
|
1509 s4o.print(GET_VAR); |
|
1510 s4o.print("("); |
|
1511 s4o.print(FB_FUNCTION_PARAM); |
|
1512 s4o.print("->EN)) {\n"); |
|
1513 s4o.indent_right(); |
|
1514 s4o.print(s4o.indent_spaces); |
|
1515 s4o.print(SET_VAR); |
|
1516 s4o.print("("); |
|
1517 s4o.print(FB_FUNCTION_PARAM); |
|
1518 s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n"); |
|
1519 s4o.print(s4o.indent_spaces + "return;\n"); |
|
1520 s4o.indent_left(); |
|
1521 s4o.print(s4o.indent_spaces + "}\n"); |
|
1522 s4o.print(s4o.indent_spaces + "else {\n"); |
|
1523 s4o.indent_right(); |
|
1524 s4o.print(s4o.indent_spaces); |
|
1525 s4o.print(SET_VAR); |
|
1526 s4o.print("("); |
|
1527 s4o.print(FB_FUNCTION_PARAM); |
|
1528 s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n"); |
|
1529 s4o.indent_left(); |
|
1530 s4o.print(s4o.indent_spaces + "}\n"); |
|
1531 |
|
1532 /* (C.4) Initialize TEMP variables */ |
|
1533 /* function body */ |
|
1534 s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n"); |
|
1535 vardecl = new generate_c_vardecl_c(&s4o, |
|
1536 generate_c_vardecl_c::init_vf, |
|
1537 generate_c_vardecl_c::temp_vt); |
|
1538 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
|
1539 delete vardecl; |
|
1540 s4o.print("\n"); |
|
1541 |
|
1542 /* (C.5) Function code */ |
|
1543 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); |
|
1544 symbol->fblock_body->accept(generate_c_code); |
|
1545 print_end_of_block_label(s4o); |
|
1546 s4o.print(s4o.indent_spaces + "return;\n"); |
|
1547 s4o.indent_left(); |
|
1548 s4o.print(s4o.indent_spaces + "} // "); |
|
1549 symbol->fblock_name->accept(print_base); |
|
1550 s4o.print(FB_FUNCTION_SUFFIX); |
|
1551 s4o.print(s4o.indent_spaces + "() \n\n"); |
|
1552 |
|
1553 /* (C.6) Step undefinitions */ |
|
1554 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
|
1555 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::stepundef_sd); |
|
1556 |
|
1557 /* (C.7) Action undefinitions */ |
|
1558 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::actionundef_sd); |
|
1559 delete sfcdecl; |
|
1560 |
|
1561 s4o.indent_left(); |
|
1562 s4o.print("\n\n\n\n"); |
|
1563 } |
|
1564 return; |
|
1565 } |
|
1566 |
|
1567 |
|
1568 /************/ |
|
1569 /* Programs */ |
|
1570 /************/ |
|
1571 public: |
|
1572 /* NOTE: The following function will be called twice: |
|
1573 * 1st time: s4o will reference the .h file, and print_declaration=true |
|
1574 * Here, we generate the function prototypes... |
|
1575 * 2nd time: s4o will reference the .c file, and print_declaration=false |
|
1576 * Here we generate the source code! |
|
1577 */ |
|
1578 /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ |
|
1579 //SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused) |
|
1580 static void handle_program(program_declaration_c *symbol, stage4out_c &s4o, bool print_declaration) { |
|
1581 generate_c_vardecl_c *vardecl; |
|
1582 generate_c_sfcdecl_c *sfcdecl; |
|
1583 generate_c_base_c print_base(&s4o); |
|
1584 TRACE("program_declaration_c"); |
|
1585 |
|
1586 /* (A) Program data structure declaration... */ |
|
1587 if (print_declaration) { |
|
1588 /* (A.1) Data structure declaration */ |
|
1589 s4o.print("// PROGRAM "); |
|
1590 symbol->program_type_name->accept(print_base); |
|
1591 s4o.print("\n// Data part\n"); |
|
1592 s4o.print("typedef struct {\n"); |
|
1593 s4o.indent_right(); |
|
1594 |
|
1595 /* (A.2) Public variables: i.e. the program parameters... */ |
|
1596 s4o.print(s4o.indent_spaces + "// PROGRAM Interface - IN, OUT, IN_OUT variables\n"); |
|
1597 vardecl = new generate_c_vardecl_c(&s4o, |
|
1598 generate_c_vardecl_c::local_vf, |
|
1599 generate_c_vardecl_c::input_vt | |
|
1600 generate_c_vardecl_c::output_vt | |
|
1601 generate_c_vardecl_c::inoutput_vt); |
|
1602 vardecl->print(symbol->var_declarations); |
|
1603 delete vardecl; |
|
1604 s4o.print("\n"); |
1346 |
1605 |
1347 s4o.indent_left(); |
1606 /* (A.3) Private internal variables */ |
1348 |
1607 s4o.print(s4o.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n"); |
1349 s4o.print(")\n" + s4o.indent_spaces + "{\n"); |
1608 vardecl = new generate_c_vardecl_c(&s4o, |
1350 |
1609 generate_c_vardecl_c::local_vf, |
1351 /* (B) Function local variable declaration */ |
1610 generate_c_vardecl_c::temp_vt | |
1352 /* (B.1) Variables declared in ST source code */ |
1611 generate_c_vardecl_c::private_vt | |
1353 s4o.indent_right(); |
1612 generate_c_vardecl_c::located_vt | |
1354 |
1613 generate_c_vardecl_c::external_vt); |
1355 vardecl = new generate_c_vardecl_c(&s4o, |
1614 vardecl->print(symbol->var_declarations); |
1356 generate_c_vardecl_c::localinit_vf, |
1615 delete vardecl; |
1357 generate_c_vardecl_c::output_vt | |
1616 |
1358 generate_c_vardecl_c::inoutput_vt | |
1617 /* (A.4) Generate private internal variables for SFC */ |
1359 generate_c_vardecl_c::private_vt | |
1618 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol); |
1360 generate_c_vardecl_c::eno_vt); |
1619 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::sfcdecl_sd); |
1361 vardecl->print(symbol->var_declarations_list); |
1620 delete sfcdecl; |
1362 delete vardecl; |
1621 s4o.print("\n"); |
1363 |
1622 |
1364 /* (B.2) Temporary variable for function's return value */ |
1623 /* (A.5) Program data structure type name. */ |
1365 /* It will have the same name as the function itself! */ |
1624 s4o.indent_left(); |
1366 s4o.print(s4o.indent_spaces); |
1625 s4o.print("} "); |
1367 symbol->type_name->accept(*this); /* return type */ |
1626 symbol->program_type_name->accept(print_base); |
1368 s4o.print(" "); |
1627 s4o.print(";\n\n"); |
1369 symbol->derived_function_name->accept(*this); |
1628 } |
1370 s4o.print(" = "); |
1629 |
1371 { |
1630 if (!print_declaration) { |
1372 /* get the default value of this variable's type */ |
1631 /* (A.6) Function Block inline function declaration for function invocation */ |
1373 symbol_c *default_value = type_initial_value_c::get(symbol->type_name); |
1632 generate_c_inlinefcall_c *inlinedecl = new generate_c_inlinefcall_c(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); |
1374 if (default_value == NULL) ERROR; |
1633 symbol->function_block_body->accept(*inlinedecl); |
1375 initialization_analyzer_c initialization_analyzer(default_value); |
1634 delete inlinedecl; |
1376 switch (initialization_analyzer.get_initialization_type()) { |
1635 } |
1377 case initialization_analyzer_c::struct_it: |
1636 |
1378 { |
1637 /* (B) Constructor */ |
1379 generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o); |
1638 /* (B.1) Constructor name... */ |
1380 structure_initialization->init_structure_default(symbol->type_name); |
1639 s4o.print(s4o.indent_spaces + "void "); |
1381 structure_initialization->init_structure_values(default_value); |
1640 symbol->program_type_name->accept(print_base); |
1382 delete structure_initialization; |
1641 s4o.print(FB_INIT_SUFFIX); |
1383 } |
1642 s4o.print("("); |
1384 break; |
1643 |
1385 case initialization_analyzer_c::array_it: |
1644 /* first and only parameter is a pointer to the data */ |
1386 { |
1645 symbol->program_type_name->accept(print_base); |
1387 generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o); |
1646 s4o.print(" *"); |
1388 array_initialization->init_array_size(symbol->type_name); |
1647 s4o.print(FB_FUNCTION_PARAM); |
1389 array_initialization->init_array_values(default_value); |
1648 s4o.print(", BOOL retain)"); |
1390 delete array_initialization; |
1649 |
1391 } |
1650 if (print_declaration) { |
1392 break; |
1651 s4o.print(";\n"); |
1393 default: |
1652 } else { |
1394 default_value->accept(*this); |
1653 s4o.print(" {\n"); |
1395 break; |
1654 s4o.indent_right(); |
1396 } |
1655 |
1397 } |
1656 /* (B.2) Member initializations... */ |
1398 s4o.print(";\n\n"); |
1657 s4o.print(s4o.indent_spaces); |
1399 |
1658 vardecl = new generate_c_vardecl_c(&s4o, |
1400 s4o.print(s4o.indent_spaces + "// Control execution\n"); |
1659 generate_c_vardecl_c::constructorinit_vf, |
1401 s4o.print(s4o.indent_spaces + "if (!EN) {\n"); |
1660 generate_c_vardecl_c::input_vt | |
1402 s4o.indent_right(); |
1661 generate_c_vardecl_c::output_vt | |
1403 s4o.print(s4o.indent_spaces + "if (__ENO != NULL) {\n"); |
1662 generate_c_vardecl_c::inoutput_vt | |
1404 s4o.indent_right(); |
1663 generate_c_vardecl_c::private_vt | |
1405 s4o.print(s4o.indent_spaces + "*__ENO = __BOOL_LITERAL(FALSE);\n"); |
1664 generate_c_vardecl_c::located_vt | |
1406 s4o.indent_left(); |
1665 generate_c_vardecl_c::external_vt); |
1407 s4o.print(s4o.indent_spaces + "}\n"); |
1666 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
1408 s4o.print(s4o.indent_spaces + "return "); |
1667 delete vardecl; |
1409 symbol->derived_function_name->accept(*this); |
1668 s4o.print("\n"); |
1410 s4o.print(";\n"); |
1669 |
1411 s4o.indent_left(); |
1670 /* (B.3) Generate private internal variables for SFC */ |
1412 s4o.print(s4o.indent_spaces + "}\n"); |
1671 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
1413 |
1672 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::sfcinit_sd); |
1414 /* (C) Function body */ |
1673 delete sfcdecl; |
1415 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol); |
1674 |
1416 symbol->function_body->accept(generate_c_code); |
1675 s4o.indent_left(); |
1417 |
1676 s4o.print(s4o.indent_spaces + "}\n\n"); |
1418 print_end_of_block_label(); |
1677 } |
1419 |
1678 |
1420 vardecl = new generate_c_vardecl_c(&s4o, |
1679 if (!print_declaration) { |
1421 generate_c_vardecl_c::foutputassign_vf, |
1680 /* (C) Function with PROGRAM body */ |
1422 generate_c_vardecl_c::output_vt | |
1681 /* (C.1) Step definitions */ |
1423 generate_c_vardecl_c::inoutput_vt | |
1682 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
1424 generate_c_vardecl_c::eno_vt); |
1683 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::stepdef_sd); |
1425 vardecl->print(symbol->var_declarations_list); |
1684 |
1426 delete vardecl; |
1685 /* (C.2) Action definitions */ |
1427 |
1686 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::actiondef_sd); |
1428 s4o.print(s4o.indent_spaces + "return "); |
1687 delete sfcdecl; |
1429 symbol->derived_function_name->accept(*this); |
1688 } |
1430 s4o.print(";\n"); |
1689 |
1431 s4o.indent_left(); |
1690 /* (C.3) Function declaration */ |
1432 s4o.print(s4o.indent_spaces + "}\n\n\n"); |
1691 s4o.print("// Code part\n"); |
1433 |
1692 /* function interface */ |
1434 return NULL; |
1693 s4o.print("void "); |
1435 } |
1694 symbol->program_type_name->accept(print_base); |
1436 |
1695 s4o.print(FB_FUNCTION_SUFFIX); |
1437 |
1696 s4o.print("("); |
1438 /* The remaining var_declarations_list_c, function_var_decls_c |
1697 /* first and only parameter is a pointer to the data */ |
1439 * and var2_init_decl_list_c are handled in the generate_c_vardecl_c class |
1698 symbol->program_type_name->accept(print_base); |
1440 */ |
1699 s4o.print(" *"); |
1441 |
1700 s4o.print(FB_FUNCTION_PARAM); |
1442 |
1701 s4o.print(")"); |
1443 /*****************************/ |
1702 |
1444 /* B 1.5.2 - Function Blocks */ |
1703 if (print_declaration) { |
1445 /*****************************/ |
1704 s4o.print(";\n"); |
1446 public: |
1705 } else { |
1447 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
1706 s4o.print(" {\n"); |
1448 //SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) |
1707 s4o.indent_right(); |
1449 void *visit(function_block_declaration_c *symbol) { |
1708 |
1450 generate_c_vardecl_c *vardecl; |
1709 /* (C.4) Initialize TEMP variables */ |
1451 generate_c_sfcdecl_c *sfcdecl; |
1710 /* function body */ |
1452 generate_c_typedecl_c *typedecl; |
1711 s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n"); |
1453 generate_c_inlinefcall_c *inlinedecl; |
1712 vardecl = new generate_c_vardecl_c(&s4o, |
1454 TRACE("function_block_declaration_c"); |
1713 generate_c_vardecl_c::init_vf, |
1455 |
1714 generate_c_vardecl_c::temp_vt); |
1456 /* (A) Function Block data structure declaration... */ |
1715 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
1457 typedecl = new generate_c_typedecl_c(&s4o_incl); |
1716 delete vardecl; |
1458 /* (A.1) Data structure declaration */ |
1717 s4o.print("\n"); |
1459 s4o_incl.print("// FUNCTION_BLOCK "); |
1718 |
1460 symbol->fblock_name->accept(*typedecl); |
1719 /* (C.5) Function code */ |
1461 s4o_incl.print("\n// Data part\n"); |
1720 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); |
1462 s4o_incl.print("typedef struct {\n"); |
1721 symbol->function_block_body->accept(generate_c_code); |
1463 s4o_incl.indent_right(); |
1722 print_end_of_block_label(s4o); |
1464 /* (A.2) Public variables: i.e. the function parameters... */ |
1723 s4o.print(s4o.indent_spaces + "return;\n"); |
1465 s4o_incl.print(s4o_incl.indent_spaces + "// FB Interface - IN, OUT, IN_OUT variables\n"); |
1724 s4o.indent_left(); |
1466 vardecl = new generate_c_vardecl_c(&s4o_incl, |
1725 s4o.print(s4o.indent_spaces + "} // "); |
1467 generate_c_vardecl_c::local_vf, |
1726 symbol->program_type_name->accept(print_base); |
1468 generate_c_vardecl_c::input_vt | |
1727 s4o.print(FB_FUNCTION_SUFFIX); |
1469 generate_c_vardecl_c::output_vt | |
1728 s4o.print(s4o.indent_spaces + "() \n\n"); |
1470 generate_c_vardecl_c::inoutput_vt | |
1729 |
1471 generate_c_vardecl_c::en_vt | |
1730 /* (C.6) Step undefinitions */ |
1472 generate_c_vardecl_c::eno_vt); |
1731 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
1473 vardecl->print(symbol->var_declarations); |
1732 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::stepundef_sd); |
1474 delete vardecl; |
1733 |
1475 s4o_incl.print("\n"); |
1734 /* (C.7) Action undefinitions */ |
1476 /* (A.3) Private internal variables */ |
1735 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::actionundef_sd); |
1477 s4o_incl.print(s4o_incl.indent_spaces + "// FB private variables - TEMP, private and located variables\n"); |
1736 delete sfcdecl; |
1478 vardecl = new generate_c_vardecl_c(&s4o_incl, |
1737 |
1479 generate_c_vardecl_c::local_vf, |
1738 s4o.indent_left(); |
1480 generate_c_vardecl_c::temp_vt | |
1739 s4o.print("\n\n\n\n"); |
1481 generate_c_vardecl_c::private_vt | |
1740 } |
1482 generate_c_vardecl_c::located_vt | |
1741 return; |
1483 generate_c_vardecl_c::external_vt); |
1742 } |
1484 vardecl->print(symbol->var_declarations); |
|
1485 delete vardecl; |
|
1486 |
|
1487 /* (A.4) Generate private internal variables for SFC */ |
|
1488 sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, symbol); |
|
1489 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::sfcdecl_sd); |
|
1490 delete sfcdecl; |
|
1491 s4o_incl.print("\n"); |
|
1492 |
|
1493 /* (A.5) Function Block data structure type name. */ |
|
1494 s4o_incl.indent_left(); |
|
1495 s4o_incl.print("} "); |
|
1496 symbol->fblock_name->accept(*typedecl); |
|
1497 s4o_incl.print(";\n\n"); |
|
1498 delete typedecl; |
|
1499 |
|
1500 /* (A.6) Function Block inline function declaration for function invocation */ |
|
1501 inlinedecl = new generate_c_inlinefcall_c(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); |
|
1502 symbol->fblock_body->accept(*inlinedecl); |
|
1503 delete inlinedecl; |
|
1504 |
|
1505 /* (B) Constructor */ |
|
1506 /* (B.1) Constructor name... */ |
|
1507 s4o.print(s4o.indent_spaces + "void "); |
|
1508 symbol->fblock_name->accept(*this); |
|
1509 s4o.print(FB_INIT_SUFFIX); |
|
1510 s4o.print("("); |
|
1511 |
|
1512 /* first and only parameter is a pointer to the data */ |
|
1513 symbol->fblock_name->accept(*this); |
|
1514 s4o.print(" *"); |
|
1515 s4o.print(FB_FUNCTION_PARAM); |
|
1516 s4o.print(", BOOL retain) {\n"); |
|
1517 s4o.indent_right(); |
|
1518 |
|
1519 /* (B.2) Member initializations... */ |
|
1520 s4o.print(s4o.indent_spaces); |
|
1521 vardecl = new generate_c_vardecl_c(&s4o, |
|
1522 generate_c_vardecl_c::constructorinit_vf, |
|
1523 generate_c_vardecl_c::input_vt | |
|
1524 generate_c_vardecl_c::output_vt | |
|
1525 generate_c_vardecl_c::inoutput_vt | |
|
1526 generate_c_vardecl_c::private_vt | |
|
1527 generate_c_vardecl_c::located_vt | |
|
1528 generate_c_vardecl_c::external_vt | |
|
1529 generate_c_vardecl_c::en_vt | |
|
1530 generate_c_vardecl_c::eno_vt); |
|
1531 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
|
1532 delete vardecl; |
|
1533 s4o.print("\n"); |
|
1534 |
|
1535 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
|
1536 |
|
1537 /* (B.3) Generate private internal variables for SFC */ |
|
1538 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::sfcinit_sd); |
|
1539 |
|
1540 s4o.indent_left(); |
|
1541 s4o.print(s4o.indent_spaces + "}\n\n"); |
|
1542 |
|
1543 |
|
1544 /* (C) Function with FB body */ |
|
1545 /* (C.1) Step definitions */ |
|
1546 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::stepdef_sd); |
|
1547 |
|
1548 /* (C.2) Action definitions */ |
|
1549 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::actiondef_sd); |
|
1550 |
|
1551 /* (C.3) Function declaration */ |
|
1552 s4o.print("// Code part\n"); |
|
1553 /* function interface */ |
|
1554 s4o.print("void "); |
|
1555 symbol->fblock_name->accept(*this); |
|
1556 s4o.print(FB_FUNCTION_SUFFIX); |
|
1557 s4o.print("("); |
|
1558 /* first and only parameter is a pointer to the data */ |
|
1559 symbol->fblock_name->accept(*this); |
|
1560 s4o.print(" *"); |
|
1561 s4o.print(FB_FUNCTION_PARAM); |
|
1562 s4o.print(") {\n"); |
|
1563 s4o.indent_right(); |
|
1564 |
|
1565 s4o.print(s4o.indent_spaces + "// Control execution\n"); |
|
1566 s4o.print(s4o.indent_spaces + "if (!"); |
|
1567 s4o.print(GET_VAR); |
|
1568 s4o.print("("); |
|
1569 s4o.print(FB_FUNCTION_PARAM); |
|
1570 s4o.print("->EN)) {\n"); |
|
1571 s4o.indent_right(); |
|
1572 s4o.print(s4o.indent_spaces); |
|
1573 s4o.print(SET_VAR); |
|
1574 s4o.print("("); |
|
1575 s4o.print(FB_FUNCTION_PARAM); |
|
1576 s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n"); |
|
1577 s4o.print(s4o.indent_spaces + "return;\n"); |
|
1578 s4o.indent_left(); |
|
1579 s4o.print(s4o.indent_spaces + "}\n"); |
|
1580 s4o.print(s4o.indent_spaces + "else {\n"); |
|
1581 s4o.indent_right(); |
|
1582 s4o.print(s4o.indent_spaces); |
|
1583 s4o.print(SET_VAR); |
|
1584 s4o.print("("); |
|
1585 s4o.print(FB_FUNCTION_PARAM); |
|
1586 s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n"); |
|
1587 s4o.indent_left(); |
|
1588 s4o.print(s4o.indent_spaces + "}\n"); |
|
1589 |
|
1590 /* (C.4) Initialize TEMP variables */ |
|
1591 /* function body */ |
|
1592 s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n"); |
|
1593 vardecl = new generate_c_vardecl_c(&s4o, |
|
1594 generate_c_vardecl_c::init_vf, |
|
1595 generate_c_vardecl_c::temp_vt); |
|
1596 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
|
1597 delete vardecl; |
|
1598 s4o.print("\n"); |
|
1599 |
|
1600 /* (C.5) Function code */ |
|
1601 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); |
|
1602 symbol->fblock_body->accept(generate_c_code); |
|
1603 print_end_of_block_label(); |
|
1604 s4o.print(s4o.indent_spaces + "return;\n"); |
|
1605 s4o.indent_left(); |
|
1606 s4o.print(s4o.indent_spaces + "} // "); |
|
1607 symbol->fblock_name->accept(*this); |
|
1608 s4o.print(FB_FUNCTION_SUFFIX); |
|
1609 s4o.print(s4o.indent_spaces + "() \n\n"); |
|
1610 |
|
1611 /* (C.6) Step undefinitions */ |
|
1612 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::stepundef_sd); |
|
1613 |
|
1614 /* (C.7) Action undefinitions */ |
|
1615 sfcdecl->generate(symbol->fblock_body, generate_c_sfcdecl_c::actionundef_sd); |
|
1616 |
|
1617 delete sfcdecl; |
|
1618 |
|
1619 s4o.indent_left(); |
|
1620 s4o.print("\n\n\n\n"); |
|
1621 |
|
1622 return NULL; |
|
1623 } |
|
1624 |
|
1625 |
|
1626 /* The remaining temp_var_decls_c, temp_var_decls_list_c |
|
1627 * and non_retentive_var_decls_c are handled in the generate_c_vardecl_c class |
|
1628 */ |
|
1629 |
|
1630 |
|
1631 /**********************/ |
|
1632 /* B 1.5.3 - Programs */ |
|
1633 /**********************/ |
|
1634 |
|
1635 |
|
1636 |
|
1637 public: |
|
1638 /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ |
|
1639 //SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused) |
|
1640 void *visit(program_declaration_c *symbol) { |
|
1641 generate_c_vardecl_c *vardecl; |
|
1642 generate_c_sfcdecl_c *sfcdecl; |
|
1643 generate_c_typedecl_c *typedecl; |
|
1644 generate_c_inlinefcall_c *inlinedecl; |
|
1645 TRACE("program_declaration_c"); |
|
1646 |
|
1647 /* (A) Program data structure declaration... */ |
|
1648 typedecl = new generate_c_typedecl_c(&s4o_incl); |
|
1649 /* (A.1) Data structure declaration */ |
|
1650 s4o_incl.print("// PROGRAM "); |
|
1651 symbol->program_type_name->accept(*typedecl); |
|
1652 s4o_incl.print("\n// Data part\n"); |
|
1653 s4o_incl.print("typedef struct {\n"); |
|
1654 s4o_incl.indent_right(); |
|
1655 |
|
1656 /* (A.2) Public variables: i.e. the program parameters... */ |
|
1657 s4o_incl.print(s4o_incl.indent_spaces + "// PROGRAM Interface - IN, OUT, IN_OUT variables\n"); |
|
1658 vardecl = new generate_c_vardecl_c(&s4o_incl, |
|
1659 generate_c_vardecl_c::local_vf, |
|
1660 generate_c_vardecl_c::input_vt | |
|
1661 generate_c_vardecl_c::output_vt | |
|
1662 generate_c_vardecl_c::inoutput_vt); |
|
1663 vardecl->print(symbol->var_declarations); |
|
1664 delete vardecl; |
|
1665 s4o_incl.print("\n"); |
|
1666 /* (A.3) Private internal variables */ |
|
1667 s4o_incl.print(s4o_incl.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n"); |
|
1668 vardecl = new generate_c_vardecl_c(&s4o_incl, |
|
1669 generate_c_vardecl_c::local_vf, |
|
1670 generate_c_vardecl_c::temp_vt | |
|
1671 generate_c_vardecl_c::private_vt | |
|
1672 generate_c_vardecl_c::located_vt | |
|
1673 generate_c_vardecl_c::external_vt); |
|
1674 vardecl->print(symbol->var_declarations); |
|
1675 delete vardecl; |
|
1676 |
|
1677 /* (A.4) Generate private internal variables for SFC */ |
|
1678 sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, symbol); |
|
1679 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::sfcdecl_sd); |
|
1680 delete sfcdecl; |
|
1681 s4o_incl.print("\n"); |
|
1682 |
|
1683 /* (A.5) Program data structure type name. */ |
|
1684 s4o_incl.indent_left(); |
|
1685 s4o_incl.print("} "); |
|
1686 symbol->program_type_name->accept(*typedecl); |
|
1687 s4o_incl.print(";\n\n"); |
|
1688 delete typedecl; |
|
1689 |
|
1690 /* (A.6) Function Block inline function declaration for function invocation */ |
|
1691 inlinedecl = new generate_c_inlinefcall_c(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); |
|
1692 symbol->function_block_body->accept(*inlinedecl); |
|
1693 delete inlinedecl; |
|
1694 |
|
1695 /* (B) Constructor */ |
|
1696 /* (B.1) Constructor name... */ |
|
1697 s4o.print(s4o.indent_spaces + "void "); |
|
1698 symbol->program_type_name->accept(*this); |
|
1699 s4o.print(FB_INIT_SUFFIX); |
|
1700 s4o.print("("); |
|
1701 |
|
1702 /* first and only parameter is a pointer to the data */ |
|
1703 symbol->program_type_name->accept(*this); |
|
1704 s4o.print(" *"); |
|
1705 s4o.print(FB_FUNCTION_PARAM); |
|
1706 s4o.print(", BOOL retain) {\n"); |
|
1707 s4o.indent_right(); |
|
1708 |
|
1709 /* (B.2) Member initializations... */ |
|
1710 s4o.print(s4o.indent_spaces); |
|
1711 vardecl = new generate_c_vardecl_c(&s4o, |
|
1712 generate_c_vardecl_c::constructorinit_vf, |
|
1713 generate_c_vardecl_c::input_vt | |
|
1714 generate_c_vardecl_c::output_vt | |
|
1715 generate_c_vardecl_c::inoutput_vt | |
|
1716 generate_c_vardecl_c::private_vt | |
|
1717 generate_c_vardecl_c::located_vt | |
|
1718 generate_c_vardecl_c::external_vt); |
|
1719 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
|
1720 delete vardecl; |
|
1721 s4o.print("\n"); |
|
1722 |
|
1723 sfcdecl = new generate_c_sfcdecl_c(&s4o, symbol, FB_FUNCTION_PARAM"->"); |
|
1724 |
|
1725 /* (B.3) Generate private internal variables for SFC */ |
|
1726 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::sfcinit_sd); |
|
1727 |
|
1728 s4o.indent_left(); |
|
1729 s4o.print(s4o.indent_spaces + "}\n\n"); |
|
1730 |
|
1731 /* (C) Function with PROGRAM body */ |
|
1732 /* (C.1) Step definitions */ |
|
1733 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::stepdef_sd); |
|
1734 |
|
1735 /* (C.2) Action definitions */ |
|
1736 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::actiondef_sd); |
|
1737 |
|
1738 /* (C.3) Function declaration */ |
|
1739 s4o.print("// Code part\n"); |
|
1740 /* function interface */ |
|
1741 s4o.print("void "); |
|
1742 symbol->program_type_name->accept(*this); |
|
1743 s4o.print(FB_FUNCTION_SUFFIX); |
|
1744 s4o.print("("); |
|
1745 /* first and only parameter is a pointer to the data */ |
|
1746 symbol->program_type_name->accept(*this); |
|
1747 s4o.print(" *"); |
|
1748 s4o.print(FB_FUNCTION_PARAM); |
|
1749 s4o.print(") {\n"); |
|
1750 s4o.indent_right(); |
|
1751 |
|
1752 /* (C.4) Initialize TEMP variables */ |
|
1753 /* function body */ |
|
1754 s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n"); |
|
1755 vardecl = new generate_c_vardecl_c(&s4o, |
|
1756 generate_c_vardecl_c::init_vf, |
|
1757 generate_c_vardecl_c::temp_vt); |
|
1758 vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); |
|
1759 delete vardecl; |
|
1760 s4o.print("\n"); |
|
1761 |
|
1762 /* (C.5) Function code */ |
|
1763 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); |
|
1764 symbol->function_block_body->accept(generate_c_code); |
|
1765 print_end_of_block_label(); |
|
1766 s4o.print(s4o.indent_spaces + "return;\n"); |
|
1767 s4o.indent_left(); |
|
1768 s4o.print(s4o.indent_spaces + "} // "); |
|
1769 symbol->program_type_name->accept(*this); |
|
1770 s4o.print(FB_FUNCTION_SUFFIX); |
|
1771 s4o.print(s4o.indent_spaces + "() \n\n"); |
|
1772 |
|
1773 /* (C.6) Step undefinitions */ |
|
1774 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::stepundef_sd); |
|
1775 |
|
1776 /* (C.7) Action undefinitions */ |
|
1777 sfcdecl->generate(symbol->function_block_body, generate_c_sfcdecl_c::actionundef_sd); |
|
1778 |
|
1779 delete sfcdecl; |
|
1780 |
|
1781 s4o.indent_left(); |
|
1782 s4o.print("\n\n\n\n"); |
|
1783 |
|
1784 return NULL; |
|
1785 } |
|
1786 |
|
1787 }; /* generate_c_pous_c */ |
1743 }; /* generate_c_pous_c */ |
1788 |
1744 |
|
1745 |
1789 /***********************************************************************/ |
1746 /***********************************************************************/ |
1790 /***********************************************************************/ |
1747 /***********************************************************************/ |
1791 /***********************************************************************/ |
1748 /***********************************************************************/ |
1792 /***********************************************************************/ |
1749 /***********************************************************************/ |
1793 /***********************************************************************/ |
1750 /***********************************************************************/ |
2635 /********************************/ |
2576 /********************************/ |
2636 /* B 1.3.3 - Derived data types */ |
2577 /* B 1.3.3 - Derived data types */ |
2637 /********************************/ |
2578 /********************************/ |
2638 /* TYPE type_declaration_list END_TYPE */ |
2579 /* TYPE type_declaration_list END_TYPE */ |
2639 void *visit(data_type_declaration_c *symbol) { |
2580 void *visit(data_type_declaration_c *symbol) { |
2640 switch (current_mode) { |
2581 symbol->accept(generate_c_datatypes); |
2641 case datatypes_gm: |
|
2642 symbol->accept(generate_c_datatypes); |
|
2643 break; |
|
2644 default: |
|
2645 break; |
|
2646 } |
|
2647 return NULL; |
2582 return NULL; |
2648 } |
2583 } |
2649 |
2584 |
2650 /**************************************/ |
2585 /**************************************/ |
2651 /* B.1.5 - Program organization units */ |
2586 /* B.1.5 - Program organization units */ |
2652 /**************************************/ |
2587 /**************************************/ |
2653 /***********************/ |
2588 /***********************/ |
2654 /* B 1.5.1 - Functions */ |
2589 /* B 1.5.1 - Functions */ |
2655 /***********************/ |
2590 /***********************/ |
2656 void *visit(function_declaration_c *symbol) { |
2591 void *visit(function_declaration_c *symbol) { |
2657 switch (current_mode) { |
2592 symbol->var_declarations_list->accept(generate_c_datatypes); |
2658 case datatypes_gm: |
2593 generate_c_pous_c::handle_function(symbol, pous_incl_s4o, true); |
2659 symbol->var_declarations_list->accept(generate_c_datatypes); |
2594 generate_c_pous_c::handle_function(symbol, pous_s4o, false); |
2660 break; |
|
2661 case pous_gm: |
|
2662 symbol->accept(generate_c_pous); |
|
2663 break; |
|
2664 default: |
|
2665 break; |
|
2666 } |
|
2667 return NULL; |
2595 return NULL; |
2668 } |
2596 } |
2669 |
2597 |
2670 /*****************************/ |
2598 /*****************************/ |
2671 /* B 1.5.2 - Function Blocks */ |
2599 /* B 1.5.2 - Function Blocks */ |
2672 /*****************************/ |
2600 /*****************************/ |
2673 void *visit(function_block_declaration_c *symbol) { |
2601 void *visit(function_block_declaration_c *symbol) { |
2674 switch (current_mode) { |
2602 symbol->var_declarations->accept(generate_c_datatypes); |
2675 case datatypes_gm: |
2603 generate_c_pous_c::handle_function_block(symbol, pous_incl_s4o, true); |
2676 symbol->var_declarations->accept(generate_c_datatypes); |
2604 generate_c_pous_c::handle_function_block(symbol, pous_s4o, false); |
2677 break; |
2605 return NULL; |
2678 case pous_gm: |
|
2679 symbol->accept(generate_c_pous); |
|
2680 break; |
|
2681 default: |
|
2682 break; |
|
2683 } |
|
2684 return NULL; |
|
2685 } |
2606 } |
2686 |
2607 |
2687 /**********************/ |
2608 /**********************/ |
2688 /* B 1.5.3 - Programs */ |
2609 /* B 1.5.3 - Programs */ |
2689 /**********************/ |
2610 /**********************/ |
2690 void *visit(program_declaration_c *symbol) { |
2611 void *visit(program_declaration_c *symbol) { |
2691 switch (current_mode) { |
2612 symbol->var_declarations->accept(generate_c_datatypes); |
2692 case datatypes_gm: |
2613 generate_c_pous_c::handle_program(symbol, pous_incl_s4o, true); |
2693 symbol->var_declarations->accept(generate_c_datatypes); |
2614 generate_c_pous_c::handle_program(symbol, pous_s4o, false); |
2694 break; |
2615 return NULL; |
2695 case pous_gm: |
|
2696 symbol->accept(generate_c_pous); |
|
2697 break; |
|
2698 default: |
|
2699 break; |
|
2700 } |
|
2701 return NULL; |
|
2702 } |
2616 } |
2703 |
2617 |
2704 |
2618 |
2705 /********************************/ |
2619 /********************************/ |
2706 /* B 1.7 Configuration elements */ |
2620 /* B 1.7 Configuration elements */ |
2707 /********************************/ |
2621 /********************************/ |
2708 void *visit(configuration_declaration_c *symbol) { |
2622 void *visit(configuration_declaration_c *symbol) { |
2709 switch (current_mode) { |
2623 if (symbol->global_var_declarations != NULL) |
2710 case datatypes_gm: |
2624 symbol->global_var_declarations->accept(generate_c_datatypes); |
2711 if (symbol->global_var_declarations != NULL) |
2625 static int configuration_count = 0; |
2712 symbol->global_var_declarations->accept(generate_c_datatypes); |
2626 |
2713 break; |
2627 if (configuration_count++) { |
2714 |
2628 /* the first configuration is the one we will use!! */ |
2715 case pous_gm: |
2629 STAGE4_ERROR(symbol, symbol, "A previous CONFIGURATION has already been declared (C code generation currently only allows a single configuration)."); |
2716 static int configuration_count = 0; |
2630 ERROR; |
2717 |
2631 } |
2718 if (configuration_count++) { |
2632 |
2719 /* the first configuration is the one we will use!! */ |
2633 current_configuration = symbol; |
2720 STAGE4_ERROR(symbol, symbol, "A previous CONFIGURATION has already been declared (C code generation currently only allows a single configuration)."); |
2634 |
2721 ERROR; |
2635 { |
2722 } |
2636 calculate_common_ticktime_c calculate_common_ticktime; |
2723 |
2637 symbol->accept(calculate_common_ticktime); |
2724 current_configuration = symbol; |
2638 common_ticktime = calculate_common_ticktime.get_common_ticktime(); |
2725 |
2639 if (common_ticktime == 0) { |
2726 { |
2640 STAGE4_ERROR(symbol, symbol, "You must define at least one periodic task (to set cycle period)!"); |
2727 calculate_common_ticktime_c calculate_common_ticktime; |
2641 ERROR; |
2728 symbol->accept(calculate_common_ticktime); |
2642 } |
2729 common_ticktime = calculate_common_ticktime.get_common_ticktime(); |
2643 |
2730 if (common_ticktime == 0) { |
2644 symbol->configuration_name->accept(*this); |
2731 STAGE4_ERROR(symbol, symbol, "You must define at least one periodic task (to set cycle period)!"); |
2645 |
2732 ERROR; |
2646 stage4out_c config_s4o(current_builddir, current_name, "c"); |
2733 } |
2647 stage4out_c config_incl_s4o(current_builddir, current_name, "h"); |
2734 |
2648 generate_c_config_c generate_c_config(&config_s4o, &config_incl_s4o); |
2735 symbol->configuration_name->accept(*this); |
2649 symbol->accept(generate_c_config); |
2736 |
2650 |
2737 stage4out_c config_s4o(current_builddir, current_name, "c"); |
2651 config_s4o.print("unsigned long long common_ticktime__ = "); |
2738 stage4out_c config_incl_s4o(current_builddir, current_name, "h"); |
2652 config_s4o.print_long_long_integer(common_ticktime); |
2739 generate_c_config_c generate_c_config(&config_s4o, &config_incl_s4o); |
2653 config_s4o.print("; /*ns*/\n"); |
2740 symbol->accept(generate_c_config); |
2654 config_s4o.print("unsigned long greatest_tick_count__ = "); |
2741 |
2655 config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count()); |
2742 config_s4o.print("unsigned long long common_ticktime__ = "); |
2656 config_s4o.print("; /*tick*/\n"); |
2743 config_s4o.print_long_long_integer(common_ticktime); |
2657 } |
2744 config_s4o.print("; /*ns*/\n"); |
2658 |
2745 config_s4o.print("unsigned long greatest_tick_count__ = "); |
2659 symbol->resource_declarations->accept(*this); |
2746 config_s4o.print_long_integer(calculate_common_ticktime.get_greatest_tick_count()); |
2660 |
2747 config_s4o.print("; /*tick*/\n"); |
2661 current_configuration = NULL; |
2748 } |
|
2749 |
|
2750 symbol->resource_declarations->accept(*this); |
|
2751 |
|
2752 current_configuration = NULL; |
|
2753 break; |
|
2754 |
|
2755 default: |
|
2756 break; |
|
2757 } |
|
2758 return NULL; |
2662 return NULL; |
2759 } |
2663 } |
2760 |
2664 |
2761 void *visit(resource_declaration_c *symbol) { |
2665 void *visit(resource_declaration_c *symbol) { |
2762 switch (current_mode) { |
2666 if (symbol->global_var_declarations != NULL) |
2763 case datatypes_gm: |
2667 symbol->global_var_declarations->accept(generate_c_datatypes); |
2764 if (symbol->global_var_declarations != NULL) |
2668 symbol->resource_name->accept(*this); |
2765 symbol->global_var_declarations->accept(generate_c_datatypes); |
2669 stage4out_c resources_s4o(current_builddir, current_name, "c"); |
2766 break; |
2670 generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); |
2767 case pous_gm: |
2671 symbol->accept(generate_c_resources); |
2768 symbol->resource_name->accept(*this); |
|
2769 { |
|
2770 stage4out_c resources_s4o(current_builddir, current_name, "c"); |
|
2771 generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); |
|
2772 symbol->accept(generate_c_resources); |
|
2773 } |
|
2774 break; |
|
2775 default: |
|
2776 break; |
|
2777 } |
|
2778 return NULL; |
2672 return NULL; |
2779 } |
2673 } |
2780 |
2674 |
2781 void *visit(single_resource_declaration_c *symbol) { |
2675 void *visit(single_resource_declaration_c *symbol) { |
2782 switch (current_mode) { |
2676 stage4out_c resources_s4o(current_builddir, "RESOURCE", "c"); |
2783 case pous_gm: |
2677 generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); |
2784 { |
2678 symbol->accept(generate_c_resources); |
2785 stage4out_c resources_s4o(current_builddir, "RESOURCE", "c"); |
|
2786 generate_c_resources_c generate_c_resources(&resources_s4o, current_configuration, symbol, common_ticktime); |
|
2787 symbol->accept(generate_c_resources); |
|
2788 } |
|
2789 break; |
|
2790 default: |
|
2791 break; |
|
2792 } |
|
2793 return NULL; |
2679 return NULL; |
2794 } |
2680 } |
2795 |
2681 |
2796 }; |
2682 }; |
2797 |
2683 |