oasm 0.1.5__py3-none-any.whl → 0.1.7__py3-none-any.whl

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/__init__.py CHANGED
@@ -2,151 +2,28 @@ import pkgutil
2
2
  __path__ = pkgutil.extend_path(__path__,__name__)
3
3
  __path__.reverse()
4
4
 
5
- __all__ = ['table','config','equal','expr','sym','context','flow','meta','multi','domain']
5
+ __all__ = ['table','config','equal','expr','subs','sym','context','flow','meta','multi','domain']
6
6
  from pprint import pformat
7
7
 
8
- """
9
- Open Assembly Tools (OASM) Core Module
10
-
11
- This module provides a comprehensive set of fundamental data structures and utility classes
12
- for advanced configuration management, expression processing, and assembly operations.
13
-
14
- Key features include:
15
- - Hybrid container types combining list and dictionary functionality
16
- - Configuration management with JSON persistence capabilities
17
- - Advanced expression evaluation system with operator overloading
18
- - Context management for state preservation and manipulation
19
- - Flow control utilities for programmatic assembly operations
20
- - Metaprogramming capabilities for dynamic code generation
21
- - Domain-specific language (DSL) constructs for custom assembly logic
22
-
23
- Module structure:
24
- - table: A flexible container that combines list and dictionary functionality
25
- - config: Extends table with JSON file loading and saving capabilities
26
- - equal: Deep equality comparison function for complex data structures
27
- - expr: Expression evaluation system with comprehensive operator support
28
- - sym: Symbolic expression constructor
29
- - context: Context management for maintaining and switching execution states
30
- - flow: Control flow management for assembly operations
31
- - meta: Metaprogramming utilities for dynamic code generation
32
- - multi: Multi-node assembly support for distributed operations
33
- - domain: DSL decorator for custom assembly language constructs
34
- """
35
-
36
8
  class table(list):
37
- """
38
- A flexible container that combines list and dictionary functionality.
39
-
40
- The table class extends the built-in list type while adding dictionary-like
41
- attribute access. This hybrid design allows for both sequential access by index
42
- and named access by attribute/key.
43
-
44
- Key features:
45
- - Supports list operations (append, extend, indexing)
46
- - Supports dictionary-like attribute and key access
47
- - Methods for deep copying and conversion to/from dictionaries
48
- - Callable interface that supports custom functions or method chaining
49
-
50
- Examples:
51
- t = table(1, 2, 3, a=4, b=5)
52
- print(t[0]) # Output: 1
53
- print(t.a) # Output: 4
54
- """
55
9
  def __init__(self, *args, **kwargs):
56
- """
57
- Initialize a new table instance.
58
-
59
- Parameters:
60
- *args: Positional arguments to be stored as list items
61
- **kwargs: Keyword arguments to be stored as attributes
62
-
63
- The initialization process:
64
- 1. Stores all positional arguments as items in the list
65
- 2. Stores all keyword arguments as attributes in the instance dictionary
66
- """
67
10
  super().__init__(args)
68
11
  self.__dict__.update(kwargs)
69
12
  def __getitem__(self, key=None):
70
- """
71
- Get an item from the table.
72
-
73
- Parameters:
74
- key: The key or index to retrieve. If a string, it accesses an attribute;
75
- otherwise, it accesses a list item.
76
-
77
- Returns:
78
- The requested item from the list or attribute from the dictionary.
79
-
80
- Raises:
81
- KeyError: If the key is a string and not found in __dict__
82
- IndexError: If the key is an integer and out of range for the list
83
-
84
- This method provides dual functionality:
85
- - String keys access attributes stored in __dict__
86
- - Other keys (typically integers) access list items
87
- """
88
13
  if type(key) is str:
89
14
  return self.__dict__[key]
90
15
  return super().__getitem__(key)
91
16
  def __setitem__(self, key, val):
92
- """
93
- Set an item in the table.
94
-
95
- Parameters:
96
- key: The key or index to set. If a string, it sets an attribute;
97
- otherwise, it sets a list item.
98
- val: The value to store at the specified key or index.
99
-
100
- This method provides dual functionality:
101
- - String keys set attributes in __dict__
102
- - Other keys (typically integers) set list items
103
- """
104
17
  if type(key) is str:
105
18
  self.__dict__[key] = val
106
19
  else:
107
20
  super().__setitem__(key, val)
108
21
  def __delitem__(self, key):
109
- """
110
- Delete an item from the table.
111
-
112
- Parameters:
113
- key: The key or index to delete. If a string, it deletes an attribute;
114
- otherwise, it deletes a list item.
115
-
116
- Raises:
117
- KeyError: If the key is a string and not found in __dict__
118
- IndexError: If the key is an integer and out of range for the list
119
-
120
- This method provides dual functionality:
121
- - String keys delete attributes from __dict__
122
- - Other keys (typically integers) delete list items
123
- """
124
22
  if type(key) is str:
125
23
  del self.__dict__[key]
126
24
  else:
127
25
  super().__delitem__(key)
128
26
  def __call__(self, *args, **kwargs):
129
- """
130
- Call method for the table class, supporting multiple operational modes.
131
-
132
- Parameters:
133
- *args: Positional arguments for the call
134
- **kwargs: Keyword arguments for the call
135
-
136
- Returns:
137
- - Result of the custom __call__ function if defined
138
- - Self if no arguments provided (identity operation)
139
- - Self after modification if arguments are provided (for method chaining)
140
-
141
- The method operates in three modes:
142
- 1. Custom function execution: If a '__call__' attribute exists and is callable,
143
- it is executed with the table as the first argument
144
- 2. Identity operation: If no arguments are provided, returns self
145
- 3. Modification mode: If arguments are provided:
146
- - Positional arguments extend the list part
147
- - Keyword arguments update the dictionary part
148
- - Returns self to support method chaining
149
- """
150
27
  func = self.__dict__.get('__call__',None)
