action.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from typing import *
  2. from dataclasses import *
  3. from abc import *
  4. from sccd.action_lang.static.expression import *
  5. from sccd.action_lang.static.statement import *
  6. from sccd.statechart.dynamic.event import *
  7. from sccd.util.bitmap import Bitmap
  8. @dataclass
  9. class SCDurationLiteral(DurationLiteral):
  10. # optimization: to save us from runtime duration conversions,
  11. # all durations in statechart are divided by model delta,
  12. # and evaluate to integer instead of duration type.
  13. opt: Optional[int] = None
  14. # override
  15. def eval(self, memory: MemoryInterface):
  16. return self.opt
  17. # original behavior of eval
  18. def as_duration(self):
  19. return DurationLiteral.eval(self, None)
  20. @dataclass
  21. class EvalContext:
  22. __slots__ = ["memory", "execution", "params"]
  23. memory: 'MemoryInterface'
  24. execution: 'StatechartExecution'
  25. params: List[any]
  26. @dataclass
  27. class Action(ABC, Visitable):
  28. @abstractmethod
  29. def exec(self, ctx: EvalContext):
  30. pass
  31. @abstractmethod
  32. def render(self) -> str:
  33. pass
  34. @dataclass
  35. class RaiseEvent(Action):
  36. name: str
  37. params: List[FunctionDeclaration]
  38. def _eval_params(self, ctx: EvalContext) -> List[Any]:
  39. return [p.eval(ctx.memory)(ctx.memory, ctx.execution.configuration, *ctx.params) for p in self.params]
  40. @dataclass
  41. class RaiseInternalEvent(RaiseEvent):
  42. def render(self) -> str:
  43. return '^'+self.name
  44. def exec(self, ctx: EvalContext):
  45. params = self._eval_params(ctx)
  46. ctx.execution.raise_internal(
  47. InternalEvent(name=self.name, params=params))
  48. @dataclass
  49. class RaiseOutputEvent(RaiseEvent):
  50. # outport: str
  51. def exec(self, ctx: EvalContext):
  52. params = self._eval_params(ctx)
  53. ctx.execution.raise_output(
  54. OutputEvent(name=self.name, params=params))
  55. def render(self) -> str:
  56. return '^' + self.name
  57. @dataclass
  58. class Code(Action):
  59. block: FunctionDeclaration
  60. def exec(self, ctx: EvalContext):
  61. self.block.eval(ctx.memory)(ctx.memory, ctx.execution.configuration, *ctx.params)
  62. def render(self) -> str:
  63. return '/'+self.block.render()