Adding priority support for transitions in SFC
authorlbessard
Wed, 28 Feb 2007 15:55:41 +0100
changeset 19 cee3c4e5afe2
parent 18 e6af5eb5f546
child 20 81a06a308b7e
Adding priority support for transitions in SFC
stage4/generate_cc/generate_cc_sfc.cc
--- a/stage4/generate_cc/generate_cc_sfc.cc	Tue Feb 27 17:24:10 2007 +0100
+++ b/stage4/generate_cc/generate_cc_sfc.cc	Wed Feb 28 15:55:41 2007 +0100
@@ -38,6 +38,212 @@
 /***********************************************************************/
 /***********************************************************************/
 
+class transition_element {
+  
+  private:
+    transition_c *transition;
+    char priority;
+    char index;
+    transition_element *prev;
+    transition_element *next;
+
+  public:
+    transition_element(transition_c *tr, char pr, char idx) {
+      transition = tr;
+      priority = pr;
+      index = idx;
+    }
+
+    void set_prev(transition_element *tr) {prev = tr;}
+    void set_next(transition_element *tr) {next = tr;}
+    transition_element *get_prev(void) {return prev;}
+    transition_element *get_next(void) {return next;}
+    transition_c *get_transition(void) {return transition;}
+    char get_priority(void) {return priority;}
+    char get_index(void) {return index;}
+};
+
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+class generate_cc_sfc_transitionresetsteps_c: public generate_cc_base_c {
+  
+  private:
+    char transition_number;
+  
+  public:
+    generate_cc_sfc_transitionresetsteps_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
+    : generate_cc_base_c(s4o_ptr) {
+      this->set_variable_prefix(variable_prefix);
+    }
+    
+    void set_transition_number(char number) {transition_number = number;}
+    void reset_transition_number(void) {transition_number = 0;}
+    void print_transition_number(void) {
+      char str[10];
+      sprintf(str, "%d", transition_number);
+      s4o.print(str);
+    }
+    
+    void print_step_argument(symbol_c *step_name, const char* argument) {
+      print_variable_prefix();
+      s4o.print("step_list[");
+      s4o.print(SFC_STEP_ACTION_PREFIX);
+      step_name->accept(*this);
+      s4o.print("].");
+      s4o.print(argument);
+    }
+
+    void print_reset_step(symbol_c *step_name) {
+      s4o.print(s4o.indent_spaces);
+      print_step_argument(step_name, "state");
+      s4o.print(" = 0;\n" + s4o.indent_spaces);
+      print_step_argument(step_name, "elapsed_time");
+      s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
+    }
+
+/*********************************************/
+/* B.1.6  Sequential function chart elements */
+/*********************************************/
+    
+    void *visit(initial_step_c *symbol) {return NULL;}
+    
+    void *visit(step_c *symbol) {return NULL;}
+
+    void *visit(transition_c *symbol) {
+      if (symbol->integer == NULL) {
+        s4o.print(s4o.indent_spaces + "if (");
+        print_variable_prefix();
+        s4o.print("transition_list[");
+        print_transition_number();
+        s4o.print("]) {\n");
+        s4o.indent_right();
+        symbol->from_steps->accept(*this);
+        s4o.indent_left();
+        s4o.print(s4o.indent_spaces + "}\n");
+      }
+      transition_number++;
+      return NULL;
+    }
+    
+    void *visit(steps_c *symbol) {
+      if (symbol->step_name != NULL) {
+        print_reset_step(symbol->step_name);
+      }
+      if (symbol->step_name_list != NULL) {
+        symbol->step_name_list->accept(*this);
+      }
+      return NULL;
+    }
+    
+    void *visit(step_name_list_c *symbol) {
+      for(int i = 0; i < symbol->n; i++) {
+        print_reset_step(symbol->elements[i]);
+      }
+      return NULL;
+    }
+    
+    void *visit(action_c *symbol) {return NULL;}
+
+}; /* generate_cc_sfc_transitionresetsteps_c */
+      
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+class generate_cc_sfc_transitionsetsteps_c: public generate_cc_base_c {
+  
+  private:
+    char transition_number;
+  
+  public:
+    generate_cc_sfc_transitionsetsteps_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
+    : generate_cc_base_c(s4o_ptr) {
+      this->set_variable_prefix(variable_prefix);
+    }
+    
+    void reset_transition_number(void) {transition_number = 0;}
+    void print_transition_number(void) {
+      char str[10];
+      sprintf(str, "%d", transition_number);
+      s4o.print(str);
+    }
+    
+    void print_step_argument(symbol_c *step_name, const char* argument) {
+      print_variable_prefix();
+      s4o.print("step_list[");
+      s4o.print(SFC_STEP_ACTION_PREFIX);
+      step_name->accept(*this);
+      s4o.print("].");
+      s4o.print(argument);
+    }
+
+    void print_set_step(symbol_c *step_name) {
+      s4o.print(s4o.indent_spaces);
+      print_step_argument(step_name, "state");
+      s4o.print(" = 1;\n");
+    }
+
+/*********************************************/
+/* B.1.6  Sequential function chart elements */
+/*********************************************/
+    
+    void *visit(initial_step_c *symbol) {return NULL;}
+    
+    void *visit(step_c *symbol) {return NULL;}
+
+    void *visit(transition_c *symbol) {
+      s4o.print(s4o.indent_spaces + "if (");
+      print_variable_prefix();
+      s4o.print("transition_list[");
+      print_transition_number();
+      s4o.print("]) {\n");
+      s4o.indent_right();
+      symbol->to_steps->accept(*this);
+      s4o.indent_left();
+      s4o.print(s4o.indent_spaces + "}\n");
+      transition_number++;
+      return NULL;
+    }
+    
+    void *visit(steps_c *symbol) {
+      if (symbol->step_name != NULL) {
+        print_set_step(symbol->step_name);
+      }
+      if (symbol->step_name_list != NULL) {
+        symbol->step_name_list->accept(*this);
+      }
+      return NULL;
+    }
+    
+    void *visit(step_name_list_c *symbol) {
+      for(int i = 0; i < symbol->n; i++) {
+        print_set_step(symbol->elements[i]);
+      }
+      return NULL;
+    }
+    
+    void *visit(action_c *symbol) {return NULL;}
+
+}; /* generate_cc_sfc_transitionsetsteps_c */
+
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
 class generate_cc_sfc_transitiontest_c: public generate_cc_base_c {
   
   private:
@@ -46,21 +252,24 @@
   private:
     generate_cc_il_c *generate_cc_il;
     generate_cc_st_c *generate_cc_st;
+    generate_cc_sfc_transitionresetsteps_c *generate_cc_sfc_transitionresetsteps;
     
   public:
     generate_cc_sfc_transitiontest_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
     : generate_cc_base_c(s4o_ptr) {
       generate_cc_il = new generate_cc_il_c(s4o_ptr, scope, variable_prefix);
       generate_cc_st = new generate_cc_st_c(s4o_ptr, scope, variable_prefix);
+      generate_cc_sfc_transitionresetsteps = new generate_cc_sfc_transitionresetsteps_c(s4o_ptr, scope, variable_prefix);
       this->set_variable_prefix(variable_prefix);
     }
     
     ~generate_cc_sfc_transitiontest_c(void) {
       delete generate_cc_il;
       delete generate_cc_st;
-    }
-
-    void reset_transition_number(void) {transition_number = 0;}
+      delete generate_cc_sfc_transitionresetsteps;
+    }
+
+    void set_transition_number(char number) {transition_number = number;}
     void print_transition_number(void) {
       char str[10];
       sprintf(str, "%d", transition_number);
@@ -76,14 +285,18 @@
       s4o.print(argument);
     }
 
