oasm 0.1.5__tar.gz → 0.1.7__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.5
3
+ Version: 0.1.7
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.5" # 初始版本号
3
+ version = "0.1.7" # 初始版本号
4
4
  authors = [
5
5
  { name = "nzturn", email = "nzturn@gmail.com" },
6
6
  ]
@@ -0,0 +1,674 @@
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
+ elif isinstance(obj,table):
318
+ return obj.__class__(*subs(obj[:],**kwargs),**subs(obj.__dict__,**kwargs))
319
+ else:
320
+ return obj
321
+
322
+ sym = expr(None)
323
+
324
+ class plus_minus:
325
+ def __init__(self,name):
326
+ self._name = name
327
+ def __repr__(self):
328
+ return self._name
329
+ def __call__(self,*args):
330
+ if len(args) == 1:
331
+ x = args[0]
332
+ if self._name == 'uplus':
333
+ return x
334
+ if type(x) is expr:
335
+ if len(x) > 0 and x[:][0] is uminus:
336
+ return x[:][1][0]
337
+ elif len(x) > 0 and x[:][0] is plus:
338
+ return expr(plus,table(uminus(x[:][1][0]),uminus(x[:][1][1])))
339
+ else:
340
+ return expr(uminus,table(x))
341
+ return -x
342
+ if type(args[0]) not in (int,float,expr) or type(args[1]) not in (int,float,expr):
343
+ if type(args[0]) is expr or type(args[1]) is expr:
344
+ return expr(plus if self._name == 'plus' else minus,table(*args))
345
+ return args[0]+args[1] if self._name == 'plus' else args[0]-args[1]
346
+ atom = []
347
+ term = []
348
+ for i in range(2):
349
+ x = args[i]
350
+ sub = i == 1 and self._name == 'minus'
351
+ if type(x) is expr:
352
+ if len(x) > 0 and x[:][0] is plus:
353
+ t = x[:][1]
354
+ (term if type(t[0]) is expr else atom).append(-t[0] if sub else t[0])
355
+ (term if type(t[1]) is expr else atom).append(-t[1] if sub else t[1])
356
+ else:
357
+ term.append(-x if sub else x)
358
+ else:
359
+ atom.append(-x if sub else x)
360
+ if len(atom) == 0:
361
+ r = 0
362
+ else:
363
+ r = sum(atom)
364
+ for i in term:
365
+ if type(r) is not expr and r == 0:
366
+ r = i
367
+ else:
368
+ r = expr(plus,table(r,i))
369
+ return r
370
+
371
+ plus = plus_minus('plus')
372
+ minus = plus_minus('minus')
373
+ uplus = plus_minus('uplus')
374
+ uminus = plus_minus('uminus')
375
+
376
+ class context_switch:
377
+ def __init__(self, ctx, tbl):
378
+ self.ctx = ctx
379
+ self.tbl = tbl
380
+ def __enter__(self):
381
+ self.top = self.ctx <= self.tbl
382
+ def __exit__(self, exc_type, exc_val, exc_tb):
383
+ self.ctx <= self.top
384
+
385
+ class context:
386
+ def __init__(self,*args,**kwargs):
387
+ tbl = kwargs.pop('table',table)
388
+ object.__setattr__(self,'_tbl',tbl)
389
+ object.__setattr__(self,'_new',lambda:tbl(*args,**kwargs))
390
+ object.__setattr__(self,'_stk',[])
391
+ self.__enter__()
392
+ def __getattr__(self, key):
393
+ return getattr(self._stk[-1],key)
394
+ def __setattr__(self, key, val):
395
+ setattr(self._stk[-1],key,val)
396
+ def __getitem__(self,key):
397
+ return self._stk[-1][key]
398
+ def __setitem__(self,key,val):
399
+ self._stk[-1][key] = val
400
+ def __delitem__(self,key):
401
+ del self._stk[-1][key]
402
+ def __len__(self):
403
+ return len(self._stk[-1])
404
+ def __repr__(self):
405
+ return repr(self._stk[-1])
406
+ def __call__(self, *args, **kwargs):
407
+ return self._stk[-1] if len(args) == 0 and len(kwargs) == 0 else self._stk[-1](*args,**kwargs)
408
+ def __le__(self,val):
409
+ top = self._stk[-1]
410
+ self._stk[-1] = val
411
+ return top
412
+ def __lt__(self, other):
413
+ return context_switch(self, other)
414
+ def __enter__(self):
415
+ top = self._new()
416
+ self._stk.append(top)
417
+ return top
418
+ def __exit__(self, exc_type, exc_val, exc_tb):
419
+ self._stk.pop()
420
+
421
+ class flow(table):
422
+ def __getitem__(self, key):
423
+ if type(key) is slice:
424
+ return super().__getitem__(key)
425
+ key = str(key)
426
+ val = self.__dict__.get(key,None)
427
+ if val is None:
428
+ val = self.__class__()
429
+ self.__dict__[key] = val
430
+ return val
431
+ def __getattr__(self, key):
432
+ return None if key.startswith('_') or key in ('compute','getdoc','size','shape') else self[key]
433
+ def __call__(self, *args, **kwargs):
434
+ if not (len(args) == 0 and len(kwargs) == 0):
435
+ super().append(self.__class__(*args,**kwargs))
436
+ return self
437
+ def clear(self):
438
+ super().clear()
439
+ self.__dict__.clear()
440
+
441
+ flow = context(table=flow)
442
+
443
+ class meta:
444
+ def __init__(self, *args):
445
+ self.__meta__ = args
446
+ def __getattr__(self, key):
447
+ return None if key.startswith('_') or key in ('compute','getdoc','size','shape') else self[key]
448
+ def __getitem__(self, key):
449
+ if key is None:
450
+ return self
451
+ hashable = getattr(key,'__hash__',None)
452
+ val = None if hashable is None else self.__dict__.get(key,None)
453
+ if val is None:
454
+ val = self.__class__()
455
+ val.__dict__['__meta__'] = self.__meta__ + (key,)
456
+ if hashable is not None:
457
+ self.__dict__[key] = val
458
+ return val
459
+ def __call__(self, *args, **kwargs):
460
+ return self.__meta__[0](*args,*self.__meta__[1:],**kwargs)
461
+
462
+ class multi(meta):
463
+ def __call__(self, *args, **kwargs):
464
+ if len(self.__meta__) == 1:
465
+ val = self.__class__()
466
+ val.__dict__['__meta__'] = self.__meta__ + args
467
+ return val
468
+ elif len(self.__meta__) == 2:
469
+ nodes = getattr(self.__meta__[0],'multi',None)
470
+ if nodes is None:
471
+ return self.__meta__[1](*args,**kwargs)
472
+ else:
473
+ nodes = self.__meta__[2]
474
+ if type(nodes) is range:
475
+ nodes = list(nodes)
476
+ if type(nodes) not in (tuple,list):
477
+ nodes = [nodes]
478
+ if len(nodes) == 0:
479
+ return self.__meta__[1](*args,*self.__meta__[3:],**kwargs)
480
+ env = self.__meta__[0]()
481
+ for node in nodes:
482
+ tbl = getattr(env,str(node),None)
483
+ if tbl is None:
484
+ with self.__meta__[0] as tbl:
485
+ pass
486
+ env[str(node)] = tbl
487
+ self.__meta__[0] <= tbl
488
+ self.__meta__[1](*args,*self.__meta__[3:],**kwargs)
489
+ self.__meta__[0] <= env
490
+
491
+ import ast, inspect, copy
492
+
493
+ class FindReg(ast.NodeVisitor):
494
+ def __init__(self, regq):
495
+ self.regq = regq
496
+ self.found = False
497
+ def visit_Name(self, node):
498
+ if self.regq(node.id):
499
+ self.found = True
500
+
501
+ def RegQ(node, regq):
502
+ visitor = FindReg(regq)
503
+ visitor.visit(node)
504
+ return visitor.found
505
+
506
+ class WithPass(ast.NodeTransformer):
507
+ def __init__(self, regq, env={}):
508
+ self.regq = regq
509
+ self.env = env
510
+ def visit_If(self, node):
511
+ #print(ast.dump(node))
512
+ self.generic_visit(node)
513
+ If = self.env['If']
514
+ if type(If) is not str:
515
+ If = 'If'
516
+ Else = self.env['Else']
517
+ if type(Else) is not str:
518
+ Else = 'Else'
519
+ if isinstance(node.test, ast.Call) and node.test.func.id == '_':
520
+ node.test.func.id = If
521
+ elif RegQ(node.test, self.regq):
522
+ 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)
523
+ if isinstance(node.test, ast.Call) and node.test.func.id == If:
524
+ withs = [ast.With(items=[ast.withitem(context_expr = node.test)], body=node.body, lineno=node.lineno, col_offset = node.col_offset)]
525
+ if len(node.orelse):
526
+ withs.append(ast.With(items=[\
527
+ ast.withitem(context_expr = \
528
+ ast.Call(func=ast.Name(id=Else, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset),\
529
+ args=[], keywords=[], lineno=node.lineno, col_offset = node.col_offset),\
530
+ lineno=node.lineno, col_offset = node.col_offset)], \
531
+ body=node.orelse, lineno=node.lineno, col_offset = node.col_offset))
532
+ return withs
533
+ return node
534
+ def visit_While(self, node):
535
+ #print(ast.dump(node))
536
+ self.generic_visit(node)
537
+ While = self.env['While']
538
+ if type(While) is not str:
539
+ While = 'While'
540
+ if isinstance(node.test, ast.Name) and node.test.id == '_':
541
+ 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)
542
+ elif isinstance(node.test, ast.Call) and node.test.func.id == '_':
543
+ node.test.func.id = While
544
+ elif RegQ(node.test, self.regq):
545
+ 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)
546
+ if isinstance(node.test, ast.Call) and node.test.func.id == While:
547
+ return ast.With(items=[ast.withitem(context_expr = node.test)], body=node.body, lineno=node.lineno, col_offset = node.col_offset)
548
+ return node
549
+ def visit_For(self, node):
550
+ #print(ast.dump(node))
551
+ self.generic_visit(node)
552
+ For = self.env['For']
553
+ if type(For) is not str:
554
+ For = 'For'
555
+ if isinstance(node.iter, ast.Call) and node.iter.func.id == '_':
556
+ node.iter.func.id = For
557
+ elif RegQ(node.target, self.regq):
558
+ 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)
559
+ if isinstance(node.iter, ast.Call) and node.iter.func.id == For:
560
+ node.target.ctx = ast.Load()
561
+ if len(node.iter.args) == 1 and isinstance(node.iter.args[0], ast.Call) and node.iter.args[0].func.id == 'range':
562
+ node.iter.args[0] = ast.Tuple(node.iter.args[0].args, ctx=ast.Load(), lineno=node.lineno, col_offset = node.col_offset)
563
+ node.iter.args = [node.target] + node.iter.args
564
+ return ast.With(items=[ast.withitem(context_expr = node.iter)], body=node.body, lineno=node.lineno, col_offset = node.col_offset)
565
+ return node
566
+ def visit_Assign(self, node):
567
+ #print(ast.dump(node))
568
+ self.generic_visit(node)
569
+ Set = self.env['Set']
570
+ if type(Set) is not str:
571
+ Set = 'Set'
572
+ if isinstance(node.targets[0], ast.Name) and isinstance(node.targets[0], ast.Name) and self.regq(node.targets[0].id):
573
+ node.targets[0].ctx = ast.Load()
574
+ 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)
575
+ return node
576
+ def visit_Call(self, node):
577
+ #print(ast.dump(node))
578
+ self.generic_visit(node)
579
+ Call = self.env['Call']
580
+ if type(Call) is not str:
581
+ Call = 'Call'
582
+ func = getattr(node.func, 'id', None)
583
+ if func is not None and self.env.get('#'+func, None) is not None:
584
+ 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)
585
+ return node
586
+ def visit_Return(self, node):
587
+ #print(ast.dump(node))
588
+ self.generic_visit(node)
589
+ Return = self.env['Return']
590
+ if type(Return) is not str:
591
+ Return = 'Return'
592
+ return ast.Expr(value=ast.Call(func=ast.Name(id=Return,ctx=ast.Load(),lineno=node.lineno,col_offset=node.col_offset),args=\
593
+ 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)
594
+
595
+ class SubPass(ast.NodeTransformer):
596
+ def __init__(self, env={}):
597
+ self.env = env
598
+ self.regs = {}
599
+ def visit_FunctionDef(self, node):
600
+ #print(ast.dump(node))
601
+ self.regs = {'_':[]}
602
+ reg = -1
603
+ kws = len(node.args.defaults)
604
+ for arg in node.args.args[:(-kws or None)]:
605
+ if arg.annotation is None:
606
+ reg += 1
607
+ else:
608
+ reg = arg.annotation.value
609
+ self.regs['_'].append(reg)
610
+ arg.annotation = None
611
+ self.regs[arg.arg] = ast.Subscript(value=ast.Name(id='R',ctx=ast.Load(),lineno=node.lineno,col_offset=node.col_offset), \
612
+ slice=ast.Index(value=ast.Constant(value=reg,lineno=node.lineno,col_offset=node.col_offset)), \
613
+ lineno=node.lineno,col_offset=node.col_offset)
614
+ self.regs['_'].append(reg)
615
+ node.regs = self.regs['_']
616
+ self.generic_visit(node)
617
+ self.env['#'+node.name] = self.regs['_']
618
+ self.regs = {}
619
+ Func = self.env['Func']
620
+ if type(Func) is not str:
621
+ Func = 'Func'
622
+ node.args.args = node.args.args[-kws:] if kws else []
623
+ 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), \
624
+ args=[ast.Constant(value=node.name,lineno=node.lineno,col_offset=node.col_offset)]+ \
625
+ [ast.Constant(value=i,lineno=node.lineno,col_offset=node.col_offset) for i in node.regs], \
626
+ keywords=[],lineno=node.lineno,col_offset=node.col_offset))],body=node.body, lineno=node.lineno,col_offset=node.col_offset)]
627
+ return node
628
+ def visit_Name(self, node):
629
+ #print(ast.dump(node))
630
+ if node.id != '_':
631
+ value = self.regs.get(node.id, None)
632
+ if value is not None:
633
+ value = copy.copy(value)
634
+ value.ctx = node.ctx
635
+ return value
636
+ return node
637
+ def visit_Assign(self, node):
638
+ #print(ast.dump(node))
639
+ self.generic_visit(node)
640
+ if isinstance(node.targets[0], ast.Name):
641
+ value = self.regs.get(node.targets[0].id, None)
642
+ if value is not None:
643
+ value = copy.copy(value)
644
+ value.ctx = ast.Store()
645
+ node.targets[0] = value
646
+ return node
647
+
648
+ def domain(ctx={}, regq=None, sub=None, dump=False):
649
+ def decorator(func):
650
+ src = inspect.getsourcelines(func)[0]
651
+ indent = len(src[0]) - len(src[0].lstrip())
652
+ src = ''.join([line[indent:] for line in src])
653
+ node = ast.parse(src)
654
+ node.body[0].decorator_list = []
655
+ if sub is True:
656
+ node = SubPass(ctx).visit(node)
657
+ elif isinstance(sub, ast.NodeTransformer):
658
+ node = sub(ctx).visit(node)
659
+ elif callable(sub):
660
+ node = sub(node)
661
+ if callable(regq):
662
+ node = WithPass(regq,ctx).visit(node)
663
+ if dump:
664
+ unparse = getattr(ast, 'unparse', None)
665
+ if unparse is not None:
666
+ print(unparse(node))
667
+ env = func.__globals__.copy()
668
+ env.update(ctx)
669
+ exec(compile(node, filename='', mode='exec'), env)
670
+ def wrap(*args, **kwargs):
671
+ env.update(ctx)
672
+ return eval(func.__name__, env)(*args, **kwargs)
673
+ return wrap
674
+ return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oasm
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: Open ASseMbly tools
5
5
  Author-email: nzturn <nzturn@gmail.com>
6
6
  Keywords: asm,dsl