151
28
  if func is not None:
152
29
  return func(self,*args,**kwargs)
@@ -156,18 +33,6 @@ class table(list):
156
33
  self.__dict__.update(kwargs)
157
34
  return self
158
35
  def __repr__(self):
159
- """
160
- Return a string representation of the table.
161
-
162
- Returns:
163
- str: A string representation combining list items and dictionary attributes
164
- in a format similar to '[item1,item2,...,key1=value1,key2=value2,...]'
165
-
166
- The representation includes:
167
- 1. All list items formatted with pformat for readability
168
- 2. All dictionary attributes in key=value format
169
- 3. Removes trailing commas for cleaner output
170
- """
171
36
  r = ''
172
37
  for i in self[:]:
173
38
  r += pformat(i) + ','
@@ -177,54 +42,11 @@ class table(list):
177
42
  r = r[:-1]
178
43
  return '[' + r + ']'
179
44
  def __neg__(self):
180
- """
181
- Implement the unary negation operation for the table class.
182
-
183
- Returns:
184
- table: Returns self unchanged. This is a placeholder implementation
185
- to ensure the table class works smoothly with expression systems.
186
-
187
- This implementation makes the table class compatible with expression
188
- systems that may apply unary negation operations. By returning self,
189
- it effectively ignores the negation operation while maintaining compatibility.
190
- """
191
45
  return self
192
46
  def copy(self):
193
- """
194
- Create a shallow copy of the table.
195
-
196
- Returns:
197
- table: A new table instance with copies of the list items and dictionary attributes.
198
-
199
- This method creates a new table instance where:
200
- 1. The list portion is populated with the items from the original table
201
- 2. The dictionary portion is populated with the attributes from the original table
202
- 3. The copies are shallow - nested mutable objects will still reference the same instances
203
- """
204
47
  return self.__class__(*self[:],**self.__dict__)
205
48
  @staticmethod
206
49
  def to_dict(x):
207
- """
208
- Convert a table or other data structure to a serializable dictionary.
209
-
210
- Parameters:
211
- x: The object to convert to a dictionary. This can be a table, list,
212
- tuple, dict, or any other serializable value.
213
-
214
- Returns:
215
- dict: A dictionary representation of the input object, with all nested
216
- objects also converted to dictionaries.
217
-
218
- The conversion process:
219
- 1. For table instances: Creates a dictionary with a special class marker
220
- and converts both list items and dictionary attributes recursively
221
- 2. For lists/tuples: Converts each element recursively and returns as a list
222
- 3. For dictionaries: Converts each value recursively while preserving keys
223
- 4. For other types: Returns the value unchanged
224
-
225
- This method is particularly useful for serialization purposes, allowing
226
- complex table structures to be converted to a format suitable for JSON.
227
- """
228
50
  if isinstance(x, table):
229
51
  return {f'__{x.__class__.__name__}__':table.to_dict(x[:])}|table.to_dict(x.__dict__)
230
52
  elif isinstance(x,(tuple,list)):
@@ -235,28 +57,6 @@ class table(list):
235
57
  return x
236
58
  @classmethod
237
59
  def from_dict(cls,dct):
238
- """
239
- Reconstruct a table or derived class instance from a dictionary representation.
240
-
241
- Parameters:
242
- dct (dict): A dictionary containing the serialized representation of
243
- a table or derived class instance. The dictionary should include
244
- a special class marker key (__ClassName__) if it represents a table subclass.
245
-
246
- Returns:
247
- table or type: A reconstructed table instance if the dictionary contains
248
- a class marker, or the original dictionary otherwise.
249
-
250
- The reconstruction process:
251
- 1. Checks for known table-derived classes in a predefined set
252
- 2. Searches for a special class marker in the dictionary
253
- 3. If found, extracts the list items, removes the marker, and instantiates
254
- the appropriate class with the list items and remaining dictionary attributes
255
- 4. If no class marker is found, returns the original dictionary
256
-
257
- This method works as the complement to to_dict, allowing serialized
258
- table structures to be reconstructed from their dictionary representations.
259
- """
260
60
  cls = {table,config,expr,flow._tbl}|{cls}
261
61
  for i in cls:
262
62
  if f'__{i.__name__}__' in dct:
@@ -265,50 +65,10 @@ class table(list):
265
65
  return dct
266
66
 
267
67
  class config(table):
268
- """
269
- Configuration management class with JSON file persistence capabilities.
270
-
271
- The config class extends the table container with methods for loading and
272
- saving configuration data to JSON files. This provides a convenient way to
273
- manage application settings, preferences, and other configurable data that
274
- needs to persist between sessions.
275
-
276
- Key features:
277
- - Inherits all the flexible container capabilities of the table class
278
- - JSON file loading and saving functionality
279
- - Support for hierarchical configuration inheritance
280
- - Deep copying with attribute modification for temporary configuration changes
281
-
282
- Class Attributes:
283
- root (str): Default directory path for configuration files (default: '../json')
284
- """
285
- # Default directory path for storing and retrieving configuration JSON files
286
- root = '../json'
68
+ root = '.'
287
69
 
288
70
  @classmethod
289
71
  def load(cls, name=None):
