UNPKG

3.48 kBtext/coffeescriptView Raw
1kit = require "./kit"
2{Scope} = require "./scope"
3builder = require "./builder"
4assert = require "assert"
5config = require "./config"
6graph = require "./graph"
7
8class ParBlockNode extends graph.BlockNode
9 constructor: (@sort) ->
10 @reorder = @sort.reorder
11 super()
12 _getBuilder: ->
13 return builder.empty() unless @block.length
14 block = @sort @block
15 cur = builder.empty()
16 {reorder} = @
17 for i in block
18 if i.length is 1
19 cur = cur.append(i[0].getBuilder())
20 continue
21 pure = []
22 eff = []
23 if reorder
24 for j in i
25 b = j.getBuilder()
26 if j.eff
27 eff.push b.toExpr()
28 else
29 pure.push(b.toBlock()...)
30 cur = cur.append(
31 builder.purePrefix(builder.pure(pure),
32 builder.exprEff(kit.seq(eff...))))
33 else
34 last = builder.empty()
35 for j in i
36 b = j.getBuilder()
37 if j.eff
38 eff.push((last = b).toExpr())
39 else
40 last.append(b)
41 cur = cur.append(builder.exprEff(kit.seq(eff...)))
42 cur
43
44graph.regNodeType "parBlockNode", ParBlockNode
45
46Scope::seqBlockNode = Scope::blockNode
47
48Scope::blockNode = ->
49 b = @policy.opts.block
50 p = b.par if b?
51 p = "byUsage" if p is true
52 alg = blockSortAlgs[p]
53 return @seqBlockNode() unless alg?
54 @parBlockNode(alg)
55
56mkGroup = (reorder,order) ->
57 (b) ->
58 deps = []
59 for i, x in b
60 deps.push [i, n = []]
61 for j in b[...x]
62 if order(j, i)
63 n.push j
64 removed = {}
65 res = []
66 loop
67 lx = []
68 level = []
69 for [c,d], ix in deps
70 jx = 0
71 loop
72 break if jx is d.length
73 j = d[jx]
74 if removed[j.id]
75 d.splice(jx, 1)
76 else
77 ++jx
78 if d.length
79 break unless reorder
80 else
81 lx.push ix
82 level.push c
83 assert.ok(level.length)
84 deps.splice(ix,1) for ix in lx by -1
85 removed[c.id] = true for c in level
86 res.push level
87 break unless deps.length
88 res
89
90usedOnLeftOrder = (a,b) ->
91 {uses} = a.vdeps
92 for i of b.vdeps.mods
93 return true if uses[i]
94 return false
95usedOrder = (a,b) ->
96 {uses,mods} = a.vdeps
97 for i of b.vdeps.mods
98 return true if uses[i] or mods[i]
99 return false
100
101blockSortAlgs =
102 all: (b) -> [b]
103 reorderByUsage: mkGroup(true, usedOrder)
104 reorderByLhsUsage: mkGroup(true, usedOnLeftOrder)
105 byUsage: mkGroup(false, usedOrder)
106 byLhsUsage: mkGroup(false, usedOnLeftOrder)
107
108blockSortAlgs.reorderByUsage.reorder = true
109blockSortAlgs.reorderByLhsUsage.reorder = true
110blockSortAlgs.reorderByLhsUsage.all = true
111
112class SeqBindNode extends graph.BindNode
113 constructor: (body, deps) ->
114 super(body, deps)
115 assemblePar: (deps, cur) ->
116 for i, x in deps by -1
117 cur = i.append(cur)
118 cur
119
120graph.regNodeType "seqBindNode", SeqBindNode
121
122Scope::defaultBindNode = Scope::bindNode
123
124Scope::bindNode = (body, deps) ->
125 switch @policy.opts.expr
126 when "seq" then @seqBindNode(body, deps)
127 else @defaultBindNode(body, deps)
128
129#TODO:
130class ParBranchedNode extends graph.BranchedNode
131 constructor: (fun, template) ->
132 super(fun,template)
133 _getBuilder: ->
134 super()
135
136Scope::seqBranchedNode = Scope::branchedNode
137
138graph.regNodeType "parBranchedNode", ParBranchedNode
139
140Scope::branchedNode = (body, deps) ->
141 switch @policy.opts.branch
142 when "par" then @parBranchedNode(body, deps)
143 else @seqBranchedNode(body, deps)
144
145