rust.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from sccd.test.static.syntax import *
  2. from sccd.util.indenting_writer import *
  3. from sccd.cd.codegen.rust import ClassDiagramRustGenerator
  4. from sccd.action_lang.codegen.rust import UnsupportedFeature
  5. from sccd.statechart.codegen.rust import *
  6. class TestRustGenerator(ClassDiagramRustGenerator):
  7. def __init__(self, w):
  8. super().__init__(w)
  9. def visit_TestVariant(self, variant):
  10. variant.cd.accept(self)
  11. self.w.writeln("pub fn run_test() {")
  12. self.w.indent()
  13. self.w.writeln("use sccd::controller::*;")
  14. self.w.writeln("use sccd::statechart;")
  15. self.w.writeln("use sccd::statechart::SC;")
  16. self.w.writeln("use sccd::statechart::Scheduler;")
  17. if DEBUG:
  18. self.w.writeln("debug_print_sizes::<Controller<InEvent>>();")
  19. self.w.writeln();
  20. self.w.writeln("// Setup ...")
  21. self.w.writeln("let mut raised = Vec::<OutEvent>::new();")
  22. self.w.writeln("let mut output = |out: OutEvent| {")
  23. self.w.writeln(" raised.push(out);")
  24. self.w.writeln("};")
  25. self.w.writeln("let mut controller = Controller::<InEvent>::default();")
  26. self.w.writeln("let mut sc = Statechart::<Controller::<InEvent>>::default();")
  27. self.w.writeln()
  28. self.w.writeln("// Initialize statechart (execute actions of entering default states)")
  29. self.w.writeln("sc.init(&mut controller, &mut output);")
  30. self.w.writeln()
  31. self.w.writeln("// Add test input")
  32. for i in variant.input:
  33. if len(i.events) > 1:
  34. raise UnsupportedFeature("Multiple simultaneous input events not supported")
  35. elif len(i.events) == 0:
  36. raise UnsupportedFeature("Test declares empty bag of input events")
  37. # Convert python value to rust literal
  38. # Should find a better solution ...
  39. def to_rust_literal(value):
  40. if isinstance(value, int):
  41. return str(value)
  42. elif isinstance(value, str):
  43. return '"%s"' % value
  44. else:
  45. raise Exception("Incomplete implementation")
  46. self.w.write("controller.set_timeout(%d, InEvent::%s(%s));" % (i.timestamp.opt, ident_event_enum_variant(i.events[0].name), ", ".join(to_rust_literal(p) for p in i.events[0].params)))
  47. self.w.writeln()
  48. self.w.writeln("// Run simulation, as-fast-as-possible")
  49. self.w.writeln("controller.run_until(&mut sc, Until::Eternity, &mut output);")
  50. self.w.writeln()
  51. self.w.writeln("// Check if output is correct")
  52. self.w.writeln("assert_eq!(raised, [%s]);" % ", ".join("OutEvent::%s(%s)" % (ident_event_enum_variant(e.name), ", ".join(to_rust_literal(p) for p in e.params)) for o in variant.output for e in o))
  53. self.w.dedent()
  54. self.w.writeln("}")
  55. def visit_Test(self, test):
  56. for i, v in enumerate(test.variants):
  57. self.w.writeln("mod variant%d {" % (i+1))
  58. self.w.indent()
  59. v.accept(self)
  60. self.w.dedent()
  61. self.w.writeln("}")
  62. self.w.writeln()
  63. self.w.writeln("fn main() {")
  64. for i, v in enumerate(test.variants):
  65. self.w.writeln(" eprintln!();")
  66. self.w.writeln(" eprintln!(\"Test variant %d of %d\");" % (i+1, len(test.variants)))
  67. self.w.writeln(" variant%d::run_test();" % (i+1))
  68. self.w.writeln(" eprintln!(\"Passed.\");")
  69. self.w.writeln("}")
  70. self.w.writeln()