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