stage4/generate_c/generate_c.cc
changeset 1021 21a97cdb317d
parent 1007 afb3974f8fb3
parent 1016 91bef6704b44
child 1039 52f63e622604
child 1041 56ebe2a31b5b
equal deleted inserted replaced
1008:59435d4c5e0c 1021:21a97cdb317d
   857       vardecl->print(symbol->var_declarations_list);
   857       vardecl->print(symbol->var_declarations_list);
   858       delete vardecl;
   858       delete vardecl;
   859     
   859     
   860       /* (B.2) Temporary variable for function's return value */
   860       /* (B.2) Temporary variable for function's return value */
   861       /* It will have the same name as the function itself! */
   861       /* It will have the same name as the function itself! */
   862       s4o.print(s4o.indent_spaces);
   862       /* NOTE: matiec supports a non-standard syntax, in which functions do not return a value
   863       symbol->type_name->accept(print_base); /* return type */
   863        *       (declared as returning the special non-standard datatype VOID)
   864       s4o.print(" ");
   864        *       e.g.:   FUNCTION foo: VOID
   865       symbol->derived_function_name->accept(print_base);
   865        *                ...
   866       s4o.print(" = ");
   866        *               END_FUNCTION
   867       {
   867        *       
   868         /* get the default value of this variable's type */
   868        *       These functions cannot return any value, so they do not need a variable to
   869         symbol_c *default_value = type_initial_value_c::get(symbol->type_name);
   869        *       store the return value.
   870         if (default_value == NULL) ERROR;
   870        *       Note that any attemot to sto a value in the implicit variable
   871         initialization_analyzer_c initialization_analyzer(default_value);
   871        *       e.g.:   FUNCTION foo: VOID
   872         switch (initialization_analyzer.get_initialization_type()) {
   872        *                ...
   873           case initialization_analyzer_c::struct_it:
   873        *                 foo := 42;
   874             {
   874        *               END_FUNCTION
   875               generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
   875        *       will always return a datatype incompatilibiyt error in stage 3 of matiec, 
   876               structure_initialization->init_structure_default(symbol->type_name);
   876        *       so it is safe for stage 4 to assume that this return variable will never be needed
   877               structure_initialization->init_structure_values(default_value);
   877        *       if the function's return type is VOID.
   878               delete structure_initialization;
   878        */
   879             }
   879       if (!get_datatype_info_c::is_VOID(symbol->type_name->datatype)) { // only print return variable if return datatype is not VOID
   880             break;
   880         s4o.print(s4o.indent_spaces);
   881           case initialization_analyzer_c::array_it:
   881         symbol->type_name->accept(print_base); /* return type */
   882             {
   882         s4o.print(" ");
   883               generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
   883         symbol->derived_function_name->accept(print_base);
   884               array_initialization->init_array_size(symbol->type_name);
   884         s4o.print(" = ");
   885               array_initialization->init_array_values(default_value);
   885         {
   886               delete array_initialization;
   886           /* get the default value of this variable's type */
   887             }
   887           symbol_c *default_value = type_initial_value_c::get(symbol->type_name);
   888             break;
   888           if (default_value == NULL) ERROR;
   889           default:
   889           initialization_analyzer_c initialization_analyzer(default_value);
   890             default_value->accept(print_base);
   890           switch (initialization_analyzer.get_initialization_type()) {
   891             break;
   891             case initialization_analyzer_c::struct_it:
       
   892               {
       
   893                 generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
       
   894                 structure_initialization->init_structure_default(symbol->type_name);
       
   895                 structure_initialization->init_structure_values(default_value);
       
   896                 delete structure_initialization;
       
   897               }
       
   898               break;
       
   899             case initialization_analyzer_c::array_it:
       
   900               {
       
   901                 generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
       
   902                 array_initialization->init_array_size(symbol->type_name);
       
   903                 array_initialization->init_array_values(default_value);
       
   904                 delete array_initialization;
       
   905               }
       
   906               break;
       
   907             default:
       
   908               default_value->accept(print_base);
       
   909               break;
       
   910           }
   892         }
   911         }
   893       }
   912       }
   894       s4o.print(";\n\n");
   913       s4o.print(";\n\n");
   895       
   914       
   896       s4o.print(s4o.indent_spaces + "// Control execution\n");
   915       
   897       s4o.print(s4o.indent_spaces + "if (!EN) {\n");
   916       // Only generate the code that controls the execution of the function's body if the
   898       s4o.indent_right();
   917       // function contains a declaration of both the EN and ENO variables
   899       s4o.print(s4o.indent_spaces + "if (__ENO != NULL) {\n");
   918       search_var_instance_decl_c search_var(symbol);
   900       s4o.indent_right();
   919       identifier_c  en_var("EN");
   901       s4o.print(s4o.indent_spaces + "*__ENO = __BOOL_LITERAL(FALSE);\n");
   920       identifier_c eno_var("ENO");
   902       s4o.indent_left();
   921       if (   (search_var.get_vartype(& en_var) == search_var_instance_decl_c::input_vt)
   903       s4o.print(s4o.indent_spaces + "}\n");
   922           && (search_var.get_vartype(&eno_var) == search_var_instance_decl_c::output_vt)) {
   904       s4o.print(s4o.indent_spaces + "return ");
   923         s4o.print(s4o.indent_spaces + "// Control execution\n");
   905       symbol->derived_function_name->accept(print_base);
   924         s4o.print(s4o.indent_spaces + "if (!EN) {\n");
   906       s4o.print(";\n");
   925         s4o.indent_right();
   907       s4o.indent_left();
   926         s4o.print(s4o.indent_spaces + "if (__ENO != NULL) {\n");
   908       s4o.print(s4o.indent_spaces + "}\n");
   927         s4o.indent_right();
       
   928         s4o.print(s4o.indent_spaces + "*__ENO = __BOOL_LITERAL(FALSE);\n");
       
   929         s4o.indent_left();
       
   930         s4o.print(s4o.indent_spaces + "}\n");
       
   931         if (!get_datatype_info_c::is_VOID(symbol->type_name->datatype)) { // only print return variable if return datatype is not VOID
       
   932           s4o.print(s4o.indent_spaces + "return ");
       
   933           symbol->derived_function_name->accept(print_base);
       
   934           s4o.print(";\n");
       
   935         }
       
   936         s4o.indent_left();
       
   937         s4o.print(s4o.indent_spaces + "}\n");
       
   938       }
   909     
   939     
   910       /* (C) Function body */
   940       /* (C) Function body */
   911       generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol);
   941       generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol);
   912       symbol->function_body->accept(generate_c_code);
   942       symbol->function_body->accept(generate_c_code);
   913       
   943       
   919                     generate_c_vardecl_c::inoutput_vt |
   949                     generate_c_vardecl_c::inoutput_vt |
   920                     generate_c_vardecl_c::eno_vt);
   950                     generate_c_vardecl_c::eno_vt);
   921       vardecl->print(symbol->var_declarations_list);
   951       vardecl->print(symbol->var_declarations_list);
   922       delete vardecl;
   952       delete vardecl;
   923       
   953       
   924       s4o.print(s4o.indent_spaces + "return ");
   954       if (!get_datatype_info_c::is_VOID(symbol->type_name->datatype)) { // only print 'return <fname>' if return datatype is not VOID
   925       symbol->derived_function_name->accept(print_base);
   955         s4o.print(s4o.indent_spaces + "return ");
   926       s4o.print(";\n");
   956         symbol->derived_function_name->accept(print_base);
       
   957         s4o.print(";\n");
       
   958       }
       
   959 
   927       s4o.indent_left();
   960       s4o.indent_left();
   928       s4o.print(s4o.indent_spaces + "}\n\n\n");
   961       s4o.print(s4o.indent_spaces + "}\n\n\n");
   929     
   962     
   930       return;
   963       return;
   931     }
   964     }
  1069       if (print_declaration) {
  1102       if (print_declaration) {
  1070         s4o.print(";\n");
  1103         s4o.print(";\n");
  1071       } else {
  1104       } else {
  1072         s4o.print(" {\n");
  1105         s4o.print(" {\n");
  1073         s4o.indent_right();
  1106         s4o.indent_right();
  1074       
  1107 
  1075         s4o.print(s4o.indent_spaces + "// Control execution\n");
  1108         // Only generate the code that controls the execution of the function's body if the
  1076         s4o.print(s4o.indent_spaces + "if (!");
  1109         // function contains a declaration of both the EN and ENO variables
  1077         s4o.print(GET_VAR);
  1110         search_var_instance_decl_c search_var(symbol);
  1078         s4o.print("(");
  1111         identifier_c  en_var("EN");
  1079         s4o.print(FB_FUNCTION_PARAM);
  1112         identifier_c eno_var("ENO");
  1080         s4o.print("->EN)) {\n");
  1113         if (   (search_var.get_vartype(& en_var) == search_var_instance_decl_c::input_vt)
  1081         s4o.indent_right();
  1114             && (search_var.get_vartype(&eno_var) == search_var_instance_decl_c::output_vt)) {
  1082         s4o.print(s4o.indent_spaces);
  1115 
  1083         s4o.print(SET_VAR);
  1116           s4o.print(s4o.indent_spaces + "// Control execution\n");
  1084         s4o.print("(");
  1117           s4o.print(s4o.indent_spaces + "if (!");
  1085         s4o.print(FB_FUNCTION_PARAM);
  1118           s4o.print(GET_VAR);
  1086         s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n");
  1119           s4o.print("(");
  1087         s4o.print(s4o.indent_spaces + "return;\n");
  1120           s4o.print(FB_FUNCTION_PARAM);
  1088         s4o.indent_left();
  1121           s4o.print("->EN)) {\n");
  1089         s4o.print(s4o.indent_spaces + "}\n");
  1122           s4o.indent_right();
  1090         s4o.print(s4o.indent_spaces + "else {\n");
  1123           s4o.print(s4o.indent_spaces);
  1091         s4o.indent_right();
  1124           s4o.print(SET_VAR);
  1092         s4o.print(s4o.indent_spaces);
  1125           s4o.print("(");
  1093         s4o.print(SET_VAR);
  1126           s4o.print(FB_FUNCTION_PARAM);
  1094         s4o.print("(");
  1127           s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n");
  1095         s4o.print(FB_FUNCTION_PARAM);
  1128           s4o.print(s4o.indent_spaces + "return;\n");
  1096         s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n");
  1129           s4o.indent_left();
  1097         s4o.indent_left();
  1130           s4o.print(s4o.indent_spaces + "}\n");
  1098         s4o.print(s4o.indent_spaces + "}\n");
  1131           s4o.print(s4o.indent_spaces + "else {\n");
       
  1132           s4o.indent_right();
       
  1133           s4o.print(s4o.indent_spaces);
       
  1134           s4o.print(SET_VAR);
       
  1135           s4o.print("(");
       
  1136           s4o.print(FB_FUNCTION_PARAM);
       
  1137           s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n");
       
  1138           s4o.indent_left();
       
  1139           s4o.print(s4o.indent_spaces + "}\n");
       
  1140         }
  1099       
  1141       
  1100         /* (C.4) Initialize TEMP variables */
  1142         /* (C.4) Initialize TEMP variables */
  1101         /* function body */
  1143         /* function body */
  1102         s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n");
  1144         s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n");
  1103         vardecl = new generate_c_vardecl_c(&s4o,
  1145         vardecl = new generate_c_vardecl_c(&s4o,
  1378   /* Insert the header... */
  1420   /* Insert the header... */
  1379   s4o.print("/*******************************************/\n");
  1421   s4o.print("/*******************************************/\n");
  1380   s4o.print("/*     FILE GENERATED BY iec2c             */\n");
  1422   s4o.print("/*     FILE GENERATED BY iec2c             */\n");
  1381   s4o.print("/* Editing this file is not recommended... */\n");
  1423   s4o.print("/* Editing this file is not recommended... */\n");
  1382   s4o.print("/*******************************************/\n\n");
  1424   s4o.print("/*******************************************/\n\n");
       
  1425   
       
  1426   if (runtime_options.disable_implicit_en_eno) {
       
  1427     // If we are not generating the EN and ENO parameters for functions and FB,
       
  1428     //   then make sure we use the standard library version compiled without these parameters too!
       
  1429     s4o.print("#ifndef DISABLE_EN_ENO_PARAMETERS\n");
       
  1430     s4o.print("#define DISABLE_EN_ENO_PARAMETERS\n");
       
  1431     s4o.print("#endif\n");
       
  1432   }
       
  1433   
  1383   s4o.print("#include \"iec_std_lib.h\"\n\n");
  1434   s4o.print("#include \"iec_std_lib.h\"\n\n");
  1384   s4o.print("#include \"accessor.h\"\n\n"); 
  1435   s4o.print("#include \"accessor.h\"\n\n"); 
  1385   s4o.print("#include \"POUS.h\"\n\n");
  1436   s4o.print("#include \"POUS.h\"\n\n");
  1386 
  1437 
  1387   /* (A) configuration declaration... */
  1438   /* (A) configuration declaration... */
  1683       /* Insert the header... */
  1734       /* Insert the header... */
  1684       s4o.print("/*******************************************/\n");
  1735       s4o.print("/*******************************************/\n");
  1685       s4o.print("/*     FILE GENERATED BY iec2c             */\n");
  1736       s4o.print("/*     FILE GENERATED BY iec2c             */\n");
  1686       s4o.print("/* Editing this file is not recommended... */\n");
  1737       s4o.print("/* Editing this file is not recommended... */\n");
  1687       s4o.print("/*******************************************/\n\n");
  1738       s4o.print("/*******************************************/\n\n");
       
  1739   
       
  1740       if (runtime_options.disable_implicit_en_eno) {
       
  1741         // If we are not generating the EN and ENO parameters for functions and FB,
       
  1742         //   then make sure we use the standard library version compiled without these parameters too!
       
  1743         s4o.print("#ifndef DISABLE_EN_ENO_PARAMETERS\n");
       
  1744         s4o.print("#define DISABLE_EN_ENO_PARAMETERS\n");
       
  1745         s4o.print("#endif\n");
       
  1746       }
       
  1747       
  1688       s4o.print("#include \"iec_std_lib.h\"\n\n");
  1748       s4o.print("#include \"iec_std_lib.h\"\n\n");
  1689       
  1749       
  1690       /* (A) resource declaration... */
  1750       /* (A) resource declaration... */
  1691       /* (A.1) resource name in comment */
  1751       /* (A.1) resource name in comment */
  1692       s4o.print("// RESOURCE ");
  1752       s4o.print("// RESOURCE ");
  2116 
  2176 
  2117 /***************************/
  2177 /***************************/
  2118 /* B 0 - Programming Model */
  2178 /* B 0 - Programming Model */
  2119 /***************************/
  2179 /***************************/
  2120     void *visit(library_c *symbol) {
  2180     void *visit(library_c *symbol) {
  2121       pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n#include \"accessor.h\"\n#include \"iec_std_lib.h\"\n\n");
  2181       pous_incl_s4o.print("#ifndef __POUS_H\n#define __POUS_H\n\n");
       
  2182       
       
  2183       if (runtime_options.disable_implicit_en_eno) {
       
  2184         // If we are not generating the EN and ENO parameters for functions and FB,
       
  2185         //   then make sure we use the standard library version compiled without these parameters too!
       
  2186         pous_incl_s4o.print("#ifndef DISABLE_EN_ENO_PARAMETERS\n");
       
  2187         pous_incl_s4o.print("#define DISABLE_EN_ENO_PARAMETERS\n");
       
  2188         pous_incl_s4o.print("#endif\n");
       
  2189       }
       
  2190       
       
  2191       pous_incl_s4o.print("#include \"accessor.h\"\n#include \"iec_std_lib.h\"\n\n");
  2122 
  2192 
  2123       for(int i = 0; i < symbol->n; i++) {
  2193       for(int i = 0; i < symbol->n; i++) {
  2124         symbol->elements[i]->accept(*this);
  2194         symbol->elements[i]->accept(*this);
  2125       }
  2195       }
  2126 
  2196