stage4/generate_c/generate_c_st.cc
changeset 347 44ff2a6fcadc
parent 344 8f71c46a0a55
child 349 b826f13c260e
equal deleted inserted replaced
346:620fd98a021d 347:44ff2a6fcadc
    50       complextype_base_vg,
    50       complextype_base_vg,
    51       complextype_suffix_vg,
    51       complextype_suffix_vg,
    52       fparam_output_vg
    52       fparam_output_vg
    53     } variablegeneration_t;
    53     } variablegeneration_t;
    54 
    54 
       
    55     typedef enum {
       
    56       single_cg,
       
    57       subrange_cg,
       
    58       none_cg
       
    59     } casegeneration_t;
       
    60 
    55   private:
    61   private:
    56     /* When calling a function block, we must first find it's type,
    62     /* When calling a function block, we must first find it's type,
    57      * by searching through the declarations of the variables currently
    63      * by searching through the declarations of the variables currently
    58      * in scope.
    64      * in scope.
    59      * This class does just that...
    65      * This class does just that...
    86     symbol_c* current_param_type;
    92     symbol_c* current_param_type;
    87 
    93 
    88     int fcall_number;
    94     int fcall_number;
    89     symbol_c *fbname;
    95     symbol_c *fbname;
    90 
    96 
       
    97     bool first_subrange_case_list;
       
    98 
    91     variablegeneration_t wanted_variablegeneration;
    99     variablegeneration_t wanted_variablegeneration;
       
   100     casegeneration_t wanted_casegeneration;
    92 
   101 
    93   public:
   102   public:
    94     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
   103     generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
    95     : generate_c_typedecl_c(s4o_ptr) {
   104     : generate_c_typedecl_c(s4o_ptr) {
    96       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
   105       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
   100       current_array_type = NULL;
   109       current_array_type = NULL;
   101       current_param_type = NULL;
   110       current_param_type = NULL;
   102       fcall_number = 0;
   111       fcall_number = 0;
   103       fbname = name;
   112       fbname = name;
   104       wanted_variablegeneration = expression_vg;
   113       wanted_variablegeneration = expression_vg;
       
   114       wanted_casegeneration = none_cg;
   105     }
   115     }
   106 
   116 
   107     virtual ~generate_c_st_c(void) {
   117     virtual ~generate_c_st_c(void) {
   108       delete search_fb_instance_decl;
   118       delete search_fb_instance_decl;
   109       delete search_expression_type;
   119       delete search_expression_type;
   202     wanted_variablegeneration = complextype_suffix_vg;
   212     wanted_variablegeneration = complextype_suffix_vg;
   203     symbol->accept(*this);
   213     symbol->accept(*this);
   204   }
   214   }
   205   s4o.print(")");
   215   s4o.print(")");
   206   wanted_variablegeneration = expression_vg;
   216   wanted_variablegeneration = expression_vg;
       
   217   return NULL;
       
   218 }
       
   219 
       
   220 /********************************/
       
   221 /* B 1.3.3 - Derived data types */
       
   222 /********************************/
       
   223 /*  signed_integer DOTDOT signed_integer */
       
   224 void *visit(subrange_c *symbol) {
       
   225   switch (wanted_casegeneration) {
       
   226     case subrange_cg:
       
   227       s4o.print("case_expression >= ");
       
   228       symbol->lower_limit->accept(*this);
       
   229       s4o.print(" && case_expression <= ");
       
   230       symbol->upper_limit->accept(*this);
       
   231       break;
       
   232     default:
       
   233       break;
       
   234   }
   207   return NULL;
   235   return NULL;
   208 }
   236 }
   209 
   237 
   210 /*********************/
   238 /*********************/
   211 /* B 1.4 - Variables */
   239 /* B 1.4 - Variables */
  1003   s4o.indent_left();
  1031   s4o.indent_left();
  1004   return NULL;
  1032   return NULL;
  1005 }
  1033 }
  1006 
  1034 
  1007 void *visit(case_statement_c *symbol) {
  1035 void *visit(case_statement_c *symbol) {
  1008   s4o.print("switch(");
  1036   symbol_c *expression_type = search_expression_type->get_type(symbol->expression);
       
  1037   s4o.print("{\n");
       
  1038   s4o.indent_right();
       
  1039   if (search_base_type.type_is_enumerated(expression_type)) {
       
  1040 	s4o.print(s4o.indent_spaces);
       
  1041 	expression_type->accept(*this);
       
  1042 	s4o.print(" case_expression = ");
       
  1043   }
       
  1044   else {
       
  1045 	s4o.print(s4o.indent_spaces + "IEC_LINT case_expression = (IEC_LINT)");
       
  1046   }
  1009   symbol->expression->accept(*this);
  1047   symbol->expression->accept(*this);
  1010   s4o.print(") {\n");
  1048   s4o.print(";\n" + s4o.indent_spaces + "switch (case_expression) {\n");
  1011   s4o.indent_right();
  1049   s4o.indent_right();
       
  1050   wanted_casegeneration = single_cg;
       
  1051   symbol->case_element_list->accept(*this);
       
  1052   wanted_casegeneration = subrange_cg;
       
  1053   s4o.print(s4o.indent_spaces + "default:\n");
       
  1054   s4o.indent_right();
       
  1055   first_subrange_case_list = true;
  1012   symbol->case_element_list->accept(*this);
  1056   symbol->case_element_list->accept(*this);
  1013   if (symbol->statement_list != NULL) {
  1057   if (symbol->statement_list != NULL) {
  1014     s4o.print(s4o.indent_spaces + "default:\n");
  1058 	if (!first_subrange_case_list) {
       
  1059       s4o.print(s4o.indent_spaces + "else {\n");
       
  1060       s4o.indent_right();
       
  1061 	}
       
  1062     symbol->statement_list->accept(*this);
       
  1063     if (!first_subrange_case_list) {
       
  1064       s4o.indent_left();
       
  1065       s4o.print(s4o.indent_spaces + "}\n");
       
  1066     }
       
  1067   }
       
  1068   s4o.print(s4o.indent_spaces + "break;\n");
       
  1069   s4o.indent_left();
       
  1070   wanted_casegeneration = none_cg;
       
  1071   s4o.indent_left();
       
  1072   s4o.print(s4o.indent_spaces + "}\n");
       
  1073   s4o.indent_left();
       
  1074   s4o.print(s4o.indent_spaces + "}");
       
  1075   return NULL;
       
  1076 }
       
  1077 
       
  1078 /* helper symbol for case_statement */
       
  1079 void *visit(case_element_list_c *symbol) {return print_list(symbol);}
       
  1080 
       
  1081 void *visit(case_element_c *symbol) {
       
  1082   case_element_iterator_c *case_element_iterator;
       
  1083   symbol_c* element = NULL;
       
  1084   bool first_element = true;
       
  1085 
       
  1086   switch (wanted_casegeneration) {
       
  1087     case single_cg:
       
  1088       case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_single);
       
  1089       for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
       
  1090         if (first_element) first_element = false;
       
  1091     	s4o.print(s4o.indent_spaces + "case ");
       
  1092         element->accept(*this);
       
  1093         s4o.print(":\n");
       
  1094       }
       
  1095       delete case_element_iterator;
       
  1096       break;
       
  1097 
       
  1098     case subrange_cg:
       
  1099       case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_subrange);
       
  1100       for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
       
  1101         if (first_element) {
       
  1102           if (first_subrange_case_list) {
       
  1103             s4o.print(s4o.indent_spaces + "if (");
       
  1104             first_subrange_case_list = false;
       
  1105           }
       
  1106           else {
       
  1107         	  s4o.print(s4o.indent_spaces + "else if (");
       
  1108           }
       
  1109           first_element = false;
       
  1110         }
       
  1111         else {
       
  1112           s4o.print(" && ");
       
  1113         }
       
  1114         element->accept(*this);
       
  1115       }
       
  1116       delete case_element_iterator;
       
  1117       if (!first_element) {
       
  1118         s4o.print(") {\n");
       
  1119       }
       
  1120       break;
       
  1121 
       
  1122     default:
       
  1123       break;
       
  1124   }
       
  1125 
       
  1126   if (!first_element) {
  1015     s4o.indent_right();
  1127     s4o.indent_right();
  1016     symbol->statement_list->accept(*this);
  1128     symbol->statement_list->accept(*this);
  1017     s4o.print(s4o.indent_spaces + "break;\n");
  1129     switch (wanted_casegeneration) {
  1018     s4o.indent_left();
  1130       case single_cg:
  1019   }
  1131         s4o.print(s4o.indent_spaces + "break;\n");
  1020   s4o.indent_left();
  1132         s4o.indent_left();
  1021   s4o.print(s4o.indent_spaces + "}");
  1133         break;
  1022   return NULL;
  1134       case subrange_cg:
  1023 }
  1135     	s4o.indent_left();
  1024 
  1136   	    s4o.print(s4o.indent_spaces + "}\n");
  1025 /* helper symbol for case_statement */
  1137   	    break;
  1026 void *visit(case_element_list_c *symbol) {return print_list(symbol);}
  1138       default:
  1027 
  1139         break;
  1028 void *visit(case_element_c *symbol) {
  1140     }
  1029   s4o.print(s4o.indent_spaces + "case ");
  1141   }
  1030   symbol->case_list->accept(*this);
  1142   return NULL;
  1031   s4o.print(" :\n");
  1143 }
  1032   s4o.indent_right();
       
  1033   symbol->statement_list->accept(*this);
       
  1034   s4o.print(s4o.indent_spaces + "break;\n");
       
  1035   s4o.indent_left();
       
  1036   return NULL;
       
  1037 }
       
  1038 
       
  1039 void *visit(case_list_c *symbol) {return print_list(symbol, "", ", ");}
       
  1040 
  1144 
  1041 /********************************/
  1145 /********************************/
  1042 /* B 3.2.4 Iteration Statements */
  1146 /* B 3.2.4 Iteration Statements */
  1043 /********************************/
  1147 /********************************/
  1044 void *visit(for_statement_c *symbol) {
  1148 void *visit(for_statement_c *symbol) {