Showing
11 changed files
with
238 additions
and
1540 deletions
doc/examples/andy/example.py
0 → 100644
1 | +# entities: tuple of name of the entities, initial level, tuple of decays 0 | ||
2 | +# denotes unbounded decay (omega) | ||
3 | +# examples: | ||
4 | +# entities = ( ('B',4, (0,2,2,2,3)), ('P',0, (0,0)), ('C',0, (0,0)), | ||
5 | +# ('G',0, (0,0)) ) | ||
6 | +# entities = ( ('Sugar',1, (0,2)), ('Aspartame',0, (0,2)), | ||
7 | +# ('Glycemia',2, (0,2,2,2)), ('Glucagon',0, (0,2)), | ||
8 | +# ('Insulin',0,(0,2,2)) ) | ||
9 | + | ||
10 | +entities = ( ('s1',0, (0,1)), ('s2',0, (0,1)), ('s3',0, (0,1)) ) | ||
11 | + | ||
12 | +# Activities: Tuple of (activators, inhibitors, results, duration) | ||
13 | +# activators, inhibitors are dictionaries of pairs | ||
14 | +# (entity, level) | ||
15 | +# results are dictionaries of pairs (entity, +z) | ||
16 | + | ||
17 | +# potential activities examples: | ||
18 | +# potential = ( (dict([('P',0)]),dict([('P',1)]),dict([('P',1)]),0), | ||
19 | +# (dict([('P',1)]),dict(),dict([('P',-1)]),0), | ||
20 | +# (dict([('C',0)]),dict([('C',1)]),dict([('C',1)]),0), | ||
21 | +# (dict([('C',1)]),dict(),dict([('C',-1)]),0), | ||
22 | +# (dict([('G',0)]),dict([('G',1)]),dict([('G',1)]),0), | ||
23 | +# (dict([('G',1)]),dict(),dict([('G',-1)]),0) ) | ||
24 | +# potential = ( (dict([('Sugar',1)]),dict(), | ||
25 | +# dict([('Insulin',1),('Glycemia',1)]),0), | ||
26 | +# (dict([('Aspartame',1)]),dict(),dict([('Insulin',1)]),0), | ||
27 | +# (dict(),dict([('Glycemia',1)]),dict([('Glucagon',1)]),0), | ||
28 | +# (dict([('Glycemia',3)]),dict(),dict([('Insulin',1)]),0), | ||
29 | +# (dict([('Insulin',2)]),dict(),dict([('Glycemia',-1)]),0), | ||
30 | +# (dict([('Insulin',1),('Glycemia',3)]), dict(), | ||
31 | +# dict([('Glycemia',-1)]),0), | ||
32 | +# (dict([('Insulin',1)]),dict([('Glycemia',2)]), | ||
33 | +# dict([('Glycemia',-1)]),0), | ||
34 | +# (dict([('Glucagon',1)]),dict(),dict([('Glycemia',+1)]),0) | ||
35 | +# ) | ||
36 | + | ||
37 | +potential = ( (dict(), dict([('s1',1)]), dict([('s2',1)]), 1), | ||
38 | + (dict(), dict([('s2',1)]), dict([('s3',1)]), 1), | ||
39 | + (dict(), dict([('s3',1)]), dict([('s1',1)]), 1) ) | ||
40 | + | ||
41 | +# obligatory activities examples: | ||
42 | +# obligatory = ( (dict([('P',1)]),dict(),dict([('B',1)]),1), | ||
43 | +# (dict([('C',1)]),dict(),dict([('B',-1)]),3), | ||
44 | +# (dict([('G',1)]),dict(),dict([('B',-2)]),3)) | ||
45 | + | ||
46 | +obligatory = () | ||
47 | + |
1 | -"""This package features the ABCD compiler, this is mainly a | 1 | +"""This package features the Andy compiler, this is mainly a |
2 | command-line tool but it can be called also from Python. The API is | 2 | command-line tool but it can be called also from Python. The API is |
3 | very simple and mimics the command line interface | 3 | very simple and mimics the command line interface |
4 | 4 | ||
5 | -### Function `snakes.utils.abcd.main.main` ### | 5 | +### Function `snakes.utils.andy.main.main` ### |
6 | 6 | ||
7 | :::python | 7 | :::python |
8 | - def main (args=sys.argv[1:], src=None) : ... | 8 | + def main (args=sys.argv[1:]) : ... |
9 | 9 | ||
10 | Entry point of the compiler | 10 | Entry point of the compiler |
11 | 11 | ||
12 | ##### Call API ##### | 12 | ##### Call API ##### |
13 | 13 | ||
14 | * `list args`: | 14 | * `list args`: |
15 | - * `str src`: | ||
16 | * `return PetriNet`: | 15 | * `return PetriNet`: |
17 | 16 | ||
18 | ##### Exceptions ##### | 17 | ##### Exceptions ##### | ... | ... |
1 | -import snakes.plugins | ||
2 | -snakes.plugins.load(['gv', 'ops'], 'snakes.nets', 'nets') | ||
3 | -from nets import * | ||
4 | - | ||
5 | - | ||
6 | ############################################################################### | 1 | ############################################################################### |
7 | ## AUXILIARY FUNCTIONS ######################################################## | 2 | ## AUXILIARY FUNCTIONS ######################################################## |
8 | 3 | ||
... | @@ -132,14 +127,14 @@ def potentialt (name, lp, up, lambdap, R) : | ... | @@ -132,14 +127,14 @@ def potentialt (name, lp, up, lambdap, R) : |
132 | 127 | ||
133 | ############################################################################### | 128 | ############################################################################### |
134 | ## MAIN ####################################################################### | 129 | ## MAIN ####################################################################### |
135 | -def andy2snakes(entities, potential, obligatory): | 130 | +def andy2snakes(snk, entities, potential, obligatory): |
136 | # compute maximal duration of activities | 131 | # compute maximal duration of activities |
137 | D=0 | 132 | D=0 |
138 | for alpha in potential : D = max(D, alpha[3]) | 133 | for alpha in potential : D = max(D, alpha[3]) |
139 | 134 | ||
140 | for alpha in obligatory : D = max(D, alpha[3]) | 135 | for alpha in obligatory : D = max(D, alpha[3]) |
141 | 136 | ||
142 | - n = PetriNet('andy') | 137 | + n = snk.PetriNet('andy') |
143 | 138 | ||
144 | n.globals["obligatory"] = obligatory | 139 | n.globals["obligatory"] = obligatory |
145 | n.globals["D"] = D | 140 | n.globals["D"] = D |
... | @@ -153,13 +148,13 @@ def andy2snakes(entities, potential, obligatory): | ... | @@ -153,13 +148,13 @@ def andy2snakes(entities, potential, obligatory): |
153 | level = entities[i][1] | 148 | level = entities[i][1] |
154 | deltas = entities[i][2] | 149 | deltas = entities[i][2] |
155 | vector = [0]*len(deltas) | 150 | vector = [0]*len(deltas) |
156 | - n.add_place(Place(name, [(level,0, tuple(vector))])) | 151 | + n.add_place(snk.Place(name, [(level,0, tuple(vector))])) |
157 | 152 | ||
158 | ################# clock transition | 153 | ################# clock transition |
159 | inputlist = dict() | 154 | inputlist = dict() |
160 | n.globals["inputlist"] = inputlist | 155 | n.globals["inputlist"] = inputlist |
161 | 156 | ||
162 | - n.add_transition(Transition('tc')) | 157 | + n.add_transition(snk.Transition('tc')) |
163 | 158 | ||
164 | 159 | ||
165 | # connect all obligatory clocks | 160 | # connect all obligatory clocks |
... | @@ -167,7 +162,7 @@ def andy2snakes(entities, potential, obligatory): | ... | @@ -167,7 +162,7 @@ def andy2snakes(entities, potential, obligatory): |
167 | # transition name | 162 | # transition name |
168 | obname = 'ob'+str(i) | 163 | obname = 'ob'+str(i) |
169 | # for every obligatory activity connect corresponding place to clock | 164 | # for every obligatory activity connect corresponding place to clock |
170 | - n.add_place(Place('p'+obname, [0])) | 165 | + n.add_place(snk.Place('p'+obname, [0])) |
171 | n.add_input('p'+obname, 'tc', Variable('w'+obname)) | 166 | n.add_input('p'+obname, 'tc', Variable('w'+obname)) |
172 | inputlist.update({obname:'w'+obname}) | 167 | inputlist.update({obname:'w'+obname}) |
173 | 168 | ||
... | @@ -178,20 +173,20 @@ def andy2snakes(entities, potential, obligatory): | ... | @@ -178,20 +173,20 @@ def andy2snakes(entities, potential, obligatory): |
178 | deltas = entities[i][2] | 173 | deltas = entities[i][2] |
179 | n.globals["deltas"+name] = deltas | 174 | n.globals["deltas"+name] = deltas |
180 | n.globals[name] = name | 175 | n.globals[name] = name |
181 | - n.add_input(name, 'tc', Tuple([Variable('l'+name), Variable('u'+name), Variable('lambda'+name) ])) | 176 | + n.add_input(name, 'tc', snk.Tuple([snk.Variable('l'+name), snk.Variable('u'+name), snk.Variable('lambda'+name) ])) |
182 | inputlist.update({name:['l'+name, 'u'+name, 'lambda'+name ]}) | 177 | inputlist.update({name:['l'+name, 'u'+name, 'lambda'+name ]}) |
183 | 178 | ||
184 | 179 | ||
185 | 180 | ||
186 | for i in range(0,len(entities)): | 181 | for i in range(0,len(entities)): |
187 | name=entities[i][0] | 182 | name=entities[i][0] |
188 | - n.add_output(name, 'tc', Expression("clockt(obligatory,"+name+",l"+name+',u'+name+',lambda'+name+',deltas'+name+',inputlist,D)')) | 183 | + n.add_output(name, 'tc', snk.Expression("clockt(obligatory,"+name+",l"+name+',u'+name+',lambda'+name+',deltas'+name+',inputlist,D)')) |
189 | 184 | ||
190 | 185 | ||
191 | for i in range(0,len(obligatory)): | 186 | for i in range(0,len(obligatory)): |
192 | obname = 'ob'+str(i) | 187 | obname = 'ob'+str(i) |
193 | # for every obligatory activity connect corresponding place to clock | 188 | # for every obligatory activity connect corresponding place to clock |
194 | - n.add_output('p'+obname, 'tc', Expression("clockbetat(obligatory,"+str(i)+',w'+obname+',inputlist,D)')) | 189 | + n.add_output('p'+obname, 'tc', snk.Expression("clockbetat(obligatory,"+str(i)+',w'+obname+',inputlist,D)')) |
195 | 190 | ||
196 | 191 | ||
197 | ## potential activities | 192 | ## potential activities |
... | @@ -200,15 +195,15 @@ def andy2snakes(entities, potential, obligatory): | ... | @@ -200,15 +195,15 @@ def andy2snakes(entities, potential, obligatory): |
200 | trname = 'tr'+str(i) | 195 | trname = 'tr'+str(i) |
201 | 196 | ||
202 | # for every potential activity connect corresponding place to clock | 197 | # for every potential activity connect corresponding place to clock |
203 | - n.add_place(Place('p'+trname, [0])) | 198 | + n.add_place(snk.Place('p'+trname, [0])) |
204 | - n.add_input('p'+trname, 'tc', Variable('w'+trname)) | 199 | + n.add_input('p'+trname, 'tc', snk.Variable('w'+trname)) |
205 | - n.add_output('p'+trname, 'tc', Expression('min(D,w'+trname+'+1)')) | 200 | + n.add_output('p'+trname, 'tc', snk.Expression('min(D,w'+trname+'+1)')) |
206 | 201 | ||
207 | 202 | ||
208 | activators = potential[i][0] | 203 | activators = potential[i][0] |
209 | inhibitors = potential[i][1] | 204 | inhibitors = potential[i][1] |
210 | results = potential[i][2] | 205 | results = potential[i][2] |
211 | - print results | 206 | + #print results |
212 | n.globals["results"+trname] = results | 207 | n.globals["results"+trname] = results |
213 | duration = potential[i][3] | 208 | duration = potential[i][3] |
214 | 209 | ||
... | @@ -240,14 +235,14 @@ def andy2snakes(entities, potential, obligatory): | ... | @@ -240,14 +235,14 @@ def andy2snakes(entities, potential, obligatory): |
240 | level = str(inhibitors[nameinhib[j]]) | 235 | level = str(inhibitors[nameinhib[j]]) |
241 | guard += ' and l'+spec+'< '+ level + ' and lambda' +spec+'['+level+']>='+str(duration) | 236 | guard += ' and l'+spec+'< '+ level + ' and lambda' +spec+'['+level+']>='+str(duration) |
242 | 237 | ||
243 | - n.add_transition(Transition(trname, Expression(guard))) | 238 | + n.add_transition(snk.Transition(trname, snk.Expression(guard))) |
244 | - n.add_input('p'+trname, trname, Variable('w')) | 239 | + n.add_input('p'+trname, trname, snk.Variable('w')) |
245 | - n.add_output('p'+trname, trname, Expression('0')) | 240 | + n.add_output('p'+trname, trname, snk.Expression('0')) |
246 | 241 | ||
247 | # arcs of the transition from and to involved entities | 242 | # arcs of the transition from and to involved entities |
248 | for j in range(0,len(names)) : | 243 | for j in range(0,len(names)) : |
249 | - n.add_input(names[j], trname, Tuple([Variable('l'+names[j]), Variable('u'+names[j]), Variable('lambda'+names[j]) ])) | 244 | + n.add_input(names[j], trname, snk.Tuple([snk.Variable('l'+names[j]), snk.Variable('u'+names[j]), snk.Variable('lambda'+names[j]) ])) |
250 | - n.add_output(names[j], trname, Expression("potentialt(" +names[j]+",l"+names[j]+',u'+names[j]+',lambda'+names[j]+', results'+trname+')')) | 245 | + n.add_output(names[j], trname, snk.Expression("potentialt(" +names[j]+",l"+names[j]+',u'+names[j]+',lambda'+names[j]+', results'+trname+')')) |
251 | 246 | ||
252 | return n | 247 | return n |
253 | 248 | ||
... | @@ -255,7 +250,7 @@ def andy2snakes(entities, potential, obligatory): | ... | @@ -255,7 +250,7 @@ def andy2snakes(entities, potential, obligatory): |
255 | def draw_net(net, out_name='repress'): | 250 | def draw_net(net, out_name='repress'): |
256 | net.draw(out_name+'.ps') | 251 | net.draw(out_name+'.ps') |
257 | 252 | ||
258 | -def draw_stategraph(net, entities_names, out_name='repressgraph', | 253 | +def draw_stategraph(snk, net, entities_names, out_name='repressgraph', |
259 | with_dot=True): | 254 | with_dot=True): |
260 | def node_attr (state, graph, attr) : | 255 | def node_attr (state, graph, attr) : |
261 | marking = graph[state] | 256 | marking = graph[state] |
... | @@ -264,7 +259,7 @@ def draw_stategraph(net, entities_names, out_name='repressgraph', | ... | @@ -264,7 +259,7 @@ def draw_stategraph(net, entities_names, out_name='repressgraph', |
264 | def edge_attr (trans, mode, attr) : | 259 | def edge_attr (trans, mode, attr) : |
265 | attr["label"] = trans.name | 260 | attr["label"] = trans.name |
266 | 261 | ||
267 | - s = StateGraph(net) | 262 | + s = snk.StateGraph(net) |
268 | s.build() | 263 | s.build() |
269 | 264 | ||
270 | s.draw(out_name+'.ps', node_attr=node_attr, edge_attr=edge_attr, | 265 | s.draw(out_name+'.ps', node_attr=node_attr, edge_attr=edge_attr, |
... | @@ -278,6 +273,9 @@ def draw_stategraph(net, entities_names, out_name='repressgraph', | ... | @@ -278,6 +273,9 @@ def draw_stategraph(net, entities_names, out_name='repressgraph', |
278 | g.render(out_name+"-layout.dot", engine="dot") | 273 | g.render(out_name+"-layout.dot", engine="dot") |
279 | 274 | ||
280 | if __name__=='__main__': | 275 | if __name__=='__main__': |
276 | + import snakes.plugins | ||
277 | + snakes.plugins.load(['gv', 'ops'], 'snakes.nets', 'snk') | ||
278 | + | ||
281 | # entities: tuple of name of the entities, initial level, tuple of decays 0 | 279 | # entities: tuple of name of the entities, initial level, tuple of decays 0 |
282 | # denotes unbounded decay (omega) | 280 | # denotes unbounded decay (omega) |
283 | # examples: | 281 | # examples: |
... | @@ -325,7 +323,7 @@ if __name__=='__main__': | ... | @@ -325,7 +323,7 @@ if __name__=='__main__': |
325 | 323 | ||
326 | obligatory = () | 324 | obligatory = () |
327 | 325 | ||
328 | - net = andy2snakes(entities, potential, obligatory) | 326 | + net = andy2snakes(snk, entities, potential, obligatory) |
329 | draw_net(net, out_name="repress") | 327 | draw_net(net, out_name="repress") |
330 | - draw_stategraph(net, ("s1", "s2", "s3"), out_name="repressgraph") | 328 | + draw_stategraph(snk, net, ("s1", "s2", "s3"), out_name="repressgraph") |
331 | 329 | ... | ... |
snakes/utils/andy/build.py
deleted
100644 → 0
1 | -import sys, operator, inspect, re, collections | ||
2 | -from snakes.utils.abcd import CompilationError, DeclarationError | ||
3 | -from snakes.lang.abcd.parser import ast | ||
4 | -from snakes.lang import unparse | ||
5 | -import snakes.utils.abcd.transform as transform | ||
6 | -from snakes.data import MultiSet | ||
7 | -from snakes import * | ||
8 | - | ||
9 | -class Decl (object) : | ||
10 | - OBJECT = "object" | ||
11 | - TYPE = "type" | ||
12 | - BUFFER = "buffer" | ||
13 | - SYMBOL = "symbol" | ||
14 | - CONST = "const" | ||
15 | - NET = "net" | ||
16 | - TASK = "task" | ||
17 | - IMPORT = "import" | ||
18 | - def __init__ (self, node, kind=None, **data) : | ||
19 | - self.node = node | ||
20 | - classname = node.__class__.__name__ | ||
21 | - if kind is not None : | ||
22 | - self.kind = kind | ||
23 | - elif classname == "AbcdTypedef" : | ||
24 | - self.kind = self.TYPE | ||
25 | - elif classname == "AbcdBuffer" : | ||
26 | - self.kind = self.BUFFER | ||
27 | - elif classname == "AbcdSymbol" : | ||
28 | - self.kind = self.SYMBOL | ||
29 | - elif classname == "AbcdConst" : | ||
30 | - self.kind = self.CONST | ||
31 | - elif classname == "AbcdNet" : | ||
32 | - self.kind = self.NET | ||
33 | - elif classname == "AbcdTask" : | ||
34 | - self.kind = self.TASK | ||
35 | - elif classname in ("Import", "ImportFrom") : | ||
36 | - self.kind = self.IMPORT | ||
37 | - else : | ||
38 | - self.kind = self.OBJECT | ||
39 | - for key, val in data.items() : | ||
40 | - setattr(self, key, val) | ||
41 | - | ||
42 | -class GetInstanceArgs (object) : | ||
43 | - """Bind arguments for a net instance | ||
44 | - """ | ||
45 | - def __init__ (self, node) : | ||
46 | - self.argspec = [] | ||
47 | - self.arg = {} | ||
48 | - self.buffer = {} | ||
49 | - self.net = {} | ||
50 | - self.task = {} | ||
51 | - seen = set() | ||
52 | - for a in node.args.args + node.args.kwonlyargs : | ||
53 | - if a.arg in seen : | ||
54 | - self._raise(CompilationError, | ||
55 | - "duplicate argument %r" % a.arg) | ||
56 | - seen.add(a.arg) | ||
57 | - if a.annotation is None : | ||
58 | - self.argspec.append((a.arg, "arg")) | ||
59 | - else : | ||
60 | - self.argspec.append((a.arg, a.annotation.id)) | ||
61 | - def __call__ (self, *args) : | ||
62 | - self.arg.clear() | ||
63 | - self.buffer.clear() | ||
64 | - self.net.clear() | ||
65 | - self.task.clear() | ||
66 | - for (name, kind), value in zip(self.argspec, args) : | ||
67 | - getattr(self, kind)[name] = value | ||
68 | - return self.arg, self.buffer, self.net, self.task | ||
69 | - | ||
70 | -class Builder (object) : | ||
71 | - def __init__ (self, snk, path=[], up=None) : | ||
72 | - self.snk = snk | ||
73 | - self.path = path | ||
74 | - self.up = up | ||
75 | - self.env = {"True": Decl(None, kind=Decl.CONST, value=True), | ||
76 | - "False": Decl(None, kind=Decl.CONST, value=False), | ||
77 | - "None": Decl(None, kind=Decl.CONST, value=None), | ||
78 | - "dot": Decl(None, kind=Decl.CONST, value=self.snk.dot), | ||
79 | - "BlackToken": Decl(None, kind=Decl.TYPE, | ||
80 | - type=self.snk.Instance(self.snk.BlackToken))} | ||
81 | - self.stack = [] | ||
82 | - if up : | ||
83 | - self.globals = up.globals | ||
84 | - else : | ||
85 | - self.globals = snk.Evaluator(dot=self.snk.dot, | ||
86 | - BlackToken=self.snk.BlackToken) | ||
87 | - self.instances = MultiSet() | ||
88 | - # utilities | ||
89 | - def _raise (self, error, message) : | ||
90 | - """raise an exception with appropriate location | ||
91 | - """ | ||
92 | - if self.stack : | ||
93 | - pos = "[%s:%s]: " % (self.stack[-1].lineno, | ||
94 | - self.stack[-1].col_offset) | ||
95 | - else : | ||
96 | - pos = "" | ||
97 | - raise error(pos+message) | ||
98 | - def _eval (self, expr, *largs, **kwargs) : | ||
99 | - env = self.globals.copy() | ||
100 | - if isinstance(expr, ast.AST) : | ||
101 | - expr = unparse(expr) | ||
102 | - return env(expr, dict(*largs, **kwargs)) | ||
103 | - # declarations management | ||
104 | - def __setitem__ (self, name, value) : | ||
105 | - if name in self.env : | ||
106 | - self._raise(DeclarationError, "duplicated declaration of %r" % name) | ||
107 | - self.env[name] = value | ||
108 | - def __getitem__ (self, name) : | ||
109 | - if name in self.env : | ||
110 | - return self.env[name] | ||
111 | - elif self.up is None : | ||
112 | - self._raise(DeclarationError, "%r not declared" % name) | ||
113 | - else : | ||
114 | - return self.up[name] | ||
115 | - def __contains__ (self, name) : | ||
116 | - if name in self.env : | ||
117 | - return True | ||
118 | - elif self.up is None : | ||
119 | - return False | ||
120 | - else : | ||
121 | - return name in self.up | ||
122 | - def goto (self, name) : | ||
123 | - if name in self.env : | ||
124 | - return self | ||
125 | - elif self.up is None : | ||
126 | - self._raise(DeclarationError, "%r not declared" % name) | ||
127 | - else : | ||
128 | - return self.up.goto(name) | ||
129 | - def get_buffer (self, name) : | ||
130 | - if name not in self : | ||
131 | - self._raise(DeclarationError, | ||
132 | - "buffer %r not declared" % name) | ||
133 | - decl = self[name] | ||
134 | - if decl.kind != Decl.BUFFER : | ||
135 | - self._raise(DeclarationError, | ||
136 | - "%r declared as %s but used as buffer" | ||
137 | - % (name, decl.kind)) | ||
138 | - elif decl.capacity is not None : | ||
139 | - pass | ||
140 | - #self._raise(NotImplementedError, "capacities not (yet) supported") | ||
141 | - return decl | ||
142 | - def get_net (self, name) : | ||
143 | - if name not in self : | ||
144 | - self._raise(DeclarationError, | ||
145 | - "net %r not declared" % name) | ||
146 | - decl = self[name] | ||
147 | - if decl.kind != Decl.NET : | ||
148 | - self._raise(DeclarationError, | ||
149 | - "%r declared as %s but used as net" | ||
150 | - % (name, decl.kind)) | ||
151 | - return decl | ||
152 | - def get_task (self, name) : | ||
153 | - if name not in self : | ||
154 | - self._raise(DeclarationError, | ||
155 | - "task %r not declared" % name) | ||
156 | - decl = self[name] | ||
157 | - if decl.kind != Decl.TASK : | ||
158 | - self._raise(DeclarationError, | ||
159 | - "%r declared as %s but used as task" | ||
160 | - % (name, decl.kind)) | ||
161 | - return decl | ||
162 | - # main compiler entry point | ||
163 | - def build (self, node, prefix="", fallback=None) : | ||
164 | - self.stack.append(node) | ||
165 | - if prefix : | ||
166 | - prefix += "_" | ||
167 | - method = "build_" + prefix + node.__class__.__name__ | ||
168 | - visitor = getattr(self, method, fallback or self.build_fail) | ||
169 | - try : | ||
170 | - return visitor(node) | ||
171 | - finally : | ||
172 | - self.stack.pop(-1) | ||
173 | - def build_fail (self, node) : | ||
174 | - self._raise(CompilationError, "do not know how to compile %s" | ||
175 | - % node.__class__.__name__) | ||
176 | - def build_arc (self, node) : | ||
177 | - return self.build(node, "arc", self.build_arc_expr) | ||
178 | - # specification | ||
179 | - def build_AbcdSpec (self, node) : | ||
180 | - for decl in node.context : | ||
181 | - self.build(decl) | ||
182 | - tasks = [self._build_TaskNet(decl.node) | ||
183 | - for name, decl in self.env.items() | ||
184 | - if decl.kind == Decl.TASK and decl.used] | ||
185 | - net = reduce(operator.or_, tasks, self.build(node.body)) | ||
186 | - # set local buffers marking, and hide them | ||
187 | - for name, decl in ((n, d) for n, d in self.env.items() | ||
188 | - if d.kind == Decl.BUFFER) : | ||
189 | - status = self.snk.buffer(name) | ||
190 | - for place in net.status(status) : | ||
191 | - place = net.place(place) | ||
192 | - try : | ||
193 | - place.reset(decl.marking) | ||
194 | - except ValueError as err : | ||
195 | - self._raise(CompilationError, | ||
196 | - "invalid initial marking (%s)" % err) | ||
197 | - if decl.capacity is None : | ||
198 | - cap = None | ||
199 | - else : | ||
200 | - #cap = [c.n if c else None for c in decl.capacity] | ||
201 | - # TODO: accept more than integers as capacities | ||
202 | - cap = [] | ||
203 | - for c in decl.capacity : | ||
204 | - if c is None : | ||
205 | - cap.append(None) | ||
206 | - else : | ||
207 | - try : | ||
208 | - cap.append(self._eval(c)) | ||
209 | - except : | ||
210 | - err = sys.exc_info()[1] | ||
211 | - self._raise(CompilationError, | ||
212 | - "could not evaluate %r, %s" | ||
213 | - % (unparse(c), err)) | ||
214 | - place.label(path=self.path, | ||
215 | - capacity=cap) | ||
216 | - # TODO: check capacity | ||
217 | - net.hide(status) | ||
218 | - if self.up is None : | ||
219 | - # set entry marking | ||
220 | - for place in net.status(self.snk.entry) : | ||
221 | - net.place(place).reset(self.snk.dot) | ||
222 | - # rename nodes | ||
223 | - self._rename_nodes(net) | ||
224 | - # copy global declarations | ||
225 | - net.globals.update(self.globals) | ||
226 | - # add info about source file | ||
227 | - net.label(srcfile=str(node.st.text.filename)) | ||
228 | - # add assertions | ||
229 | - net.label(asserts=node.asserts) | ||
230 | - return net | ||
231 | - def _build_TaskNet (self, node) : | ||
232 | - self._raise(NotImplementedError, "tasks not (yet) supported") | ||
233 | - def _rename_nodes (self, net) : | ||
234 | - # generate unique names | ||
235 | - total = collections.defaultdict(int) | ||
236 | - count = collections.defaultdict(int) | ||
237 | - def ren (node) : | ||
238 | - if net.has_transition(node.name) : | ||
239 | - status = node.label("srctext") | ||
240 | - else : | ||
241 | - if node.status == self.snk.entry : | ||
242 | - status = "e" | ||
243 | - elif node.status == self.snk.internal : | ||
244 | - status = "i" | ||
245 | - elif node.status == self.snk.exit : | ||
246 | - status = "x" | ||
247 | - else : | ||
248 | - status = node.label("buffer") | ||
249 | - name = ".".join(node.label("path") + [status]) | ||
250 | - if total[name] > 1 : | ||
251 | - count[name] += 1 | ||
252 | - name = "%s#%s" % (name, count[name]) | ||
253 | - return name | ||
254 | - # count occurrences of each name base | ||
255 | - _total = collections.defaultdict(int) | ||
256 | - for node in net.node() : | ||
257 | - _total[ren(node)] += 1 | ||
258 | - total = _total | ||
259 | - # rename nodes using a depth-first traversal | ||
260 | - done = set(net.status(self.snk.entry)) | ||
261 | - todo = [net.node(n) for n in done] | ||
262 | - while todo : | ||
263 | - node = todo.pop(-1) | ||
264 | - new = ren(node) | ||
265 | - if new != node.name : | ||
266 | - net.rename_node(node.name, new) | ||
267 | - done.add(new) | ||
268 | - for n in net.post(new) - done : | ||
269 | - todo.append(net.node(n)) | ||
270 | - done.add(n) | ||
271 | - # rename isolated nodes | ||
272 | - for letter, method in (("p", net.place), ("t", net.transition)) : | ||
273 | - for node in method() : | ||
274 | - if node.name not in done : | ||
275 | - net.rename_node(node.name, ren(node)) | ||
276 | - # declarations | ||
277 | - def build_AbcdTypedef (self, node) : | ||
278 | - """ | ||
279 | - >>> import snakes.nets | ||
280 | - >>> b = Builder(snakes.nets) | ||
281 | - >>> b.build(ast.AbcdTypedef(name='number', type=ast.UnionType(types=[ast.NamedType(name='int'), ast.NamedType(name='float')]))) | ||
282 | - >>> b.env['number'].type | ||
283 | - (Instance(int) | Instance(float)) | ||
284 | - >>> b.build(ast.ImportFrom(module='inspect', names=[ast.alias(name='isbuiltin')])) | ||
285 | - >>> b.build(ast.AbcdTypedef(name='builtin', type=ast.NamedType(name='isbuiltin'))) | ||
286 | - >>> b.env['builtin'].type | ||
287 | - TypeCheck(inspect.isbuiltin) | ||
288 | - """ | ||
289 | - self[node.name] = Decl(node, type=self.build(node.type)) | ||
290 | - def build_AbcdBuffer (self, node) : | ||
291 | - self[node.name] = Decl(node, | ||
292 | - type=self.build(node.type), | ||
293 | - capacity=node.capacity, | ||
294 | - marking=self._eval(node.content)) | ||
295 | - def build_AbcdSymbol (self, node) : | ||
296 | - for name in node.symbols : | ||
297 | - value = self.snk.Symbol(name, False) | ||
298 | - self[name] = Decl(node, value=value) | ||
299 | - self.globals[name] = value | ||
300 | - def build_AbcdConst (self, node) : | ||
301 | - value = self._eval(node.value) | ||
302 | - self[node.name] = Decl(node, value=value) | ||
303 | - self.globals[node.name] = value | ||
304 | - def build_AbcdNet (self, node) : | ||
305 | - self[node.name] = Decl(node, getargs=GetInstanceArgs(node)) | ||
306 | - def build_AbcdTask (self, node) : | ||
307 | - self._raise(NotImplementedError, "tasks not (yet) supported") | ||
308 | - self[node.name] = Decl(node, used=False) | ||
309 | - def build_Import (self, node) : | ||
310 | - for alias in node.names : | ||
311 | - self[alias.asname or alias.name] = Decl(node) | ||
312 | - self.globals.declare(unparse(node)) | ||
313 | - def build_ImportFrom (self, node) : | ||
314 | - self.build_Import(node) | ||
315 | - # processes | ||
316 | - def build_AbcdAction (self, node) : | ||
317 | - if node.guard is True : | ||
318 | - return self._build_True(node) | ||
319 | - elif node.guard is False : | ||
320 | - return self._build_False(node) | ||
321 | - else : | ||
322 | - return self._build_action(node) | ||
323 | - def _build_True (self, node) : | ||
324 | - net = self.snk.PetriNet("true") | ||
325 | - e = self.snk.Place("e", [], self.snk.tBlackToken, | ||
326 | - status=self.snk.entry) | ||
327 | - e.label(path=self.path) | ||
328 | - net.add_place(e) | ||
329 | - x = self.snk.Place("x", [], self.snk.tBlackToken, | ||
330 | - status=self.snk.exit) | ||
331 | - x.label(path=self.path) | ||
332 | - net.add_place(x) | ||
333 | - t = self.snk.Transition("t") | ||
334 | - t.label(srctext=node.st.source(), | ||
335 | - srcloc=(node.st.srow, node.st.scol, | ||
336 | - node.st.erow, node.st.ecol), | ||
337 | - path=self.path) | ||
338 | - net.add_transition(t) | ||
339 | - net.add_input("e", "t", self.snk.Value(self.snk.dot)) | ||
340 | - net.add_output("x", "t", self.snk.Value(self.snk.dot)) | ||
341 | - return net | ||
342 | - def _build_False (self, node) : | ||
343 | - net = self.snk.PetriNet("false") | ||
344 | - e = self.snk.Place("e", [], self.snk.tBlackToken, | ||
345 | - status=self.snk.entry) | ||
346 | - e.label(path=self.path) | ||
347 | - net.add_place(e) | ||
348 | - x = self.snk.Place("x", [], self.snk.tBlackToken, | ||
349 | - status=self.snk.exit) | ||
350 | - x.label(path=self.path) | ||
351 | - net.add_place(x) | ||
352 | - return net | ||
353 | - def _build_action (self, node) : | ||
354 | - net = self.snk.PetriNet("flow") | ||
355 | - e = self.snk.Place("e", [], self.snk.tBlackToken, | ||
356 | - status=self.snk.entry) | ||
357 | - e.label(path=self.path) | ||
358 | - net.add_place(e) | ||
359 | - x = self.snk.Place("x", [], self.snk.tBlackToken, | ||
360 | - status=self.snk.exit) | ||
361 | - x.label(path=self.path) | ||
362 | - net.add_place(x) | ||
363 | - t = self.snk.Transition("t", self.snk.Expression(unparse(node.guard)), | ||
364 | - status=self.snk.tick("action")) | ||
365 | - t.label(srctext=node.st.source(), | ||
366 | - srcloc=(node.st.srow, node.st.scol, | ||
367 | - node.st.erow, node.st.ecol), | ||
368 | - path=self.path) | ||
369 | - net.add_transition(t) | ||
370 | - net.add_input("e", "t", self.snk.Value(self.snk.dot)) | ||
371 | - net.add_output("x", "t", self.snk.Value(self.snk.dot)) | ||
372 | - net = reduce(operator.or_, [self.build(a) for a in node.accesses], | ||
373 | - net) | ||
374 | - net.hide(self.snk.tick("action")) | ||
375 | - return net | ||
376 | - def build_AbcdFlowOp (self, node) : | ||
377 | - return self.build(node.op)(self.build(node.left), | ||
378 | - self.build(node.right)) | ||
379 | - def _get_instance_arg (self, arg) : | ||
380 | - if arg.__class__.__name__ == "Name" and arg.id in self : | ||
381 | - return self[arg.id] | ||
382 | - else : | ||
383 | - try : | ||
384 | - self._eval(arg) | ||
385 | - except : | ||
386 | - self._raise(CompilationError, | ||
387 | - "could not evaluate argument %r" | ||
388 | - % arg.st.source()) | ||
389 | - return arg | ||
390 | - def build_AbcdInstance (self, node) : | ||
391 | - if node.net not in self : | ||
392 | - self._raise(DeclarationError, "%r not declared" % node.net) | ||
393 | - elif node.starargs : | ||
394 | - self._raise(CompilationError, "* argument not allowed here") | ||
395 | - elif node.kwargs : | ||
396 | - self._raise(CompilationError, "** argument not allowed here") | ||
397 | - decl = self[node.net] | ||
398 | - if decl.kind != Decl.NET : | ||
399 | - self._raise(DeclarationError, | ||
400 | - "%r declared as %s but used as net" | ||
401 | - % (name, decl.kind)) | ||
402 | - # unpack args | ||
403 | - posargs, kwargs = [], {} | ||
404 | - for arg in node.args : | ||
405 | - posargs.append(self._get_instance_arg(arg)) | ||
406 | - for kw in node.keywords : | ||
407 | - kwargs[kw.arg] = self._get_instance_arg(kw.value) | ||
408 | - # bind args | ||
409 | - try : | ||
410 | - args, buffers, nets, tasks = decl.getargs(*posargs, **kwargs) | ||
411 | - except TypeError : | ||
412 | - c, v, t = sys.exc_info() | ||
413 | - self._raise(CompilationError, str(v)) | ||
414 | - for d, kind in ((buffers, Decl.BUFFER), | ||
415 | - (nets, Decl.NET), | ||
416 | - (tasks, Decl.TASK)) : | ||
417 | - for k, v in d.items() : | ||
418 | - if v.kind != kind : | ||
419 | - self._raise(DeclarationError, | ||
420 | - "%r declared as %s but used as %s" | ||
421 | - % (k, v.kind, kind)) | ||
422 | - d[k] = v.node.name | ||
423 | - # build sub-net | ||
424 | - binder = transform.ArgsBinder(args, buffers, nets, tasks) | ||
425 | - spec = binder.visit(decl.node.body) | ||
426 | - if node.asname : | ||
427 | - name = str(node.asname) | ||
428 | - else : | ||
429 | - name = node.st.source() | ||
430 | - if name in self.instances : | ||
431 | - name = "%s#%s" % (name, self.instances(name)) | ||
432 | - self.instances.add(name) | ||
433 | - path = self.path + [name] | ||
434 | - builder = self.__class__(self.snk, path, self) | ||
435 | - net = builder.build(spec) | ||
436 | - src = (node.st.source(), | ||
437 | - node.st.srow, node.st.scol, | ||
438 | - node.st.erow, node.st.ecol) | ||
439 | - for trans in net.transition() : | ||
440 | - try : | ||
441 | - lbl = trans.label("instances") | ||
442 | - trans.label(instances=[src] + lbl) | ||
443 | - except KeyError : | ||
444 | - trans.label(instances=[src]) | ||
445 | - for place in net.place() : | ||
446 | - if place.status == self.snk.Status(None) : | ||
447 | - try : | ||
448 | - lbl = place.label("instances") | ||
449 | - place.label(instances=[src] + lbl) | ||
450 | - except KeyError : | ||
451 | - place.label(instances=[src]) | ||
452 | - return net | ||
453 | - # control flow operations | ||
454 | - def build_Sequence (self, node) : | ||
455 | - return self.snk.PetriNet.__and__ | ||
456 | - def build_Choice (self, node) : | ||
457 | - return self.snk.PetriNet.__add__ | ||
458 | - def build_Parallel (self, node) : | ||
459 | - return self.snk.PetriNet.__or__ | ||
460 | - def build_Loop (self, node) : | ||
461 | - return self.snk.PetriNet.__mul__ | ||
462 | - # accesses : | ||
463 | - def build_SimpleAccess (self, node) : | ||
464 | - decl = self.get_buffer(node.buffer) | ||
465 | - net = self.snk.PetriNet("access") | ||
466 | - net.add_transition(self.snk.Transition("t", status=self.snk.tick("action"))) | ||
467 | - b = self.snk.Place(str(node.buffer), [], decl.type, | ||
468 | - status=self.snk.buffer(node.buffer)) | ||
469 | - b.label(path=self.path, | ||
470 | - buffer=str(node.buffer), | ||
471 | - srctext=decl.node.st.source(), | ||
472 | - srcloc=(decl.node.st.srow, decl.node.st.scol, | ||
473 | - decl.node.st.erow, decl.node.st.ecol)) | ||
474 | - net.add_place(b) | ||
475 | - self.build(node.arc)(net, node.buffer, "t", self.build_arc(node.tokens)) | ||
476 | - return net | ||
477 | - def build_FlushAccess (self, node) : | ||
478 | - decl = self.get_buffer(node.buffer) | ||
479 | - net = self.snk.PetriNet("access") | ||
480 | - net.add_transition(self.snk.Transition("t", status=self.snk.tick("action"))) | ||
481 | - b = self.snk.Place(str(node.buffer), [], decl.type, | ||
482 | - status=self.snk.buffer(node.buffer)) | ||
483 | - b.label(path=self.path, | ||
484 | - buffer=str(node.buffer), | ||
485 | - srctext=decl.node.st.source(), | ||
486 | - srcloc=(decl.node.st.srow, decl.node.st.scol, | ||
487 | - decl.node.st.erow, decl.node.st.ecol)) | ||
488 | - net.add_place(b) | ||
489 | - net.add_input(node.buffer, "t", self.snk.Flush(node.target)) | ||
490 | - return net | ||
491 | - def build_SwapAccess (self, node) : | ||
492 | - decl = self.get_buffer(node.buffer) | ||
493 | - net = self.snk.PetriNet("access") | ||
494 | - net.add_transition(self.snk.Transition("t", status=self.snk.tick("action"))) | ||
495 | - b = self.snk.Place(node.buffer, [], decl.type, | ||
496 | - status=self.snk.buffer(node.buffer)) | ||
497 | - b.label(path=self.path, | ||
498 | - buffer=str(node.buffer), | ||
499 | - srctext=decl.node.st.source(), | ||
500 | - srcloc=(decl.node.st.srow, decl.node.st.scol, | ||
501 | - decl.node.st.erow, decl.node.st.ecol)) | ||
502 | - net.add_place(b) | ||
503 | - net.add_input(node.buffer, "t", self.build_arc(node.target)) | ||
504 | - net.add_output(node.buffer, "t", self.build_arc(node.tokens)) | ||
505 | - return net | ||
506 | - def build_Spawn (self, node) : | ||
507 | - self._raise(NotImplementedError, "tasks not (yet) supported") | ||
508 | - def build_Wait (self, node) : | ||
509 | - self._raise(NotImplementedError, "tasks not (yet) supported") | ||
510 | - def build_Suspend (self, node) : | ||
511 | - self._raise(NotImplementedError, "tasks not (yet) supported") | ||
512 | - def build_Resume (self, node) : | ||
513 | - self._raise(NotImplementedError, "tasks not (yet) supported") | ||
514 | - # arc labels | ||
515 | - def build_arc_Name (self, node) : | ||
516 | - if node.id in self : | ||
517 | - decl = self[node.id] | ||
518 | - if decl.kind in (Decl.CONST, Decl.SYMBOL) : | ||
519 | - return self.snk.Value(decl.value) | ||
520 | - return self.snk.Variable(node.id) | ||
521 | - def build_arc_Num (self, node) : | ||
522 | - return self.snk.Value(node.n) | ||
523 | - def build_arc_Str (self, node) : | ||
524 | - return self.snk.Value(node.s) | ||
525 | - def build_arc_Tuple (self, node) : | ||
526 | - return self.snk.Tuple([self.build_arc(elt) for elt in node.elts]) | ||
527 | - def build_arc_expr (self, node) : | ||
528 | - return self.snk.Expression(unparse(node)) | ||
529 | - # arcs | ||
530 | - def build_Produce (self, node) : | ||
531 | - def arc (net, place, trans, label) : | ||
532 | - net.add_output(place, trans, label) | ||
533 | - return arc | ||
534 | - def build_Test (self, node) : | ||
535 | - def arc (net, place, trans, label) : | ||
536 | - net.add_input(place, trans, self.snk.Test(label)) | ||
537 | - return arc | ||
538 | - def build_Consume (self, node) : | ||
539 | - def arc (net, place, trans, label) : | ||
540 | - net.add_input(place, trans, label) | ||
541 | - return arc | ||
542 | - def build_Fill (self, node) : | ||
543 | - def arc (net, place, trans, label) : | ||
544 | - net.add_output(place, trans, self.snk.Flush(str(label))) | ||
545 | - return arc | ||
546 | - # types | ||
547 | - def build_UnionType (self, node) : | ||
548 | - return reduce(operator.or_, (self.build(child) | ||
549 | - for child in node.types)) | ||
550 | - def build_IntersectionType (self, node) : | ||
551 | - return reduce(operator.and_, (self.build(child) | ||
552 | - for child in node.types)) | ||
553 | - def build_CrossType (self, node) : | ||
554 | - return self.snk.CrossProduct(*(self.build(child) | ||
555 | - for child in node.types)) | ||
556 | - def build_ListType (self, node) : | ||
557 | - return self.snk.List(self.build(node.items)) | ||
558 | - def build_TupleType (self, node) : | ||
559 | - return self.snk.Collection(self.snk.Instance(tuple), | ||
560 | - (self.build(node.items))) | ||
561 | - def build_SetType (self, node) : | ||
562 | - return self.snk.Set(self.build(node.items)) | ||
563 | - def build_DictType (self, node) : | ||
564 | - return self.snk.Mapping(keys=self.build(node.keys), | ||
565 | - items=self.build(node.items), | ||
566 | - _dict=self.snk.Instance(self.snk.hdict)) | ||
567 | - def build_EnumType (self, node) : | ||
568 | - return self.snk.OneOf(*(self._eval(child) for child in node.items)) | ||
569 | - def build_NamedType (self, node) : | ||
570 | - name = node.name | ||
571 | - if name in self and self[name].kind == Decl.TYPE : | ||
572 | - return self[name].type | ||
573 | - elif name in self.globals : | ||
574 | - obj = self.globals[name] | ||
575 | - if inspect.isclass(obj) : | ||
576 | - return self.snk.Instance(obj) | ||
577 | - elif inspect.isroutine(obj) : | ||
578 | - return self.snk.TypeCheck(obj) | ||
579 | - elif hasattr(sys.modules["__builtin__"], name) : | ||
580 | - obj = getattr(sys.modules["__builtin__"], name) | ||
581 | - if inspect.isclass(obj) : | ||
582 | - return self.snk.Instance(obj) | ||
583 | - elif inspect.isroutine(obj) : | ||
584 | - return self.snk.TypeCheck(obj) | ||
585 | - self._raise(CompilationError, | ||
586 | - "invalid type %r" % name) | ||
587 | - | ||
588 | -if __name__ == "__main__" : | ||
589 | - import doctest | ||
590 | - doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE | ||
591 | - | doctest.REPORT_ONLY_FIRST_FAILURE | ||
592 | - | doctest.ELLIPSIS) | ||
593 | - from snakes.lang.abcd.parser import parse | ||
594 | - node = parse(open(sys.argv[1]).read()) | ||
595 | - import snakes.plugins | ||
596 | - snk = snakes.plugins.load(["ops", "gv", "labels"], "snakes.nets", "snk") | ||
597 | - build = Builder(snk) | ||
598 | - net = build.build(node) | ||
599 | - net.draw(sys.argv[1] + ".png") |
snakes/utils/andy/checker.py
deleted
100644 → 0
1 | -import heapq | ||
2 | -from snakes.nets import StateGraph | ||
3 | -import snakes.lang | ||
4 | -import snkast as ast | ||
5 | - | ||
6 | -class Checker (object) : | ||
7 | - def __init__ (self, net) : | ||
8 | - self.g = StateGraph(net) | ||
9 | - self.f = [self.build(f) for f in net.label("asserts")] | ||
10 | - def build (self, tree) : | ||
11 | - src = """ | ||
12 | -def check (_) : | ||
13 | - return %s | ||
14 | -""" % tree.st.source()[7:] | ||
15 | - ctx = dict(self.g.net.globals) | ||
16 | - ctx["bounded"] = self.bounded | ||
17 | - exec(src, ctx) | ||
18 | - fun = ctx["check"] | ||
19 | - fun.lineno = tree.lineno | ||
20 | - return fun | ||
21 | - def bounded (self, marking, max) : | ||
22 | - return all(len(marking(p)) == 1 for p in marking) | ||
23 | - def run (self) : | ||
24 | - for state in self.g : | ||
25 | - marking = self.g.net.get_marking() | ||
26 | - for place in marking : | ||
27 | - if max(marking(place).values()) > 1 : | ||
28 | - return None, self.trace(state) | ||
29 | - for check in self.f : | ||
30 | - try : | ||
31 | - if not check(marking) : | ||
32 | - return check.lineno, self.trace(state) | ||
33 | - except : | ||
34 | - pass | ||
35 | - return None, None | ||
36 | - def path (self, tgt, src=0) : | ||
37 | - q = [(0, src, ())] | ||
38 | - visited = set() | ||
39 | - while True : | ||
40 | - (c, v1, path) = heapq.heappop(q) | ||
41 | - if v1 not in visited : | ||
42 | - path = path + (v1,) | ||
43 | - if v1 == tgt : | ||
44 | - return path | ||
45 | - visited.add(v1) | ||
46 | - for v2 in self.g.successors(v1) : | ||
47 | - if v2 not in visited : | ||
48 | - heapq.heappush(q, (c+1, v2, path)) | ||
49 | - def trace (self, state) : | ||
50 | - path = self.path(state) | ||
51 | - return tuple(self.g.successors(i)[j] | ||
52 | - for i, j in zip(path[:-1], path[1:])) |
snakes/utils/andy/html.py
deleted
100644 → 0
1 | -from snakes.compat import io | ||
2 | -from snakes.lang.abcd.parser import ast, parse | ||
3 | -import os, tempfile, re, codecs, collections | ||
4 | -try : | ||
5 | - from cgi import escape | ||
6 | -except : | ||
7 | - from html import escape | ||
8 | - | ||
9 | -template_css = u"""/* ABCD source code */ | ||
10 | - .abcd { border:solid 1px #DDD; border-radius:5px; padding:5px 10px; margin:5px; background-color:#F4F4F4; overflow:auto; } | ||
11 | - .abcd .comment { color:#888; } | ||
12 | - .abcd .ident { color:#808; } | ||
13 | - .abcd .string { color:#088; } | ||
14 | - .abcd .kw { color:#800; font-weight:bold; } | ||
15 | - .abcd .flow { color:#800; font-weight:bold; } | ||
16 | - .abcd .buffer .decl { color:#080; font-weight:bold; } | ||
17 | - .abcd .net .decl { color:#008; font-weight:bold; } | ||
18 | - .abcd .instance .name { color:#008; } | ||
19 | - .abcd .action .delim { font-weight:bold; } | ||
20 | - .abcd .action .name { color:#080; } | ||
21 | - .abcd .highlight { background-color:yellow; } | ||
22 | -/* Petri net picture */ | ||
23 | - .petrinet { border:solid 1px #DDD; border-radius:5px; padding:5px 10px; margin:5px; background-color:#FFF; overflow:auto; clear:both; } | ||
24 | -/* Objects tree */ | ||
25 | - .tree { border:solid 1px #DDD; border-radius:5px; padding:5px 10px; margin:5px; background-color:#F4F4F4; overflow:auto; font-family:monospace; } | ||
26 | - .tree .kw { color:#800; font-weight:bold; } | ||
27 | - .tree .buffer { color:#080; font-weight:bold; } | ||
28 | - .tree .ident { color:#808; } | ||
29 | - .tree .instance .name { color:#008; } | ||
30 | - .tree .action .delim { font-weight:bold; } | ||
31 | - .tree .action .name { color:#080; } | ||
32 | - .tree .string { color:#088; } | ||
33 | - .tree .highlight { background-color:yellow; } | ||
34 | -""" | ||
35 | - | ||
36 | -template_html = u'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | ||
37 | -<html xmlns="http://www.w3.org/1999/xhtml"> | ||
38 | -<head><title>%(filename)s</title> | ||
39 | -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||
40 | -<style type="text/css">%(css)s</style> | ||
41 | -%(headers)s | ||
42 | -%(jscode)s | ||
43 | -</head><body> | ||
44 | -<h1><tt>%(filename)s</tt></h1> | ||
45 | -%(abcd)s | ||
46 | -%(tree)s | ||
47 | -%(svg)s | ||
48 | -</body></html> | ||
49 | -''' | ||
50 | - | ||
51 | -template_tree = '''<div class="tree">%(tree)s</div>''' | ||
52 | - | ||
53 | -template_headers = '''<script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script>''' | ||
54 | - | ||
55 | -template_jscode = '''<script type="text/javascript"> | ||
56 | -var nodeColor; | ||
57 | -function abcdon () { | ||
58 | - obj = jQuery(this); | ||
59 | - if (obj.attr("class") == "node") { | ||
60 | - node = obj.children().children().first(); | ||
61 | - nodeColor = node.attr("fill"); | ||
62 | - node.attr("fill", "yellow"); | ||
63 | - } else { | ||
64 | - obj.addClass("highlight"); | ||
65 | - } | ||
66 | - jQuery(obj.attr("data-abcd")).addClass("highlight"); | ||
67 | -}; | ||
68 | -function abcdoff () { | ||
69 | - obj = jQuery(this); | ||
70 | - if (obj.attr("class") == "node") { | ||
71 | - node = obj.children().children().first(); | ||
72 | - node.attr("fill", nodeColor); | ||
73 | - } else { | ||
74 | - obj.removeClass("highlight"); | ||
75 | - } | ||
76 | - jQuery(obj.attr("data-abcd")).removeClass("highlight"); | ||
77 | -}; | ||
78 | -function treeon () { | ||
79 | - obj = jQuery(this); | ||
80 | - if (obj.attr("class") != "node") { | ||
81 | - obj.addClass("highlight"); | ||
82 | - } | ||
83 | - jQuery(obj.attr("data-tree")).addClass("highlight"); | ||
84 | -}; | ||
85 | -function treeoff () { | ||
86 | - obj = jQuery(this); | ||
87 | - if (obj.attr("class") != "node") { | ||
88 | - obj.removeClass("highlight"); | ||
89 | - } | ||
90 | - jQuery(obj.attr("data-tree")).removeClass("highlight"); | ||
91 | -}; | ||
92 | -function neton () { | ||
93 | - obj = jQuery(this); | ||
94 | - jQuery(obj.attr("data-net")).each(function () { | ||
95 | - node = jQuery(this).children().children().first(); | ||
96 | - nodeColor = node.attr("fill"); | ||
97 | - node.attr("fill", "yellow"); | ||
98 | - }); | ||
99 | - obj.addClass("highlight"); | ||
100 | -}; | ||
101 | -function netoff () { | ||
102 | - obj = jQuery(this); | ||
103 | - jQuery(obj.attr("data-net")).each(function () { | ||
104 | - node = jQuery(this).children().children().first(); | ||
105 | - node.attr("fill", nodeColor); | ||
106 | - }); | ||
107 | - obj.removeClass("highlight"); | ||
108 | -}; | ||
109 | -function setwidth () { | ||
110 | - abcd = jQuery(".abcd"); | ||
111 | - tree = jQuery(".tree"); | ||
112 | - width = (jQuery(".petrinet").outerWidth(true) / 2) - 35; | ||
113 | - console.log(width); | ||
114 | - height = Math.max(abcd.height(), tree.height()); | ||
115 | - abcd.css({float: "left", width: width, height: height}); | ||
116 | - tree.css({float: "right", width: width, height: height}); | ||
117 | -} | ||
118 | -jQuery(document).ready(function() { | ||
119 | - jQuery("[data-abcd]").hover(abcdon, abcdoff); | ||
120 | - jQuery("[data-tree]").hover(treeon, treeoff); | ||
121 | - jQuery("[data-net]").hover(neton, netoff); | ||
122 | - jQuery(".tree .instance, .tree .action").each(function () { | ||
123 | - obj = jQuery(this); | ||
124 | - obj.html(jQuery(obj.attr("data-abcd")).html()); | ||
125 | - }); | ||
126 | - setwidth(); | ||
127 | - jQuery(window).resize(setwidth); | ||
128 | -}); | ||
129 | -</script>''' | ||
130 | - | ||
131 | -class Span (object) : | ||
132 | - def __init__ (self, cls=[], id=None, net=[], abcd=[], tree=[]) : | ||
133 | - self.cls = set([cls]) if isinstance(cls, str) else set(cls) | ||
134 | - self.id = id | ||
135 | - self.net = set([net]) if isinstance(net, str) else set(net) | ||
136 | - self.abcd = set([abcd]) if isinstance(abcd, str) else set(abcd) | ||
137 | - self.tree = set([tree]) if isinstance(tree, str) else set(tree) | ||
138 | - def copy (self, **attr) : | ||
139 | - span = self.__class__(cls=self.cls, id=self.id, net=self.net, | ||
140 | - abcd=self.abcd, tree=self.tree) | ||
141 | - for k, v in attr.items() : | ||
142 | - if isinstance(getattr(span, k), set) : | ||
143 | - v = set(v) | ||
144 | - setattr(span, k, v) | ||
145 | - return span | ||
146 | - def __bool__ (self) : | ||
147 | - return self.__nonzero__() | ||
148 | - def __nonzero__ (self) : | ||
149 | - return bool(self.cls or self.id or self.net or self.abcd | ||
150 | - or self.tree) | ||
151 | - def span (self) : | ||
152 | - attr = [] | ||
153 | - for src, dst in (("cls", "class"), ("id", "id"), | ||
154 | - ("net", "data-net"), ("abcd", "data-abcd"), | ||
155 | - ("tree", "data-tree")) : | ||
156 | - val = getattr(self, src) | ||
157 | - if not val : | ||
158 | - continue | ||
159 | - elif isinstance(val, str) : | ||
160 | - attr.append("%s=%r" % (dst, val)) | ||
161 | - elif dst.startswith("data-") : | ||
162 | - attr.append("%s=%r" % (dst, ", ".join("#" + v for v in val))) | ||
163 | - else : | ||
164 | - attr.append("%s=%r" % (dst, ", ".join(val))) | ||
165 | - return "<span %s>" % " ".join(attr) | ||
166 | - def __str__ (self) : | ||
167 | - return self.span() | ||
168 | - | ||
169 | -keywords = {"False", "True", "and", "as", "assert", "buffer", "const", | ||
170 | - "else", "enum", "for", "from", "if", "import", "in", "is", | ||
171 | - "lambda", "net", "not", "or", "symbol", "task", "typedef"} | ||
172 | - | ||
173 | -class ABCD2HTML (ast.NodeVisitor) : | ||
174 | - def __init__ (self, tree) : | ||
175 | - self.tree = tree | ||
176 | - self.x = "%%0%uX" % len("%x" % (tree.st.erow + 1)) | ||
177 | - self.st = {} | ||
178 | - self.path = [] | ||
179 | - self.nets = {} | ||
180 | - self.visit(tree) | ||
181 | - def __getitem__ (self, id) : | ||
182 | - cls = id.__class__.__name__ | ||
183 | - if cls in ("Place", "Transition") : | ||
184 | - x, y, _, _ = id.label("srcloc") | ||
185 | - c = "B" if cls == "Place" else "A" | ||
186 | - id = self.newid(c, x, y) | ||
187 | - elif isinstance(id, tuple) : | ||
188 | - id = self.newid(*id) | ||
189 | - if isinstance(self.st[id], Span) : | ||
190 | - return self.st[id] | ||
191 | - else : | ||
192 | - return self.st[id].span | ||
193 | - def newid (self, c, x, y) : | ||
194 | - return "".join([c[0].upper(), self.x % x, "%X" % y]) | ||
195 | - def setspan (self, cls, node, **args) : | ||
196 | - if isinstance(node, ast.AST) : | ||
197 | - node = node.st | ||
198 | - if cls in ("action", "buffer", "instance", "net") : | ||
199 | - x, y = node.srow, node.scol | ||
200 | - ident = self.newid(cls, x, y) | ||
201 | - ident = args.pop("id", ident) | ||
202 | - span = node.span = Span(cls=cls.lower(), id=ident, **args) | ||
203 | - self.st[ident] = node | ||
204 | - elif node is None : | ||
205 | - span = Span(cls=cls.lower(), **args) | ||
206 | - if "id" in args : | ||
207 | - self.st[args["id"]] = span | ||
208 | - else : | ||
209 | - span = node.span = Span(cls=cls.lower(), **args) | ||
210 | - if "id" in args : | ||
211 | - self.st[args["id"]] = node | ||
212 | - return span | ||
213 | - def visit_AbcdBuffer (self, node) : | ||
214 | - t = node.st | ||
215 | - while t.symbol != "abcd_buffer" : | ||
216 | - t = t[0] | ||
217 | - self.setspan("decl", t[1]) | ||
218 | - self.setspan("buffer", node) | ||
219 | - self.generic_visit(node) | ||
220 | - def visit_AbcdNet (self, node) : | ||
221 | - t = node.st | ||
222 | - while t.symbol != "abcd_net" : | ||
223 | - t = t[0] | ||
224 | - self.setspan("decl", t[1]) | ||
225 | - self.setspan("body", node.body) | ||
226 | - span = self.setspan("net", node) | ||
227 | - self.setspan("proto", None, id="P" + span.id) | ||
228 | - self.nets[".".join(self.path + [node.name])] = span.id | ||
229 | - self.path.append(node.name) | ||
230 | - self.generic_visit(node) | ||
231 | - self.path.pop(-1) | ||
232 | - def visit_AbcdInstance (self, node) : | ||
233 | - t = node.st | ||
234 | - while t.symbol != "abcd_instance" : | ||
235 | - t = t[0] | ||
236 | - self.setspan("name", t[0]) | ||
237 | - pid = "P" + self.nets[".".join(self.path + [node.net])] | ||
238 | - span = self.setspan("instance", node, abcd=[pid]) | ||
239 | - self[pid].abcd.add(span.id) | ||
240 | - self.generic_visit(node) | ||
241 | - def visit_AbcdAction (self, node) : | ||
242 | - t = node.st | ||
243 | - while t[0].text != '[' : | ||
244 | - t = t[0] | ||
245 | - span = self.setspan("action", node) | ||
246 | - self.setspan("delim", t[0], id="L" + span.id) | ||
247 | - self.setspan("delim", t[-1], id="R" + span.id) | ||
248 | - self.generic_visit(node) | ||
249 | - def visit_AbcdFlowOp (self, node) : | ||
250 | - t = node.st | ||
251 | - while len(t) == 1 : | ||
252 | - t = t[0] | ||
253 | - while t[0].text == '(' : | ||
254 | - t = t[1] | ||
255 | - for op in t[1::2] : | ||
256 | - self.setspan("flow", op) | ||
257 | - self.generic_visit(node) | ||
258 | - def visit_SimpleAccess (self, node) : | ||
259 | - self.setspan("name", node.st[0]) | ||
260 | - self.setspan("access", node) | ||
261 | - self.generic_visit(node) | ||
262 | - def visit_FlushAccess (self, node) : | ||
263 | - self.visit_SimpleAccess(node) | ||
264 | - def visit_SwapAccess (self, node) : | ||
265 | - self.visit_SimpleAccess(node) | ||
266 | - def escape (self, text) : | ||
267 | - return escape(text) | ||
268 | - def build (self, st) : | ||
269 | - # collect text skipped during parsing (blanks and comments) | ||
270 | - output = io.StringIO() | ||
271 | - if st.srow > self.row : | ||
272 | - for line in st.text.lexer.lines[self.row-1:st.srow-1] : | ||
273 | - output.write(line[self.col:]) | ||
274 | - self.col = 0 | ||
275 | - output.write(st.text.lexer.lines[st.srow-1][:st.scol]) | ||
276 | - elif st.scol > self.col : | ||
277 | - output.write(st.text.lexer.lines[self.row-1][self.col:st.scol]) | ||
278 | - # insert skipped text with comments rendering | ||
279 | - for line in output.getvalue().splitlines(True) : | ||
280 | - if "#" in line : | ||
281 | - left, right = line.split("#", 1) | ||
282 | - self.output.write("%s<span class=%r>%s</span>" | ||
283 | - % (self.escape(left), | ||
284 | - "comment", | ||
285 | - self.escape("#" + right))) | ||
286 | - else : | ||
287 | - self.output.write(self.escape(line)) | ||
288 | - # adjust current position in source code | ||
289 | - self.row, self.col = st.srow, st.scol | ||
290 | - # close span for net declaration | ||
291 | - span = getattr(st, "span", Span()) | ||
292 | - if "body" in (c.lower() for c in span.cls) : | ||
293 | - self.output.write("</span>") | ||
294 | - # generate <span ...> if necessary | ||
295 | - if span : | ||
296 | - self.output.write(str(span)) | ||
297 | - # generate span for net declaration | ||
298 | - if (span.id or "").startswith("N") : | ||
299 | - self.output.write(str(self["P" + span.id])) | ||
300 | - # render tree or its children | ||
301 | - if len(st) : | ||
302 | - for child in st : | ||
303 | - # add span tags on special elements | ||
304 | - if not hasattr(child, "span") : | ||
305 | - if child.symbol == "NAME" : | ||
306 | - if child.text in keywords : | ||
307 | - self.setspan("kw", child) | ||
308 | - else : | ||
309 | - self.setspan("ident", child) | ||
310 | - elif child.symbol == "STRING" : | ||
311 | - self.setspan("string", child) | ||
312 | - elif child.symbol == "COLON" : | ||
313 | - self.setspan("kw", child) | ||
314 | - self.build(child) | ||
315 | - else : | ||
316 | - if st.symbol not in ("DEDENT", "ENDMARKER") : | ||
317 | - self.output.write(self.escape(st.text)) | ||
318 | - self.row, self.col = st.erow, st.ecol | ||
319 | - # generate </span> if necessary | ||
320 | - if span : | ||
321 | - self.output.write("</span>") | ||
322 | - def html (self) : | ||
323 | - self.output = io.StringIO() | ||
324 | - self.indent, self.row, self.col = False, 1, 0 | ||
325 | - self.build(self.tree.st) | ||
326 | - return "<pre class='abcd'>%s</pre>" % self.output.getvalue() | ||
327 | - | ||
328 | -def Tree () : | ||
329 | - return collections.defaultdict(Tree) | ||
330 | - | ||
331 | -class TreeInfo (object) : | ||
332 | - def __init__ (self, span, name) : | ||
333 | - self.span, self.name = span, name | ||
334 | - def __hash__ (self) : | ||
335 | - return hash(self.name) | ||
336 | - def __eq__ (self, other) : | ||
337 | - try : | ||
338 | - return self.name == other.name | ||
339 | - except : | ||
340 | - return False | ||
341 | - def __ne__ (self, other) : | ||
342 | - return not self.__eq__(other) | ||
343 | - def __iter__ (self) : | ||
344 | - yield self.span | ||
345 | - yield self.name | ||
346 | - | ||
347 | -_svgclean = [(re.compile(r, re.I), s) for r, s in | ||
348 | - [(r"<[?!][^>]*>\n*", ""), | ||
349 | - (r"<title>[^<>]*</title>\n*", ""), | ||
350 | - (r"<g [^<>]*></g>\n*", ""), | ||
351 | - ]] | ||
352 | - | ||
353 | -class Net2HTML (object) : | ||
354 | - def __init__ (self, net, gv, abcd) : | ||
355 | - self.gv = gv | ||
356 | - self.abcd = abcd | ||
357 | - self.tree = Tree() | ||
358 | - self.n2a = collections.defaultdict(set) | ||
359 | - self.n2t = {} | ||
360 | - snk = net.label("snakes") | ||
361 | - self.count = collections.defaultdict(int) | ||
362 | - for place in net.place() : | ||
363 | - nid = gv.nodemap[place.name] | ||
364 | - if place.status in (snk.entry, snk.internal, snk.exit) : | ||
365 | - for char, trans in ([("R", net.transition(t)) | ||
366 | - for t in place.pre] | ||
367 | - + [("L", net.transition(t)) | ||
368 | - for t in place.post]) : | ||
369 | - span = abcd[trans] | ||
370 | - self.n2a[nid].add(char + span.id) | ||
371 | - else : | ||
372 | - self.addtree(0, "buffer", place) | ||
373 | - for trans in net.transition() : | ||
374 | - self.addtree(10, "action", trans) | ||
375 | - def addtree (self, weight, kind, node) : | ||
376 | - nid = self.gv.nodemap[node.name] | ||
377 | - aid = self.abcd[node] | ||
378 | - tid = aid.copy(id=("T%X" % self.count[aid.id]) + aid.id, | ||
379 | - tree=[], abcd=[aid.id], net=[nid]) | ||
380 | - self.count[aid.id] += 1 | ||
381 | - aid.tree.add(tid.id) | ||
382 | - aid.net.add(nid) | ||
383 | - self.n2a[nid].add(aid.id) | ||
384 | - self.n2t[nid] = tid.id | ||
385 | - pos = self.tree | ||
386 | - path = node.label("path") | ||
387 | - try : | ||
388 | - inst = node.label("instances") | ||
389 | - except : | ||
390 | - inst = [None] * len(path) | ||
391 | - for name, (_, srow, scol, _, _) in zip(path, inst) : | ||
392 | - a = self.abcd["I", srow, scol] | ||
393 | - t = a.copy(id=("T%X" % self.count[a.id]) + a.id, | ||
394 | - tree=[], abcd=[a.id], net=[]) | ||
395 | - self.count[a.id] += 1 | ||
396 | - a.tree.add(t.id) | ||
397 | - pos = pos[((20, srow, scol), "instance", TreeInfo(t, name))] | ||
398 | - prefix = sum(len(p) for p in path) + len(path) | ||
399 | - srow, scol, _, _ = node.label("srcloc") | ||
400 | - pos[((weight, srow, scol), kind, (node, node.name[prefix:]))] = tid | ||
401 | - def _tree (self, tree, indent="") : | ||
402 | - yield indent + "<ul>" | ||
403 | - for (_, kind, data), child in sorted(tree.items()) : | ||
404 | - if kind == "instance" : | ||
405 | - yield indent + "<li>%s%s</span>" % tuple(data) | ||
406 | - for item in self._tree(child, indent + " ") : | ||
407 | - yield item | ||
408 | - yield indent + "</li>" | ||
409 | - else : | ||
410 | - node, name = data | ||
411 | - if kind == "buffer" : | ||
412 | - content = ("<span class='kw'>buffer</span> " | ||
413 | - "<span class='name'>%s</span> = " | ||
414 | - "<span class='content'>%s</span>" | ||
415 | - % (name, node.tokens)) | ||
416 | - yield indent + "<li>%s%s</span></li>" % (child, content) | ||
417 | - elif kind == "action" : | ||
418 | - content = name | ||
419 | - yield (indent + "<li>%s%s</span><ul class='modes'>" | ||
420 | - + "</ul></li>") % (child, content) | ||
421 | - else : | ||
422 | - raise ValueError("unexpected data %r" % kind) | ||
423 | - yield indent + "</ul>" | ||
424 | - def html (self) : | ||
425 | - return template_tree % {"tree" : "\n".join(self._tree(self.tree))} | ||
426 | - def svg (self) : | ||
427 | - # load SVG file | ||
428 | - with tempfile.NamedTemporaryFile(suffix=".svg") as tmp : | ||
429 | - self.gv.render(tmp.name) | ||
430 | - with codecs.open(tmp.name, "r", "utf-8") as infile : | ||
431 | - svg = infile.read() | ||
432 | - for r, s in _svgclean : | ||
433 | - svg = r.sub(s, svg) | ||
434 | - for node, abcd in self.n2a.items() : | ||
435 | - abcd = ", ".join("#" + t for t in abcd) | ||
436 | - if node in self.n2t : | ||
437 | - svg = svg.replace(' id="%s" ' % node, | ||
438 | - ' id="%s" data-abcd="%s" data-tree="#%s" ' | ||
439 | - % (node, abcd, self.n2t[node])) | ||
440 | - else : | ||
441 | - svg = svg.replace(' id="%s" ' % node, | ||
442 | - ' id="%s" data-abcd="%s" ' % (node, abcd)) | ||
443 | - return u"<div class='petrinet'>%s</div>" % svg | ||
444 | - | ||
445 | -def build (abcd, node, net, gv, outfile, tpl=template_html, **args) : | ||
446 | - abcd = ABCD2HTML(node) | ||
447 | - pnet = Net2HTML(net, gv, abcd) | ||
448 | - d = {"filename" : node.st.filename, | ||
449 | - "css" : template_css, | ||
450 | - "jscode" : template_jscode, | ||
451 | - "headers" : template_headers, | ||
452 | - "abcd" : abcd.html(), | ||
453 | - "tree" : pnet.html(), | ||
454 | - "svg" : pnet.svg()} | ||
455 | - d.update(args) | ||
456 | - if tpl is not None and outfile : | ||
457 | - with codecs.open(outfile, "w", "utf-8") as out : | ||
458 | - out.write(tpl % d) | ||
459 | - return d |
1 | import sys, optparse, os.path, webbrowser | 1 | import sys, optparse, os.path, webbrowser |
2 | import pdb, traceback | 2 | import pdb, traceback |
3 | import snakes.plugins | 3 | import snakes.plugins |
4 | -from snakes.utils.abcd.build import Builder | 4 | +from snakes.utils.andy import CompilationError, DeclarationError |
5 | -from snakes.lang.abcd.parser import parse | 5 | +from snakes.utils.andy.simul import Simulator, AndySimulator |
6 | -from snakes.lang.pgen import ParseError | 6 | +from snakes.utils.andy.andy import andy2snakes |
7 | -from snakes.utils.abcd import CompilationError, DeclarationError | ||
8 | -from snakes.utils.abcd.simul import Simulator, ABCDSimulator | ||
9 | -from snakes.utils.abcd.checker import Checker | ||
10 | -from snakes.utils.abcd.html import build as html | ||
11 | from snakes.utils.simul.html import json | 7 | from snakes.utils.simul.html import json |
12 | 8 | ||
13 | ## | 9 | ## |
... | @@ -26,11 +22,11 @@ ERR_OUTPUT = 7 | ... | @@ -26,11 +22,11 @@ ERR_OUTPUT = 7 |
26 | ERR_BUG = 255 | 22 | ERR_BUG = 255 |
27 | 23 | ||
28 | def log (message) : | 24 | def log (message) : |
29 | - sys.stdout.write("abcd: %s\n" % message.strip()) | 25 | + sys.stdout.write("andy: %s\n" % message.strip()) |
30 | sys.stdout.flush() | 26 | sys.stdout.flush() |
31 | 27 | ||
32 | def err (message) : | 28 | def err (message) : |
33 | - sys.stderr.write("abcd: %s\n" % message.strip()) | 29 | + sys.stderr.write("andy: %s\n" % message.strip()) |
34 | sys.stderr.flush() | 30 | sys.stderr.flush() |
35 | 31 | ||
36 | def die (code, message=None) : | 32 | def die (code, message=None) : |
... | @@ -66,7 +62,7 @@ def bug () : | ... | @@ -66,7 +62,7 @@ def bug () : |
66 | 62 | ||
67 | gv_engines = ("dot", "neato", "twopi", "circo", "fdp") | 63 | gv_engines = ("dot", "neato", "twopi", "circo", "fdp") |
68 | 64 | ||
69 | -opt = optparse.OptionParser(prog="abcd", | 65 | +opt = optparse.OptionParser(prog="andy", |
70 | usage="%prog [OPTION]... FILE") | 66 | usage="%prog [OPTION]... FILE") |
71 | opt.add_option("-l", "--load", | 67 | opt.add_option("-l", "--load", |
72 | dest="plugins", action="append", default=[], | 68 | dest="plugins", action="append", default=[], |
... | @@ -81,9 +77,6 @@ for engine in gv_engines : | ... | @@ -81,9 +77,6 @@ for engine in gv_engines : |
81 | dest="gv" + engine, action="store", default=None, | 77 | dest="gv" + engine, action="store", default=None, |
82 | help="draw net using '%s' (from GraphViz)" % engine, | 78 | help="draw net using '%s' (from GraphViz)" % engine, |
83 | metavar="OUTFILE") | 79 | metavar="OUTFILE") |
84 | -opt.add_option("-a", "--all-names", | ||
85 | - dest="allnames", action="store_true", default=False, | ||
86 | - help="draw control-flow places names (default: hide)") | ||
87 | opt.add_option("--debug", | 80 | opt.add_option("--debug", |
88 | dest="debug", action="store_true", default=False, | 81 | dest="debug", action="store_true", default=False, |
89 | help="launch debugger on compiler error (default: no)") | 82 | help="launch debugger on compiler error (default: no)") |
... | @@ -98,22 +91,13 @@ opt.add_option("--port", | ... | @@ -98,22 +91,13 @@ opt.add_option("--port", |
98 | dest="port", action="store", default=8000, type=int, | 91 | dest="port", action="store", default=8000, type=int, |
99 | help="port on which the simulator server runs", | 92 | help="port on which the simulator server runs", |
100 | metavar="PORT") | 93 | metavar="PORT") |
101 | -opt.add_option("-H", "--html", | ||
102 | - dest="html", action="store", default=None, | ||
103 | - help="save net as HTML", | ||
104 | - metavar="OUTFILE") | ||
105 | -opt.add_option("--check", | ||
106 | - dest="check", action="store_true", default=False, | ||
107 | - help="check assertions") | ||
108 | 94 | ||
109 | def getopts (args) : | 95 | def getopts (args) : |
110 | - global options, abcd, tmp | 96 | + global options, andy, tmp |
111 | (options, args) = opt.parse_args(args) | 97 | (options, args) = opt.parse_args(args) |
112 | plugins = [] | 98 | plugins = [] |
113 | for p in options.plugins : | 99 | for p in options.plugins : |
114 | plugins.extend(t.strip() for t in p.split(",")) | 100 | plugins.extend(t.strip() for t in p.split(",")) |
115 | - if "ops" not in options.plugins : | ||
116 | - plugins.append("ops") | ||
117 | if "labels" not in plugins : | 101 | if "labels" not in plugins : |
118 | plugins.append("labels") | 102 | plugins.append("labels") |
119 | for engine in gv_engines : | 103 | for engine in gv_engines : |
... | @@ -121,7 +105,7 @@ def getopts (args) : | ... | @@ -121,7 +105,7 @@ def getopts (args) : |
121 | if gvopt and "gv" not in plugins : | 105 | if gvopt and "gv" not in plugins : |
122 | plugins.append("gv") | 106 | plugins.append("gv") |
123 | break | 107 | break |
124 | - if (options.html or options.simul) and "gv" not in plugins : | 108 | + if (options.simul) and "gv" not in plugins : |
125 | plugins.append("gv") | 109 | plugins.append("gv") |
126 | options.plugins = plugins | 110 | options.plugins = plugins |
127 | if len(args) < 1 : | 111 | if len(args) < 1 : |
... | @@ -132,17 +116,13 @@ def getopts (args) : | ... | @@ -132,17 +116,13 @@ def getopts (args) : |
132 | err("more than one input file provided") | 116 | err("more than one input file provided") |
133 | opt.print_help() | 117 | opt.print_help() |
134 | die(ERR_ARG) | 118 | die(ERR_ARG) |
135 | - abcd = args[0] | 119 | + andy = args[0] |
136 | - if options.pnml == abcd : | 120 | + if options.pnml == andy : |
137 | err("input file also used as output (--pnml)") | 121 | err("input file also used as output (--pnml)") |
138 | opt.print_help() | 122 | opt.print_help() |
139 | die(ERR_ARG) | 123 | die(ERR_ARG) |
140 | - if options.html == abcd : | ||
141 | - err("input file also used as output (--html)") | ||
142 | - opt.print_help() | ||
143 | - die(ERR_ARG) | ||
144 | for engine in gv_engines : | 124 | for engine in gv_engines : |
145 | - if getattr(options, "gv%s" % engine) == abcd : | 125 | + if getattr(options, "gv%s" % engine) == andy : |
146 | err("input file also used as output (--%s)" % engine) | 126 | err("input file also used as output (--%s)" % engine) |
147 | opt.print_help() | 127 | opt.print_help() |
148 | die(ERR_ARG) | 128 | die(ERR_ARG) |
... | @@ -151,58 +131,9 @@ def getopts (args) : | ... | @@ -151,58 +131,9 @@ def getopts (args) : |
151 | ## drawing nets | 131 | ## drawing nets |
152 | ## | 132 | ## |
153 | 133 | ||
154 | -def place_attr (place, attr) : | ||
155 | - # fix color | ||
156 | - if place.status == snk.entry : | ||
157 | - attr["fillcolor"] = "green" | ||
158 | - elif place.status == snk.internal : | ||
159 | - pass | ||
160 | - elif place.status == snk.exit : | ||
161 | - attr["fillcolor"] = "orange" | ||
162 | - else : | ||
163 | - attr["fillcolor"] = "lightblue" | ||
164 | - # fix shape | ||
165 | - if (not options.allnames | ||
166 | - and place.status in (snk.entry, snk.internal, snk.exit)) : | ||
167 | - attr["shape"] = "circle" | ||
168 | - # render marking | ||
169 | - if place._check == snk.tBlackToken : | ||
170 | - count = len(place.tokens) | ||
171 | - if count == 0 : | ||
172 | - marking = " " | ||
173 | - elif count == 1 : | ||
174 | - marking = "•" | ||
175 | - else : | ||
176 | - marking = "%s•" % count | ||
177 | - else : | ||
178 | - marking = str(place.tokens) | ||
179 | - # node label | ||
180 | - if (options.allnames | ||
181 | - or place.status not in (snk.entry, snk.internal, snk.exit)) : | ||
182 | - attr["label"] = "%s\\n%s" % (place.name, marking) | ||
183 | - else : | ||
184 | - attr["label"] = "%s" % marking | ||
185 | - | ||
186 | -def trans_attr (trans, attr) : | ||
187 | - pass | ||
188 | - | ||
189 | -def arc_attr (label, attr) : | ||
190 | - if label == snk.Value(snk.dot) : | ||
191 | - del attr["label"] | ||
192 | - elif isinstance(label, snk.Test) : | ||
193 | - attr["arrowhead"] = "none" | ||
194 | - attr["label"] = " %s " % label._annotation | ||
195 | - elif isinstance(label, snk.Flush) : | ||
196 | - attr["arrowhead"] = "box" | ||
197 | - attr["label"] = " %s " % label._annotation | ||
198 | - | ||
199 | - | ||
200 | def draw (net, target, engine="dot") : | 134 | def draw (net, target, engine="dot") : |
201 | try : | 135 | try : |
202 | - return net.draw(target, engine=engine, | 136 | + return net.draw(target, engine=engine) |
203 | - place_attr=place_attr, | ||
204 | - trans_attr=trans_attr, | ||
205 | - arc_attr=arc_attr) | ||
206 | except : | 137 | except : |
207 | die(ERR_OUTPUT, str(sys.exc_info()[1])) | 138 | die(ERR_OUTPUT, str(sys.exc_info()[1])) |
208 | 139 | ||
... | @@ -222,49 +153,36 @@ def save_pnml (net, target) : | ... | @@ -222,49 +153,36 @@ def save_pnml (net, target) : |
222 | ## simulator (not standalone) | 153 | ## simulator (not standalone) |
223 | ## | 154 | ## |
224 | 155 | ||
225 | -def simulate (source, filename="<string>") : | 156 | +def simulate (entities, potential, obligatory, filename='<string>') : |
226 | global options, snk | 157 | global options, snk |
227 | getopts(["--simul", filename]) | 158 | getopts(["--simul", filename]) |
228 | - node = parse(source, filename=filename) | ||
229 | snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk") | 159 | snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk") |
230 | - build = Builder(snk) | 160 | + net = andy2snakes(snk, entities, potential, obligatory) |
231 | - net = build.build(node) | ||
232 | net.label(srcfile=filename, snakes=snk) | 161 | net.label(srcfile=filename, snakes=snk) |
233 | - return ABCDSimulator(node, net, draw(net, None)) | 162 | + return AndySimulator(net) |
234 | 163 | ||
235 | ## | 164 | ## |
236 | ## main | 165 | ## main |
237 | ## | 166 | ## |
238 | 167 | ||
239 | -def main (args=sys.argv[1:], src=None) : | 168 | +def main (args=sys.argv[1:]) : |
240 | global options, snk | 169 | global options, snk |
241 | # get options | 170 | # get options |
242 | try: | 171 | try: |
243 | - if src is None : | 172 | + getopts(args) |
244 | - getopts(args) | ||
245 | - else : | ||
246 | - getopts(list(args) + ["<string>"]) | ||
247 | except SystemExit : | 173 | except SystemExit : |
248 | raise | 174 | raise |
249 | except : | 175 | except : |
250 | die(ERR_OPT, str(sys.exc_info()[1])) | 176 | die(ERR_OPT, str(sys.exc_info()[1])) |
251 | - # read source | 177 | + # read andy spec |
252 | - if src is not None : | 178 | + try: |
253 | - source = src | 179 | + env = {} |
254 | - else : | 180 | + execfile(andy, env) |
255 | - try : | 181 | + del env['__builtins__'] |
256 | - source = open(abcd).read() | 182 | + except: |
257 | - except : | 183 | + die(ERR_IO, "could not read input file %r" % andy) |
258 | - die(ERR_IO, "could not read input file %r" % abcd) | 184 | + # compile to net |
259 | - # parse | 185 | + dirname = os.path.dirname(andy) |
260 | - try : | ||
261 | - node = parse(source, filename=abcd) | ||
262 | - except ParseError : | ||
263 | - die(ERR_PARSE, str(sys.exc_info()[1])) | ||
264 | - except : | ||
265 | - bug() | ||
266 | - # compile | ||
267 | - dirname = os.path.dirname(abcd) | ||
268 | if dirname and dirname not in sys.path : | 186 | if dirname and dirname not in sys.path : |
269 | sys.path.append(dirname) | 187 | sys.path.append(dirname) |
270 | elif "." not in sys.path : | 188 | elif "." not in sys.path : |
... | @@ -273,14 +191,13 @@ def main (args=sys.argv[1:], src=None) : | ... | @@ -273,14 +191,13 @@ def main (args=sys.argv[1:], src=None) : |
273 | snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk") | 191 | snk = snakes.plugins.load(options.plugins, "snakes.nets", "snk") |
274 | except : | 192 | except : |
275 | die(ERR_PLUGIN, str(sys.exc_info()[1])) | 193 | die(ERR_PLUGIN, str(sys.exc_info()[1])) |
276 | - build = Builder(snk) | 194 | + |
277 | - try : | 195 | + try: |
278 | - net = build.build(node) | 196 | + net = andy2snakes(snk, env['entities'], env['potential'], |
279 | - net.label(srcfile=abcd, snakes=snk) | 197 | + env['obligatory']) |
280 | - except (CompilationError, DeclarationError) : | 198 | + except: |
281 | - die(ERR_COMPILE, str(sys.exc_info()[1])) | ||
282 | - except : | ||
283 | bug() | 199 | bug() |
200 | + | ||
284 | # output | 201 | # output |
285 | if options.pnml : | 202 | if options.pnml : |
286 | save_pnml(net, options.pnml) | 203 | save_pnml(net, options.pnml) |
... | @@ -288,17 +205,10 @@ def main (args=sys.argv[1:], src=None) : | ... | @@ -288,17 +205,10 @@ def main (args=sys.argv[1:], src=None) : |
288 | target = getattr(options, "gv%s" % engine) | 205 | target = getattr(options, "gv%s" % engine) |
289 | if target : | 206 | if target : |
290 | draw(net, target, engine) | 207 | draw(net, target, engine) |
291 | - if options.html : | ||
292 | - try : | ||
293 | - html(abcd, node, net, draw(net, None), options.html) | ||
294 | - except : | ||
295 | - bug() | ||
296 | trace, lineno = [], None | 208 | trace, lineno = [], None |
297 | - if options.check : | ||
298 | - lineno, trace = Checker(net).run() | ||
299 | if options.simul : | 209 | if options.simul : |
300 | try : | 210 | try : |
301 | - simul = Simulator(node, net, draw(net, None), options.port) | 211 | + simul = Simulator(net, options.port) |
302 | except : | 212 | except : |
303 | bug() | 213 | bug() |
304 | simul.start() | 214 | simul.start() | ... | ... |
1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
2 | <html> | 2 | <html> |
3 | - <head> | 3 | +<head> |
4 | - <link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/> | 4 | + <link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/> |
5 | - <link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/> | 5 | + <link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/> |
6 | - <link type="text/css" href="r/css/docs.css" rel="stylesheet"/> | 6 | + <link type="text/css" href="r/css/docs.css" rel="stylesheet"/> |
7 | - <link type="text/css" href="r/simulator.css" rel="stylesheet"/> | 7 | + <link type="text/css" href="r/simulator.css" rel="stylesheet"/> |
8 | - <link type="text/css" href="r/model.css" rel="stylesheet"/> | 8 | + <link type="text/css" href="r/model.css" rel="stylesheet"/> |
9 | - <script src="r/jquery.min.js"></script> | 9 | + <script src="r/jquery.min.js"></script> |
10 | - <script src="r/js/bootstrap.min.js"></script> | 10 | + <script src="r/js/bootstrap.min.js"></script> |
11 | - <script src="r/jquery.periodic.js"></script> | 11 | + <script src="r/jquery.periodic.js"></script> |
12 | - <script src="r/js/bootstrap.file-input.js"></script> | 12 | + <script src="r/js/bootstrap.file-input.js"></script> |
13 | - <script src="r/d3.min.js"></script> | 13 | + <script src="r/d3.min.js"></script> |
14 | - <script src="r/js/petri.js"></script> | 14 | + <script src="r/js/petri.js"></script> |
15 | - <script src="r/simulator.js"></script> | 15 | + <script src="r/simulator.js"></script> |
16 | - </head> | ||
17 | <style> | 16 | <style> |
18 | - path { | 17 | + path { stroke: steelblue; |
19 | - stroke: steelblue; | 18 | + stroke-width: 2; |
20 | - stroke-width: 2; | 19 | + fill: none; } |
21 | - fill: none; | 20 | + line { stroke: black; } |
22 | - } | 21 | + text { font-family: Arial; |
23 | - | 22 | + font-size: 9pt; } |
24 | - line { | ||
25 | - stroke: black; | ||
26 | - } | ||
27 | - | ||
28 | - text { | ||
29 | - font-family: Arial; | ||
30 | - font-size: 9pt; | ||
31 | - } | ||
32 | - | ||
33 | </style> | 23 | </style> |
34 | - <body> | 24 | +</head> |
35 | - | 25 | +<body> |
36 | <header class="navbar navbar-static-top"> | 26 | <header class="navbar navbar-static-top"> |
37 | - <div class="container"> | ||
38 | <nav class="navbar navbar-default" role="navigation"> | 27 | <nav class="navbar navbar-default" role="navigation"> |
39 | <div class="container-fluid"> | 28 | <div class="container-fluid"> |
40 | - <div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-6"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Simulation SNAKES</a></div> | 29 | + <div class="navbar-header"> |
41 | - <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-6"> | 30 | + <button type="button" class="navbar-toggle" |
42 | - <ul id="nav_sim" class="nav navbar-nav"> | 31 | + data-toggle="collapse" |
43 | - <li><a href="#" id="ui-reset">Reset Simulation</a></li> | 32 | + data-target="#bs-example-navbar-collapse-6"> |
44 | - <li><a href="#" id="ui-quit">Stop Simulation</a></li> | 33 | + <span class="sr-only">Toggle navigation</span> |
45 | - <li><a href="#" id="ui-help">Help</a></li> | 34 | + </button> |
46 | - </ul> | 35 | + <a class="navbar-brand" href="#">Simulation SNAKES</a> |
47 | </div> | 36 | </div> |
37 | + <div class="collapse navbar-collapse" | ||
38 | + id="bs-example-navbar-collapse-6"> | ||
39 | + <ul class="nav navbar-nav" id="nav_sim"> | ||
40 | + <li><a id="ui-reset">Reset Simulation</a></li> | ||
41 | + <li><a id="ui-quit">Stop Simulation</a></li> | ||
42 | + <li><a id="ui-help">Help</a></li> | ||
43 | + </ul> | ||
44 | + </div><!-- /.navbar-collapse --> | ||
48 | </div> | 45 | </div> |
49 | </nav> | 46 | </nav> |
50 | - </div> | ||
51 | </header> | 47 | </header> |
52 | - <div class="container"> | 48 | + <!-- model to be simulated --> |
53 | - | 49 | + %(model)s |
54 | - %(model)s | ||
55 | 50 | ||
56 | - <div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> | 51 | + <!-- information about the simulator --> |
57 | - <div class="modal-dialog"> | 52 | + <div aria-hidden="true" aria-labelledby="myModalLabel" class="modal fade" |
58 | - <div class="modal-content"> | 53 | + id="about" role="dialog" tabindex="-1"> |
59 | - <div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | 54 | + <div class="modal-dialog"> |
60 | - <h4 class="modal-title" id="myModalLabel">Petri Net</h4> | 55 | + <div class="modal-content"> |
61 | - </div> | 56 | + <div class="modal-header"> |
62 | - <div class="modal-body"> | 57 | + <button aria-hidden="true" class="close" |
63 | - <p><span class="title">ABCD simulator is part of the SNAKES toolkit</span><br /> (C) 2014 Franck Pommereau</p> | 58 | + data-dismiss="modal" type="button">x</button> |
64 | - <p><a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES" target="_blank">SNAKES homepage</a></p> | 59 | + <h4 class="modal-title" id="myModalLabel">Petri Net</h4> |
65 | - </div> | 60 | + </div> |
66 | - <div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div> | 61 | + <div class="modal-body"> |
62 | + <p> | ||
63 | + <span class="title">Andy simulator is part of the | ||
64 | + SNAKES toolkit</span><br /> | ||
65 | + (C) 2014 Franck Pommereau | ||
66 | + </p> | ||
67 | + <p> | ||
68 | + <a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES" | ||
69 | + target="_blank">SNAKES homepage</a> | ||
70 | + </p> | ||
71 | + </div> | ||
72 | + <div class="modal-footer"> | ||
73 | + <button class="btn btn-default" data-dismiss="modal" | ||
74 | + type="button">Close</button> | ||
67 | </div> | 75 | </div> |
68 | </div> | 76 | </div> |
69 | </div> | 77 | </div> |
70 | -<script> | 78 | + </div> |
71 | - $(document).ready(function(){ | 79 | + <script> |
72 | - $.simisc({ | 80 | + $(document).ready(function(){ |
73 | - "nav":{ | 81 | + $.simisc({ "nav":{ "about": { "text": "About", |
74 | - "about": { | 82 | + "attr": { "id":"ui-about", |
75 | - "text": "About", | 83 | + "data-toggle": "modal", |
76 | - "attr": { | 84 | + "data-target": "#about" |
77 | - "id":"ui-about", | 85 | + } } }, |
78 | - "data-toggle": "modal", | 86 | + "graph": { "color": { "y":"red", |
79 | - "data-target": "#about" | 87 | + "x":"blue" } } }); |
80 | - } | 88 | + }); |
81 | - }, | 89 | + </script> |
82 | - "net": { | ||
83 | - "text": "Petri Net", | ||
84 | - "attr": { | ||
85 | - "id":"ui-net", | ||
86 | - "data-toggle": "modal", | ||
87 | - "data-target": "#net" | ||
88 | - } | ||
89 | - } | ||
90 | - }, | ||
91 | - "graph": { | ||
92 | - "activate": false | ||
93 | - } | ||
94 | - }); | ||
95 | - }); | ||
96 | -</script> | ||
97 | </body> | 90 | </body> |
98 | </html> | 91 | </html> | ... | ... |
1 | +<div class="container-fluid"> | ||
2 | +<div class="row"> | ||
1 | <div class="page-header"> | 3 | <div class="page-header"> |
2 | - <h1><tt>%(filename)s</tt> <small> powered by Franck</small></h1> | 4 | + <h1><tt>Andy Simulator</tt> <small> powered by Franck</small></h1> |
5 | +</div> | ||
3 | </div> | 6 | </div> |
4 | -<div class="row"> | ||
5 | - <div class="col-md-3"> | ||
6 | 7 | ||
8 | +<div class="row"> | ||
9 | + <div class="col-md-4"> | ||
7 | <div class="row"> | 10 | <div class="row"> |
8 | <h3>Player</h3> | 11 | <h3>Player</h3> |
9 | - <div id="player"></div> | 12 | + <div id="player"> </div> |
10 | </div> | 13 | </div> |
11 | - </div> | ||
12 | -</div> | ||
13 | -<div id="model" class="row"> | ||
14 | - <div class="col-md-6"> | ||
15 | <div class="row"> | 14 | <div class="row"> |
16 | - <h3>ABCD</h3> | 15 | + <h3>Modes</h3> |
17 | - <div class="abcd">%(abcd)s</div> | 16 | + <div id="modes"> </div> |
18 | </div> | 17 | </div> |
19 | 18 | ||
20 | - </div> | ||
21 | - <div class=col-md-6> | ||
22 | <div class="row"> | 19 | <div class="row"> |
23 | - <h3>Tree</h3> | 20 | + <h3>Command Panel</h3> |
24 | - <div class="tree">%(tree)s</div> | 21 | + <div id="Command_center"> </div> |
25 | </div> | 22 | </div> |
26 | </div> | 23 | </div> |
27 | 24 | ||
28 | - <div class="col-md-12"> | 25 | + <div class="col-md-8"> |
29 | - <div id="trace_zone"></div> | 26 | + <div class="row"> |
27 | + <h3>Net Graph</h3> | ||
28 | + <div id="graph"> </div> | ||
29 | + </div> | ||
30 | </div> | 30 | </div> |
31 | </div> | 31 | </div> |
32 | 32 | ||
33 | -<div class="modal fade" id="net" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> | 33 | +<div class="row"> |
34 | - <div class="modal-dialog" style="width:auto;"> | 34 | + <div class="col-md-12"> |
35 | - <div class="modal-content" style="overflow: scroll;"> | 35 | + <div id="trace_zone"> </div> |
36 | - %(net)s | ||
37 | - </div> | ||
38 | </div> | 36 | </div> |
39 | -</div> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
37 | +</div> | ||
38 | +</div> | ... | ... |
1 | from snakes.utils.simul import BaseSimulator, BaseHTTPSimulator | 1 | from snakes.utils.simul import BaseSimulator, BaseHTTPSimulator |
2 | -import snakes.utils.abcd.html as html | ||
3 | 2 | ||
4 | -class ABCDSimulator (BaseSimulator) : | 3 | +class AndySimulator (BaseSimulator) : |
5 | - def __init__ (self, node, net, gv) : | ||
6 | - BaseSimulator.__init__(self, net) | ||
7 | - a2html = html.ABCD2HTML(node) | ||
8 | - n2html = html.Net2HTML(net, gv, a2html) | ||
9 | - self.info = {"filename" : node.st.filename, | ||
10 | - "abcd" : a2html.html(), | ||
11 | - "tree" : n2html.html(), | ||
12 | - "net" : n2html.svg()} | ||
13 | - self.tree = {} | ||
14 | - for node in net.node() : | ||
15 | - nid = gv.nodemap[node.name] | ||
16 | - if nid in n2html.n2t : | ||
17 | - self.tree[node.name] = "#" + n2html.n2t[nid] | ||
18 | - self.places = [place.name for place in net.place() | ||
19 | - if place.name in self.tree] | ||
20 | - self.abcd = {} | ||
21 | - self.transid = [] | ||
22 | - for trans in net.transition() : | ||
23 | - nid = gv.nodemap[trans.name] | ||
24 | - self.transid.append(self.tree[trans.name]) | ||
25 | - if nid in n2html.n2a : | ||
26 | - self.abcd[trans.name] = ", ".join("#" + i for i in | ||
27 | - n2html.n2a[nid]) | ||
28 | - def init (self, state=-1) : | ||
29 | - res = BaseSimulator.init(self, state) | ||
30 | - res.update(self.info) | ||
31 | - res["help"] = self.init_help() | ||
32 | - return res | ||
33 | - def init_help (self) : | ||
34 | - help = BaseSimulator.init_help(self) | ||
35 | - help.update({ | ||
36 | - "#model .abcd" : { | ||
37 | - "title" : "Source", | ||
38 | - "content" : "ABCD source code" | ||
39 | - }, | ||
40 | - "#model .tree" : { | ||
41 | - "title" : "State", | ||
42 | - "content" : "hierarchy of ABCD objects", | ||
43 | - }, | ||
44 | - "#model .petrinet" : { | ||
45 | - "title" : "Net", | ||
46 | - "content" : "Petri nets semantics" | ||
47 | - }}) | ||
48 | - return help | ||
49 | def getstate (self, state) : | 4 | def getstate (self, state) : |
5 | + ret = BaseSimulator.getstate(self, state) | ||
50 | marking = self.states[state] | 6 | marking = self.states[state] |
51 | - modes = dict((t, []) for t in self.transid) | 7 | + ret["variables"] = dict((place, tokens.items()[0]) |
52 | - for i, (trans, mode) in enumerate(marking.modes) : | 8 | + for place, tokens in marking.items()) |
53 | - modes[self.tree[trans.name]].append({"state" : state, | 9 | + ret["groups"] = ["timed", "even", "odd"] |
54 | - "mode" : i, | 10 | + modes = [] |
55 | - "html" : str(mode)}) | 11 | + for i, (trans, binding) in enumerate(marking.modes) : |
56 | - return {"id" : state, | 12 | + if (state + i) % 5 == 0 : |
57 | - "states" : | 13 | + groups = ["timed"] |
58 | - [{"do" : "dropclass", | 14 | + else : |
59 | - "select" : "#model .active", | 15 | + groups = [] |
60 | - "class" : "active"}] | 16 | + modes.append( |
61 | - + [{"do" : "addclass", | 17 | + {"state" : state, |
62 | - "select" : self.abcd[trans.name], | 18 | + "mode" : i, |
63 | - "class" : "active"} for trans, mode in marking.modes] | 19 | + "html" : "%s (%s)" % (trans.name[7:], binding), |
64 | - + [{"do" : "addclass", | 20 | + "groups" : groups + ["odd" if (state % 2) else "even"] |
65 | - "select" : self.tree[trans.name], | 21 | + }) |
66 | - "class" : "active"} for trans, mode in marking.modes] | 22 | + ret["modes"] = [{"select": "#modes", "items": modes}] |
67 | - + [{"do" : "settext", | 23 | + return ret |
68 | - "select" : "%s .content" % self.tree[place], | 24 | + |
69 | - "text" : "{}"} for place in self.places | 25 | +#class Simulator (BaseHTTPSimulator) : |
70 | - if place not in marking] | 26 | +# def __init__ (self, **system) : |
71 | - + [{"do" : "settext", | 27 | +# simul = AndySimulator(**system) |
72 | - "select" : "%s .content" % self.tree[place], | 28 | +# BaseHTTPSimulator.__init__(self, simulator=simul) |
73 | - "text" : str(marking[place])} for place in marking | ||
74 | - if place in self.tree], | ||
75 | - "modes" : [{"select" : "%s + .modes" % trans, | ||
76 | - "items" : items} | ||
77 | - for trans, items in modes.items()], | ||
78 | - } | ||
79 | 29 | ||
80 | class Simulator (BaseHTTPSimulator) : | 30 | class Simulator (BaseHTTPSimulator) : |
81 | - def __init__ (self, node, net, gv, port) : | 31 | + def __init__ (self, net, port) : |
82 | - simul = ABCDSimulator(node, net, gv) | 32 | + simul = AndySimulator(net) |
83 | BaseHTTPSimulator.__init__(self, net, simulator=simul, port=port) | 33 | BaseHTTPSimulator.__init__(self, net, simulator=simul, port=port) |
84 | - def init_model (self) : | 34 | +# def init_model (self) : |
85 | - return self.res["model.html"] % self.simul.info | 35 | +# return self.res["model.html"] % self.simul.info |
86 | - def init_ui (self) : | 36 | +# def init_ui (self) : |
87 | - return BaseHTTPSimulator.init_ui(self)[:-1] + [{ | 37 | +# return BaseHTTPSimulator.init_ui(self)[:-1] + [{ |
88 | - "label" : "Show net", | 38 | +# "label" : "Show net", |
89 | - "id" : "ui-shownet", | 39 | +# "id" : "ui-shownet", |
90 | - "href" : "#", | 40 | +# "href" : "#", |
91 | - "script" : "dialog($('#model .petrinet').html())" | 41 | +# "script" : "dialog($('#model .petrinet').html())" |
92 | - }] | 42 | +# }] |
43 | + | ... | ... |
snakes/utils/andy/transform.py
deleted
100644 → 0
1 | -from snakes.lang.abcd.parser import ast | ||
2 | - | ||
3 | -class NodeCopier (ast.NodeTransformer) : | ||
4 | - def copy (self, node, **replace) : | ||
5 | - args = {} | ||
6 | - for name in node._fields + node._attributes : | ||
7 | - old = getattr(node, name, None) | ||
8 | - if name in replace : | ||
9 | - new = replace[name] | ||
10 | - elif isinstance(old, list): | ||
11 | - new = [] | ||
12 | - for val in old : | ||
13 | - if isinstance(val, ast.AST) : | ||
14 | - new.append(self.visit(val)) | ||
15 | - else : | ||
16 | - new.append(val) | ||
17 | - elif isinstance(old, ast.AST): | ||
18 | - new = self.visit(old) | ||
19 | - else : | ||
20 | - new = old | ||
21 | - args[name] = new | ||
22 | - if hasattr(node, "st") : | ||
23 | - args["st"] = node.st | ||
24 | - return node.__class__(**args) | ||
25 | - def generic_visit (self, node) : | ||
26 | - return self.copy(node) | ||
27 | - | ||
28 | -class ArgsBinder (NodeCopier) : | ||
29 | - def __init__ (self, args, buffers, nets, tasks) : | ||
30 | - NodeCopier.__init__(self) | ||
31 | - self.args = args | ||
32 | - self.buffers = buffers | ||
33 | - self.nets = nets | ||
34 | - self.tasks = tasks | ||
35 | - def visit_Name (self, node) : | ||
36 | - if node.id in self.args : | ||
37 | - return self.copy(self.args[node.id]) | ||
38 | - else : | ||
39 | - return self.copy(node) | ||
40 | - def visit_Instance (self, node) : | ||
41 | - if node.net in self.nets : | ||
42 | - return self.copy(node, net=self.nets[node.net]) | ||
43 | - else : | ||
44 | - return self.copy(node) | ||
45 | - def _visit_access (self, node) : | ||
46 | - if node.buffer in self.buffers : | ||
47 | - return self.copy(node, buffer=self.buffers[node.buffer]) | ||
48 | - else : | ||
49 | - return self.copy(node) | ||
50 | - def visit_SimpleAccess (self, node) : | ||
51 | - return self._visit_access(node) | ||
52 | - def visit_FlushAccess (self, node) : | ||
53 | - return self._visit_access(node) | ||
54 | - def visit_SwapAccess (self, node) : | ||
55 | - return self._visit_access(node) | ||
56 | - def _visit_task (self, node) : | ||
57 | - if node.net in self.tasks : | ||
58 | - return self.copy(node, net=self.tasks[node.net]) | ||
59 | - else : | ||
60 | - return self.copy(node) | ||
61 | - def visit_Spawn (self, node) : | ||
62 | - return self._visit_task(node) | ||
63 | - def visit_Wait (self, node) : | ||
64 | - return self._visit_task(node) | ||
65 | - def visit_Suspend (self, node) : | ||
66 | - return self._visit_task(node) | ||
67 | - def visit_Resume (self, node) : | ||
68 | - return self._visit_task(node) | ||
69 | - def visit_AbcdNet (self, node) : | ||
70 | - args = self.args.copy() | ||
71 | - buffers = self.buffers.copy() | ||
72 | - nets = self.nets.copy() | ||
73 | - tasks = self.tasks.copy() | ||
74 | - netargs = ([a.arg for a in node.args.args + node.args.kwonlyargs] | ||
75 | - + [node.args.vararg, node.args.kwarg]) | ||
76 | - copy = True | ||
77 | - for a in netargs : | ||
78 | - for d in (args, buffers, nets, tasks) : | ||
79 | - if a in d : | ||
80 | - del d[a] | ||
81 | - copy = False | ||
82 | - if copy : | ||
83 | - return self.copy(node) | ||
84 | - else : | ||
85 | - return self.__class__(args, buffers, nets, tasks).visit(node) | ||
86 | - | ||
87 | -if __name__ == "__main__" : | ||
88 | - import doctest | ||
89 | - doctest.testmod() |
-
Please register or login to post a comment