Guest User

Untitled

a guest
Dec 13th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.68 KB | None | 0 0
  1. package com.d360.oam
  2.  
  3.  
  4. class Inter(val dependencies: Code, val code: Code, val prims: Prims) {
  5. constructor(code: Code, prims: Prims) : this(listOf(), code, prims)
  6. private var instance: Instance = Instance(0, mutableListOf())
  7. private var values = mutableListOf<Value>()
  8. private var coeffects = mutableListOf<Coeffect>()
  9.  
  10. private var queue = mutableListOf<Token>()
  11.  
  12. sealed class Realized {
  13. data class Values(val vals: List<Value>) : Realized()
  14. data class Pend(val pending: Pending) : Realized()
  15. object Stopped : Realized()
  16. }
  17.  
  18. private fun getCode(pc: Int) : CodeFun {
  19. return if (pc < 0) {
  20. code[Math.abs(pc) - 1]
  21. } else {
  22. dependencies[pc]
  23. }
  24. }
  25.  
  26.  
  27. private tailrec fun tick(pc: Pc, stack: Stack, env: Env) {
  28. val op = getCode(pc.pc).code[pc.epc]
  29. fun realized(args: List<Int>): Realized {
  30. val values = mutableListOf<Value>()
  31. for (arg in args) {
  32. val argV = env[arg]
  33. when (argV) {
  34. is EnvPending -> {
  35. val v = argV.pend
  36. v.value.let {
  37. when (it) {
  38. is Pend -> {
  39. return Realized.Pend(argV.pend)
  40. }
  41. is PendStopped -> {
  42. return Realized.Stopped
  43. }
  44. is PendVal -> values.add(it.v)
  45. }
  46. }
  47. }
  48. is EnvVal -> {
  49. values.add(argV.v)
  50. }
  51. }
  52. }
  53. return Realized.Values(values)
  54. }
  55.  
  56. when (op) {
  57. is OpConst -> {
  58. publish(stack, env, VConst(op.const))
  59. halt(stack, env)
  60. }
  61. is OpLabel -> {
  62. publish(stack, env, VLabel(op.pc))
  63. halt(stack, env)
  64. }
  65. is OpStop -> halt(stack, env)
  66. is OpParallel -> {
  67. incrementInstances(stack)
  68. tick(Pc(pc.pc, op.left), stack, env.toMutableList())
  69. tick(Pc(pc.pc, op.right), stack, env)
  70. }
  71. is OpOtherwise -> {
  72. val frame = FOtherwise(false, 1, Pc(pc.pc, op.right))
  73. tick(Pc(pc.pc, op.left), Cons(frame, stack), env)
  74. }
  75. is OpPruning -> {
  76. val pending = Pending(Pend, mutableListOf())
  77. val frame = FPruning(1, pending)
  78. op.index?.let { env.set(it, EnvPending(pending)) }
  79. tick(Pc(pc.pc, op.right), Cons(frame, stack), env)
  80. tick(Pc(pc.pc, op.left), stack, env)
  81. }
  82. is OpSequential -> {
  83. val frame = FSequential(op.index, Pc(pc.pc, op.right))
  84. tick(Pc(pc.pc, op.left), Cons(frame, stack), env)
  85. }
  86. is OpClosure -> {
  87. publish(stack, env, VClosure(op.pc, op.toCopy, env))
  88. halt(stack, env)
  89. }
  90. is OpTailCall -> {
  91. val t = op.target as? TFun ?: throw RuntimeException()
  92. val f = getCode(t.pc)
  93. var i = 0
  94. for (arg in op.args) {
  95. env[i] = env[arg]
  96. i++
  97. }
  98. queue.add(Token(Pc(t.pc, f.code.lastIndex), env, stack))
  99. }
  100. is OpCall -> {
  101. val t = op.target
  102. when (t) {
  103. is TPrim -> {
  104. val impl = prims[t.impl]
  105. val args = realized(op.args)
  106. // System.err.println("----CALL PRIM ${op.target} ${args}")
  107. when (args) {
  108. is Realized.Values -> {
  109. val res = impl(args.vals)
  110. when (res) {
  111. is PrimVal -> {
  112. publish(stack, env, res.v)
  113. halt(stack, env)
  114. }
  115. is PrimHalt -> halt(stack, env)
  116. is PrimUnsupported -> throw UnsupportedOperationException()
  117. }
  118. }
  119. is Realized.Stopped -> halt(stack, env)
  120. is Realized.Pend ->
  121. args.pending.waiters.add(Token(pc, env, stack))
  122. }
  123. }
  124. is TFun -> {
  125. val f = getCode(t.pc)
  126. val newEnv = MutableList(f.envSize) { index ->
  127. if (index < op.args.size) {
  128. env[op.args[index]]
  129. } else {
  130. EnvVal(VConst(ConstNull))
  131. }
  132. }
  133. val frame = FCall(env)
  134. tick(Pc(t.pc, f.code.lastIndex), Cons(frame, stack), newEnv)
  135. }
  136. is TDynamic -> {
  137. val realized = realized(listOf(t.index))
  138. when (realized) {
  139. is Realized.Values -> {
  140. val v = realized.vals[0]
  141. when (v) {
  142. is VClosure -> {
  143. val f = getCode(v.pc)
  144. val newEnv = MutableList(f.envSize) { index ->
  145. if (index < v.toCopy) {
  146. v.env[index]
  147. } else if (index < op.args.size + v.toCopy) {
  148. env[op.args[index - v.toCopy]]
  149. } else {
  150. EnvVal(VConst(ConstNull))
  151. }
  152. }
  153. val frame = FCall(env)
  154. tick(Pc(v.pc, f.code.lastIndex), Cons(frame, stack), newEnv)
  155. }
  156. is VLabel -> {
  157. val f = getCode(v.pc)
  158. val newEnv = MutableList(f.envSize) { index ->
  159. if (index < op.args.size) {
  160. env[op.args[index]]
  161. } else {
  162. EnvVal(VConst(ConstNull))
  163. }
  164. }
  165. val frame = FCall(env)
  166. tick(Pc(v.pc, f.code.lastIndex), Cons(frame, stack), newEnv)
  167. }
  168. is VTuple -> {
  169. val index = realized(listOf(op.args[0]))
  170.  
  171. when (index) {
  172. is Realized.Values -> {
  173. val indexV = index.vals[0]
  174. // System.err.println("---TUPLE ACCESS ${v} ${indexV}")
  175. when (indexV) {
  176. is VConst -> {
  177. if (indexV.const is ConstInt) {
  178. publish(stack, env, v.v[indexV.const.v])
  179. halt(stack, env)
  180. } else {
  181. throw RuntimeException()
  182. }
  183. }
  184. else -> throw RuntimeException()
  185. }
  186. }
  187. is Realized.Stopped -> halt(stack, env)
  188. is Realized.Pend ->
  189. index.pending.waiters.add(Token(pc, env, stack))
  190. }
  191. }
  192. }
  193. }
  194. is Realized.Stopped -> halt(stack, env)
  195. is Realized.Pend ->
  196. realized.pending.waiters.add(Token(pc, env, stack))
  197. }
  198. }
  199. }
  200. }
  201. is OpCoeffect -> {
  202. val realized = realized(listOf(op.index))
  203. when (realized) {
  204. is Realized.Values -> {
  205. val v = realized.vals[0]
  206. val id = instance.currentCoeffect
  207. instance.currentCoeffect += 1
  208. instance.blocks.add(Block(id, Token(pc, env.toMutableList(), stack)))
  209. coeffects.add(Coeffect(id, v))
  210. }
  211. is Realized.Stopped -> halt(stack, env)
  212. is Realized.Pend ->
  213. realized.pending.waiters.add(Token(pc, env, stack))
  214. }
  215. }
  216. }
  217. }
  218.  
  219. private tailrec fun publish(stack: Stack, env: Env, v: Value) {
  220. val s = stack.value
  221. when (s) {
  222. is FResult -> values.add(v)
  223. is FSequential -> {
  224. incrementInstances(stack)
  225. s.index?.let { env.set(it, EnvVal(v)) }
  226. tick(s.right, stack.next!!, env)
  227. }
  228. is FOtherwise -> {
  229. s.first_value = true
  230. publish(stack.next!!, env, v)
  231. }
  232. is FPruning -> {
  233. if (s.pending.value is PendVal) {
  234. return
  235. }
  236. s.pending.value = PendVal(v)
  237. for (w in s.pending.waiters) {
  238. tick(w.pc, w.stack, w.env)
  239. }
  240. }
  241. is FCall -> {
  242. publish(stack.next!!, s.env, v)
  243. }
  244. }
  245. }
  246.  
  247. private fun halt(stack: Stack, env: Env) {
  248. val s = stack.value
  249. when (s) {
  250. is FResult -> {
  251. }
  252. is FOtherwise -> {
  253. if (!s.first_value && s.instances == 1) {
  254. tick(s.otherwise, stack.next!!, env)
  255. } else if (s.instances == 1) {
  256. halt(stack.next!!, env)
  257. } else {
  258. s.instances -= 1
  259. }
  260. }
  261. is FPruning -> {
  262. if (s.pending.value is Pend && s.instances == 1) {
  263. s.pending.value = PendStopped
  264. } else {
  265. s.instances -= 1
  266. }
  267. }
  268. is FSequential, is FCall -> {
  269. halt(stack.next!!, env)
  270. }
  271. }
  272. }
  273.  
  274. private fun incrementInstances(stack: Stack) {
  275. loop@ for (s in stack) {
  276. when (s) {
  277. is FOtherwise -> {
  278. s.instances += 1; break@loop
  279. }
  280. is FPruning -> {
  281. s.instances += 1; break@loop
  282. }
  283. }
  284. }
  285. }
  286.  
  287. fun isAlive(stack: Stack) : Boolean {
  288. for (s in stack) {
  289. if (s is FPruning && !(s.pending.value is Pend)) {
  290. return false
  291. }
  292. }
  293. return true
  294. }
  295.  
  296. fun checkKilled(justUnblocked: Int) : List<Int> {
  297. val killed = mutableListOf<Int>()
  298. val newBlocks = mutableListOf<Block>()
  299. for (block in instance.blocks) {
  300. when {
  301. block.id == justUnblocked -> {}
  302. !isAlive(block.token.stack) -> killed.add(block.id)
  303. else -> newBlocks.add(block)
  304. }
  305. }
  306. instance.blocks.clear()
  307. instance.blocks.addAll(newBlocks)
  308. return killed
  309. }
  310.  
  311. fun runLoop() {
  312. while (queue.isNotEmpty()) {
  313. val token = queue.removeAt(queue.size - 1)
  314. tick(token.pc, token.stack, token.env)
  315. }
  316. }
  317.  
  318. fun run(): Snapshot {
  319. val l = code.last()
  320. val pc = Pc(-code.lastIndex - 1, l.code.lastIndex)
  321. val stack = Cons(FResult, null)
  322. val env: MutableList<EnvValue> = MutableList(l.envSize, { EnvVal(VConst(ConstNull)) })
  323. values = mutableListOf<Value>()
  324. coeffects = mutableListOf<Coeffect>()
  325. queue.add(Token(pc, env, stack))
  326. runLoop()
  327. return Snapshot(values, coeffects, listOf(), instance)
  328. }
  329.  
  330. fun unblock(instance: Instance, id: Int, value: Value): Snapshot {
  331. this.instance = instance
  332. values = mutableListOf<Value>()
  333. coeffects = mutableListOf<Coeffect>()
  334. val block = instance.blocks.find { it.id == id }
  335. if (block == null) {
  336. throw RuntimeException("Unknown coeffect")
  337. } else {
  338. publish(block.token.stack, block.token.env, value)
  339. runLoop()
  340. val killed = checkKilled(id)
  341. return Snapshot(values, coeffects, killed, instance)
  342. }
  343. }
  344.  
  345. fun unblock(id: Int, value: Value): Snapshot {
  346. return unblock(instance, id, value)
  347. }
  348. }
Add Comment
Please, Sign In to add comment