stage4/generate_cc/generate_cc_st.cc
changeset 16 e8b99f896416
parent 0 fb772792efd1
child 22 08bcc40be1fa
--- a/stage4/generate_cc/generate_cc_st.cc	Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_cc/generate_cc_st.cc	Tue Feb 20 18:17:21 2007 +0100
@@ -32,7 +32,10 @@
  */
 
 
-
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
 
 
 class generate_cc_st_c: public generate_cc_typedecl_c {
@@ -53,16 +56,27 @@
      */
     search_fb_instance_decl_c *search_fb_instance_decl;
 
+    /* When compiling st code, it becomes necessary to determine the
+     * data type of st expressions. To do this, we must first find the
+     * st operand's declaration, within the scope of the function block
+     * or function currently being processed.
+     * The following object does just that...
+     * This object instance will then later be called while the
+     * remaining st code is being handled.
+     */
+    search_expression_type_c *search_expression_type;
 
   public:
     generate_cc_st_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
     : generate_cc_typedecl_c(s4o_ptr) {
       search_fb_instance_decl = new search_fb_instance_decl_c(scope);
+      search_expression_type = new search_expression_type_c(scope);
       this->set_variable_prefix(variable_prefix);
     }
 
     virtual ~generate_cc_st_c(void) {
       delete search_fb_instance_decl;
+      delete search_expression_type;
     }
 
 
@@ -107,25 +121,141 @@
     }
 
   private:
+  
 /***************************************/
 /* B.3 - Language ST (Structured Text) */
 /***************************************/
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
-void *visit(or_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " || ");}
-/* TODO ...  XOR expression... */
-void *visit(xor_expression_c *symbol) {ERROR; return print_binary_expression(symbol->l_exp, symbol->r_exp, " XOR ");}
-void *visit(and_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " && ");}
-void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " == ");}
-void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " != ");}
-void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");}
-void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");}
-void *visit(le_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");}
-void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");}
-void *visit(add_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " + ");}
-void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " - ");}
-void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " * ");}
+void *visit(or_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (typeid(*left_type) == typeid(bool_type_name_c) && typeid(*right_type) == typeid(bool_type_name_c)) {
+    return print_binary_expression(symbol->l_exp, symbol->r_exp, " || ");
+  }
+  if (search_expression_type->is_numeric_compatible(left_type) && search_expression_type->is_numeric_compatible(right_type)) {
+    return print_binary_expression(symbol->l_exp, symbol->r_exp, " | ");
+  }
+  ERROR;
+  return NULL;
+}
+
+void *visit(xor_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (typeid(*left_type) == typeid(bool_type_name_c) && typeid(*right_type) == typeid(bool_type_name_c)) {
+    s4o.print("(");
+    symbol->l_exp->accept(*this);
+    s4o.print(" && !");
+    symbol->r_exp->accept(*this);
+    s4o.print(") || (!");
+    symbol->l_exp->accept(*this);
+    s4o.print(" && ");
+    symbol->r_exp->accept(*this);
+    s4o.print(")");
+  }
+  if (search_expression_type->is_numeric_compatible(left_type) && search_expression_type->is_numeric_compatible(right_type)) {
+    return print_binary_expression(symbol->l_exp, symbol->r_exp, " ^ ");
+  }
+  ERROR;
+  return NULL;
+}
+
+void *visit(and_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (typeid(*left_type) == typeid(bool_type_name_c) && typeid(*right_type) == typeid(bool_type_name_c)) {
+    return print_binary_expression(symbol->l_exp, symbol->r_exp, " && ");
+  }
+  if (search_expression_type->is_numeric_compatible(left_type) && search_expression_type->is_numeric_compatible(right_type)) {
+    return print_binary_expression(symbol->l_exp, symbol->r_exp, " & ");
+  }
+  ERROR;
+  return NULL;
+}
+
+void *visit(equ_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_compare_function("__compare_timespec", "==", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " == ");
+}
+
+void *visit(notequ_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_compare_function("__compare_timespec", "!=", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " != ");
+}
+
+void *visit(lt_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_compare_function("__compare_timespec", "<", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");
+}
+
+void *visit(gt_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_compare_function("__compare_timespec", ">", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");
+}
+
+void *visit(le_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_compare_function("__compare_timespec", "<=", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");
+}
+
+void *visit(ge_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_compare_function("__compare_timespec", ">=", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");
+}
+
+void *visit(add_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+	symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+	if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+		return print_binary_function("__add_timespec", symbol->l_exp, symbol->r_exp);
+	}
+	return print_binary_expression(symbol->l_exp, symbol->r_exp, " + ");
+}
+
+void *visit(sub_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_binary_function("__sub_timespec", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " - ");
+}
+
+void *visit(mul_expression_c *symbol) {
+  symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+    return print_binary_function("__mul_timespec", symbol->l_exp, symbol->r_exp);
+  }
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " * ");
+}
+
 void *visit(div_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " / ");}
 void *visit(mod_expression_c *symbol) {
   s4o.print("((");