+    void print_reset_step(symbol_c *step_name) {
+      s4o.print(s4o.indent_spaces);
+      print_step_argument(step_name, "state");
+      s4o.print(" = 0;\n" + s4o.indent_spaces);
+      print_step_argument(step_name, "elapsed_time");
+      s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
+    }
+
 /*********************************************/
 /* B.1.6  Sequential function chart elements */
 /*********************************************/
     
-    void *visit(initial_step_c *symbol) {return NULL;}
-    
-    void *visit(step_c *symbol) {return NULL;}
-
     void *visit(transition_c *symbol) {
       s4o.print(s4o.indent_spaces + "if (");
       symbol->from_steps->accept(*this);
@@ -110,6 +323,17 @@
         symbol->transition_condition_st->accept(*generate_cc_st);
         s4o.print(";\n");
       }
+      if (symbol->integer != NULL) {
+        s4o.print(s4o.indent_spaces + "if (");
+        print_variable_prefix();
+        s4o.print("transition_list[");
+        print_transition_number();
+        s4o.print("]) {\n");
+        s4o.indent_right();
+        symbol->from_steps->accept(*generate_cc_sfc_transitionresetsteps);
+        s4o.indent_left();
+        s4o.print(s4o.indent_spaces + "}\n");
+      }
       s4o.indent_left();
       s4o.print(s4o.indent_spaces + "}\n" + s4o.indent_spaces + "else {\n");
       s4o.indent_right();
