DEVS_generator.py 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. # DEVS Generator by Sam Pieters. Inspired on the generatic generator by Joeri Excelmans
  2. #
  3. # Visits SCCD-domain constructs (see sccd_constructs.py) and converts them
  4. # to a DEVS language AST (see generic_language_constructs.py), that can
  5. # then be visited by a target language writer (only supports python).
  6. from sccd.compiler.utils import Enum, Logger
  7. from sccd.compiler.visitor import Visitor
  8. from sccd.compiler.sccd_constructs import FormalParameter
  9. from sccd.compiler.stateful_writer import StatefulWriter
  10. import sccd.compiler.generic_language_constructs as GLC
  11. Platforms = Enum("Threads", "GameLoop", "EventLoop")
  12. class DEVSGenerator(Visitor):
  13. def __init__(self, platform):
  14. self.platform = platform
  15. self.writer = StatefulWriter()
  16. def generic_visit(self, node):
  17. Logger.showWarning("GenericGenerator has no visit method for node of type '" + str(type(node)) + "'.")
  18. def get(self):
  19. return self.writer.get()
  20. def visit_ClassDiagram(self, class_diagram):
  21. header = ("Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, "
  22. "and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)\n")
  23. if class_diagram.name or class_diagram.author or class_diagram.description:
  24. header += "\n"
  25. if class_diagram.author:
  26. header += "Model author: " + class_diagram.author + "\n"
  27. if class_diagram.name:
  28. header += "Model name: " + class_diagram.name + "\n"
  29. if class_diagram.description.strip():
  30. header += "Model description:\n"
  31. header += class_diagram.description.strip()
  32. self.writer.addMultiLineComment(header)
  33. self.writer.addVSpace()
  34. self.writer.addInclude(([GLC.RuntimeModuleIdentifier(), "DEVS_statecharts_core"]))
  35. # TODO: how to add just one element and not everything ('*')
  36. self.writer.addInclude((["pypdevs", "DEVS"]))
  37. self.writer.addInclude((["pypdevs", "infinity"]))
  38. self.writer.addInclude((["pypdevs", "simulator"]))
  39. if class_diagram.top.strip():
  40. self.writer.addRawCode(class_diagram.top)
  41. self.writer.addVSpace()
  42. self.writer.beginPackage(class_diagram.name)
  43. # visit children
  44. for c in class_diagram.classes:
  45. c.accept(self)
  46. self.writer.beginClass("ObjectManagerState")
  47. self.writer.beginConstructor()
  48. self.writer.beginMethodBody()
  49. self.writer.addAssignment(GLC.SelfProperty("to_send"), f"[(None, \"{class_diagram.default_class.name}\", Event(\"start_instance\", None, [0], 0))]")
  50. self.writer.endMethodBody()
  51. self.writer.endConstructor()
  52. self.writer.endClass()
  53. self.writer.beginClass("ObjectManager", ["AtomicDEVS"])
  54. self.writer.beginConstructor()
  55. self.writer.addFormalParameter("name")
  56. self.writer.beginMethodBody()
  57. self.writer.beginSuperClassConstructorCall("AtomicDEVS")
  58. self.writer.addActualParameter("name")
  59. self.writer.endSuperClassConstructorCall()
  60. self.writer.addAssignment(GLC.SelfProperty("State"), GLC.FunctionCall("ObjectManagerState"))
  61. self.writer.addAssignment(GLC.SelfProperty("input"),
  62. GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String("input")]))
  63. self.writer.addAssignment(GLC.SelfProperty("output"), "{}")
  64. for class_name in class_diagram.class_names:
  65. self.writer.addAssignment(GLC.SelfProperty(f"output[\"{class_name}\"]"),
  66. GLC.FunctionCall(GLC.SelfProperty("addOutPort")))
  67. self.writer.endMethodBody()
  68. self.writer.endConstructor()
  69. # TODO: Added the default methods for an Atomic DEVS model, need to write implementation
  70. self.writer.beginMethod("extTransition")
  71. self.writer.addFormalParameter("inputs")
  72. self.writer.beginMethodBody()
  73. self.writer.addAssignment("all_inputs", "inputs[self.input]")
  74. self.writer.beginForLoopIterateArray("all_inputs", "input")
  75. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("State.to_send.append"), ["input"]))
  76. self.writer.endForLoopIterateArray()
  77. self.writer.add(GLC.ReturnStatement(GLC.SelfProperty("State")))
  78. self.writer.endMethodBody()
  79. self.writer.endMethod()
  80. self.writer.beginMethod("intTransition")
  81. self.writer.beginMethodBody()
  82. self.writer.addAssignment(GLC.SelfProperty("State.to_send"), GLC.ArrayExpression())
  83. self.writer.add(GLC.ReturnStatement(GLC.SelfProperty("State")))
  84. self.writer.endMethodBody()
  85. self.writer.endMethod()
  86. self.writer.beginMethod("outputFnc")
  87. self.writer.beginMethodBody()
  88. self.writer.addAssignment("out_dict", "{}")
  89. self.writer.beginForLoopIterateArray(GLC.SelfProperty("State.to_send"), "(source, target, message)")
  90. self.writer.beginIf(GLC.ArrayContains("out_dict", "self.output[target]"))
  91. self.writer.add(GLC.FunctionCall("out_dict[self.output[target]].append", ["(source, target, message)"]))
  92. self.writer.endIf()
  93. self.writer.beginElse()
  94. self.writer.addAssignment(f"out_dict[self.output[target]]", "[(source, target, message)]")
  95. self.writer.endElse()
  96. self.writer.endForLoopIterateArray()
  97. self.writer.add(GLC.ReturnStatement("out_dict"))
  98. self.writer.endMethodBody()
  99. self.writer.endMethod()
  100. self.writer.beginMethod("timeAdvance")
  101. self.writer.beginMethodBody()
  102. self.writer.beginIf((GLC.SelfProperty("State.to_send")))
  103. self.writer.add(GLC.ReturnStatement("0"))
  104. self.writer.endIf()
  105. self.writer.add(GLC.ReturnStatement("INFINITY"))
  106. self.writer.endMethodBody()
  107. self.writer.endMethod()
  108. self.writer.endClass()
  109. # End ObjectManager Class
  110. # Begin Controller Class
  111. self.writer.beginClass("Controller", ["CoupledDEVS"])
  112. self.writer.beginConstructor()
  113. self.writer.addFormalParameter("name")
  114. for p in class_diagram.default_class.constructors[0].parameters:
  115. p.accept(self)
  116. self.writer.beginMethodBody()
  117. self.writer.beginSuperClassConstructorCall("CoupledDEVS")
  118. self.writer.addActualParameter("name")
  119. self.writer.endSuperClassConstructorCall()
  120. for i in class_diagram.inports:
  121. self.writer.addAssignment(GLC.SelfProperty(i),
  122. GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String(i)]))
  123. for o in class_diagram.outports:
  124. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String(o)]))
  125. # Add AtomicDEVS models
  126. self.writer.addAssignment(GLC.SelfProperty("objectmanager"), (GLC.FunctionCall(GLC.SelfProperty("addSubModel"),
  127. [GLC.FunctionCall(
  128. "ObjectManager",
  129. GLC.ActualParameters([
  130. GLC.String(
  131. "ObjectManager")]))])))
  132. for (i, class_name) in enumerate(class_diagram.class_names):
  133. self.writer.addAssignment(GLC.SelfProperty(f"atomic{i}"),
  134. (GLC.FunctionCall(GLC.SelfProperty("addSubModel"), [GLC.FunctionCall(class_name,
  135. GLC.ActualParameters(
  136. [
  137. GLC.String(
  138. class_name)]))])))
  139. # Add links between the models
  140. for (i, the_class) in enumerate(class_diagram.classes):
  141. self.writer.add((GLC.FunctionCall(GLC.SelfProperty("connectPorts"),
  142. [GLC.SelfProperty(f"atomic{i}.obj_manager_out"),
  143. GLC.SelfProperty(f"objectmanager.input")])))
  144. self.writer.add((GLC.FunctionCall(GLC.SelfProperty("connectPorts"),
  145. [GLC.SelfProperty(f"objectmanager.output[\"{the_class.name}\"]"),
  146. GLC.SelfProperty(f"atomic{i}.obj_manager_in")])))
  147. for association in the_class.associations:
  148. temp = class_diagram.class_names.index(association.to_class)
  149. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("connectPorts"),
  150. [GLC.SelfProperty(f"atomic{i}.outputs[\"{association.name}\"]"),
  151. GLC.SelfProperty(f"atomic{temp}.input")]))
  152. # TODO: What to do with "actual_parameters"?
  153. # actual_parameters = [p.getIdent() for p in class_diagram.default_class.constructors[0].parameters]
  154. # self.writer.add(GLC.FunctionCall(GLC.Property(GLC.SelfProperty("object_manager"), "createInstance"), [GLC.String(class_diagram.default_class.name), GLC.ArrayExpression(actual_parameters)]))
  155. self.writer.endMethodBody()
  156. self.writer.endConstructor()
  157. self.writer.endClass()
  158. # End Controller Class
  159. # visit test node if there is one
  160. if class_diagram.test:
  161. class_diagram.test.accept(self)
  162. self.writer.endPackage()
  163. # CLASS
  164. def visit_Class(self, class_node):
  165. """
  166. Generate code for Class construct
  167. """
  168. super_classes = []
  169. if not class_node.super_class_objs:
  170. if class_node.statechart:
  171. super_classes.append("AtomicDEVS")
  172. super_classes.append("ObjectManagerBase")
  173. if class_node.super_classes:
  174. for super_class in class_node.super_classes:
  175. super_classes.append(super_class)
  176. self.writer.beginClass(f"{class_node.name}Instance", ["RuntimeClassBase"])
  177. self.writer.beginConstructor()
  178. self.writer.addFormalParameter("atomdevs")
  179. for p in class_node.constructors[0].getParams():
  180. self.writer.addFormalParameter(p.getIdent(), p.getDefault())
  181. self.writer.beginMethodBody()
  182. self.writer.beginSuperClassConstructorCall("RuntimeClassBase")
  183. self.writer.addActualParameter("atomdevs")
  184. self.writer.endSuperClassConstructorCall()
  185. self.writer.addAssignment(GLC.SelfProperty("associations"), "{}")
  186. for association in class_node.associations:
  187. self.writer.addAssignment(
  188. GLC.SelfProperty(f"associations[\"{association.name}\"]"),
  189. GLC.FunctionCall("Association",
  190. [GLC.String(association.to_class), f"{association.min}", f"{association.max}"]))
  191. # TODO: Switch instance to write in constructor instead of the atomic devs because corresponds better
  192. constructor = class_node.constructors[0]
  193. if class_node.statechart:
  194. self.writer.addVSpace()
  195. if constructor.parent_class.statechart.big_step_maximality == "take_one":
  196. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "big_step_maximality"), GLC.Property("StatechartSemantics", "TakeOne"))
  197. elif constructor.parent_class.statechart.big_step_maximality == "take_many":
  198. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "big_step_maximality"), GLC.Property("StatechartSemantics", "TakeMany"))
  199. if constructor.parent_class.statechart.internal_event_lifeline == "queue":
  200. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "internal_event_lifeline"), GLC.Property("StatechartSemantics", "Queue"))
  201. elif constructor.parent_class.statechart.internal_event_lifeline == "next_small_step":
  202. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "internal_event_lifeline"), GLC.Property("StatechartSemantics", "NextSmallStep"))
  203. elif constructor.parent_class.statechart.internal_event_lifeline == "next_combo_step":
  204. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "internal_event_lifeline"), GLC.Property("StatechartSemantics", "NextComboStep"))
  205. if constructor.parent_class.statechart.input_event_lifeline == "first_small_step":
  206. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "input_event_lifeline"), GLC.Property("StatechartSemantics", "FirstSmallStep"))
  207. elif constructor.parent_class.statechart.input_event_lifeline == "first_combo_step":
  208. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "input_event_lifeline"), GLC.Property("StatechartSemantics", "FirstComboStep"))
  209. elif constructor.parent_class.statechart.input_event_lifeline == "whole":
  210. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "input_event_lifeline"), GLC.Property("StatechartSemantics", "Whole"))
  211. if constructor.parent_class.statechart.priority == "source_parent":
  212. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "priority"), GLC.Property("StatechartSemantics", "SourceParent"))
  213. elif constructor.parent_class.statechart.priority == "source_child":
  214. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "priority"), GLC.Property("StatechartSemantics", "SourceChild"))
  215. if constructor.parent_class.statechart.concurrency == "single":
  216. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "concurrency"), GLC.Property("StatechartSemantics", "Single"))
  217. elif constructor.parent_class.statechart.concurrency == "many":
  218. self.writer.addAssignment(GLC.Property(GLC.SelfProperty("semantics"), "concurrency"), GLC.Property("StatechartSemantics", "Many"))
  219. self.writer.addVSpace()
  220. self.writer.addComment("build Statechart structure")
  221. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("build_statechart_structure"), []))
  222. if constructor.parent_class.attributes:
  223. self.writer.addVSpace()
  224. self.writer.addComment("user defined attributes")
  225. for attribute in constructor.parent_class.attributes:
  226. if attribute.init_value is None :
  227. self.writer.addAssignment(GLC.SelfProperty(attribute.name), GLC.NoneExpression())
  228. else :
  229. self.writer.addAssignment(GLC.SelfProperty(attribute.name), attribute.init_value)
  230. self.writer.addVSpace()
  231. self.writer.addComment("call user defined constructor")
  232. self.writer.beginSuperClassMethodCall(f"{constructor.parent_class.name}Instance", "user_defined_constructor")
  233. for p in constructor.getParams():
  234. # we can't do p.accept(self) here because 'p' is a FormalParameter
  235. # and we want to write it as an actual parameter
  236. self.writer.addActualParameter(p.getIdent())
  237. self.writer.endSuperClassMethodCall()
  238. for inp in class_node.inports:
  239. self.writer.addAssignment(GLC.SelfProperty(f"inports[\"{inp}\"]"), f"(\'{inp}\', len(atomdevs.instances))")
  240. self.writer.endMethodBody()
  241. self.writer.endConstructor()
  242. # visit constructor
  243. # user defined constructor
  244. self.writer.beginMethod("user_defined_constructor")
  245. for p in constructor.getParams():
  246. p.accept(self)
  247. self.writer.beginMethodBody()
  248. for super_class in constructor.parent_class.super_classes:
  249. # begin call
  250. if super_class in constructor.parent_class.super_class_objs:
  251. self.writer.beginSuperClassMethodCall(super_class, "user_defined_constructor")
  252. else:
  253. self.writer.beginSuperClassConstructorCall(super_class)
  254. # write actual parameters
  255. if super_class in constructor.super_class_parameters:
  256. for p in constructor.super_class_parameters[super_class]:
  257. self.writer.addActualParameter(p)
  258. # end call
  259. if super_class in constructor.parent_class.super_class_objs:
  260. self.writer.endSuperClassMethodCall()
  261. else:
  262. self.writer.endSuperClassConstructorCall()
  263. self.writer.addRawCode(constructor.body)
  264. self.writer.endMethodBody()
  265. self.writer.endMethod()
  266. # visit destructor
  267. class_node.destructors[0].accept(self)
  268. # visit methods
  269. for i in class_node.methods:
  270. i.accept(self)
  271. # compile and initialize Statechart
  272. if class_node.statechart:
  273. class_node.statechart.accept(self)
  274. self.writer.beginMethod("initializeStatechart")
  275. self.writer.beginMethodBody()
  276. self.writer.addComment("enter default state")
  277. # get effective target of initial transition
  278. self.writer.addAssignment(
  279. GLC.SelfProperty("default_targets"),
  280. GLC.FunctionCall(
  281. GLC.Property(
  282. GLC.MapIndexedExpression(
  283. GLC.SelfProperty("states"),
  284. GLC.String(class_node.statechart.root.initial)
  285. ),
  286. "getEffectiveTargetStates"
  287. )
  288. )
  289. )
  290. self.writer.add(GLC.SuperClassMethodCall(
  291. "RuntimeClassBase",
  292. "initializeStatechart",
  293. []
  294. ))
  295. self.writer.endMethodBody()
  296. self.writer.endMethod()
  297. self.writer.endClass()
  298. self.writer.beginClass(class_node.name, super_classes)
  299. # TODO: Added the default methods for an Atomic DEVS model, need to write implementation
  300. self.writer.beginMethod("extTransition")
  301. self.writer.addFormalParameter("inputs")
  302. self.writer.beginMethodBody()
  303. self.writer.addAssignment(GLC.SelfProperty("simulated_time"), GLC.AdditionExpression(GLC.SelfProperty("simulated_time"), GLC.SelfProperty("elapsed")))
  304. self.writer.addAssignment(GLC.SelfProperty("next_time"), "0")
  305. self.writer.addAssignment("all_inputs", "[]")
  306. class_node.inports.extend(["obj_manager_in", "input"])
  307. for inport in class_node.inports:
  308. self.writer.beginIf(GLC.ArrayContains("inputs", GLC.SelfProperty(inport)))
  309. self.writer.add(GLC.FunctionCall("all_inputs.extend", [f"inputs[self.{inport}]"]))
  310. self.writer.endIf()
  311. #class_node.outports.extend(["obj_manager_out", "output"])
  312. self.writer.beginForLoopIterateArray("all_inputs", "input")
  313. self.writer.beginElseIf(GLC.FunctionCall("isinstance", ["input", "str"]))
  314. self.writer.addAssignment("tem", GLC.FunctionCall("eval", ["input"]))
  315. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("addInput"), ["tem"]))
  316. self.writer.endElseIf()
  317. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("create_instance")))
  318. parameters = [GLC.SelfExpression()]
  319. for i, _ in enumerate(constructor.parameters):
  320. parameters.append(f"input[2].parameters[{i+2}]")
  321. self.writer.addAssignment("new_instance", GLC.FunctionCall(f"{class_node.name}Instance", parameters))
  322. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("instances.append"), ["new_instance"]))
  323. self.writer.addAssignment("p", "new_instance.associations.get(\"parent\")")
  324. self.writer.beginIf("p")
  325. self.writer.add(GLC.FunctionCall("p.addInstance", ["input[2].instance"]))
  326. self.writer.endIf()
  327. self.writer.addAssignment("ev", GLC.FunctionCall("Event", ["\"instance_created\"", "None", "[f\"{input[2].parameters[0]}[{len(self.instances)-1}]\"], input[2].instance"]))
  328. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("to_send.append"), ["(input[1], input[0], ev)"]))
  329. self.writer.endElseIf()
  330. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("start_instance")))
  331. self.writer.addAssignment("instance", "self.instances[input[2].instance]")
  332. self.writer.add(GLC.FunctionCall("instance.start"))
  333. self.writer.addAssignment("ev", GLC.FunctionCall("Event", ["\"instance_started\"", "None", "[f\"{input[0]}[{len(self.instances)-1}]\"], input[2].instance"]))
  334. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("to_send.append"), ["(input[0], input[1], ev)"]))
  335. self.writer.endElseIf()
  336. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("delete_instance")))
  337. self.writer.endElseIf()
  338. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("associate_instance")))
  339. self.writer.endElseIf()
  340. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("disassociate_instance")))
  341. self.writer.endElseIf()
  342. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("instance_created")))
  343. self.writer.addAssignment("instance", "self.instances[input[2].instance]")
  344. self.writer.add(GLC.FunctionCall("instance.addEvent", ["input[2]"]))
  345. self.writer.endElseIf()
  346. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("instance_started")))
  347. self.writer.addAssignment("instance", "self.instances[input[2].instance]")
  348. self.writer.add(GLC.FunctionCall("instance.addEvent", ["input[2]"]))
  349. self.writer.endElseIf()
  350. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("instance_deleted")))
  351. self.writer.endElseIf()
  352. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("instance_associated")))
  353. self.writer.endElseIf()
  354. self.writer.beginElseIf(GLC.EqualsExpression("input[2].name", GLC.String("instance_disassociated")))
  355. self.writer.endElseIf()
  356. self.writer.beginElse()
  357. self.writer.addAssignment("ev", "input[2]")
  358. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("addInput"), ["ev"]))
  359. self.writer.endElse()
  360. self.writer.endForLoopIterateArray()
  361. self.writer.add(GLC.ReturnStatement(GLC.SelfProperty("instances")))
  362. self.writer.endMethodBody()
  363. self.writer.endMethod()
  364. self.writer.beginMethod("intTransition")
  365. self.writer.beginMethodBody()
  366. self.writer.addAssignment("earliest", GLC.FunctionCall("min", [GLC.SelfProperty("getEarliestEventTime()"), GLC.AdditionExpression(GLC.SelfProperty("simulated_time"), GLC.SelfProperty("input_queue.getEarliestTime()"))]))
  367. self.writer.beginIf(GLC.NotExpression(GLC.EqualsExpression("earliest", "INFINITY")))
  368. self.writer.addAssignment(GLC.SelfProperty("simulated_time"), "earliest")
  369. self.writer.endIf()
  370. self.writer.addAssignment(GLC.SelfProperty("to_send"), "[]")
  371. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("handleInput")))
  372. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("stepAll")))
  373. self.writer.addAssignment("next_earliest", GLC.FunctionCall("min", [GLC.SelfProperty("getEarliestEventTime()"), GLC.SelfProperty("input_queue.getEarliestTime()")]))
  374. self.writer.beginElseIf(GLC.NotExpression(GLC.EqualsExpression("len(self.to_send)", "0")))
  375. self.writer.addAssignment(GLC.SelfProperty("next_time"), "0")
  376. self.writer.endElseIf()
  377. self.writer.beginElseIf(GLC.EqualsExpression("next_earliest", "INFINITY"))
  378. self.writer.addAssignment(GLC.SelfProperty("next_time"), "INFINITY")
  379. self.writer.endElseIf()
  380. self.writer.beginElse()
  381. self.writer.addAssignment(GLC.SelfProperty("next_time"), "next_earliest - earliest")
  382. self.writer.endElse()
  383. self.writer.add(GLC.ReturnStatement(GLC.SelfProperty("instances")))
  384. self.writer.endMethodBody()
  385. self.writer.endMethod()
  386. self.writer.beginMethod("outputFnc")
  387. self.writer.beginMethodBody()
  388. self.writer.addAssignment("to_dict", "{}")
  389. self.writer.beginForLoopIterateArray(GLC.SelfProperty("to_send"), "sending")
  390. self.writer.beginIf(GLC.EqualsExpression("sending[2].port", "None"))
  391. self.writer.beginIf(GLC.ArrayContains("to_dict", "self.obj_manager_out"))
  392. self.writer.add(GLC.FunctionCall("to_dict[self.obj_manager_out].append", ["sending"]))
  393. self.writer.endIf()
  394. self.writer.beginElse()
  395. self.writer.addAssignment("to_dict[self.obj_manager_out]", "[sending]")
  396. self.writer.endElse()
  397. self.writer.endIf()
  398. self.writer.beginElse()
  399. self.writer.addAssignment("the_port", "None")
  400. self.writer.beginForLoopIterateArray(GLC.SelfProperty("OPorts"), "port")
  401. self.writer.beginIf(GLC.EqualsExpression("port.name", "sending[0]"))
  402. self.writer.addAssignment("the_port", "port")
  403. self.writer.endIf()
  404. self.writer.endForLoopIterateArray()
  405. self.writer.beginIf(GLC.ArrayContains("to_dict", "the_port"))
  406. self.writer.add(GLC.FunctionCall("to_dict[the_port].append", ["sending"]))
  407. self.writer.endIf()
  408. self.writer.beginElse()
  409. self.writer.addAssignment("to_dict[the_port]", "[sending]")
  410. self.writer.endElse()
  411. self.writer.endElse()
  412. self.writer.endForLoopIterateArray()
  413. self.writer.add(GLC.ReturnStatement("to_dict"))
  414. self.writer.endMethodBody()
  415. self.writer.endMethod()
  416. self.writer.beginMethod("timeAdvance")
  417. self.writer.beginMethodBody()
  418. #self.writer.beginIf(GLC.NotExpression(GLC.EqualsExpression(GLC.FunctionCall("len", [GLC.SelfProperty("to_send")]), "0")))
  419. #self.writer.add(GLC.ReturnStatement("0"))
  420. #self.writer.endIf()
  421. #self.writer.add(GLC.ReturnStatement(GLC.FunctionCall(GLC.SelfProperty("getEarliestEventTime"))))
  422. self.writer.add(GLC.ReturnStatement(GLC.SelfProperty("next_time")))
  423. self.writer.endMethodBody()
  424. self.writer.endMethod()
  425. # visit constructor
  426. class_node.constructors[0].name = class_node.name
  427. class_node.constructors[0].accept(self)
  428. self.writer.endClass()
  429. # CLASS -- CONSTRUCTOR
  430. def visit_Constructor(self, constructor):
  431. self.writer.beginConstructor()
  432. self.writer.addFormalParameter("name")
  433. self.writer.beginMethodBody() # constructor body
  434. self.writer.beginSuperClassConstructorCall("AtomicDEVS")
  435. self.writer.addActualParameter("name")
  436. self.writer.endSuperClassConstructorCall()
  437. self.writer.beginSuperClassConstructorCall("ObjectManagerBase")
  438. self.writer.endSuperClassConstructorCall()
  439. self.writer.addAssignment(GLC.SelfProperty("elapsed"), "0")
  440. self.writer.addAssignment(GLC.SelfProperty("name"), GLC.String(constructor.name))
  441. #self.writer.addAssignment(GLC.SelfProperty("obj_manager_in"),
  442. # GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String("obj_manager_in")]))
  443. self.writer.addAssignment(GLC.SelfProperty("obj_manager_out"),
  444. GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String("obj_manager_out")]))
  445. #self.writer.addAssignment(GLC.SelfProperty("input"), GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String("input")]))
  446. self.writer.addAssignment(GLC.SelfProperty("outputs"), "{}")
  447. for association in constructor.parent_class.associations:
  448. self.writer.addAssignment(GLC.SelfProperty(f"outputs[\"{association.name}\"]"),
  449. GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String(association.name)]))
  450. for p in constructor.parent_class.inports:
  451. self.writer.addAssignment(GLC.SelfProperty(p),
  452. GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String(p)]))
  453. for p in constructor.parent_class.outports:
  454. self.writer.addAssignment(
  455. GLC.MapIndexedExpression(GLC.SelfProperty("outports"), GLC.String(p)),
  456. GLC.FunctionCall(GLC.Property("controller", "addOutputPort"), [GLC.String(p), GLC.SelfExpression()]))
  457. if constructor.parent_class.name == constructor.parent_class.class_diagram.default_class.name:
  458. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("instances.append"), [f"{constructor.parent_class.name}Instance(self)"]))
  459. self.writer.addAssignment(GLC.SelfProperty("next_time"), "INFINITY")
  460. self.writer.endMethodBody()
  461. self.writer.endConstructor()
  462. def visit_FormalParameter(self, formal_parameter):
  463. self.writer.addFormalParameter(formal_parameter.getIdent(), formal_parameter.getDefault())
  464. ### CLASS -- DESTRUCTOR
  465. def visit_Destructor(self, destructor):
  466. self.writer.beginMethod("user_defined_destructor")
  467. self.writer.beginMethodBody()
  468. if destructor.body.strip():
  469. self.writer.addRawCode(destructor.body)
  470. if destructor.parent_class.super_classes:
  471. self.writer.addComment("call super class destructors")
  472. for super_class in destructor.parent_class.super_classes:
  473. # begin call
  474. if super_class in destructor.parent_class.super_class_objs:
  475. self.writer.beginSuperClassMethodCall(super_class, "user_defined_destructor")
  476. self.writer.endSuperClassMethodCall()
  477. else:
  478. self.writer.beginSuperClassDestructorCall(super_class)
  479. self.writer.endSuperClassDestructorCall()
  480. pass
  481. # self.writer.beginSuperClassMethodCall(super_class, "user_defined_destructor")
  482. # self.writer.endSuperClassMethodCall()
  483. self.writer.endMethodBody()
  484. self.writer.endMethod()
  485. # CLASS -- METHOD
  486. def visit_Method(self, method):
  487. self.writer.addVSpace()
  488. self.writer.beginMethod(method.name, "user defined method")
  489. for p in method.parameters:
  490. p.accept(self)
  491. self.writer.beginMethodBody()
  492. self.writer.addRawCode(method.body)
  493. self.writer.endMethodBody()
  494. self.writer.endMethod()
  495. # CLASS -- ASSOCIATION
  496. def visit_Association(self, association):
  497. self.writer.addAssignment(
  498. GLC.MapIndexedExpression(
  499. GLC.Property("instance", "associations"),
  500. GLC.String(association.name)),
  501. GLC.NewExpression("Association",
  502. [GLC.String(association.to_class), str(association.min), str(association.max)]))
  503. # CLASS -- STATECHART
  504. def visit_StateChart(self, statechart):
  505. self.writer.addVSpace()
  506. self.writer.beginMethod("build_statechart_structure", "builds Statechart structure")
  507. self.writer.beginMethodBody()
  508. def writeState(s, i):
  509. self.writer.addVSpace()
  510. self.writer.addComment("state %s" % ("<root>" if s.is_root else s.new_full_name))
  511. index_expr = GLC.MapIndexedExpression(GLC.SelfProperty("states"), GLC.String(s.new_full_name))
  512. clazz = "State"
  513. if s.is_parallel_state:
  514. clazz = "ParallelState"
  515. elif s.is_history:
  516. if s.is_history_deep:
  517. clazz = "DeepHistoryState"
  518. else:
  519. clazz = "ShallowHistoryState"
  520. self.writer.addAssignment(
  521. index_expr,
  522. GLC.NewExpression(clazz, [str(i), GLC.String(s.new_full_name), GLC.SelfExpression()])
  523. )
  524. if not s.is_root:
  525. if s.enter_action.action or s.has_timers:
  526. self.writer.add(
  527. GLC.FunctionCall(
  528. GLC.Property(
  529. index_expr,
  530. "setEnter"
  531. ),
  532. [GLC.SelfProperty(s.friendly_name + "_enter")]
  533. )
  534. )
  535. if s.exit_action.action or s.has_timers:
  536. self.writer.add(
  537. GLC.FunctionCall(
  538. GLC.Property(
  539. index_expr,
  540. "setExit"
  541. ),
  542. [GLC.SelfProperty(s.friendly_name + "_exit")]
  543. )
  544. )
  545. # write all states
  546. for (i, s) in enumerate(statechart.states):
  547. writeState(s, i)
  548. # add children to composite states
  549. self.writer.addVSpace()
  550. self.writer.addComment("add children")
  551. for (i, s) in enumerate(statechart.composites):
  552. for c in s.children:
  553. self.writer.add(
  554. GLC.FunctionCall(
  555. GLC.Property(
  556. GLC.MapIndexedExpression(
  557. GLC.SelfProperty("states"),
  558. GLC.String(s.new_full_name)
  559. ),
  560. "addChild"),
  561. [GLC.MapIndexedExpression(GLC.SelfProperty("states"), GLC.String(c.new_full_name))]
  562. )
  563. )
  564. # fix tree at root, such that 'descendants' and 'ancestors' fields are filled in
  565. self.writer.add(
  566. GLC.FunctionCall(
  567. GLC.Property(
  568. GLC.MapIndexedExpression(
  569. GLC.SelfProperty("states"),
  570. GLC.String("")
  571. ),
  572. "fixTree"
  573. )
  574. )
  575. )
  576. # defaults
  577. for (i, s) in enumerate(statechart.composites):
  578. if not s.is_parallel_state:
  579. self.writer.addAssignment(
  580. GLC.Property(
  581. GLC.MapIndexedExpression(
  582. GLC.SelfProperty("states"),
  583. GLC.String(s.new_full_name)
  584. ),
  585. "default_state"
  586. ),
  587. GLC.MapIndexedExpression(
  588. GLC.SelfProperty("states"),
  589. GLC.String(s.initial)
  590. )
  591. )
  592. # transitions
  593. for s in statechart.basics + statechart.composites:
  594. if s.transitions:
  595. self.writer.addVSpace()
  596. self.writer.addComment("transition %s" % s.new_full_name)
  597. for (i, t) in enumerate(s.transitions + s.else_transitions):
  598. # instantiate new Transition instance
  599. self.writer.addAssignment(
  600. GLC.LocalVariableDeclaration(
  601. "%s_%i" % (s.friendly_name, i)
  602. ),
  603. GLC.NewExpression(
  604. "Transition",
  605. [
  606. GLC.SelfExpression(),
  607. GLC.MapIndexedExpression(
  608. GLC.SelfProperty("states"),
  609. GLC.String(s.new_full_name),
  610. ),
  611. GLC.ArrayExpression(
  612. [
  613. GLC.MapIndexedExpression(
  614. GLC.SelfProperty("states"),
  615. GLC.String(target_node.new_full_name)
  616. )
  617. for target_node in t.target.target_nodes
  618. ]
  619. )
  620. ]
  621. )
  622. )
  623. # if any action associated with transition: set executable_content to correct function (generated later)
  624. if t.action.sub_actions:
  625. self.writer.add(
  626. GLC.FunctionCall(
  627. GLC.Property(
  628. "%s_%i" % (s.friendly_name, i),
  629. "setAction"
  630. ),
  631. [GLC.SelfProperty("%s_%i_exec" % (s.friendly_name, i))]
  632. )
  633. )
  634. # if any trigger associated with transition: instantiate correct Event instance
  635. trigger = None
  636. if t.trigger.is_after:
  637. trigger = GLC.NewExpression("Event", [GLC.String("_%iafter" % (t.trigger.getAfterIndex()))])
  638. elif t.trigger.event:
  639. trigger = GLC.NewExpression("Event",
  640. [
  641. GLC.String(t.trigger.event),
  642. GLC.NoneExpression() if t.trigger.port is None else GLC.FunctionCall(
  643. GLC.SelfProperty("getInPortName"),
  644. [GLC.String(t.trigger.port)]
  645. )
  646. ]
  647. )
  648. else:
  649. trigger = GLC.NoneExpression()
  650. if trigger:
  651. self.writer.add(
  652. GLC.FunctionCall(
  653. GLC.Property(
  654. "%s_%i" % (s.friendly_name, i),
  655. "setTrigger"
  656. ),
  657. [trigger]
  658. )
  659. )
  660. # if any guard associated with transition: set guard to correct function (generated later)
  661. if t.guard:
  662. self.writer.add(
  663. GLC.FunctionCall(
  664. GLC.Property(
  665. "%s_%i" % (s.friendly_name, i),
  666. "setGuard"
  667. ),
  668. [GLC.SelfProperty("%s_%i_guard" % (s.friendly_name, i))]
  669. )
  670. )
  671. self.writer.add(
  672. GLC.FunctionCall(
  673. GLC.Property(
  674. GLC.MapIndexedExpression(
  675. GLC.SelfProperty("states"),
  676. GLC.String(s.new_full_name)
  677. ),
  678. "addTransition"
  679. ),
  680. ["%s_%i" % (s.friendly_name, i)]
  681. )
  682. )
  683. self.writer.endMethodBody()
  684. self.writer.endMethod()
  685. # enter/exit actions
  686. for (i, s) in enumerate(statechart.composites + statechart.basics):
  687. if not s.is_root:
  688. if s.enter_action.action or s.has_timers:
  689. s.enter_action.accept(self)
  690. if s.exit_action.action or s.has_timers:
  691. s.exit_action.accept(self)
  692. # transition actions and guards
  693. for s in statechart.composites + statechart.basics:
  694. for (i, t) in enumerate(s.transitions):
  695. if t.action.sub_actions:
  696. self.writeTransitionAction(t, i)
  697. if t.hasGuard():
  698. self.writeTransitionGuard(t, i)
  699. def visit_FormalEventParameter(self, formal_event_parameter):
  700. self.writer.add(formal_event_parameter.name)
  701. def writeFormalEventParameters(self, transition):
  702. parameters = transition.getTrigger().getParameters()
  703. if (len(parameters) > 0):
  704. for index, parameter in enumerate(parameters):
  705. self.writer.startRecordingExpression()
  706. parameter.accept(self)
  707. parameter_expr = self.writer.stopRecordingExpression()
  708. self.writer.addAssignment(
  709. GLC.LocalVariableDeclaration(parameter_expr),
  710. GLC.ArrayIndexedExpression("parameters", str(index)))
  711. def writeTransitionAction(self, transition, index):
  712. self.writer.beginMethod("%s_%i_exec" % (transition.parent_node.friendly_name, index))
  713. # parameters, start method
  714. self.writer.addFormalParameter("parameters")
  715. self.writer.beginMethodBody()
  716. # handle parameters to actually use them
  717. self.writeFormalEventParameters(transition)
  718. # write action
  719. transition.getAction().accept(self)
  720. # end method
  721. self.writer.endMethodBody()
  722. self.writer.endMethod()
  723. def writeTransitionGuard(self, transition, index):
  724. self.writer.beginMethod("%s_%i_guard" % (transition.parent_node.friendly_name, index))
  725. # parameters, start method
  726. self.writer.addFormalParameter("parameters")
  727. self.writer.beginMethodBody()
  728. # handle parameters to actually use them
  729. self.writeFormalEventParameters(transition)
  730. # get guard condition
  731. self.writer.startRecordingExpression()
  732. transition.getGuard().accept(self) # --> visit_Expression
  733. expr = self.writer.stopRecordingExpression()
  734. # return statement, end method
  735. self.writer.add(GLC.ReturnStatement(expr))
  736. self.writer.endMethodBody()
  737. self.writer.endMethod()
  738. def visit_EnterAction(self, enter_method):
  739. parent_node = enter_method.parent_node
  740. self.writer.beginMethod(parent_node.friendly_name + "_enter")
  741. self.writer.beginMethodBody()
  742. if enter_method.action:
  743. enter_method.action.accept(self)
  744. # take care of any AFTER events
  745. for transition in parent_node.transitions:
  746. trigger = transition.getTrigger()
  747. if trigger.isAfter():
  748. self.writer.startRecordingExpression()
  749. trigger.after.accept(self)
  750. after = self.writer.stopRecordingExpression()
  751. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("addTimer"), [str(trigger.getAfterIndex()), after]))
  752. self.writer.endMethodBody()
  753. self.writer.endMethod()
  754. def visit_ExitAction(self, exit_method):
  755. parent_node = exit_method.parent_node
  756. self.writer.beginMethod(parent_node.friendly_name + "_exit")
  757. self.writer.beginMethodBody()
  758. # take care of any AFTER events
  759. for transition in parent_node.transitions:
  760. trigger = transition.getTrigger()
  761. if trigger.isAfter():
  762. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("removeTimer"), [str(trigger.getAfterIndex())]))
  763. # execute user-defined exit action if present
  764. if exit_method.action:
  765. exit_method.action.accept(self)
  766. self.writer.endMethodBody()
  767. self.writer.endMethod()
  768. # helper method
  769. def writeEnterHistory(self, entered_node, is_deep):
  770. ### OLD CODE (TODO)
  771. self.writer.beginMethod("enterHistory" + ("Deep" if is_deep else "Shallow") + "_" + entered_node.full_name)
  772. self.writer.beginMethodBody()
  773. self.writer.beginIf(GLC.EqualsExpression(
  774. GLC.ArrayLength(
  775. GLC.MapIndexedExpression(
  776. GLC.SelfProperty("history_state"),
  777. GLC.SelfProperty(entered_node.full_name))),
  778. "0"))
  779. defaults = entered_node.defaults
  780. for node in defaults:
  781. if node.is_basic:
  782. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enter_" + node.full_name)))
  783. elif node.is_composite:
  784. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enterDefault_" + node.full_name)))
  785. self.writer.endIf()
  786. self.writer.beginElse()
  787. children = entered_node.children
  788. if entered_node.is_parallel_state:
  789. for child in children:
  790. if not child.is_history:
  791. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enter_" + child.full_name)))
  792. self.writer.add(GLC.FunctionCall(
  793. GLC.SelfProperty("enterHistory" + ("Deep" if is_deep else "Shallow") + "_" + child.full_name)))
  794. else:
  795. for child in children:
  796. if not child.is_history:
  797. self.writer.beginIf(GLC.ArrayContains(
  798. GLC.MapIndexedExpression(
  799. GLC.SelfProperty("history_state"),
  800. GLC.SelfProperty(entered_node.full_name)),
  801. GLC.SelfProperty(child.full_name)))
  802. if child.is_composite:
  803. if is_deep:
  804. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enter_" + child.full_name)))
  805. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enterHistoryDeep_" + child.full_name)))
  806. else:
  807. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enterDefault_" + child.full_name)))
  808. else:
  809. self.writer.add(GLC.FunctionCall(GLC.SelfProperty("enter_" + child.full_name)))
  810. self.writer.endIf()
  811. self.writer.endElse()
  812. self.writer.endMethodBody()
  813. self.writer.endMethod()
  814. def visit_SelfReference(self, self_reference):
  815. self.writer.add(GLC.SelfExpression())
  816. def visit_StateReference(self, state_ref):
  817. self.writer.beginArray()
  818. for node in state_ref.getNodes():
  819. self.writer.add(GLC.SelfProperty(node.full_name))
  820. self.writer.endArray()
  821. def visit_InStateCall(self, in_state_call):
  822. self.writer.add(
  823. GLC.FunctionCall(
  824. GLC.SelfProperty("inState"),
  825. [
  826. GLC.ArrayExpression(
  827. [GLC.String(target_node.new_full_name) for target in in_state_call.targets for target_node in
  828. target.target_nodes]
  829. )
  830. ]
  831. )
  832. )
  833. def visit_ElseGuard(self, else_guard):
  834. self.writer.add(
  835. GLC.String("ELSE_GUARD")
  836. )
  837. def visit_Expression(self, expression):
  838. self.writer.startRecordingExpression()
  839. self.writer.beginGlue()
  840. for part in expression.expression_parts:
  841. part.accept(self)
  842. self.writer.endGlue()
  843. expr = self.writer.stopRecordingExpression()
  844. self.writer.add(expr)
  845. def visit_ExpressionPartString(self, e):
  846. self.writer.add(e.string)
  847. def visit_RaiseEvent(self, raise_event):
  848. self.writer.startRecordingExpression()
  849. self.writer.begin(GLC.NewExpression("Event"))
  850. self.writer.addActualParameter(GLC.String(raise_event.getEventName()))
  851. if raise_event.isOutput():
  852. self.writer.addActualParameter(
  853. GLC.FunctionCall(
  854. GLC.SelfProperty("getOutPortName"),
  855. [GLC.String(raise_event.getPort())]
  856. )
  857. )
  858. else:
  859. self.writer.addActualParameter(GLC.NoneExpression())
  860. self.writer.end()
  861. new_event_expr = self.writer.stopRecordingExpression()
  862. self.writer.startRecordingExpression()
  863. self.writer.beginArray()
  864. if raise_event.isCD():
  865. self.writer.add(GLC.SelfExpression())
  866. for param in raise_event.getParameters():
  867. param.accept(self) # -> visit_Expression will cause expressions to be added to array
  868. self.writer.endArray()
  869. parameters_array_expr = self.writer.stopRecordingExpression()
  870. new_event_expr.getActualParameters().add(parameters_array_expr)
  871. if raise_event.isNarrow():
  872. self.writer.add(GLC.FunctionCall(
  873. GLC.Property(GLC.SelfProperty("big_step"), "outputEventOM"), [
  874. GLC.NewExpression("Event", [
  875. GLC.String("narrow_cast"),
  876. GLC.NoneExpression(),
  877. GLC.ArrayExpression([
  878. GLC.SelfExpression(),
  879. raise_event.getTarget(),
  880. new_event_expr])])]))
  881. elif raise_event.isLocal():
  882. self.writer.add(GLC.FunctionCall(
  883. GLC.SelfProperty("raiseInternalEvent"),
  884. [new_event_expr]))
  885. elif raise_event.isOutput():
  886. self.writer.add(GLC.FunctionCall(
  887. GLC.Property(GLC.SelfProperty("big_step"), "outputEvent"),
  888. [new_event_expr]))
  889. elif raise_event.isCD():
  890. self.writer.add(GLC.FunctionCall(
  891. GLC.Property(GLC.SelfProperty("big_step"), "outputEventOM"),
  892. [new_event_expr]))
  893. elif raise_event.isBroad():
  894. self.writer.add(GLC.FunctionCall(
  895. GLC.Property(GLC.SelfProperty("big_step"), "outputEventOM"),
  896. [GLC.NewExpression("Event", [
  897. GLC.String("broad_cast"),
  898. GLC.NoneExpression(),
  899. GLC.ArrayExpression([
  900. GLC.SelfExpression(),
  901. new_event_expr])])]))
  902. def visit_Script(self, script):
  903. self.writer.addRawCode(script.code)
  904. def visit_Log(self, log):
  905. self.writer.add(GLC.LogStatement(log.message))
  906. def visit_Assign(self, assign):
  907. self.writer.startRecordingExpression()
  908. assign.lvalue.accept(self) # --> visit_Expression
  909. lvalue = self.writer.stopRecordingExpression()
  910. self.writer.startRecordingExpression()
  911. assign.expression.accept(self) # --> visit_Expression
  912. rvalue = self.writer.stopRecordingExpression()
  913. self.writer.addAssignment(lvalue, rvalue)