290
- """
291
- Load configuration data from a JSON file.
292
-
293
- Parameters:
294
- name (str, optional): The name of the configuration file to load.
295
- If not provided, the class name is used.
296
-
297
- Returns:
298
- config: A new config instance populated with the loaded data.
299
-
300
- Raises:
301
- FileNotFoundError: If the specified configuration file does not exist
302
- json.JSONDecodeError: If the file contains invalid JSON
303
-
304
- The loading process:
305
- 1. Collects configuration data from parent classes (excluding table and config)
306
- 2. Loads data from the specified JSON file
307
- 3. Merges the parent class data with the file data
308
- 4. Reconstructs and returns a config instance using from_dict
309
-
310
- The file path is constructed as: {config.root}/{cls.__module__}.{name or cls.__name__}.json
311
- """
312
72
  import json
313
73
  dct = {}
314
74
  for i in cls.__bases__:
@@ -324,30 +84,6 @@ class config(table):
324
84
  return val
325
85
 
326
86
  def save(self, *args):
327
- """
328
- Save configuration data to JSON files.
329
-
330
- Parameters:
331
- *args: Classes or instances to save. If not provided, saves for all
332
- parent classes and the instance itself.
333
-
334
- Raises:
335
- IOError: If there are issues writing to the file system
336
- TypeError: If the data cannot be serialized to JSON
337
-
338
- The saving process:
339
- 1. If no arguments are provided, determines the save targets from the
340
- class hierarchy (excluding object, type, and immediate parents)
341
- 2. Creates a copy of the instance dictionary
342
- 3. For each target class/instance:
343
- - Constructs the file path based on module and class/instance name
344
- - For class targets: Only saves attributes defined in class annotations
345
- - For instance targets: Saves all attributes
346
- - Adds a special class marker for potential future reconstruction
347
- - Writes the data to a JSON file
348
-
349
- The file path format is: {config.root}/{target.__module__}.{target_name}.json
350
- """
351
87
  import json
352
88
  if len(args) == 0:
353
89
  args = self.__class__.__mro__[::-1][4:-1] + (self,)
@@ -360,26 +96,6 @@ class config(table):
360
96
  json.dump(dct|{f'__{i.__class__.__name__}__':[]},f)
361
97
 
362
98
  def __call__(self,*args,**kwargs):
363
- """
364
- Create a modified deep copy of the configuration or execute a custom callable.
365
-
366
- Parameters:
367
- *args: Positional arguments for the custom callable
368
- **kwargs: Keyword arguments to modify in the copied configuration
369
-
370
- Returns:
371
- - Result of the custom __call__ function if defined
372
- - A deep copy of the configuration with modified attributes if no custom callable exists
373
-
374
- The method operates in two modes:
375
- 1. Custom function execution: If a '__call__' attribute exists and is callable,
376
- it is executed with the configuration as the first argument
377
- 2. Deep copy mode: Creates a deep copy of the configuration and updates its
378
- attributes with the provided keyword arguments
379
-
380
- This method is particularly useful for creating temporary configuration
381
- variations while preserving the original configuration intact.
382
- """
383
99
  func = self.__dict__.get('__call__',None)
384
100
  if func is not None:
385
101
  return func(self,*args,**kwargs)
@@ -392,30 +108,6 @@ class config(table):
392
108
  import operator
393
109
 
394
110
  def equal(x, y):
395
- """
396
- Deep equality comparison for complex data structures.
397
-
398
- Parameters:
399
- x: First object to compare
400
- y: Second object to compare
401
-
402
- Returns:
403
- bool: True if x and y are deeply equal, False otherwise
404
-
405
- This function performs a recursive deep comparison between two objects,
406
- handling nested structures like lists, tuples, dictionaries, and table instances.
407
-
408
- The comparison process:
409
- 1. Checks if x and y are of the same type
410
- 2. For objects with __getitem__ method (like tables), gets their items
411
- 3. For tuples, lists, and dictionaries, performs element-wise recursive comparison:
412
- - For dictionaries: Checks that all keys in x exist in y and have equal values
413
- - For sequences: Checks that all corresponding elements are equal
414
- 4. For other types, falls back to the standard == operator
415
-
416
- This function is particularly useful for comparing complex nested data structures
417
- where shallow comparison (using ==) would not be sufficient.
418
- """
419
111
  if type(x) != type(y):
420
112
  return False
421
113
  if getattr(x,'__getitem__',None) is not None:
@@ -436,44 +128,7 @@ def equal(x, y):
436
128
  return x == y
437
129
 
438
130
  class expr(table):
439
- """
440
- Expression evaluation system with comprehensive operator support.
441
-
442
- The expr class extends the table container to provide a powerful expression
443
- evaluation system. It allows for the construction and evaluation of symbolic
444
- expressions with support for attribute access, item access, method calls,
445
- and a wide range of operators.
446
-
447
- Key features:
448
- - Chainable attribute and item access for building complex expressions
449
- - Comprehensive operator overloading for arithmetic and comparison operations
450
- - Lazy evaluation of expressions
451
- - Support for nested expressions and function calls
452
- - Self-referential expression handling
453
-
454
- This class forms the core of the expression evaluation system, enabling
455
- concise and powerful expression building for various assembly and configuration tasks.
456
- """
457
131
  def __getitem__(self, key):
