IncludeCPP 3.3.20__py3-none-any.whl → 3.4.2__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.
@@ -0,0 +1,390 @@
1
+ """
2
+ CSSL Data Types - Advanced container types for CSO Service Script Language
3
+
4
+ Types:
5
+ - datastruct<T>: Universal container (lazy declarator) - can hold any type
6
+ - shuffled<T>: Unorganized fast storage for multiple returns
7
+ - iterator<T>: Advanced iterator with programmable tasks
8
+ - combo<T>: Filter/search spaces for open parameter matching
9
+ - dataspace<T>: SQL/data storage container
10
+ - openquote<T>: SQL openquote container
11
+ """
12
+
13
+ from typing import Any, Dict, List, Optional, Callable, Union, TypeVar, Generic
14
+ from dataclasses import dataclass, field
15
+ import copy
16
+
17
+
18
+ T = TypeVar('T')
19
+
20
+
21
+ class DataStruct(list):
22
+ """Universal container - lazy declarator that can hold any type.
23
+
24
+ Like a vector but more flexible. Can hold strings, ints, floats,
25
+ objects, etc. at the cost of performance.
26
+
27
+ Usage:
28
+ datastruct<dynamic> myData;
29
+ myData +<== someValue;
30
+ myData.content() # Returns all elements
31
+ """
32
+
33
+ def __init__(self, element_type: str = 'dynamic'):
34
+ super().__init__()
35
+ self._element_type = element_type
36
+ self._metadata: Dict[str, Any] = {}
37
+
38
+ def content(self) -> list:
39
+ """Return all elements as a list"""
40
+ return list(self)
41
+
42
+ def add(self, item: Any) -> 'DataStruct':
43
+ """Add an item to the datastruct"""
44
+ self.append(item)
45
+ return self
46
+
47
+ def remove_where(self, predicate: Callable[[Any], bool]) -> 'DataStruct':
48
+ """Remove items matching predicate"""
49
+ to_remove = [item for item in self if predicate(item)]
50
+ for item in to_remove:
51
+ self.remove(item)
52
+ return self
53
+
54
+ def find_where(self, predicate: Callable[[Any], bool]) -> Optional[Any]:
55
+ """Find first item matching predicate"""
56
+ for item in self:
57
+ if predicate(item):
58
+ return item
59
+ return None
60
+
61
+ def convert(self, target_type: type) -> Any:
62
+ """Convert first element to target type"""
63
+ if len(self) > 0:
64
+ return target_type(self[0])
65
+ return None
66
+
67
+
68
+ class Shuffled(list):
69
+ """Unorganized fast storage for multiple returns.
70
+
71
+ Stores data unorganized for fast and efficient access.
72
+ Supports receiving multiple return values from functions.
73
+
74
+ Usage:
75
+ shuffled<string> results;
76
+ results +<== someFunc(); # Catches all returns
77
+ results.read() # Returns all content as list
78
+ """
79
+
80
+ def __init__(self, element_type: str = 'dynamic'):
81
+ super().__init__()
82
+ self._element_type = element_type
83
+
84
+ def read(self) -> list:
85
+ """Return all content as a list"""
86
+ return list(self)
87
+
88
+ def collect(self, func: Callable, *args) -> 'Shuffled':
89
+ """Collect all returns from a function"""
90
+ result = func(*args)
91
+ if isinstance(result, (list, tuple)):
92
+ self.extend(result)
93
+ else:
94
+ self.append(result)
95
+ return self
96
+
97
+
98
+ class Iterator:
99
+ """Advanced iterator with programmable tasks.
100
+
101
+ Provides iterator positions within a data container with
102
+ the ability to attach tasks (functions) to iterators.
103
+
104
+ Usage:
105
+ iterator<int, 16> Map; # Create 16-element iterator space
106
+ Map::iterator::set(0, 5); # Set iterator 0 to position 5
107
+ Map::iterator::task(0, myFunc); # Attach task to iterator
108
+ """
109
+
110
+ def __init__(self, element_type: str = 'int', size: int = 16):
111
+ self._element_type = element_type
112
+ self._size = size
113
+ self._data: List[Any] = [None] * size
114
+ self._iterators: Dict[int, int] = {0: 0, 1: 1} # Default: 2 iterators at positions 0 and 1
115
+ self._tasks: Dict[int, Callable] = {}
116
+
117
+ def insert(self, index: int, value: Any) -> 'Iterator':
118
+ """Insert value at index"""
119
+ if 0 <= index < self._size:
120
+ self._data[index] = value
121
+ return self
122
+
123
+ def fill(self, value: Any) -> 'Iterator':
124
+ """Fill all positions with value"""
125
+ self._data = [value] * self._size
126
+ return self
127
+
128
+ def at(self, index: int) -> Any:
129
+ """Get value at index"""
130
+ if 0 <= index < self._size:
131
+ return self._data[index]
132
+ return None
133
+
134
+ def is_all(self, check_value: bool) -> bool:
135
+ """Check if all values are 1 (True) or 0 (False)"""
136
+ expected = 1 if check_value else 0
137
+ return all(v == expected for v in self._data if v is not None)
138
+
139
+ def end(self) -> int:
140
+ """Return last index"""
141
+ return self._size - 1
142
+
143
+ class IteratorControl:
144
+ """Static methods for iterator control"""
145
+
146
+ @staticmethod
147
+ def set(iterator_obj: 'Iterator', iterator_id: int, position: int):
148
+ """Set iterator position"""
149
+ iterator_obj._iterators[iterator_id] = position
150
+
151
+ @staticmethod
152
+ def move(iterator_obj: 'Iterator', iterator_id: int, steps: int):
153
+ """Move iterator by steps"""
154
+ if iterator_id in iterator_obj._iterators:
155
+ iterator_obj._iterators[iterator_id] += steps
156
+
157
+ @staticmethod
158
+ def insert(iterator_obj: 'Iterator', iterator_id: int, value: Any):
159
+ """Insert value at current iterator position"""
160
+ if iterator_id in iterator_obj._iterators:
161
+ pos = iterator_obj._iterators[iterator_id]
162
+ if 0 <= pos < iterator_obj._size:
163
+ iterator_obj._data[pos] = value
164
+
165
+ @staticmethod
166
+ def pop(iterator_obj: 'Iterator', iterator_id: int):
167
+ """Delete value at current iterator position"""
168
+ if iterator_id in iterator_obj._iterators:
169
+ pos = iterator_obj._iterators[iterator_id]
170
+ if 0 <= pos < iterator_obj._size:
171
+ iterator_obj._data[pos] = None
172
+
173
+ @staticmethod
174
+ def task(iterator_obj: 'Iterator', iterator_id: int, func: Callable):
175
+ """Attach a task function to iterator"""
176
+ iterator_obj._tasks[iterator_id] = func
177
+
178
+ @staticmethod
179
+ def dtask(iterator_obj: 'Iterator', iterator_id: int):
180
+ """Clear task from iterator"""
181
+ if iterator_id in iterator_obj._tasks:
182
+ del iterator_obj._tasks[iterator_id]
183
+
184
+ @staticmethod
185
+ def run_task(iterator_obj: 'Iterator', iterator_id: int):
186
+ """Run the task at current iterator position"""
187
+ if iterator_id in iterator_obj._tasks and iterator_id in iterator_obj._iterators:
188
+ pos = iterator_obj._iterators[iterator_id]
189
+ task = iterator_obj._tasks[iterator_id]
190
+ # Create a position wrapper
191
+ class IteratorPos:
192
+ def __init__(self, data, idx):
193
+ self._data = data
194
+ self._idx = idx
195
+ def read(self):
196
+ return self._data[self._idx]
197
+ def write(self, value):
198
+ self._data[self._idx] = value
199
+
200
+ task(IteratorPos(iterator_obj._data, pos))
201
+
202
+
203
+ class Combo:
204
+ """Filter/search space for open parameter matching.
205
+
206
+ Creates a search/filter space that can match parameters
207
+ based on filter databases and similarity.
208
+
209
+ Usage:
210
+ combo<open&string> nameSpace;
211
+ nameSpace +<== [combo::filterdb] filterDB;
212
+ special_name = OpenFind(&nameSpace);
213
+ """
214
+
215
+ def __init__(self, element_type: str = 'dynamic'):
216
+ self._element_type = element_type
217
+ self._filterdb: List[Any] = []
218
+ self._blocked: List[Any] = []
219
+ self._data: List[Any] = []
220
+ self._like_pattern: Optional[str] = None
221
+
222
+ @property
223
+ def filterdb(self) -> List[Any]:
224
+ return self._filterdb
225
+
226
+ @filterdb.setter
227
+ def filterdb(self, value: List[Any]):
228
+ self._filterdb = value
229
+
230
+ @property
231
+ def blocked(self) -> List[Any]:
232
+ return self._blocked
233
+
234
+ @blocked.setter
235
+ def blocked(self, value: List[Any]):
236
+ self._blocked = value
237
+
238
+ def like(self, pattern: str) -> 'Combo':
239
+ """Set similarity pattern (94-100% match)"""
240
+ self._like_pattern = pattern
241
+ return self
242
+
243
+ def matches(self, value: Any) -> bool:
244
+ """Check if value matches combo criteria"""
245
+ # Check if blocked
246
+ if value in self._blocked:
247
+ return False
248
+
249
+ # Check filterdb if present
250
+ if self._filterdb:
251
+ if value not in self._filterdb:
252
+ return False
253
+
254
+ # Check like pattern if present
255
+ if self._like_pattern and isinstance(value, str):
256
+ similarity = self._calculate_similarity(value, self._like_pattern)
257
+ if similarity < 0.94:
258
+ return False
259
+
260
+ return True
261
+
262
+ def _calculate_similarity(self, s1: str, s2: str) -> float:
263
+ """Calculate string similarity (simple Levenshtein-based)"""
264
+ if s1 == s2:
265
+ return 1.0
266
+ if not s1 or not s2:
267
+ return 0.0
268
+
269
+ # Simple character-based similarity
270
+ s1_lower = s1.lower()
271
+ s2_lower = s2.lower()
272
+
273
+ matching = sum(c1 == c2 for c1, c2 in zip(s1_lower, s2_lower))
274
+ return matching / max(len(s1), len(s2))
275
+
276
+ def find_match(self, items: List[Any]) -> Optional[Any]:
277
+ """Find first matching item from list"""
278
+ for item in items:
279
+ if self.matches(item):
280
+ return item
281
+ return None
282
+
283
+
284
+ class DataSpace(dict):
285
+ """SQL/data storage container for structured data.
286
+
287
+ Used for SQL table definitions and structured data storage.
288
+
289
+ Usage:
290
+ dataspace<sql::table> table = { ... };
291
+ @Sql.Structured(&table);
292
+ """
293
+
294
+ def __init__(self, space_type: str = 'dynamic'):
295
+ super().__init__()
296
+ self._space_type = space_type
297
+ self._sections: Dict[str, Any] = {}
298
+
299
+ def content(self) -> dict:
300
+ """Return all content"""
301
+ return dict(self)
302
+
303
+ def section(self, name: str, *types) -> 'DataSpace':
304
+ """Create a section with specified types"""
305
+ self._sections[name] = {
306
+ 'types': types,
307
+ 'data': []
308
+ }
309
+ return self
310
+
311
+
312
+ class OpenQuote:
313
+ """SQL openquote container for organized data handling.
314
+
315
+ Creates a datastruct together with sql::db.oqt() for easy
316
+ data organization and retrieval.
317
+
318
+ Usage:
319
+ openquote<datastruct<dynamic>&@sql::db.oqt(@db)> Queue;
320
+ Queue.save("Section", "data1", "data2", 123);
321
+ Queue.where(Section="value", KEY="match");
322
+ """
323
+
324
+ def __init__(self, db_reference: Any = None):
325
+ self._data: List[Dict[str, Any]] = []
326
+ self._db_ref = db_reference
327
+
328
+ def save(self, section: str, *values) -> 'OpenQuote':
329
+ """Save data to a section"""
330
+ self._data.append({
331
+ 'section': section,
332
+ 'values': list(values)
333
+ })
334
+ return self
335
+
336
+ def where(self, **kwargs) -> Optional[Any]:
337
+ """Find data matching criteria"""
338
+ for entry in self._data:
339
+ if all(entry.get(k) == v or (k == 'Section' and entry.get('section') == v)
340
+ for k, v in kwargs.items()):
341
+ return entry
342
+ return None
343
+
344
+ def all(self) -> List[Dict[str, Any]]:
345
+ """Return all data"""
346
+ return self._data
347
+
348
+
349
+ def OpenFind(combo_or_type: Union[Combo, type], index: int = 0) -> Optional[Any]:
350
+ """Find open parameter by type or combo space.
351
+
352
+ Usage:
353
+ string name = OpenFind<string>(0); # Find string at index 0
354
+ string special = OpenFind(&@comboSpace); # Find by combo
355
+ """
356
+ if isinstance(combo_or_type, Combo):
357
+ # Find by combo space
358
+ return combo_or_type.find_match([]) # Would need open params context
359
+ elif isinstance(combo_or_type, type):
360
+ # Find by type at index - needs open params context
361
+ pass
362
+ return None
363
+
364
+
365
+ # Type factory functions for CSSL
366
+ def create_datastruct(element_type: str = 'dynamic') -> DataStruct:
367
+ return DataStruct(element_type)
368
+
369
+ def create_shuffled(element_type: str = 'dynamic') -> Shuffled:
370
+ return Shuffled(element_type)
371
+
372
+ def create_iterator(element_type: str = 'int', size: int = 16) -> Iterator:
373
+ return Iterator(element_type, size)
374
+
375
+ def create_combo(element_type: str = 'dynamic') -> Combo:
376
+ return Combo(element_type)
377
+
378
+ def create_dataspace(space_type: str = 'dynamic') -> DataSpace:
379
+ return DataSpace(space_type)
380
+
381
+ def create_openquote(db_ref: Any = None) -> OpenQuote:
382
+ return OpenQuote(db_ref)
383
+
384
+
385
+ __all__ = [
386
+ 'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
387
+ 'OpenFind',
388
+ 'create_datastruct', 'create_shuffled', 'create_iterator',
389
+ 'create_combo', 'create_dataspace', 'create_openquote'
390
+ ]
@@ -0,0 +1,132 @@
1
+ """
2
+ CSSL Bridge - Python API for CSSL Language
3
+ Provides CsslLang class for executing CSSL code from Python.
4
+ """
5
+
6
+ import threading
7
+ from pathlib import Path
8
+ from typing import Any, List, Optional, Callable
9
+
10
+
11
+ class CsslLang:
12
+ """
13
+ CSSL Language interface for Python.
14
+
15
+ Usage:
16
+ from includecpp import CSSL
17
+ cssl = CSSL.CsslLang()
18
+ result = cssl.exec("script.cssl", arg1, arg2)
19
+ cssl.T_exec("async_script.cssl", arg1) # Threaded
20
+ """
21
+
22
+ def __init__(self, output_callback: Optional[Callable[[str, str], None]] = None):
23
+ """
24
+ Initialize CSSL runtime.
25
+
26
+ Args:
27
+ output_callback: Optional callback for output (text, level)
28
+ """
29
+ self._output_callback = output_callback
30
+ self._runtime = None
31
+ self._threads: List[threading.Thread] = []
32
+
33
+ def _get_runtime(self):
34
+ """Lazy load CSSL runtime."""
35
+ if self._runtime is None:
36
+ from .cssl import CSSLRuntime
37
+ self._runtime = CSSLRuntime(output_callback=self._output_callback)
38
+ return self._runtime
39
+
40
+ def exec(self, path_or_code: str, *args) -> Any:
41
+ """
42
+ Execute CSSL code or file.
43
+
44
+ Args:
45
+ path_or_code: Path to .cssl file or CSSL code string
46
+ *args: Arguments to pass to the script
47
+
48
+ Returns:
49
+ Execution result
50
+ """
51
+ runtime = self._get_runtime()
52
+
53
+ # Check if it's a file path
54
+ path = Path(path_or_code)
55
+ if path.exists() and path.suffix in ('.cssl', '.cssl-mod'):
56
+ source = path.read_text(encoding='utf-8')
57
+ else:
58
+ source = path_or_code
59
+
60
+ # Set arguments in runtime scope
61
+ runtime.global_scope.set('args', list(args))
62
+ runtime.global_scope.set('argc', len(args))
63
+
64
+ # Execute as standalone program
65
+ try:
66
+ result = runtime.execute_program(source)
67
+ return result
68
+ except Exception as e:
69
+ raise RuntimeError(f"CSSL Error: {e}") from e
70
+
71
+ def T_exec(self, path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
72
+ """
73
+ Execute CSSL code asynchronously in a thread.
74
+
75
+ Args:
76
+ path_or_code: Path to .cssl file or CSSL code string
77
+ *args: Arguments to pass to the script
78
+ callback: Optional callback when execution completes
79
+
80
+ Returns:
81
+ Thread object
82
+ """
83
+ def _run():
84
+ try:
85
+ result = self.exec(path_or_code, *args)
86
+ if callback:
87
+ callback(result)
88
+ except Exception as e:
89
+ if callback:
90
+ callback(e)
91
+
92
+ thread = threading.Thread(target=_run, daemon=True)
93
+ thread.start()
94
+ self._threads.append(thread)
95
+ return thread
96
+
97
+ def wait_all(self, timeout: Optional[float] = None):
98
+ """Wait for all async executions to complete."""
99
+ for thread in self._threads:
100
+ thread.join(timeout=timeout)
101
+ self._threads.clear()
102
+
103
+ def get_output(self) -> List[str]:
104
+ """Get output buffer from last execution."""
105
+ runtime = self._get_runtime()
106
+ return list(runtime.output_buffer)
107
+
108
+ def clear_output(self):
109
+ """Clear output buffer."""
110
+ runtime = self._get_runtime()
111
+ runtime.output_buffer.clear()
112
+
113
+ def set_global(self, name: str, value: Any):
114
+ """Set a global variable in CSSL runtime."""
115
+ runtime = self._get_runtime()
116
+ runtime.global_scope.set(name, value)
117
+
118
+ def get_global(self, name: str) -> Any:
119
+ """Get a global variable from CSSL runtime."""
120
+ runtime = self._get_runtime()
121
+ return runtime.global_scope.get(name)
122
+
123
+
124
+ # Singleton for convenience
125
+ _default_instance: Optional[CsslLang] = None
126
+
127
+ def get_cssl() -> CsslLang:
128
+ """Get default CSSL instance."""
129
+ global _default_instance
130
+ if _default_instance is None:
131
+ _default_instance = CsslLang()
132
+ return _default_instance