primitives.py 21 KB

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