458
- """
459
- Get an item from the expression or extend the expression chain.
460
-
461
- Parameters:
462
- key: The key/index to access or add to the expression chain.
463
- If a slice, it accesses list items; otherwise, it extends the expression.
464
-
465
- Returns:
466
- - List items if key is a slice
467
- - A new expr instance with the key appended to the expression chain
468
-
469
- This method has dual functionality:
470
- 1. If the key is a full slice (:), it returns the underlying list items
471
- 2. Otherwise, it creates a new expression by appending the key to the current expression
472
-
473
- Special handling for self-references:
474
- - If the expression contains a 'self' attribute, it preserves this attribute
475
- in the new expression while temporarily removing it during construction
476
- """
477
132
  if type(key) is slice and key == slice(None,None,None):
478
133
  return super().__getitem__(key)
479
134
  dct = self.__dict__
@@ -486,44 +141,8 @@ class expr(table):
486
141
  else:
487
142
  return self.__class__(*self,key,**dct)
488
143
  def __getattr__(self, key):
489
- """
490
- Extend the expression chain with attribute access or handle special cases.
491
-
492
- Parameters:
493
- key: The attribute name to access
494
-
495
- Returns:
496
- - None if the key starts with '_' or is one of the special method names
497
- - A new expr instance with the attribute name appended to the expression chain otherwise
498
-
499
- This method handles attribute access for the expression system, with special behavior for:
500
- 1. Special methods and attributes (starting with '_'): Returns None to avoid conflicts
501
- 2. Known special method names: Returns None for methods like 'compute', 'getdoc', etc.
502
- 3. Regular attribute access: Extends the expression chain by calling self[key]
503
-
504
- This allows for elegant expression building with attribute chaining while avoiding
505
- conflicts with Python's internal methods and handling special method cases appropriately.
506
- """
507
144
  return None if key.startswith('_') or key in ('compute','getdoc','size','shape') else self[key]
508
145
  def __repr__(self):
509
- """
510
- Return a string representation of the expression.
511
-
512
- Returns:
513
- str: A string representation of the expression in a human-readable format
514
- that shows the expression's structure and components.
515
-
516
- The representation depends on the expression's content:
517
- - Empty expressions return 'expr()'
518
- - Symbolic expressions (starting with None) begin with 'sym'
519
- - Regular expressions begin with 'expr(value)'
520
- - String components are appended with dot notation (e.g., '.attribute')
521
- - Table components are appended as function calls (e.g., '(args)')
522
- - Other components are appended as index access (e.g., '[index]')
523
-
524
- This method helps with debugging and visualization of complex expressions
525
- by creating a clear textual representation of the expression chain.
526
- """
527
146
  if len(self) == 0:
528
147
  return 'expr()'
529
148
  line = 'sym' if self[:][0] is None else 'expr('+pformat(self[:][0])+')'
@@ -536,30 +155,6 @@ class expr(table):
536
155
  line += f'[{i}]'
537
156
  return line[1:] if line.startswith('.') else line
538
157
  def __call__(self, *args, **kwargs):
539
- """
540
- Evaluate the expression with the provided arguments.
541
-
542
- Parameters:
543
- *args: Arguments to be used during evaluation (not used in the current implementation)
544
- **kwargs: Keyword arguments to be used during evaluation (not used in the current implementation)
545
-
546
- Returns:
547
- The result of evaluating the expression chain
548
-
549
- This method evaluates the expression by processing each element in the expression chain:
550
- 1. Starts with the initial value (first element of the chain)
551
- 2. For each subsequent element in the chain:
552
- - Evaluates any nested expressions in the current element
553
- - Applies the appropriate operation based on the element type:
554
- - If string: Performs attribute access
555
- - If table: Performs function call with arguments from the table
556
- - Otherwise: Performs item/index access
557
- 3. Handles self-referential expressions through the 'self' attribute
558
- 4. Provides error recovery by converting exceptions into new expression nodes when appropriate
559
-
560
- The evaluation process supports complex nested expressions and maintains proper context for
561
- expressions that reference themselves through the 'self' attribute.
562
- """
563
158
  r = self[:][0]
564
159
  body = self[:][1:]
565
160
  body.append(table(*args,**kwargs))
@@ -632,503 +227,101 @@ class expr(table):
632
227
  #print(self[:],args,kwargs,self.__dict__,r)
633
228
  return r
634
229
  def __lt__(a, b):
635
- """
636
- Create a new expression representing less than comparison of a and b.
637
-
638
- Parameters:
639
- a: The left operand for comparison
640
- b: The right operand for comparison
641
-
642
- Returns:
643
- expr: A new expression that evaluates to a < b
644
- """
645
230
  return a.__class__(operator.__lt__,table(a,b))
646
231
  def __le__(a, b):
647
- """
648
- Create a new expression representing less than or equal comparison of a and b.
649
-
650
- Parameters:
651
- a: The left operand for comparison
652
- b: The right operand for comparison
653
-
654
- Returns:
655
- expr: A new expression that evaluates to a <= b
656
- """
657
232
  return a.__class__(operator.__le__,table(a,b))
658
233
  def __eq__(a, b):
659
- """
660
- Create a new expression representing equality comparison of a and b.
661
-
662
- Parameters:
663
- a: The left operand for comparison
664
- b: The right operand for comparison
665
-
666
- Returns:
667
- expr: A new expression that evaluates to a == b
668
- """
669
234
  return a.__class__(operator.__eq__,table(a,b))
670
235
  def __ne__(a, b):
671
- """
672
- Create a new expression representing inequality comparison of a and b.
673
-
674
- Parameters:
675
- a: The left operand for comparison
676
- b: The right operand for comparison
677
-
678
- Returns:
679
- expr: A new expression that evaluates to a != b
680
- """
681
236
  return a.__class__(operator.__ne__,table(a,b))
682
237
  def __ge__(a, b):
