134 */ |
134 */ |
135 #define VAR_LEADER "__" |
135 #define VAR_LEADER "__" |
136 #define TEMP_VAR VAR_LEADER "TMP_" |
136 #define TEMP_VAR VAR_LEADER "TMP_" |
137 #define SOURCE_VAR VAR_LEADER "SRC_" |
137 #define SOURCE_VAR VAR_LEADER "SRC_" |
138 |
138 |
|
139 /* please see the comment before the RET_operator_c visitor for details... */ |
|
140 #define END_LABEL VAR_LEADER "end" |
|
141 |
|
142 |
139 /***********************************************************************/ |
143 /***********************************************************************/ |
140 /***********************************************************************/ |
144 /***********************************************************************/ |
141 /***********************************************************************/ |
145 /***********************************************************************/ |
142 /***********************************************************************/ |
146 /***********************************************************************/ |
143 |
147 |
423 generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
427 generate_c_pous_c(stage4out_c *s4o_ptr, stage4out_c *s4o_incl_ptr) |
424 : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { |
428 : generate_c_typedecl_c(s4o_ptr, s4o_incl_ptr) { |
425 generate_c_pous_c::s4o_ptr = s4o_ptr; |
429 generate_c_pous_c::s4o_ptr = s4o_ptr; |
426 }; |
430 }; |
427 virtual ~generate_c_pous_c(void) {} |
431 virtual ~generate_c_pous_c(void) {} |
|
432 |
|
433 private: |
|
434 void print_end_of_block_label(void) { |
|
435 /* Print and __end label for return statements! |
|
436 * If label is not used by at least one goto, compiler will generate a warning. |
|
437 * To work around this we introduce the useless goto. |
|
438 */ |
|
439 s4o.print("\n"); |
|
440 s4o.print(s4o.indent_spaces); |
|
441 s4o.print("/* to humour the compiler, we insert a goto */\n"); |
|
442 s4o.print(s4o.indent_spaces); |
|
443 s4o.print("goto "); |
|
444 s4o.print(END_LABEL); |
|
445 s4o.print(";\n"); |
|
446 s4o.indent_left(); |
|
447 |
|
448 /* write the label marking the end of the code block */ |
|
449 /* please see the comment before the RET_operator_c visitor for details... */ |
|
450 /* also needed for return_statement_c */ |
|
451 s4o.print("\n"); |
|
452 s4o.print(s4o.indent_spaces); |
|
453 s4o.print(END_LABEL); |
|
454 s4o.print(":\n"); |
|
455 s4o.indent_right(); |
|
456 |
|
457 /* since every label must be followed by at least one statement, and |
|
458 * only the functions will introduce the return statement after this label, |
|
459 * function blocks written in IL would result in invalid C++ code. |
|
460 * To work around this we introduce the equivalent of a 'nop' operation |
|
461 * to humour the compiler... |
|
462 */ |
|
463 s4o.print(s4o.indent_spaces); |
|
464 s4o.print("/* to humour the compiler, we insert a nop */\n"); |
|
465 s4o.print(s4o.indent_spaces); |
|
466 s4o.print("if (0);\n\n"); |
|
467 } |
|
468 |
428 |
469 |
429 |
470 |
430 public: |
471 public: |
431 /********************/ |
472 /********************/ |
432 /* 2.1.6 - Pragmas */ |
473 /* 2.1.6 - Pragmas */ |
590 s4o.print(s4o.indent_spaces + "}\n"); |
631 s4o.print(s4o.indent_spaces + "}\n"); |
591 |
632 |
592 /* (C) Function body */ |
633 /* (C) Function body */ |
593 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol); |
634 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol); |
594 symbol->function_body->accept(generate_c_code); |
635 symbol->function_body->accept(generate_c_code); |
|
636 |
|
637 print_end_of_block_label(); |
595 |
638 |
596 vardecl = new generate_c_vardecl_c(&s4o, |
639 vardecl = new generate_c_vardecl_c(&s4o, |
597 generate_c_vardecl_c::foutputassign_vf, |
640 generate_c_vardecl_c::foutputassign_vf, |
598 generate_c_vardecl_c::output_vt | |
641 generate_c_vardecl_c::output_vt | |
599 generate_c_vardecl_c::inoutput_vt | |
642 generate_c_vardecl_c::inoutput_vt | |
774 s4o.print("\n"); |
817 s4o.print("\n"); |
775 |
818 |
776 /* (C.5) Function code */ |
819 /* (C.5) Function code */ |
777 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); |
820 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); |
778 symbol->fblock_body->accept(generate_c_code); |
821 symbol->fblock_body->accept(generate_c_code); |
|
822 print_end_of_block_label(); |
779 s4o.indent_left(); |
823 s4o.indent_left(); |
780 s4o.print(s4o.indent_spaces + "} // "); |
824 s4o.print(s4o.indent_spaces + "} // "); |
781 symbol->fblock_name->accept(*this); |
825 symbol->fblock_name->accept(*this); |
782 s4o.print(FB_FUNCTION_SUFFIX); |
826 s4o.print(FB_FUNCTION_SUFFIX); |
783 s4o.print(s4o.indent_spaces + "() \n\n"); |
827 s4o.print(s4o.indent_spaces + "() \n\n"); |
934 s4o.print("\n"); |
978 s4o.print("\n"); |
935 |
979 |
936 /* (C.5) Function code */ |
980 /* (C.5) Function code */ |
937 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); |
981 generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); |
938 symbol->function_block_body->accept(generate_c_code); |
982 symbol->function_block_body->accept(generate_c_code); |
|
983 print_end_of_block_label(); |
939 s4o.indent_left(); |
984 s4o.indent_left(); |
940 s4o.print(s4o.indent_spaces + "} // "); |
985 s4o.print(s4o.indent_spaces + "} // "); |
941 symbol->program_type_name->accept(*this); |
986 symbol->program_type_name->accept(*this); |
942 s4o.print(FB_FUNCTION_SUFFIX); |
987 s4o.print(FB_FUNCTION_SUFFIX); |
943 s4o.print(s4o.indent_spaces + "() \n\n"); |
988 s4o.print(s4o.indent_spaces + "() \n\n"); |