oasm 0.1.4__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oasm
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Open ASseMbly tools
5
5
  Author-email: nzturn <nzturn@gmail.com>
6
6
  Keywords: asm,dsl
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oasm" # 包名(需确保在PyPI唯一)
3
- version = "0.1.4" # 初始版本号
3
+ version = "0.1.6" # 初始版本号
4
4
  authors = [
5
5
  { name = "nzturn", email = "nzturn@gmail.com" },
6
6
  ]
@@ -0,0 +1,672 @@
1
+ import pkgutil
2
+ __path__ = pkgutil.extend_path(__path__,__name__)
3
+ __path__.reverse()
4
+
5
+ __all__ = ['table','config','equal','expr','subs','sym','context','flow','meta','multi','domain']
6
+ from pprint import pformat
7
+
8
+ class table(list):
9
+ def __init__(self, *args, **kwargs):
10
+ super().__init__(args)
11
+ self.__dict__.update(kwargs)
12
+ def __getitem__(self, key=None):
13
+ if type(key) is str:
14
+ return self.__dict__[key]
15
+ return super().__getitem__(key)
16
+ def __setitem__(self, key, val):
17
+ if type(key) is str:
18
+ self.__dict__[key] = val
19
+ else:
20
+ super().__setitem__(key, val)
21
+ def __delitem__(self, key):
22
+ if type(key) is str:
23
+ del self.__dict__[key]
24
+ else:
25
+ super().__delitem__(key)
26
+ def __call__(self, *args, **kwargs):
27
+ func = self.__dict__.get('__call__',None)
28
+ if func is not None:
29
+ return func(self,*args,**kwargs)
30
+ if len(args) == 0 and len(kwargs) == 0:
31
+ return self
32
+ super().extend(args)
33
+ self.__dict__.update(kwargs)
34
+ return self
35
+ def __repr__(self):
36
+ r = ''
37
+ for i in self[:]:
38
+ r += pformat(i) + ','
39
+ for k,v in self.__dict__.items():
40
+ r += f'{k}={pformat(v)},'
41
+ if len(r) > 0 and r[-1] == ',':
42
+ r = r[:-1]
43
+ return '[' + r + ']'
44
+ def __neg__(self):
45
+ return self
46
+ def copy(self):
47
+ return self.__class__(*self[:],**self.__dict__)
48
+ @staticmethod
49
+ def to_dict(x):
50
+ if isinstance(x, table):
51
+ return {f'__{x.__class__.__name__}__':table.to_dict(x[:])}|table.to_dict(x.__dict__)
52
+ elif isinstance(x,(tuple,list)):
53
+ return [table.to_dict(v) for v in x]
54
+ elif isinstance(x,dict):
55
+ return {k:table.to_dict(v) for k,v in x.items()}
56
+ else:
57
+ return x
58
+ @classmethod
59
+ def from_dict(cls,dct):
60
+ cls = {table,config,expr,flow._tbl}|{cls}
61
+ for i in cls:
62
+ if f'__{i.__name__}__' in dct:
63
+ lst = dct.pop(f'__{i.__name__}__')
64
+ return i(*lst,**dct)
65
+ return dct
66
+
67
+ class config(table):
68
+ root = '.'
69
+
70
+ @classmethod
71
+ def load(cls, name=None):
72
+ import json
73
+ dct = {}
74
+ for i in cls.__bases__:
75
+ if i not in (table,config):
76
+ dct |= i.load().__dict__
77
+ with open(f'{config.root}/{cls.__module__}.{name or cls.__name__}.json') as f:
78
+ val = json.load(f)
79
+ if type(val) is dict:
80
+ dct |= val
81
+ return cls.from_dict(dct)
82
+ else:
83
+ val.__dict__ = dct | val.__dict__
84
+ return val
85
+
86
+ def save(self, *args):
87
+ import json
88
+ if len(args) == 0:
89
+ args = self.__class__.__mro__[::-1][4:-1] + (self,)
90
+ dct = self.__dict__.copy()
91
+ for i in args:
92
+ with open(f"{config.root}/{i.__module__}.{getattr(i,'__name__',i.__class__.__name__)}.json",'w') as f:
93
+ if type(i) is type:
94
+ json.dump({k:dct.pop(k) for k in i.__annotations__}|{f'__{i.__name__}__':[]},f)
95
+ else:
96
+ json.dump(dct|{f'__{i.__class__.__name__}__':[]},f)
97
+
98
+ def __call__(self,*args,**kwargs):
99
+ func = self.__dict__.get('__call__',None)
100
+ if func is not None:
101
+ return func(self,*args,**kwargs)
102
+ import copy
103
+ r = copy.deepcopy(self)
104
+ for k,v in kwargs.items():
105
+ setattr(r,k,v)
106
+ return r
107
+
108
+ import operator
109
+
110
+ def equal(x, y):
111
+ if type(x) != type(y):
112
+ return False
113
+ if getattr(x,'__getitem__',None) is not None:
114
+ x = x[:]
115
+ y = y[:]
116
+ if type(x) in (tuple,list,dict):
117
+ if len(x) != len(y):
118
+ return False
119
+ if type(x) is dict:
120
+ for k,v in x.items():
121
+ if not equal(v,y.get(k,None)):
122
+ return False
123
+ else:
124
+ for i in range(len(x)):
125
+ if not equal(x[i],y[i]):
126
+ return False
127
+ return True
128
+ return x == y
129
+
130
+ class expr(table):
131
+ def __getitem__(self, key):
132
+ if type(key) is slice and key == slice(None,None,None):
133
+ return super().__getitem__(key)
134
+ dct = self.__dict__
135
+ if 'self' in dct:
136
+ this = dct.pop('self')
137
+ r = self.__class__(*self,key,**dct)
138
+ r.__dict__['self'] = this
139
+ dct['self'] = this
140
+ return r
141
+ else:
142
+ return self.__class__(*self,key,**dct)
143
+ def __getattr__(self, key):
144
+ return None if key.startswith('_') or key in ('compute','getdoc','size','shape') else self[key]
145
+ def __repr__(self):
146
+ if len(self) == 0:
147
+ return 'expr()'
148
+ line = 'sym' if self[:][0] is None else 'expr('+pformat(self[:][0])+')'
149
+ for i in self[:][1:]:
150
+ if type(i) is str:
151
+ line += f'.{i}'
152
+ elif type(i) is table:
153
+ line += '(' + repr(i)[1:-1] + ')'
154
+ else:
155
+ line += f'[{i}]'
156
+ return line[1:] if line.startswith('.') else line
157
+ def __call__(self, *args, **kwargs):
158
+ r = self[:][0]
159
+ body = self[:][1:]
160
+ body.append(table(*args,**kwargs))
161
+ for i in range(len(body)):
162
+ key = body[i]
163
+ if type(key) is table:
164
+ t = table(*key[:],**key.__dict__)
165
+ for k in range(len(key)):
166
+ v = t[k]
167
+ if type(v) is self.__class__:
168
+ dct = self.__dict__|v.__dict__
169
+ if 'self' in dct:
170
+ this = dct.pop('self')
171
+ v = self.__class__(*v[:],**dct)
172
+ v.__dict__['self'] = this
173
+ t[k] = v()
174
+ else:
175
+ t[k] = self.__class__(*v[:],**dct)()
176
+ for k,v in key.__dict__.items():
177
+ if type(v) is self.__class__:
178
+ dct = self.__dict__|v.__dict__
179
+ if 'self' in dct:
180
+ this = dct.pop('self')
181
+ v = self.__class__(*v[:],**dct)
182
+ v.__dict__['self'] = this
183
+ t.__dict__[k] = v()
184
+ else:
185
+ t.__dict__[k] = self.__class__(*v[:],**dct)()
186
+ if type(r) is self.__class__:
187
+ try:
188
+ v = r[:][0]
189
+ if v is None:
190
+ v = self.__dict__
191
+ for k in r[:][1:-1]:
192
+ geti = getattr(v,'__getitem__',None)
193
+ v = getattr(v,k) if geti is None else geti(k)
194
+ k = r[:][-1]
195
+ f = getattr(v,k,None) if type(k) is str else None
196
+ if callable(f):
197
+ r = f(*t[:],**t.__dict__)
198
+ else:
199
+ if len(t) == 0 and len(t.__dict__) == 0:
200
+ geti = getattr(v,'__getitem__',None)
201
+ try:
202
+ r = getattr(v,k) if geti is None else geti(k)
203
+ except:
204
+ if r[:][0] is None:
205
+ v = None
206
+ r = v[k] if type(v) is self.__class__ else self.__class__(v,k)
207
+ else:
208
+ seti = getattr(v,'__setitem__',None)
209
+ if len(t) == 1 and len(t.__dict__) == 0:
210
+ t = t[0]
211
+ setattr(v,k,t) if seti is None else seti(k,t)
212
+ r = expr(r[:][0])
213
+ except:
214
+ if not (i == len(body) - 1 and len(args) == 0 and len(kwargs) == 0):
215
+ r = r[t] if type(r) is self.__class__ else self.__class__(r,t)
216
+ elif callable(r):
217
+ try:
218
+ r = r(*t[:],**t.__dict__)
219
+ except:
220
+ if not (i == len(body) - 1 and len(args) == 0 and len(kwargs) == 0):
221
+ r = self.__class__(r,t)
222
+ else:
223
+ if not (i == len(body) - 1 and len(args) == 0 and len(kwargs) == 0):
224
+ r = self.__class__(r,t)
225
+ else:
226
+ r = r[key] if type(r) is self.__class__ else self.__class__(r,key)
227
+ #print(self[:],args,kwargs,self.__dict__,r)
228
+ return r
229
+ def __lt__(a, b):
230
+ return a.__class__(operator.__lt__,table(a,b))
231
+ def __le__(a, b):
232
+ return a.__class__(operator.__le__,table(a,b))
233
+ def __eq__(a, b):
234
+ return a.__class__(operator.__eq__,table(a,b))
235
+ def __ne__(a, b):
236
+ return a.__class__(operator.__ne__,table(a,b))
237
+ def __ge__(a, b):
238
+ return a.__class__(operator.__ge__,table(a,b))
239
+ def __gt__(a, b):
240
+ return a.__class__(operator.__gt__,table(a,b))
241
+ def __not__(a):
242
+ return a.__class__(operator.__not__,table(a))
243
+ def __abs__(a):
244
+ return a.__class__(operator.__abs__,table(a))
245
+ def __round__(a):
246
+ return a.__class__(round,table(a))
247
+ def __add__(a, b):
248
+ return plus(a,b)
249
+ def __radd__(a, b):
250
+ return plus(b,a)
251
+ def __iadd__(a, b):
252
+ return plus(a,b)
253
+ def __and__(a, b):
254
+ return a.__class__(operator.__and__,table(a,b))
255
+ def __rand__(a, b):
256
+ return a.__class__(operator.__and__,table(b,a))
257
+ def __floordiv__(a, b):
258
+ return a.__class__(operator.__floordiv__,table(a,b))
259
+ def __rfloordiv__(a, b):
260
+ return a.__class__(operator.__floordiv__,table(b,a))
261
+ def __inv__(a):
262
+ return a.__class__(operator.__inv__,table(a))
263
+ def __invert__(a):
264
+ return a.__class__(operator.__invert__,table(a))
265
+ def __lshift__(a, b):
266
+ return a.__class__(operator.__lshift__,table(a,b))
267
+ def __rlshift__(a, b):
268
+ return a.__class__(operator.__lshift__,table(b,a))
269
+ def __mod__(a, b):
270
+ return a.__class__(operator.__mod__,table(a,b))
271
+ def __rmod__(a, b):
272
+ return a.__class__(operator.__mod__,table(b,a))
273
+ def __mul__(a, b):
274
+ return a.__class__(operator.__mul__,table(a,b))
275
+ def __rmul__(a, b):
276
+ return a.__class__(operator.__mul__,table(b,a))
277
+ def __matmul__(a, b):
278
+ return a.__class__(operator.__matmul__,table(a,b))
279
+ def __rmatmul__(a, b):
280
+ return a.__class__(operator.__matmul__,table(b,a))
281
+ def __neg__(a):
282
+ return uminus(a)
283
+ def __or__(a, b):
284
+ return a.__class__(operator.__or__,table(a,b))
285
+ def __ror__(a, b):
286
+ return a.__class__(operator.__or__,table(b,a))
287
+ def __pos__(a):
288
+ return uplus(a)
289
+ def __pow__(a, b):
290
+ return a.__class__(operator.__pow__,table(a,b))
291
+ def __rpow__(a, b):
292
+ return a.__class__(operator.__pow__,table(b,a))
293
+ def __rshift__(a, b):
294
+ return a.__class__(operator.__rshift__,table(a,b))
295
+ def __rrshift__(a, b):
296
+ return a.__class__(operator.__rshift__,table(b,a))
297
+ def __sub__(a, b):
298
+ return minus(a,b)
299
+ def __rsub__(a, b):
300
+ return minus(b,a)
301
+ def __truediv__(a, b):
302
+ return a.__class__(operator.__truediv__,table(a,b))
303
+ def __rtruediv__(a, b):
304
+ return a.__class__(operator.__truediv__,table(b,a))
305
+ def __xor__(a, b):
306
+ return a.__class__(operator.__xor__,table(a,b))
307
+ def __rxor__(a, b):
308
+ return a.__class__(operator.__xor__,table(b,a))
309
+
310
+ def subs(obj, **kwargs):
311
+ if type(obj) in (tuple,list):
312
+ return type(obj)([subs(i,**kwargs) for i in obj])
313
+ elif type(obj) is dict:
314
+ return {k:subs(v,**kwargs) for k,v in obj.items()}
315
+ elif type(obj) is expr:
316
+ return expr(*obj[:],**obj.__dict__,**kwargs)()
317
+ else:
318
+ return obj
319
+
320
+ sym = expr(None)
321
+
322
+ class plus_minus:
323
+ def __init__(self,name):
324
+ self._name = name
325
+ def __repr__(self):
326
+ return self._name
327
+ def __call__(self,*args):
328
+ if len(args) == 1:
329
+ x = args[0]
330
+ if self._name == 'uplus':
331
+ return x
332
+ if type(x) is expr:
333
+ if len(x) > 0 and x[:][0] is uminus:
334
+ return x[:][1][0]
335
+ elif len(x) > 0 and x[:][0] is plus:
336
+ return expr(plus,table(uminus(x[:][1][0]),uminus(x[:][1][1])))
337
+ else:
338
+ return expr(uminus,table(x))
339
+ return -x
340
+ if type(args[0]) not in (int,float,expr) or type(args[1]) not in (int,float,expr):
341
+ if type(args[0]) is expr or type(args[1]) is expr:
342
+ return expr(plus if self._name == 'plus' else minus,table(*args))
343
+ return args[0]+args[1] if self._name == 'plus' else args[0]-args[1]
344
+ atom = []
345
+ term = []
346
+ for i in range(2):
347
+ x = args[i]
348
+ sub = i == 1 and self._name == 'minus'
349
+ if type(x) is expr:
350
+ if len(x) > 0 and x[:][0] is plus:
351
+ t = x[:][1]
352
+ (term if type(t[0]) is expr else atom).append(-t[0] if sub else t[0])
353
+ (term if type(t[1]) is expr else atom).append(-t[1] if sub else t[1])
354
+ else:
355
+ term.append(-x if sub else x)
356
+ else:
357
+ atom.append(-x if sub else x)
358
+ if len(atom) == 0:
359
+ r = 0
360
+ else:
361
+ r = sum(atom)
362
+ for i in term:
363
+ if type(r) is not expr and r == 0:
364
+ r = i
365
+ else:
366
+ r = expr(plus,table(r,i))
367
+ return r
368
+
369
+ plus = plus_minus('plus')
370
+ minus = plus_minus('minus')
371
+ uplus = plus_minus('uplus')
372
+ uminus = plus_minus('uminus')
373
+
374
+ class context_switch:
375
+ def __init__(self, ctx, tbl):
376
+ self.ctx = ctx
377
+ self.tbl = tbl
378
+ def __enter__(self):
379
+ self.top = self.ctx <= self.tbl
380
+ def __exit__(self, exc_type, exc_val, exc_tb):
381
+ self.ctx <= self.top
382
+
383
+ class context:
384
+ def __init__(self,*args,**kwargs):
385
+ tbl = kwargs.pop('table',table)
386
+ object.__setattr__(self,'_tbl',tbl)
387
+ object.__setattr__(self,'_new',lambda:tbl(*args,**kwargs))
388
+ object.__setattr__(self,'_stk',[])
389
+ self.__enter__()
390
+ def __getattr__(self, key):
391
+ return getattr(self._stk[-1],key)
392
+ def __setattr__(self, key, val):
393
+ setattr(self._stk[-1],key,val)
394
+ def __getitem__(self,key):
395
+ return self._stk[-1][key]
396
+ def __setitem__(self,key,val):
397
+ self._stk[-1][key] = val
398
+ def __delitem__(self,key):
399
+ del self._stk[-1][key]
400
+ def __len__(self):
401
+ return len(self._stk[-1])
402
+ def __repr__(self):
403
+ return repr(self._stk[-1])
404
+ def __call__(self, *args, **kwargs):
405
+ return self._stk[-1] if len(args) == 0 and len(kwargs) == 0 else self._stk[-1](*args,**kwargs)
406
+ def __le__(self,val):
407
+ top = self._stk[-1]
408
+ self._stk[-1] = val
409
+ return top
410
+ def __lt__(self, other):
411
+ return context_switch(self, other)
412
+ def __enter__(self):
413
+ top = self._new()
414
+ self._stk.append(top)
415
+ return top
416
+ def __exit__(self, exc_type, exc_val, exc_tb):
417
+ self._stk.pop()
418
+
419
+ class flow(table):
420
+ def __getitem__(self, key):
421
+ if type(key) is slice:
422
+ return super().__getitem__(key)
423
+ key = str(key)
424
+ val = self.__dict__.get(key,None)
425
+ if val is None:
426
+ val = self.__class__()
427
+ self.__dict__[key] = val
428
+ return val
429
+ def __getattr__(self, key):
430
+ return None if key.startswith('_') or key in ('compute','getdoc','size','shape') else self[key]
431
+ def __call__(self, *args, **kwargs):
432
+ if not (len(args) == 0 and len(kwargs) == 0):
433
+ super().append(self.__class__(*args,**kwargs))
434
+ return self
435
+ def clear(self):
436
+ super().clear()
437
+ self.__dict__.clear()
438
+
439
+ flow = context(table=flow)
440
+
441
+ class meta:
442
+ def __init__(self, *args):
443
+ self.__meta__ = args
444
+ def __getattr__(self, key):
445
+ return None if key.startswith('_') or key in ('compute','getdoc','size','shape') else self[key]
446
+ def __getitem__(self, key):
447
+ if key is None:
448
+ return self
449
+ hashable = getattr(key,'__hash__',None)
450
+ val = None if hashable is None else self.__dict__.get(key,None)
451
+ if val is None:
452
+ val = self.__class__()
453
+ val.__dict__['__meta__'] = self.__meta__ + (key,)
454
+ if hashable is not None:
455
+ self.__dict__[key] = val
456
+ return val
457
+ def __call__(self, *args, **kwargs):
458
+ return self.__meta__[0](*args,*self.__meta__[1:],**kwargs)
459
+
460
+ class multi(meta):
461
+ def __call__(self, *args, **kwargs):
462
+ if len(self.__meta__) == 1:
463
+ val = self.__class__()
464
+ val.__dict__['__meta__'] = self.__meta__ + args
465
+ return val
466
+ elif len(self.__meta__) == 2:
467
+ nodes = getattr(self.__meta__[0],'multi',None)
468
+ if nodes is None:
469
+ return self.__meta__[1](*args,**kwargs)
470
+ else:
471
+ nodes = self.__meta__[2]
472
+ if type(nodes) is range:
473
+ nodes = list(nodes)
474
+ if type(nodes) not in (tuple,list):
475
+ nodes = [nodes]
476
+ if len(nodes) == 0:
477
+ return self.__meta__[1](*args,*self.__meta__[3:],**kwargs)
478
+ env = self.__meta__[0]()
479
+ for node in nodes:
480
+ tbl = getattr(env,str(node),None)
481
+ if tbl is None:
482
+ with self.__meta__[0] as tbl:
483
+ pass
484
+ env[str(node)] = tbl
485
+ self.__meta__[0] <= tbl
486
+ self.__meta__[1](*args,*self.__meta__[3:],**kwargs)
487
+ self.__meta__[0] <= env
488
+
489
+ import ast, inspect, copy
490
+
491
+ class FindReg(ast.NodeVisitor):
492
+ def __init__(self, regq):
493
+ self.regq = regq
494
+ self.found = False
495
+ def visit_Name(self, node):
496
+ if self.regq(node.id):
497
+ self.found = True
498
+
499
+ def RegQ(node, regq):
500
+ visitor = FindReg(regq)
501
+ visitor.visit(node)
502
+ return visitor.found
503
+
504
+ class WithPass(ast.NodeTransformer):
505
+ def __init__(self, regq, env={}):
506
+ self.regq = regq
507
+ self.env = env
508
+ def visit_If(self, node):
509
+ #print(ast.dump(node))
510
+ self.generic_visit(node)
511
+ If = self.env['If']
512
+ if type(If) is not str:
513
+ If = 'If'
514
+ Else = self.env['Else']
515
+ if type(Else) is not str:
516
+ Else = 'Else'
517
+ if isinstance(node.test, ast.Call) and node.test.func.id == '_':
518
+ node.test.func.id = If
519
+ elif RegQ(node.test, self.regq):
520
+ node.test = ast.Call(func=ast.Name(id=If, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset), args=[node.test], keywords=[], lineno=node.lineno, col_offset = node.col_offset)
521
+ if isinstance(node.test, ast.Call) and node.test.func.id == If:
522
+ withs = [ast.With(items=[ast.withitem(context_expr = node.test)], body=node.body, lineno=node.lineno, col_offset = node.col_offset)]
523
+ if len(node.orelse):
524
+ withs.append(ast.With(items=[\
525
+ ast.withitem(context_expr = \
526
+ ast.Call(func=ast.Name(id=Else, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset),\
527
+ args=[], keywords=[], lineno=node.lineno, col_offset = node.col_offset),\
528
+ lineno=node.lineno, col_offset = node.col_offset)], \
529
+ body=node.orelse, lineno=node.lineno, col_offset = node.col_offset))
530
+ return withs
531
+ return node
532
+ def visit_While(self, node):
533
+ #print(ast.dump(node))
534
+ self.generic_visit(node)
535
+ While = self.env['While']
536
+ if type(While) is not str:
537
+ While = 'While'
538
+ if isinstance(node.test, ast.Name) and node.test.id == '_':
539
+ node.test = ast.Call(func=ast.Name(id=While, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset), args=[], keywords=[], lineno=node.lineno, col_offset = node.col_offset)
540
+ elif isinstance(node.test, ast.Call) and node.test.func.id == '_':
541
+ node.test.func.id = While
542
+ elif RegQ(node.test, self.regq):
543
+ node.test = ast.Call(func=ast.Name(id=While, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset), args=[node.test], keywords=[], lineno=node.lineno, col_offset = node.col_offset)
544
+ if isinstance(node.test, ast.Call) and node.test.func.id == While:
545
+ return ast.With(items=[ast.withitem(context_expr = node.test)], body=node.body, lineno=node.lineno, col_offset = node.col_offset)
546
+ return node
547
+ def visit_For(self, node):
548
+ #print(ast.dump(node))
549
+ self.generic_visit(node)
550
+ For = self.env['For']
551
+ if type(For) is not str:
552
+ For = 'For'
553
+ if isinstance(node.iter, ast.Call) and node.iter.func.id == '_':
554
+ node.iter.func.id = For
555
+ elif RegQ(node.target, self.regq):
556
+ node.iter = ast.Call(func=ast.Name(id=For, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset), args=[node.iter], keywords=[], lineno=node.lineno, col_offset = node.col_offset)
557
+ if isinstance(node.iter, ast.Call) and node.iter.func.id == For:
558
+ node.target.ctx = ast.Load()
559
+ if len(node.iter.args) == 1 and isinstance(node.iter.args[0], ast.Call) and node.iter.args[0].func.id == 'range':
560
+ node.iter.args[0] = ast.Tuple(node.iter.args[0].args, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset)
561
+ node.iter.args = [node.target] + node.iter.args
562
+ return ast.With(items=[ast.withitem(context_expr = node.iter)], body=node.body, lineno=node.lineno, col_offset = node.col_offset)
563
+ return node
564
+ def visit_Assign(self, node):
565
+ #print(ast.dump(node))
566
+ self.generic_visit(node)
567
+ Set = self.env['Set']
568
+ if type(Set) is not str:
569
+ Set = 'Set'
570
+ if isinstance(node.targets[0], ast.Name) and isinstance(node.targets[0], ast.Name) and self.regq(node.targets[0].id):
571
+ node.targets[0].ctx = ast.Load()
572
+ return ast.Expr(value=ast.Call(func=ast.Name(id=Set, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset), args=[node.targets[0], node.value], keywords=[], lineno=node.lineno, col_offset = node.col_offset), lineno=node.lineno, col_offset = node.col_offset)
573
+ return node
574
+ def visit_Call(self, node):
575
+ #print(ast.dump(node))
576
+ self.generic_visit(node)
577
+ Call = self.env['Call']
578
+ if type(Call) is not str:
579
+ Call = 'Call'
580
+ func = getattr(node.func, 'id', None)
581
+ if func is not None and self.env.get('#'+func, None) is not None:
582
+ return ast.Call(func=ast.Name(id=Call,ctx=ast.Load(),lineno=node.lineno,col_offset=node.col_offset),args=[ast.Constant(value=node.func.id,lineno=node.lineno,col_offset=node.col_offset)]+node.args,keywords=[],lineno=node.lineno,col_offset=node.col_offset)
583
+ return node
584
+ def visit_Return(self, node):
585
+ #print(ast.dump(node))
586
+ self.generic_visit(node)
587
+ Return = self.env['Return']
588
+ if type(Return) is not str:
589
+ Return = 'Return'
590
+ return ast.Expr(value=ast.Call(func=ast.Name(id=Return,ctx=ast.Load(),lineno=node.lineno,col_offset=node.col_offset),args=\
591
+ node.value.elts if type(node.value) is ast.Tuple else ([] if node.value is None else [node.value]),keywords=[],lineno=node.lineno,col_offset=node.col_offset), lineno=node.lineno, col_offset = node.col_offset)
592
+
593
+ class SubPass(ast.NodeTransformer):
594
+ def __init__(self, env={}):
595
+ self.env = env
596
+ self.regs = {}
597
+ def visit_FunctionDef(self, node):
598
+ #print(ast.dump(node))
599
+ self.regs = {'_':[]}
600
+ reg = -1
601
+ kws = len(node.args.defaults)
602
+ for arg in node.args.args[:(-kws or None)]:
603
+ if arg.annotation is None:
604
+ reg += 1
605
+ else:
606
+ reg = arg.annotation.value
607
+ self.regs['_'].append(reg)
608
+ arg.annotation = None
609
+ self.regs[arg.arg] = ast.Subscript(value=ast.Name(id='R',ctx=ast.Load(),lineno=node.lineno,col_offset=node.col_offset), \
610
+ slice=ast.Index(value=ast.Constant(value=reg,lineno=node.lineno,col_offset=node.col_offset)), \
611
+ lineno=node.lineno,col_offset=node.col_offset)
612
+ self.regs['_'].append(reg)
613
+ node.regs = self.regs['_']
614
+ self.generic_visit(node)
615
+ self.env['#'+node.name] = self.regs['_']
616
+ self.regs = {}
617
+ Func = self.env['Func']
618
+ if type(Func) is not str:
619
+ Func = 'Func'
620
+ node.args.args = node.args.args[-kws:] if kws else []
621
+ node.body = [ast.With(items=[ast.withitem(context_expr=ast.Call(func=ast.Name(id=Func,ctx=ast.Load(),lineno=node.lineno, col_offset = node.col_offset), \
622
+ args=[ast.Constant(value=node.name,lineno=node.lineno,col_offset=node.col_offset)]+ \
623
+ [ast.Constant(value=i,lineno=node.lineno,col_offset=node.col_offset) for i in node.regs], \
624
+ keywords=[],lineno=node.lineno,col_offset=node.col_offset))],body=node.body, lineno=node.lineno,col_offset=node.col_offset)]
625
+ return node
626
+ def visit_Name(self, node):
627
+ #print(ast.dump(node))
628
+ if node.id != '_':
629
+ value = self.regs.get(node.id, None)
630
+ if value is not None:
631
+ value = copy.copy(value)
632
+ value.ctx = node.ctx
633
+ return value
634
+ return node
635
+ def visit_Assign(self, node):
636
+ #print(ast.dump(node))
637
+ self.generic_visit(node)
638
+ if isinstance(node.targets[0], ast.Name):
639
+ value = self.regs.get(node.targets[0].id, None)
640
+ if value is not None:
641
+ value = copy.copy(value)
642
+ value.ctx = ast.Store()
643
+ node.targets[0] = value
644
+ return node
645
+
646
+ def domain(ctx={}, regq=None, sub=None, dump=False):
647
+ def decorator(func):
648
+ src = inspect.getsourcelines(func)[0]
649
+ indent = len(src[0]) - len(src[0].lstrip())
650
+ src = ''.join([line[indent:] for line in src])
651
+ node = ast.parse(src)
652
+ node.body[0].decorator_list = []
653
+ if sub is True:
654
+ node = SubPass(ctx).visit(node)
655
+ elif isinstance(sub, ast.NodeTransformer):
656
+ node = sub(ctx).visit(node)
657
+ elif callable(sub):
658
+ node = sub(node)
659
+ if callable(regq):
660
+ node = WithPass(regq,ctx).visit(node)
661
+ if dump:
662
+ unparse = getattr(ast, 'unparse', None)
663
+ if unparse is not None:
664
+ print(unparse(node))
665
+ env = func.__globals__.copy()
666
+ env.update(ctx)
667
+ exec(compile(node, filename='', mode='exec'), env)
668
+ def wrap(*args, **kwargs):
669
+ env.update(ctx)
670
+ return eval(func.__name__, env)(*args, **kwargs)
671
+ return wrap
672
+ return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oasm
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Open ASseMbly tools
5
5
  Author-email: nzturn <nzturn@gmail.com>
6
6
  Keywords: asm,dsl