683
- """
684
- Create a new expression representing greater than or equal comparison of a and b.
685
-
686
- Parameters:
687
- a: The left operand for comparison
688
- b: The right operand for comparison
689
-
690
- Returns:
691
- expr: A new expression that evaluates to a >= b
692
- """
693
238
  return a.__class__(operator.__ge__,table(a,b))
694
239
  def __gt__(a, b):
695
- """
696
- Create a new expression representing greater than comparison of a and b.
697
-
698
- Parameters:
699
- a: The left operand for comparison
700
- b: The right operand for comparison
701
-
702
- Returns:
703
- expr: A new expression that evaluates to a > b
704
- """
705
240
  return a.__class__(operator.__gt__,table(a,b))
706
241
  def __not__(a):
707
- """
708
- Create a new expression representing logical NOT of a.
709
-
710
- Parameters:
711
- a: The operand for logical NOT
712
-
713
- Returns:
714
- expr: A new expression that evaluates to not a
715
- """
716
242
  return a.__class__(operator.__not__,table(a))
717
243
  def __abs__(a):
718
- """
719
- Create a new expression representing absolute value of a.
720
-
721
- Parameters:
722
- a: The operand for absolute value
723
-
724
- Returns:
725
- expr: A new expression that evaluates to abs(a)
726
- """
727
244
  return a.__class__(operator.__abs__,table(a))
728
245
  def __round__(a):
729
- """
730
- Create a new expression representing rounding of a.
731
-
732
- Parameters:
733
- a: The operand for rounding
734
-
735
- Returns:
736
- expr: A new expression that evaluates to round(a)
737
- """
738
246
  return a.__class__(round,table(a))
739
247
  def __add__(a, b):
740
- """
741
- Create a new expression representing addition of a and b.
742
-
743
- Parameters:
744
- a: The left operand for addition
745
- b: The right operand for addition
746
-
747
- Returns:
748
- expr: A new expression that evaluates to a + b
749
- """
750
248
  return plus(a,b)
751
249
  def __radd__(a, b):
752
- """
753
- Create a new expression representing reverse addition of b and a.
754
-
755
- Parameters:
756
- a: The right operand for addition
757
- b: The left operand for addition
758
-
759
- Returns:
760
- expr: A new expression that evaluates to b + a
761
- """
762
250
  return plus(b,a)
763
251
  def __iadd__(a, b):
764
- """
765
- Create a new expression representing in-place addition of a and b.
766
-
767
- Parameters:
768
- a: The left operand for addition
769
- b: The right operand for addition
770
-
771
- Returns:
772
- expr: A new expression that evaluates to a + b
773
- """
774
252
  return plus(a,b)
775
253
  def __and__(a, b):
776
- """
777
- Create a new expression representing bitwise AND of a and b.
778
-
779
- Parameters:
780
- a: The left operand for bitwise AND
781
- b: The right operand for bitwise AND
782
-
783
- Returns:
784
- expr: A new expression that evaluates to a & b
785
- """
786
254
  return a.__class__(operator.__and__,table(a,b))
787
255
  def __rand__(a, b):
788
- """
789
- Create a new expression representing reverse bitwise AND of b and a.
790
-
791
- Parameters:
792
- a: The right operand for bitwise AND
793
- b: The left operand for bitwise AND
794
-
795
- Returns:
796
- expr: A new expression that evaluates to b & a
797
- """
798
256
  return a.__class__(operator.__and__,table(b,a))
799
257
  def __floordiv__(a, b):
800
- """
801
- Create a new expression representing floor division of a by b.
802
-
803
- Parameters:
804
- a: The dividend
805
- b: The divisor
806
-
807
- Returns:
808
- expr: A new expression that evaluates to a // b
809
- """
810
258
  return a.__class__(operator.__floordiv__,table(a,b))
811
259
  def __rfloordiv__(a, b):
812
- """
813
- Create a new expression representing reverse floor division of b by a.
814
-
815
- Parameters:
816
- a: The divisor
817
- b: The dividend
818
-
819
- Returns:
820
- expr: A new expression that evaluates to b // a
821
- """
822
260
  return a.__class__(operator.__floordiv__,table(b,a))
823
261
  def __inv__(a):
824
- """
825
- Create a new expression representing bitwise inversion of a.
826
-
827
- Parameters:
828
- a: The operand for bitwise inversion
829
-
830
- Returns:
831
- expr: A new expression that evaluates to ~a
832
- """
833
262
  return a.__class__(operator.__inv__,table(a))
834
263
  def __invert__(a):
835
- """
836
- Create a new expression representing bitwise NOT of a.
837
-
838
- Parameters:
839
- a: The operand for bitwise NOT
840
-
841
- Returns:
842
- expr: A new expression that evaluates to ~a
843
- """
844
264
  return a.__class__(operator.__invert__,table(a))
845
265
  def __lshift__(a, b):
846
- """
847
- Create a new expression representing bitwise left shift of a by b.
848
-
849
- Parameters:
850
- a: The value to be shifted
851
- b: The number of positions to shift
852
-
853
- Returns:
854
- expr: A new expression that evaluates to a << b
855
- """
856
266
  return a.__class__(operator.__lshift__,table(a,b))
857
267
  def __rlshift__(a, b):
858
- """
859
- Create a new expression representing reverse bitwise left shift of b by a.
860
-
861
- Parameters:
862
- a: The number of positions to shift
863
- b: The value to be shifted
864
-
865
- Returns:
866
- expr: A new expression that evaluates to b << a
867
- """
868
268
  return a.__class__(operator.__lshift__,table(b,a))