@@ -144,8 +368,6 @@
       }
       return NULL;
     }
-    
-    void *visit(action_c *symbol) {return NULL;}
 
 }; /* generate_cc_sfc_transitiontest_c */
 
@@ -157,39 +379,84 @@
 /***********************************************************************/
 /***********************************************************************/
 
-class generate_cc_sfc_transitionresetsteps_c: public generate_cc_base_c {
+class generate_cc_sfc_transitionsort_c: public iterator_visitor_c {
   
   private:
     char transition_number;
-  
+    transition_element *first_transition;
+    transition_element *last_transition;
+  
+  private:
+    generate_cc_sfc_transitiontest_c *generate_cc_sfc_transitiontest;
+    
   public:
-    generate_cc_sfc_transitionresetsteps_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
-    : generate_cc_base_c(s4o_ptr) {
-      this->set_variable_prefix(variable_prefix);
+    generate_cc_sfc_transitionsort_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) {
+      generate_cc_sfc_transitiontest = new generate_cc_sfc_transitiontest_c(s4o_ptr, scope, variable_prefix);
+      first_transition = NULL;
+      last_transition = NULL;
+    }
+
+    ~generate_cc_sfc_transitionsort_c(void) {
+      delete generate_cc_sfc_transitiontest;
+    }
+    
+    void append_transition(transition_c *transition, char priority, char index) {
+      transition_element *new_transition = new transition_element(transition, priority, index);
+      new_transition->set_prev(last_transition);
+      if (last_transition != NULL) {
+        last_transition->set_next(new_transition);
+      }
+      else {
+        first_transition = new_transition;
+      }
+      last_transition = new_transition;
+      transition_number++;
+    }
+    
+    void sort_transitions(void) {
+      int i, j;
+      transition_element *current_transition;
+      transition_element *next_transition;
+      for (i = transition_number; i > 1; i--) {
+        current_transition = first_transition;
+        for (j = 0; j < i - 1; j++) {
+          next_transition = current_transition->get_next();
+          if (current_transition->get_priority() > next_transition->get_priority()) {
+            if (current_transition->get_prev() != NULL) {
+              current_transition->get_prev()->set_next(next_transition);
+            }
+            else {
+              first_transition = next_transition;
+            }
+            if (next_transition->get_next() != NULL) {
+              next_transition->get_next()->set_prev(current_transition);
+            }
+            else {
+              last_transition = current_transition;
+            }
+            current_transition->set_next(next_transition->get_next());
+            next_transition->set_prev(current_transition->get_prev());
+            current_transition->set_prev(next_transition);
+            next_transition->set_next(current_transition);
+          }
+          else {
+            current_transition = next_transition;
+          }
+        }
+      }
     }
     
     void reset_transition_number(void) {transition_number = 0;}
-    void print_transition_number(void) {
-      char str[10];
-      sprintf(str, "%d", transition_number);
-      s4o.print(str);
-    }
-    
-    void print_step_argument(symbol_c *step_name, const char* argument) {
-      print_variable_prefix();
-      s4o.print("step_list[");
-      s4o.print(SFC_STEP_ACTION_PREFIX);
-      step_name->accept(*this);
-      s4o.print("].");
-      s4o.print(argument);
-    }
-
-    void print_reset_step(symbol_c *step_name) {
-      s4o.print(s4o.indent_spaces);
-      print_step_argument(step_name, "state");
-      s4o.print(" = 0;\n" + s4o.indent_spaces);
-      print_step_argument(step_name, "elapsed_time");
-      s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
+    
+    void generate(symbol_c *symbol) {
+      symbol->accept(*this);
+      sort_transitions();
+      transition_element *next_transition = first_transition;
+      while (next_transition != NULL) {
+        generate_cc_sfc_transitiontest->set_transition_number(next_transition->get_index());
+        next_transition->get_transition()->accept(*generate_cc_sfc_transitiontest);
+        next_transition = next_transition->get_next();
+      }
     }
 
 /*********************************************/
@@ -199,125 +466,20 @@
     void *visit(initial_step_c *symbol) {return NULL;}
     
     void *visit(step_c *symbol) {return NULL;}
-
+    
     void *visit(transition_c *symbol) {
-      s4o.print(s4o.indent_spaces + "if (");
-      print_variable_prefix();
-      s4o.print("transition_list[");
-      print_transition_number();
-      s4o.print("]) {\n");
-      s4o.indent_right();
-      symbol->from_steps->accept(*this);
-      s4o.indent_left();
-      s4o.print(s4o.indent_spaces + "}\n");
-      transition_number++;
-      return NULL;
-    }
-    
-    void *visit(steps_c *symbol) {
-      if (symbol->step_name != NULL) {
-        print_reset_step(symbol->step_name);
-      }
-      if (symbol->step_name_list != NULL) {
-        symbol->step_name_list->accept(*this);
-      }
-      return NULL;
-    }
-    
-    void *visit(step_name_list_c *symbol) {
-      for(int i = 0; i < symbol->n; i++) {
-        print_reset_step(symbol->elements[i]);
+      if (symbol->integer != NULL) {
+        append_transition(symbol, atoi(((token_c *)symbol->integer)->value), transition_number);
+      }
+      else {
+        append_transition(symbol, 0, transition_number);
       }
       return NULL;
     }
     
     void *visit(action_c *symbol) {return NULL;}
 
-}; /* generate_cc_sfc_transitionresetsteps_c */
-      
-
-
-
-/***********************************************************************/
-/***********************************************************************/
-/***********************************************************************/
-/***********************************************************************/
-
-class generate_cc_sfc_transitionsetsteps_c: public generate_cc_base_c {
-  
-  private:
-    char transition_number;
-  
-  public:
-    generate_cc_sfc_transitionsetsteps_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
-    : generate_cc_base_c(s4o_ptr) {
-      this->set_variable_prefix(variable_prefix);
-    }
-    
-    void reset_transition_number(void) {transition_number = 0;}
-    void print_transition_number(void) {
-      char str[10];
-      sprintf(str, "%d", transition_number);
-      s4o.print(str);
-    }
-    
-    void print_step_argument(symbol_c *step_name, const char* argument) {
-      print_variable_prefix();
-      s4o.print("step_list[");
-      s4o.print(SFC_STEP_ACTION_PREFIX);
-      step_name->accept(*this);
-      s4o.print("].");
-      s4o.print(argument);
-    }
-
-    void print_set_step(symbol_c *step_name) {
-      s4o.print(s4o.indent_spaces);
-      print_step_argument(step_name, "state");
-      s4o.print(" = 1;\n");
-    }
-
-/*********************************************/
-/* B.1.6  Sequential function chart elements */
-/*********************************************/
-    
-    void *visit(initial_step_c *symbol) {return NULL;}
-    
-    void *visit(step_c *symbol) {return NULL;}
-
-    void *visit(transition_c *symbol) {
-      s4o.print(s4o.indent_spaces + "if (");
-      print_variable_prefix();
-      s4o.print("transition_list[");
-      print_transition_number();
-      s4o.print("]) {\n");
-      s4o.indent_right();
-      symbol->to_steps->accept(*this);
-      s4o.indent_left();
-      s4o.print(s4o.indent_spaces + "}\n");
-      transition_number++;
-      return NULL;
-    }
-    
-    void *visit(steps_c *symbol) {
-      if (symbol->step_name != NULL) {
-        print_set_step(symbol->step_name);
-      }
-      if (symbol->step_name_list != NULL) {
-        symbol->step_name_list->accept(*this);
-      }
-      return NULL;
-    }
-    
-    void *visit(step_name_list_c *symbol) {
-      for(int i = 0; i < symbol->n; i++) {
-        print_set_step(symbol->elements[i]);
-      }
-      return NULL;
-    }
-    
-    void *visit(action_c *symbol) {return NULL;}
-
-}; /* generate_cc_sfc_transitionsetsteps_c */
+};/* generate_cc_sfc_transitionsort_c */
 
 
 
@@ -572,7 +734,7 @@
 class generate_cc_sfc_c: public generate_cc_typedecl_c {
   
   private:
-    generate_cc_sfc_transitiontest_c *generate_cc_sfc_transitiontest;
+    generate_cc_sfc_transitionsort_c *generate_cc_sfc_transitionsort;
     generate_cc_sfc_transitionresetsteps_c *generate_cc_sfc_transitionresetsteps;
     generate_cc_sfc_transitionsetsteps_c *generate_cc_sfc_transitionsetsteps;
     generate_cc_sfc_stepassociation_c *generate_cc_sfc_stepassociation;
@@ -581,7 +743,7 @@
   public:
     generate_cc_sfc_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
     : generate_cc_typedecl_c(s4o_ptr) {
-      generate_cc_sfc_transitiontest = new generate_cc_sfc_transitiontest_c(s4o_ptr, scope, variable_prefix);
+      generate_cc_sfc_transitionsort = new generate_cc_sfc_transitionsort_c(s4o_ptr, scope, variable_prefix);
       generate_cc_sfc_transitionresetsteps = new generate_cc_sfc_transitionresetsteps_c(s4o_ptr, scope, variable_prefix);
       generate_cc_sfc_transitionsetsteps = new generate_cc_sfc_transitionsetsteps_c(s4o_ptr, scope, variable_prefix);
       generate_cc_sfc_stepassociation = new generate_cc_sfc_stepassociation_c(s4o_ptr, scope, variable_prefix);
@@ -590,7 +752,7 @@
     }
   
     virtual ~generate_cc_sfc_c(void) {
-      delete generate_cc_sfc_transitiontest;
+      delete generate_cc_sfc_transitionsort;
       delete generate_cc_sfc_transitionresetsteps;
       delete generate_cc_sfc_transitionsetsteps;
       delete generate_cc_sfc_stepassociation;
@@ -696,8 +858,8 @@
       
       /* generate transition tests */
       s4o.print(s4o.indent_spaces + "// Transitions fire test\n");
-      generate_cc_sfc_transitiontest->reset_transition_number();
-      symbol->accept(*generate_cc_sfc_transitiontest);
+      generate_cc_sfc_transitionsort->reset_transition_number();
+      generate_cc_sfc_transitionsort->generate(symbol);
       s4o.print("\n");
       
       /* generate transition reset steps */