Переглянути джерело

Rust: fix internal event lifeline bug

Joeri Exelmans 4 роки тому
батько
коміт
ec39dd73ea

+ 9 - 8
rust/src/statechart.rs

@@ -1,8 +1,8 @@
 // Helpers and traits implemented by, or used by from-statechart-generated Rust code.
 
 pub trait EventLifeline<T> {
-  fn get(&self) -> &T;
-  fn get_mut(&mut self) -> &mut T;
+  fn current(&self) -> &T;
+  fn raise(&mut self) -> &mut T;
   fn cycle(&mut self);
 }
 
@@ -12,10 +12,10 @@ pub struct SameRoundLifeline<T> {
 }
 
 impl<T: Default> EventLifeline<T> for SameRoundLifeline<T> {
-  fn get(&self) -> &T {
+  fn current(&self) -> &T {
     &self.current
   }
-  fn get_mut(&mut self) -> &mut T {
+  fn raise(&mut self) -> &mut T {
     &mut self.current
   }
   fn cycle(&mut self) {
@@ -43,16 +43,17 @@ pub struct NextRoundLifeline<T> {
 }
 
 impl<T: Default> EventLifeline<T> for NextRoundLifeline<T> {
-  fn get(&self) -> &T {
+  fn current(&self) -> &T {
     match self.current {
       Which::One => &self.one,
       Which::Two => &self.two,
     }
   }
-  fn get_mut(&mut self) -> &mut T {
+  fn raise(&mut self) -> &mut T {
     match self.current {
-      Which::One => &mut self.one,
-      Which::Two => &mut self.two,
+      // Raise in the next round
+      Which::One => &mut self.two,
+      Which::Two => &mut self.one,
     }
   }
   fn cycle(&mut self) {

+ 14 - 6
src/sccd/statechart/codegen/rust.py

@@ -74,10 +74,14 @@ class StatechartRustGenerator(ActionLangRustGenerator):
 
     def visit_RaiseOutputEvent(self, a):
         # TODO: evaluate event parameters
+        if DEBUG:
+            self.w.writeln("eprintln!(\"raise out %s:%s\");" % (a.outport, a.name))
         self.w.writeln("(output)(statechart::OutEvent{port:\"%s\", event:\"%s\"});" % (a.outport, a.name))
 
     def visit_RaiseInternalEvent(self, a):
-        self.w.writeln("internal.get_mut().%s = Some(%s{});" % (ident_event_field(a.name), (ident_event_type(a.name))))
+        if DEBUG:
+            self.w.writeln("eprintln!(\"raise internal %s\");" % (a.name))
+        self.w.writeln("internal.raise().%s = Some(%s{});" % (ident_event_field(a.name), (ident_event_type(a.name))))
 
     def visit_Code(self, a):
             a.block.accept(self)
@@ -472,7 +476,7 @@ class StatechartRustGenerator(ActionLangRustGenerator):
                             if bit(e.id) & input_events:
                                 condition.append("let Some(InEvent::%s) = &input" % ident_event_type(e.name))
                             elif bit(e.id) & internal_events:
-                                condition.append("let Some(%s) = &internal.get().%s" % (ident_event_type(e.name), ident_event_field(e.name)))
+                                condition.append("let Some(%s) = &internal.current().%s" % (ident_event_type(e.name), ident_event_field(e.name)))
                             else:
                                 # Bug in SCCD :(
                                 raise Exception("Illegal event ID")
@@ -668,16 +672,20 @@ class StatechartRustGenerator(ActionLangRustGenerator):
             self.w.writeln("use std::mem::size_of;")
             self.w.writeln("fn debug_print_sizes<TimerId: Copy>() {")
             self.w.writeln("  eprintln!(\"------------------------\");")
+            self.w.writeln("  eprintln!(\"Semantics: %s\");" % sc.semantics)
+            self.w.writeln("  eprintln!(\"------------------------\");")
             self.w.writeln("  eprintln!(\"info: Statechart: {} bytes\", size_of::<Statechart<TimerId>>());")
             self.w.writeln("  eprintln!(\"info:   DataModel: {} bytes\", size_of::<DataModel>());")
             self.w.writeln("  eprintln!(\"info:   Timers: {} bytes\", size_of::<Timers<TimerId>>());")
-            def write_state_size(state):
-                self.w.writeln("  eprintln!(\"info:   State %s: {} bytes\", size_of::<%s>());" % (state.full_name, ident_type(state)))
+            self.w.writeln("  eprintln!(\"info:   History: {} bytes\", %s);" % " + ".join(["0"] + list("size_of::<%s>()" % ident_type(h.parent) for h in tree.history_states)))
+
+            def write_state_size(state, indent=0):
+                self.w.writeln("  eprintln!(\"info:   %sState %s: {} bytes\", size_of::<%s>());" % ("  "*indent, state.full_name, ident_type(state)))
                 for child in state.real_children:
-                    write_state_size(child)
+                    write_state_size(child, indent+1)
             write_state_size(tree.root)
             self.w.writeln("  eprintln!(\"info: InEvent: {} bytes\", size_of::<InEvent>());")
-            self.w.writeln("  eprintln!(\"info: statechart::OutEvent: {} bytes\", size_of::<statechart::OutEvent>());")
+            self.w.writeln("  eprintln!(\"info: OutEvent: {} bytes\", size_of::<statechart::OutEvent>());")
             self.w.writeln("  eprintln!(\"info: Arenas: {} bytes\", size_of::<Arenas>());")
             self.w.writeln("  eprintln!(\"------------------------\");")
             self.w.writeln("}")

+ 2 - 3
src/sccd/test/codegen/rust.py

@@ -23,8 +23,6 @@ class TestRustGenerator(ClassDiagramRustGenerator):
 
         self.w.writeln("let mut raised = Vec::<statechart::OutEvent>::new();")
         self.w.writeln("let mut output = |out: statechart::OutEvent| {")
-        if DEBUG:
-            self.w.writeln("  eprintln!(\"^{}:{}\", out.port, out.event);")
         self.w.writeln("  raised.push(out);")
         self.w.writeln("};")
         self.w.writeln("let mut controller = controller::Controller::<InEvent>::new();")
@@ -55,7 +53,8 @@ class TestRustGenerator(ClassDiagramRustGenerator):
         self.w.writeln("fn main() {")
 
         for i, v in enumerate(test.variants):
-            self.w.writeln("  eprintln!(\"Test variant %d\");" % i)
+            self.w.writeln("  eprintln!();")
+            self.w.writeln("  eprintln!(\"Test variant %d of %d\");" % (i+1, len(test.variants)))
             self.w.writeln("  variant%d::run();" % i)
             self.w.writeln("  eprintln!(\"Passed.\");")
         self.w.writeln("}")