869
269
  def __mod__(a, b):
870
- """
871
- Create a new expression representing modulo operation of a by b.
872
-
873
- Parameters:
874
- a: The dividend
875
- b: The divisor
876
-
877
- Returns:
878
- expr: A new expression that evaluates to a % b
879
- """
880
270
  return a.__class__(operator.__mod__,table(a,b))
881
271
  def __rmod__(a, b):
882
- """
883
- Create a new expression representing reverse modulo operation of b by a.
884
-
885
- Parameters:
886
- a: The divisor
887
- b: The dividend
888
-
889
- Returns:
890
- expr: A new expression that evaluates to b % a
891
- """
892
272
  return a.__class__(operator.__mod__,table(b,a))
893
273
  def __mul__(a, b):
894
- """
895
- Create a new expression representing multiplication of a and b.
896
-
897
- Parameters:
898
- a: The left operand for multiplication
899
- b: The right operand for multiplication
900
-
901
- Returns:
902
- expr: A new expression that evaluates to a * b
903
- """
904
274
  return a.__class__(operator.__mul__,table(a,b))
905
275
  def __rmul__(a, b):
906
- """
907
- Create a new expression representing reverse multiplication of b and a.
908
-
909
- Parameters:
910
- a: The right operand for multiplication
911
- b: The left operand for multiplication
912
-
913
- Returns:
914
- expr: A new expression that evaluates to b * a
915
- """
916
276
  return a.__class__(operator.__mul__,table(b,a))
917
277
  def __matmul__(a, b):
918
- """
919
- Create a new expression representing matrix multiplication of a and b.
920
-
921
- Parameters:
922
- a: The left operand for matrix multiplication
923
- b: The right operand for matrix multiplication
924
-
925
- Returns:
926
- expr: A new expression that evaluates to a @ b
927
- """
928
278
  return a.__class__(operator.__matmul__,table(a,b))
929
279
  def __rmatmul__(a, b):
930
- """
931
- Create a new expression representing reverse matrix multiplication of b and a.
932
-
933
- Parameters:
934
- a: The right operand for matrix multiplication
935
- b: The left operand for matrix multiplication
936
-
937
- Returns:
938
- expr: A new expression that evaluates to b @ a
939
- """
940
280
  return a.__class__(operator.__matmul__,table(b,a))
941
281
  def __neg__(a):
942
- """
943
- Create a new expression representing unary negation of a.
944
-
945
- Parameters:
946
- a: The operand for unary negation
947
-
948
- Returns:
949
- expr: A new expression that evaluates to -a
950
- """
951
282
  return uminus(a)
952
283
  def __or__(a, b):
953
- """
954
- Create a new expression representing bitwise OR of a and b.
955
-
956
- Parameters:
957
- a: The left operand for bitwise OR
958
- b: The right operand for bitwise OR
959
-
960
- Returns:
961
- expr: A new expression that evaluates to a | b
962
- """
963
284
  return a.__class__(operator.__or__,table(a,b))
964
285
  def __ror__(a, b):
965
- """
966
- Create a new expression representing reverse bitwise OR of b and a.
967
-
968
- Parameters:
969
- a: The right operand for bitwise OR
970
- b: The left operand for bitwise OR
971
-
972
- Returns:
973
- expr: A new expression that evaluates to b | a
974
- """
975
286
  return a.__class__(operator.__or__,table(b,a))
976
287
  def __pos__(a):
977
- """
978
- Create a new expression representing unary plus of a.
979
-
980
- Parameters:
981
- a: The operand for unary plus
982
-
983
- Returns:
984
- expr: A new expression that evaluates to +a
985
- """
986
288
  return uplus(a)
987
289
  def __pow__(a, b):
988
- """
989
- Create a new expression representing exponentiation of a to the power of b.
990
-
991
- Parameters:
992
- a: The base
993
- b: The exponent
994
-
995
- Returns:
996
- expr: A new expression that evaluates to a ** b
997
- """
998
290
  return a.__class__(operator.__pow__,table(a,b))
999
291
  def __rpow__(a, b):
1000
- """
1001
- Create a new expression representing reverse exponentiation of b to the power of a.
1002
-
1003
- Parameters:
1004
- a: The exponent
1005
- b: The base
1006
-
1007
- Returns:
1008
- expr: A new expression that evaluates to b ** a
1009
- """
1010
292
  return a.__class__(operator.__pow__,table(b,a))
1011
293
  def __rshift__(a, b):
1012
- """
1013
- Create a new expression representing bitwise right shift of a by b.
1014
-
1015
- Parameters:
1016
- a: The value to be shifted
1017
- b: The number of positions to shift
1018
-
1019
- Returns:
1020
- expr: A new expression that evaluates to a >> b
1021
- """
1022
294
  return a.__class__(operator.__rshift__,table(a,b))
1023
295
  def __rrshift__(a, b):
1024
- """
1025
- Create a new expression representing reverse bitwise right shift of b by a.
1026
-
1027
- Parameters:
1028
- a: The number of positions to shift
1029
- b: The value to be shifted
1030
-
1031
- Returns:
1032
- expr: A new expression that evaluates to b >> a
1033
- """
1034
296
  return a.__class__(operator.__rshift__,table(b,a))
1035
297
  def __sub__(a, b):
1036
- """
1037
- Create a new expression representing subtraction of b from a.
1038
-
1039
- Parameters:
1040
- a: The minuend
1041
- b: The subtrahend
1042
-
1043
- Returns:
1044
- expr: A new expression that evaluates to a - b
1045
- """
1046
298
  return minus(a,b)
