--- a/stage4/generate_c/generate_c_st.cc Wed Jul 13 13:57:29 2011 +0200
+++ b/stage4/generate_c/generate_c_st.cc Fri Sep 02 18:15:55 2011 +0200
@@ -52,6 +52,12 @@
fparam_output_vg
} variablegeneration_t;
+ typedef enum {
+ single_cg,
+ subrange_cg,
+ none_cg
+ } casegeneration_t;
+
private:
/* When calling a function block, we must first find it's type,
* by searching through the declarations of the variables currently
@@ -88,7 +94,10 @@
int fcall_number;
symbol_c *fbname;
+ bool first_subrange_case_list;
+
variablegeneration_t wanted_variablegeneration;
+ casegeneration_t wanted_casegeneration;
public:
generate_c_st_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL)
@@ -102,6 +111,7 @@
fcall_number = 0;
fbname = name;
wanted_variablegeneration = expression_vg;
+ wanted_casegeneration = none_cg;
}
virtual ~generate_c_st_c(void) {
@@ -207,6 +217,24 @@
return NULL;
}
+/********************************/
+/* B 1.3.3 - Derived data types */
+/********************************/
+/* signed_integer DOTDOT signed_integer */
+void *visit(subrange_c *symbol) {
+ switch (wanted_casegeneration) {
+ case subrange_cg:
+ s4o.print("case_expression >= ");
+ symbol->lower_limit->accept(*this);
+ s4o.print(" && case_expression <= ");
+ symbol->upper_limit->accept(*this);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
/*********************/
/* B 1.4 - Variables */
/*********************/
@@ -1005,38 +1033,114 @@
}
void *visit(case_statement_c *symbol) {
- s4o.print("switch(");
+ symbol_c *expression_type = search_expression_type->get_type(symbol->expression);
+ s4o.print("{\n");
+ s4o.indent_right();
+ if (search_base_type.type_is_enumerated(expression_type)) {
+ s4o.print(s4o.indent_spaces);
+ expression_type->accept(*this);
+ s4o.print(" case_expression = ");
+ }
+ else {
+ s4o.print(s4o.indent_spaces + "IEC_LINT case_expression = (IEC_LINT)");
+ }
symbol->expression->accept(*this);
- s4o.print(") {\n");
+ s4o.print(";\n" + s4o.indent_spaces + "switch (case_expression) {\n");
s4o.indent_right();
+ wanted_casegeneration = single_cg;
+ symbol->case_element_list->accept(*this);
+ wanted_casegeneration = subrange_cg;
+ s4o.print(s4o.indent_spaces + "default:\n");
+ s4o.indent_right();
+ first_subrange_case_list = true;
symbol->case_element_list->accept(*this);
if (symbol->statement_list != NULL) {
- s4o.print(s4o.indent_spaces + "default:\n");
+ if (!first_subrange_case_list) {
+ s4o.print(s4o.indent_spaces + "else {\n");
+ s4o.indent_right();
+ }
+ symbol->statement_list->accept(*this);
+ if (!first_subrange_case_list) {
+ s4o.indent_left();
+ s4o.print(s4o.indent_spaces + "}\n");
+ }
+ }
+ s4o.print(s4o.indent_spaces + "break;\n");
+ s4o.indent_left();
+ wanted_casegeneration = none_cg;
+ s4o.indent_left();
+ s4o.print(s4o.indent_spaces + "}\n");
+ s4o.indent_left();
+ s4o.print(s4o.indent_spaces + "}");
+ return NULL;
+}
+
+/* helper symbol for case_statement */
+void *visit(case_element_list_c *symbol) {return print_list(symbol);}
+
+void *visit(case_element_c *symbol) {
+ case_element_iterator_c *case_element_iterator;
+ symbol_c* element = NULL;
+ bool first_element = true;
+
+ switch (wanted_casegeneration) {
+ case single_cg:
+ case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_single);
+ for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
+ if (first_element) first_element = false;
+ s4o.print(s4o.indent_spaces + "case ");
+ element->accept(*this);
+ s4o.print(":\n");
+ }
+ delete case_element_iterator;
+ break;
+
+ case subrange_cg:
+ case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_subrange);
+ for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
+ if (first_element) {
+ if (first_subrange_case_list) {
+ s4o.print(s4o.indent_spaces + "if (");
+ first_subrange_case_list = false;
+ }
+ else {
+ s4o.print(s4o.indent_spaces + "else if (");
+ }
+ first_element = false;
+ }
+ else {
+ s4o.print(" && ");
+ }
+ element->accept(*this);
+ }
+ delete case_element_iterator;
+ if (!first_element) {
+ s4o.print(") {\n");
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (!first_element) {
s4o.indent_right();
symbol->statement_list->accept(*this);
- s4o.print(s4o.indent_spaces + "break;\n");
- s4o.indent_left();
- }
- s4o.indent_left();
- s4o.print(s4o.indent_spaces + "}");
- return NULL;
-}
-
-/* helper symbol for case_statement */
-void *visit(case_element_list_c *symbol) {return print_list(symbol);}
-
-void *visit(case_element_c *symbol) {
- s4o.print(s4o.indent_spaces + "case ");
- symbol->case_list->accept(*this);
- s4o.print(" :\n");
- s4o.indent_right();
- symbol->statement_list->accept(*this);
- s4o.print(s4o.indent_spaces + "break;\n");
- s4o.indent_left();
- return NULL;
-}
-
-void *visit(case_list_c *symbol) {return print_list(symbol, "", ", ");}
+ switch (wanted_casegeneration) {
+ case single_cg:
+ s4o.print(s4o.indent_spaces + "break;\n");
+ s4o.indent_left();
+ break;
+ case subrange_cg:
+ s4o.indent_left();
+ s4o.print(s4o.indent_spaces + "}\n");
+ break;
+ default:
+ break;
+ }
+ }
+ return NULL;
+}
/********************************/
/* B 3.2.4 Iteration Statements */