primitives.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. import time as python_time
  2. class PrimitiveFinished(Exception):
  3. """Exception to indicate the result value of a primitive, as a return cannot be used."""
  4. def __init__(self, value):
  5. Exception.__init__(self)
  6. self.result = value
  7. class InterpretedFunctionFinished(Exception):
  8. """Exception to indicate the result value of an interpreted function, as a return
  9. cannot be used."""
  10. def __init__(self, value):
  11. Exception.__init__(self)
  12. self.result = value
  13. # Functions annotated with __exception_return use the JIT's calling convention instead of
  14. # the kernel's: returns are handled by throwing a PrimitiveFinished exception; the caller's
  15. # returnvalue is not modified.
  16. #
  17. # ### Rationale for __exception_return
  18. #
  19. # __exception_return is a useful mechanism because it allows us to have a __call_function
  20. # implementation that has O(1) state read overhead. A previous implementation of
  21. # __call_function checked if the caller's frame had been popped whenever
  22. # ModelverseKernel.execute_yield threw a StopIteration exception. However, that incurs O(n) overhead
  23. # _per call,_ where n is the number of StopIteration exceptions that are thrown during the call.
  24. # O(n) is pretty bad, but this actually becomes O(n * m) when m calls to __call_function are
  25. # nested. And that's just not acceptable.
  26. # __exception_return requires kernel support, but I think the complexity gains are well worth it;
  27. # I reckon JIT-to-interpreter switches aren't going to get a whole lot cheaper than this.
  28. EXCEPTION_RETURN_KEY = "__exception_return"
  29. """A dictionary key for functions which request that the kernel throw a InterpretedFunctionFinished
  30. exception with the return value instead of injecting the return value in the caller's frame."""
  31. def integer_subtraction(a, b, **remainder):
  32. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  33. result, = yield [("CNV", [a_value - b_value])]
  34. raise PrimitiveFinished(result)
  35. def integer_addition(a, b, **remainder):
  36. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  37. result, = yield [("CNV", [a_value + b_value])]
  38. raise PrimitiveFinished(result)
  39. def integer_multiplication(a, b, **remainder):
  40. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  41. result, = yield [("CNV", [a_value * b_value])]
  42. raise PrimitiveFinished(result)
  43. def integer_division(a, b, **remainder):
  44. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  45. result, = yield [("CNV", [int(a_value) / b_value])]
  46. raise PrimitiveFinished(result)
  47. def integer_gt(a, b, **remainder):
  48. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  49. result, = yield [("CNV", [a_value > b_value])]
  50. raise PrimitiveFinished(result)
  51. def integer_lt(a, b, **remainder):
  52. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  53. result, = yield [("CNV", [a_value < b_value])]
  54. raise PrimitiveFinished(result)
  55. def integer_neg(a, **remainder):
  56. a_value, = yield [("RV", [a])]
  57. result, = yield [("CNV", [-a_value])]
  58. raise PrimitiveFinished(result)
  59. def bool_and(a, b, **remainder):
  60. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  61. result, = yield [("CNV", [a_value and b_value])]
  62. raise PrimitiveFinished(result)
  63. def bool_or(a, b, **remainder):
  64. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  65. result, = yield [("CNV", [a_value or b_value])]
  66. raise PrimitiveFinished(result)
  67. def bool_not(a, **remainder):
  68. a_value, = yield [("RV", [a])]
  69. result, = yield [("CNV", [not a_value])]
  70. raise PrimitiveFinished(result)
  71. def float_subtraction(a, b, **remainder):
  72. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  73. result, = yield [("CNV", [a_value - b_value])]
  74. raise PrimitiveFinished(result)
  75. def float_addition(a, b, **remainder):
  76. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  77. result, = yield [("CNV", [a_value + b_value])]
  78. raise PrimitiveFinished(result)
  79. def float_multiplication(a, b, **remainder):
  80. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  81. result, = yield [("CNV", [a_value * b_value])]
  82. raise PrimitiveFinished(result)
  83. def float_division(a, b, **remainder):
  84. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  85. result, = yield [("CNV", [float(a_value) / float(b_value)])]
  86. raise PrimitiveFinished(result)
  87. def float_gt(a, b, **remainder):
  88. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  89. result, = yield [("CNV", [a_value > b_value])]
  90. raise PrimitiveFinished(result)
  91. def float_lt(a, b, **remainder):
  92. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  93. result, = yield [("CNV", [a_value < b_value])]
  94. raise PrimitiveFinished(result)
  95. def float_neg(a, **remainder):
  96. a_value, = yield [("RV", [a])]
  97. result, = yield [("CNV", [-a_value])]
  98. raise PrimitiveFinished(result)
  99. def string_join(a, b, **remainder):
  100. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  101. result, = yield [("CNV", [str(a_value) + str(b_value)])]
  102. raise PrimitiveFinished(result)
  103. def string_split(a, b, **remainder):
  104. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  105. result = a_value.split(b_value)
  106. elems = yield [("CN", [])] + [("CNV", [v]) for v in result]
  107. new_val = elems[0]
  108. yield [("CD", [new_val, i, v]) for i, v in enumerate(elems[1:])]
  109. raise PrimitiveFinished(new_val)
  110. def string_get(a, b, **remainder):
  111. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  112. result, = yield [("CNV", [a_value[b_value]])]
  113. raise PrimitiveFinished(result)
  114. def string_len(a, **remainder):
  115. a_value, = yield [("RV", [a])]
  116. result, = yield [("CNV", [len(a_value)])]
  117. raise PrimitiveFinished(result)
  118. def value_eq(a, b, **remainder):
  119. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  120. result, = yield [("CNV", [a_value == b_value])]
  121. raise PrimitiveFinished(result)
  122. def value_neq(a, b, **remainder):
  123. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  124. result, = yield [("CNV", [a_value != b_value])]
  125. raise PrimitiveFinished(result)
  126. def element_eq(a, b, **remainder):
  127. result, = yield [("CNV", [a == b])]
  128. raise PrimitiveFinished(result)
  129. def element_neq(a, b, **remainder):
  130. result, = yield [("CNV", [a != b])]
  131. raise PrimitiveFinished(result)
  132. def cast_a2s(a, **remainder):
  133. a_value, = yield [("RV", [a])]
  134. result, = yield [("CNV", [str(a_value["value"])])]
  135. raise PrimitiveFinished(result)
  136. def cast_i2f(a, **remainder):
  137. a_value, = yield [("RV", [a])]
  138. result, = yield [("CNV", [float(a_value)])]
  139. raise PrimitiveFinished(result)
  140. def cast_i2s(a, **remainder):
  141. a_value, = yield [("RV", [a])]
  142. result, = yield [("CNV", [str(a_value)])]
  143. raise PrimitiveFinished(result)
  144. def cast_i2b(a, **remainder):
  145. a_value, = yield [("RV", [a])]
  146. result, = yield [("CNV", [bool(a_value)])]
  147. raise PrimitiveFinished(result)
  148. def cast_f2i(a, **remainder):
  149. a_value, = yield [("RV", [a])]
  150. result, = yield [("CNV", [int(a_value)])]
  151. raise PrimitiveFinished(result)
  152. def cast_f2s(a, **remainder):
  153. a_value, = yield [("RV", [a])]
  154. result, = yield [("CNV", [str(a_value)])]
  155. raise PrimitiveFinished(result)
  156. def cast_f2b(a, **remainder):
  157. a_value, = yield [("RV", [a])]
  158. result, = yield [("CNV", [bool(a_value)])]
  159. raise PrimitiveFinished(result)
  160. def cast_s2i(a, **remainder):
  161. a_value, = yield [("RV", [a])]
  162. result, = yield [("CNV", [int(a_value)])]
  163. raise PrimitiveFinished(result)
  164. def cast_s2f(a, **remainder):
  165. a_value, = yield [("RV", [a])]
  166. result, = yield [("CNV", [float(a_value)])]
  167. raise PrimitiveFinished(result)
  168. def cast_s2b(a, **remainder):
  169. a_value, = yield [("RV", [a])]
  170. result, = yield [("CNV", [bool(a_value)])]
  171. raise PrimitiveFinished(result)
  172. def cast_b2i(a, **remainder):
  173. a_value, = yield [("RV", [a])]
  174. result, = yield [("CNV", [int(a_value)])]
  175. raise PrimitiveFinished(result)
  176. def cast_b2f(a, **remainder):
  177. a_value, = yield [("RV", [a])]
  178. result, = yield [("CNV", [float(a_value)])]
  179. raise PrimitiveFinished(result)
  180. def cast_b2s(a, **remainder):
  181. a_value, = yield [("RV", [a])]
  182. result, = yield [("CNV", [str(a_value)])]
  183. raise PrimitiveFinished(result)
  184. def cast_e2s(a, **remainder):
  185. a_value, = yield [("RV", [a])]
  186. result, = yield [("CNV", ["{ID: %s, value: %s}" % (a, a_value)])]
  187. raise PrimitiveFinished(result)
  188. def cast_v2s(a, **remainder):
  189. a_value, = yield [("RV", [a])]
  190. if isinstance(a_value, (str, unicode)):
  191. # String should be encoded to distinguish between 3 and "3"
  192. a_value = '"%s"' % a_value
  193. elif isinstance(a_value, dict):
  194. # Action or type
  195. a_value = a_value["value"]
  196. result, = yield [("CNV", ["%s" % (a_value)])]
  197. raise PrimitiveFinished(result)
  198. def cast_id2s(a, **remainder):
  199. result, = yield [("CNV", ["%s" % (a)])]
  200. raise PrimitiveFinished(result)
  201. def list_append(a, b, **remainder):
  202. a_outgoing, = yield [("RO", [a])]
  203. _ = yield [("CD", [a, len(a_outgoing), b])]
  204. raise PrimitiveFinished(a)
  205. def list_insert(a, b, c, **remainder):
  206. a_outgoing, c_value = yield [("RO", [a]), ("RV", [c])]
  207. links = yield [("RD", [a, i]) for i in range(c_value, len(a_outgoing))] + \
  208. [("RDE", [a, i]) for i in range(c_value, len(a_outgoing))]
  209. values = links[:len(links)/2]
  210. edges = links[len(links)/2:]
  211. yield [("CD", [a, c_value, b])] + \
  212. [("CD", [a, c_value + 1 + index, value]) for index, value in enumerate(values)] + \
  213. [("DE", [i]) for i in edges]
  214. raise PrimitiveFinished(a)
  215. def list_delete(a, b, **remainder):
  216. a_outgoing, b_value = yield [("RO", [a]), ("RV", [b])]
  217. links = yield [("RD", [a, i]) for i in range(b_value, len(a_outgoing))] + \
  218. [("RDE", [a, i]) for i in range(b_value, len(a_outgoing))]
  219. values = links[:len(links)/2]
  220. edges = links[len(links)/2:]
  221. yield [("CD", [a, b_value + index, value]) for index, value in enumerate(values[1:])] + \
  222. [("DE", [i]) for i in edges]
  223. raise PrimitiveFinished(a)
  224. def list_read(a, b, **remainder):
  225. b_value, = yield [("RV", [b])]
  226. result, = yield [("RD", [a, b_value])]
  227. if result is None:
  228. raise Exception("List read out of bounds: %s" % b_value)
  229. raise PrimitiveFinished(result)
  230. def list_len(a, **remainder):
  231. outgoings, = yield [("RO", [a])]
  232. result, = yield [("CNV", [len(outgoings)])]
  233. raise PrimitiveFinished(result)
  234. def dict_add(a, b, c, **remainder):
  235. new_edge, = yield [("CE", [a, c])]
  236. yield [("CE", [new_edge, b])]
  237. raise PrimitiveFinished(a)
  238. def dict_add_fast(a, b, c, **remainder):
  239. v, = yield [("RV", [b])]
  240. yield [("CD", [a, v, c])]
  241. raise PrimitiveFinished(a)
  242. def dict_delete(a, b, **remainder):
  243. b_value, = yield [("RV", [b])]
  244. edge, = yield [("RDE", [a, b_value])]
  245. if edge is None:
  246. print("Failed dict_delete for value %s!" % b_value)
  247. keys, = yield [("RDK", [a])]
  248. keys = yield [("RV", [i]) for i in keys]
  249. print("Keys: " + str(keys))
  250. yield [("DE", [edge])]
  251. raise PrimitiveFinished(a)
  252. def dict_delete_node(a, b, **remainder):
  253. edge, = yield [("RDNE", [a, b])]
  254. if edge is None:
  255. print("Failed dict_delete_node!")
  256. yield [("DE", [edge])]
  257. raise PrimitiveFinished(a)
  258. def dict_read(a, b, **remainder):
  259. b_value, = yield [("RV", [b])]
  260. result, = yield [("RD", [a, b_value])]
  261. raise PrimitiveFinished(result)
  262. def dict_read_edge(a, b, **remainder):
  263. b_value, = yield [("RV", [b])]
  264. result, = yield [("RDE", [a, b_value])]
  265. raise PrimitiveFinished(result)
  266. def dict_read_node(a, b, **remainder):
  267. result, = yield [("RDN", [a, b])]
  268. raise PrimitiveFinished(result)
  269. def dict_in(a, b, **remainder):
  270. b_value, = yield [("RV", [b])]
  271. value, = yield [("RD", [a, b_value])]
  272. is_in = value is not None
  273. result, = yield [("CNV", [is_in])]
  274. raise PrimitiveFinished(result)
  275. def dict_in_node(a, b, **remainder):
  276. value, = yield [("RDN", [a, b])]
  277. result, = yield [("CNV", [value is not None])]
  278. raise PrimitiveFinished(result)
  279. def dict_len(a, **remainder):
  280. outgoings, = yield [("RO", [a])]
  281. result, = yield [("CNV", [len(outgoings)])]
  282. raise PrimitiveFinished(result)
  283. def dict_keys(a, **remainder):
  284. keys, result = yield [("RDK", [a]), ("CN", [])]
  285. yield [("CE", [result, v]) for v in keys]
  286. raise PrimitiveFinished(result)
  287. def dict_reverse(a, b, **remainder):
  288. edges, = yield [("RO", [a])]
  289. expanded_edges, = yield [("RE", [i]) for i in edges]
  290. for i, edge in enumerate(expanded_edges):
  291. if b == edge[1]:
  292. # Found our edge: edges[i]
  293. outgoing, = yield [("RO", [edges[i]])]
  294. result, = yield [("RE", [outgoing[0]])]
  295. raise PrimitiveFinished(result[1])
  296. result, = yield [("CNV", ["(unknown: %s)" % b])]
  297. raise PrimitiveFinished(result)
  298. def is_physical_int(a, **remainder):
  299. t, = yield [("RV", [a])]
  300. result, = yield [("CNV", [isinstance(t, int) or isinstance(t, long)])]
  301. raise PrimitiveFinished(result)
  302. def is_physical_string(a, **remainder):
  303. t, = yield [("RV", [a])]
  304. result, = yield [("CNV", [isinstance(t, str) or isinstance(t, unicode)])]
  305. raise PrimitiveFinished(result)
  306. def is_physical_float(a, **remainder):
  307. t, = yield [("RV", [a])]
  308. result, = yield [("CNV", [isinstance(t, float)])]
  309. raise PrimitiveFinished(result)
  310. def is_physical_boolean(a, **remainder):
  311. t, = yield [("RV", [a])]
  312. result, = yield [("CNV", [isinstance(t, bool)])]
  313. raise PrimitiveFinished(result)
  314. def is_physical_action(a, **remainder):
  315. t, = yield [("RV", [a])]
  316. result, = yield [("CNV", [isinstance(t, dict) and t["value"] in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]])]
  317. raise PrimitiveFinished(result)
  318. def create_node(**remainder):
  319. result, = yield [("CN", [])]
  320. raise PrimitiveFinished(result)
  321. def create_edge(a, b, **remainder):
  322. result, = yield [("CE", [a, b])]
  323. raise PrimitiveFinished(result)
  324. def create_value(a, **remainder):
  325. a_value, = yield [("RV", [a])]
  326. result, = yield [("CNV", [a_value])]
  327. raise PrimitiveFinished(result)
  328. def read_nr_out(a, **remainder):
  329. outgoing, = yield [("RO", [a])]
  330. result, = yield [("CNV", [len(outgoing)])]
  331. raise PrimitiveFinished(result)
  332. def read_out(a, b, root, **remainder):
  333. outgoing, b_value = yield [("RO", [a]), ("RV", [b])]
  334. raise PrimitiveFinished(sorted(outgoing)[b_value] if len(outgoing) > b_value else root)
  335. def read_nr_in(a, **remainder):
  336. incoming, = yield [("RI", [a])]
  337. result, = yield [("CNV", [len(incoming)])]
  338. raise PrimitiveFinished(result)
  339. def read_in(a, b, root, **remainder):
  340. incoming, b_value = yield [("RI", [a]), ("RV", [b])]
  341. raise PrimitiveFinished(sorted(incoming)[b_value] if len(incoming) > b_value else root)
  342. def read_edge_src(a, **remainder):
  343. result, = yield [("RE", [a])]
  344. raise PrimitiveFinished(result[0])
  345. def read_edge_dst(a, **remainder):
  346. result, = yield [("RE", [a])]
  347. raise PrimitiveFinished(result[1])
  348. def delete_element(a, **remainder):
  349. edge, = yield [("RE", [a])]
  350. if edge[0] is None:
  351. # Not an edge:
  352. yield [("DN", [a])]
  353. result, = yield [("CNV", [False])]
  354. raise PrimitiveFinished(result)
  355. else:
  356. yield [("DE", [a])]
  357. result, = yield [("CNV", [True])]
  358. raise PrimitiveFinished(result)
  359. def read_root(root, **remainder):
  360. raise PrimitiveFinished(root)
  361. def set_add(a, b, **remainder):
  362. #yield [("CE", [a, b])]
  363. #raise PrimitiveFinished(a)
  364. outgoing, b_value = yield [("RO", [a]), ("RV", [b])]
  365. if outgoing:
  366. elements = yield [("RE", [i]) for i in outgoing]
  367. values = yield [("RV", [i[1]]) for i in elements]
  368. if b_value is not None and b_value in values:
  369. raise PrimitiveFinished(a)
  370. elif b_value is None and b in elements:
  371. raise PrimitiveFinished(a)
  372. else:
  373. yield [("CE", [a, b])]
  374. raise PrimitiveFinished(a)
  375. else:
  376. yield [("CE", [a, b])]
  377. raise PrimitiveFinished(a)
  378. def set_pop(a, **remainder):
  379. outgoing, = yield [("RO", [a])]
  380. v, _ = yield [("RE", [outgoing[0]]), ("DE", [outgoing[0]])]
  381. raise PrimitiveFinished(v[1])
  382. def set_remove(a, b, **remainder):
  383. outgoing, b_value = yield [("RO", [a]), ("RV", [b])]
  384. elements = yield [("RE", [i]) for i in outgoing]
  385. values = yield [("RV", [i[1]]) for i in elements]
  386. yield [("DE", [identifier]) for identifier, edge in zip(outgoing, values) if edge == b_value]
  387. raise PrimitiveFinished(a)
  388. def set_remove_node(a, b, **remainder):
  389. outgoing, = yield [("RO", [a])]
  390. elements = yield [("RE", [i]) for i in outgoing]
  391. elements = [elements] if not isinstance(elements[0], list) else elements
  392. yield [("DE", [identifier]) for identifier, edge in zip(outgoing, elements) if edge[1] == b]
  393. raise PrimitiveFinished(a)
  394. def set_in(a, b, **remainder):
  395. outgoing, b_value = yield [("RO", [a]), ("RV", [b])]
  396. if outgoing:
  397. elements = yield [("RE", [i]) for i in outgoing]
  398. values = yield [("RV", [i[1]]) for i in elements]
  399. if b_value in values:
  400. result, = yield [("CNV", [True])]
  401. else:
  402. result, = yield [("CNV", [False])]
  403. else:
  404. result, = yield [("CNV", [False])]
  405. raise PrimitiveFinished(result)
  406. def set_in_node(a, b, **remainder):
  407. outgoing, = yield [("RO", [a])]
  408. if outgoing:
  409. elements = yield [("RE", [i]) for i in outgoing]
  410. if b in [v[1] for v in elements]:
  411. result, = yield [("CNV", [True])]
  412. else:
  413. result, = yield [("CNV", [False])]
  414. else:
  415. result, = yield [("CNV", [False])]
  416. raise PrimitiveFinished(result)
  417. def is_edge(a, **remainder):
  418. edge, = yield [("RE", [a])]
  419. result, = yield [("CNV", [edge[0] is not None])]
  420. raise PrimitiveFinished(result)
  421. #TODO deprecate
  422. def deserialize(a, root, **remainder):
  423. value, = yield [("RV", [a])]
  424. id_mappings = {}
  425. complex_primitives = frozenset(["if", "while", "assign", "call", "break", "continue", "return","resolve","access", "constant", "input", "output", "declare", "global"])
  426. for l in value.split("\n"):
  427. try:
  428. graph_type, constructor = l.split(None, 1)
  429. except:
  430. continue
  431. if graph_type == "N":
  432. # Node
  433. id_mappings[constructor], = yield [("CN", [])]
  434. elif graph_type == "V":
  435. # Node with Value
  436. name, temp = constructor.split("(", 1)
  437. string_value = temp[:-1]
  438. if string_value in complex_primitives:
  439. value = {"value": string_value}
  440. else:
  441. #TODO this is very dangerous!
  442. value = eval(string_value)
  443. id_mappings[name], = yield [("CNV", [value])]
  444. elif graph_type == "E":
  445. # Edge
  446. name, temp = constructor.split("(", 1)
  447. source, target = temp[:-1].split(",", 1)
  448. if target[0] == "?" and target not in id_mappings:
  449. hierarchy = target[1:].split("/")
  450. current, = yield [("RD", [root, "__hierarchy"])]
  451. for i in hierarchy:
  452. current, = yield [("RD", [current, i])]
  453. id_mappings[target] = current
  454. try:
  455. source = int(source)
  456. except:
  457. source = id_mappings[source]
  458. try:
  459. target = int(target)
  460. except:
  461. target = id_mappings[target]
  462. # Both nodes will normally be already present in the matching dictionary, so can just pass them along
  463. id_mappings[name], = yield [("CE", [source, target])]
  464. elif graph_type == "D":
  465. source, value, target = constructor.split(",",3)
  466. if value in complex_primitives:
  467. value = {"value": value}
  468. else:
  469. #TODO this is very dangerous!
  470. value = eval(value)
  471. if target[0] == "?" and target not in id_mappings:
  472. hierarchy = target[1:].split("/")
  473. current, = yield [("RD", [root, "__hierarchy"])]
  474. for i in hierarchy:
  475. current, = yield [("RD", [current, i])]
  476. id_mappings[target] = current
  477. try:
  478. source = int(source)
  479. except:
  480. source = id_mappings[source]
  481. try:
  482. target = int(target)
  483. except:
  484. target = id_mappings[target]
  485. yield [("CD", [source, value, target])]
  486. else:
  487. print("Unknown graph type: " + str(graph_type))
  488. raise PrimitiveFinished(id_mappings["auto_initial_IP"])
  489. def log(a, **remainder):
  490. a_value, = yield [("RV", [a])]
  491. print("== LOG == " + str(a_value))
  492. raise PrimitiveFinished(a)
  493. def read_taskroot(task_root, **remainder):
  494. raise PrimitiveFinished(task_root)
  495. def time(**remainder):
  496. a, = yield [("CNV", [python_time.time()])]
  497. raise PrimitiveFinished(a)
  498. def hash(a, **remainder):
  499. a_value, = yield [("RV", [a])]
  500. import hashlib
  501. b_value = hashlib.sha512(a_value).hexdigest()
  502. b, = yield [("CNV", [b_value])]
  503. raise PrimitiveFinished(b)