1047
299
  def __rsub__(a, b):
1048
- """
1049
- Create a new expression representing reverse subtraction of a from b.
1050
-
1051
- Parameters:
1052
- a: The subtrahend
1053
- b: The minuend
1054
-
1055
- Returns:
1056
- expr: A new expression that evaluates to b - a
1057
- """
1058
300
  return minus(b,a)
1059
301
  def __truediv__(a, b):
1060
- """
1061
- Create a new expression representing true division of a by b.
1062
-
1063
- Parameters:
1064
- a: The dividend
1065
- b: The divisor
1066
-
1067
- Returns:
1068
- expr: A new expression that evaluates to a / b (floating point)
1069
- """
1070
302
  return a.__class__(operator.__truediv__,table(a,b))
1071
303
  def __rtruediv__(a, b):
1072
- """
1073
- Create a new expression representing reverse true division of b by a.
1074
-
1075
- Parameters:
1076
- a: The divisor
1077
- b: The dividend
1078
-
1079
- Returns:
1080
- expr: A new expression that evaluates to b / a (floating point)
1081
- """
1082
304
  return a.__class__(operator.__truediv__,table(b,a))
1083
305
  def __xor__(a, b):
1084
- """
1085
- Create a new expression representing bitwise XOR of a and b.
1086
-
1087
- Parameters:
1088
- a: The left operand for bitwise XOR
1089
- b: The right operand for bitwise XOR
1090
-
1091
- Returns:
1092
- expr: A new expression that evaluates to a ^ b
1093
- """
1094
306
  return a.__class__(operator.__xor__,table(a,b))
1095
307
  def __rxor__(a, b):
1096
- """
1097
- Create a new expression representing reverse bitwise XOR of b and a.
1098
-
1099
- Parameters:
1100
- a: The right operand for bitwise XOR
1101
- b: The left operand for bitwise XOR
1102
-
1103
- Returns:
1104
- expr: A new expression that evaluates to b ^ a
1105
- """
1106
308
  return a.__class__(operator.__xor__,table(b,a))
1107
-
1108
- # Root symbolic expression for creating symbolic references
1109
- sym = expr(None) # Symbolic expression root used for creating attribute-based symbol paths
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)
1110
323
 
1111
324
  class plus_minus:
1112
- """Plus and Minus operation handler for symbolic and numeric expressions.
1113
-
1114
- This class handles both unary and binary arithmetic operations (addition and subtraction)
1115
- for symbolic expressions and numeric values. It implements intelligent expression
1116
- simplification and proper handling of mixed symbolic and numeric operands.
1117
-
1118
- Key features:
1119
- - Handles unary operations (uplus, uminus) with single arguments
1120
- - Handles binary operations (plus, minus) with two arguments
1121
- - Supports mixed operand types (int, float, expr)
1122
- - Performs expression simplification by combining numeric terms
1123
- - Properly propagates unary minus through nested expressions
1124
- - Maintains symbolic structure for non-numeric operations
1125
-
1126
- The class is instantiated as four global instances:
1127
- - plus: Binary addition operator
1128
- - minus: Binary subtraction operator
1129
- - uplus: Unary plus operator (identity)
1130
- - uminus: Unary minus operator (negation)
1131
- """
1132
325
  def __init__(self,name):
1133
326
  self._name = name
1134
327
  def __repr__(self):
@@ -1190,25 +383,6 @@ class context_switch:
1190
383
  self.ctx <= self.top
1191
384
 
1192
385
  class context:
1193
- """
1194
- Context management class with stack-based scoping and attribute forwarding.
1195
-
1196
- The context class provides a stack-based scoping mechanism that allows
1197
- for pushing and popping context frames. It forwards attribute and item
1198
- access operations to the top of the stack, while maintaining a stack of
1199
- context objects for nested scoping.
1200
-
1201
- Key features:
1202
- - Stack-based context management with push/pop functionality
1203
- - Attribute and item forwarding to the top context frame
1204
- - Context switching support via operator overloading
1205
- - Automatic context creation and cleanup with __enter__/__exit__
1206
- - Customizable table type for context frames
1207
-
1208
- This class is particularly useful for creating nested scopes where
1209
- variables can be temporarily shadowed or modified, with automatic
1210
- restoration when exiting the scope.
1211
- """
1212
386
  def __init__(self,*args,**kwargs):
1213
387
  tbl = kwargs.pop('table',table)
1214
388
  object.__setattr__(self,'_tbl',tbl)
@@ -1245,24 +419,6 @@ class context:
1245
419
  self._stk.pop()
1246
420
 
1247
421
  class flow(table):
1248
- """
1249
- Flow control container with dynamic attribute and item access.
1250
-
1251
- The flow class extends the table container to provide a specialized
1252
- container for managing flow control structures. It features dynamic
1253
- attribute and item access with auto-vivification - creating new flow
1254
- instances on-demand when accessing non-existent keys.
1255
-
1256
- Key features:
1257
- - Auto-vivification: Creates new flow instances for non-existent keys
1258
- - Unified attribute and item access
1259
- - String-based key normalization
1260
- - Special handling for reserved attributes
1261
- - Compatibility with table operations
1262
-
1263
- This class is designed to facilitate the creation of tree-like structures
1264
- for flow control, where nodes can be dynamically created as needed.
1265
- """
1266
422
  def __getitem__(self, key):
1267
423
  if type(key) is slice:
1268
424
  return super().__getitem__(key)
@@ -1285,23 +441,6 @@ class flow(table):
1285
441
  flow = context(table=flow)
1286
442
 
1287
443
  class meta:
1288
- """
1289
- Metadata container for tracking hierarchical information and enabling function calls.
1290
-
1291
- The meta class provides a hierarchical container that stores metadata as a tuple
1292
- (__meta__) and supports dynamic attribute and item access. When accessing non-existent
1293
- keys, it creates new meta instances with extended metadata tuples.
1294
-
1295
- Key features:
1296
- - Hierarchical metadata storage as tuples
1297
- - Dynamic creation of child meta instances on attribute/item access
1298
- - Function call delegation to the first metadata element
1299
- - Unified attribute and item access patterns
1300
- - Special handling for None keys (returns self)
1301
-
1302
- This class is primarily used to create hierarchical function call patterns,
1303
- where metadata forms a path that can be traversed and eventually executed as a function call.
1304
- """
1305
444
  def __init__(self, *args):
1306
445
  self.__meta__ = args
1307
446
  def __getattr__(self, key):
@@ -1321,24 +460,6 @@ class meta:
1321
460
  return self.__meta__[0](*args,*self.__meta__[1:],**kwargs)
1322
461
 
1323
462
  class multi(meta):
1324
- """
1325
- Multi-target container for managing multiple instances or operations.
1326
-
1327
- The multi class extends meta to provide specialized functionality for managing
1328
- multiple targets or performing operations across multiple instances. It enhances
1329
- the meta class with multi-target function call behavior and special handling for
1330
- collections of nodes.
1331
-
1332
- Key features:
1333
- - Extended metadata tracking from meta class
1334
- - Multi-target function call delegation
1335
- - Special handling for node collections (lists, tuples, ranges)
1336
- - Support for single-target and multi-target modes
1337
- - Automatic conversion of range objects to lists
1338
-
1339
- This class is designed to facilitate operations that need to be applied to multiple
1340
- targets, providing a unified interface for both single and multiple target scenarios.
1341
- """
1342
463
  def __call__(self, *args, **kwargs):
1343
464
  if len(self.__meta__) == 1:
1344
465
  val = self.__class__()
@@ -1525,43 +646,6 @@ class SubPass(ast.NodeTransformer):
1525
646
  return node
1526
647
 
1527
648
  def domain(ctx={}, regq=None, sub=None, dump=False):
1528
- """Domain-specific language (DSL) decorator for custom assembly language constructs.
1529
-
1530
- This decorator enables the creation of domain-specific assembly languages by transforming
1531
- function source code through AST manipulation. It provides a framework for customizing
1532
- and extending assembly-like syntax for specific hardware or application domains.
1533
-
1534
- Args:
1535
- ctx (dict, optional): Context dictionary containing variables and symbols available
1536
- in the DSL environment. Defaults to empty dict.
1537
- regq (callable, optional): Register query function used to identify and process
1538
- register references in the DSL code. If provided, triggers the WithPass AST
1539
- transformation.
1540
- sub (bool/callable, optional): AST transformation option:
1541
- - True: Apply SubPass transformation with the provided context
1542
- - ast.NodeTransformer instance: Apply custom transformer class with context
1543
- - callable: Apply custom callable transformation directly to the AST
1544
- - None: No substitution transformation (default)
1545
- dump (bool, optional): If True and regq is provided, prints the unparsed transformed
1546
- AST for debugging purposes. Defaults to False.
1547
-
1548
- Returns:
1549
- callable: A decorator that transforms the decorated function's source code via AST
1550
- manipulation and returns a wrapper that executes the transformed code in the
1551
- augmented environment.
1552
-
1553
- Process flow:
1554
- 1. Extracts the source code of the decorated function
1555
- 2. Normalizes indentation to process the code correctly
1556
- 3. Parses the code into an Abstract Syntax Tree (AST)
1557
- 4. Removes existing decorators from the AST
1558
- 5. Applies specified AST transformations (substitution and/or register query)
1559
- 6. Compiles the transformed AST into executable code
1560
- 7. Creates a wrapped function that executes in the augmented environment
1561
-
1562
- This decorator is particularly useful for creating hardware-specific assembly languages,
1563
- instruction set simulators, and domain-specific compilation passes within the oasm framework.
1564
- """
1565
649
  def decorator(func):
1566
650
  src = inspect.getsourcelines(func)[0]
1567
651
  indent = len(src[0]) - len(src[0].lstrip())
@@ -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
@@ -0,0 +1,5 @@
1
+ oasm/__init__.py,sha256=2sDXVVF7QBc1VwR0TowymfmTZjb-W03CXL9bZYjAmdk,28069
2
+ oasm-0.1.7.dist-info/METADATA,sha256=DtRW39u4QnMR1gAwy6giIBjs3mQFp0JCdUlZpFCtszQ,370
3
+ oasm-0.1.7.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
4
+ oasm-0.1.7.dist-info/top_level.txt,sha256=EacQcwgujQK1Vg--A4w6awZ2LPUTDx7kHNRd9BsavOc,5
5
+ oasm-0.1.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,5 +0,0 @@
1
- oasm/__init__.py,sha256=7hI7IyEOnV3VoPq6ocWUXSiZ9PdoISLXp4NjGyHHYbk,66151
2
- oasm-0.1.5.dist-info/METADATA,sha256=FJSdJI3ECMter4fbaNsYhL46NRnfT3uvtNGNL-9R5pQ,370
3
- oasm-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
4
- oasm-0.1.5.dist-info/top_level.txt,sha256=EacQcwgujQK1Vg--A4w6awZ2LPUTDx7kHNRd9BsavOc,5
5
- oasm-0.1.5.dist-info/RECORD,,