IncludeCPP 3.3.20__py3-none-any.whl → 3.4.8__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.
- includecpp/__init__.py +59 -58
- includecpp/cli/commands.py +400 -21
- includecpp/core/cppy_converter.py +143 -18
- includecpp/core/cssl/__init__.py +40 -0
- includecpp/core/cssl/cssl_builtins.py +1693 -0
- includecpp/core/cssl/cssl_events.py +621 -0
- includecpp/core/cssl/cssl_modules.py +2803 -0
- includecpp/core/cssl/cssl_parser.py +1791 -0
- includecpp/core/cssl/cssl_runtime.py +1587 -0
- includecpp/core/cssl/cssl_syntax.py +488 -0
- includecpp/core/cssl/cssl_types.py +438 -0
- includecpp/core/cssl_bridge.py +409 -0
- includecpp/core/cssl_bridge.pyi +311 -0
- includecpp/core/project_ui.py +684 -34
- includecpp/generator/parser.cpp +81 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/METADATA +48 -4
- includecpp-3.4.8.dist-info/RECORD +41 -0
- includecpp-3.3.20.dist-info/RECORD +0 -31
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/WHEEL +0 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/entry_points.txt +0 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,438 @@
|
|
|
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
|
+
class Parameter:
|
|
350
|
+
"""Parameter accessor for CSSL exec() arguments.
|
|
351
|
+
|
|
352
|
+
Provides access to arguments passed to CSSL.exec() via parameter.get(index).
|
|
353
|
+
|
|
354
|
+
Usage in CSSL:
|
|
355
|
+
parameter.get(0) # Get first argument
|
|
356
|
+
parameter.get(1) # Get second argument
|
|
357
|
+
parameter.count() # Get total argument count
|
|
358
|
+
parameter.all() # Get all arguments as list
|
|
359
|
+
"""
|
|
360
|
+
|
|
361
|
+
def __init__(self, args: List[Any] = None):
|
|
362
|
+
self._args = args if args is not None else []
|
|
363
|
+
|
|
364
|
+
def get(self, index: int, default: Any = None) -> Any:
|
|
365
|
+
"""Get argument at index, returns default if not found"""
|
|
366
|
+
if 0 <= index < len(self._args):
|
|
367
|
+
return self._args[index]
|
|
368
|
+
return default
|
|
369
|
+
|
|
370
|
+
def count(self) -> int:
|
|
371
|
+
"""Return total number of arguments"""
|
|
372
|
+
return len(self._args)
|
|
373
|
+
|
|
374
|
+
def all(self) -> List[Any]:
|
|
375
|
+
"""Return all arguments as a list"""
|
|
376
|
+
return list(self._args)
|
|
377
|
+
|
|
378
|
+
def has(self, index: int) -> bool:
|
|
379
|
+
"""Check if argument exists at index"""
|
|
380
|
+
return 0 <= index < len(self._args)
|
|
381
|
+
|
|
382
|
+
def __iter__(self):
|
|
383
|
+
return iter(self._args)
|
|
384
|
+
|
|
385
|
+
def __len__(self):
|
|
386
|
+
return len(self._args)
|
|
387
|
+
|
|
388
|
+
def __getitem__(self, index: int) -> Any:
|
|
389
|
+
return self.get(index)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def OpenFind(combo_or_type: Union[Combo, type], index: int = 0) -> Optional[Any]:
|
|
393
|
+
"""Find open parameter by type or combo space.
|
|
394
|
+
|
|
395
|
+
Usage:
|
|
396
|
+
string name = OpenFind<string>(0); # Find string at index 0
|
|
397
|
+
string special = OpenFind(&@comboSpace); # Find by combo
|
|
398
|
+
"""
|
|
399
|
+
if isinstance(combo_or_type, Combo):
|
|
400
|
+
# Find by combo space
|
|
401
|
+
return combo_or_type.find_match([]) # Would need open params context
|
|
402
|
+
elif isinstance(combo_or_type, type):
|
|
403
|
+
# Find by type at index - needs open params context
|
|
404
|
+
pass
|
|
405
|
+
return None
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
# Type factory functions for CSSL
|
|
409
|
+
def create_datastruct(element_type: str = 'dynamic') -> DataStruct:
|
|
410
|
+
return DataStruct(element_type)
|
|
411
|
+
|
|
412
|
+
def create_shuffled(element_type: str = 'dynamic') -> Shuffled:
|
|
413
|
+
return Shuffled(element_type)
|
|
414
|
+
|
|
415
|
+
def create_iterator(element_type: str = 'int', size: int = 16) -> Iterator:
|
|
416
|
+
return Iterator(element_type, size)
|
|
417
|
+
|
|
418
|
+
def create_combo(element_type: str = 'dynamic') -> Combo:
|
|
419
|
+
return Combo(element_type)
|
|
420
|
+
|
|
421
|
+
def create_dataspace(space_type: str = 'dynamic') -> DataSpace:
|
|
422
|
+
return DataSpace(space_type)
|
|
423
|
+
|
|
424
|
+
def create_openquote(db_ref: Any = None) -> OpenQuote:
|
|
425
|
+
return OpenQuote(db_ref)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
__all__ = [
|
|
429
|
+
'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
|
|
430
|
+
'OpenFind', 'Parameter',
|
|
431
|
+
'create_datastruct', 'create_shuffled', 'create_iterator',
|
|
432
|
+
'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter'
|
|
433
|
+
]
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def create_parameter(args: List[Any] = None) -> Parameter:
|
|
437
|
+
"""Create a Parameter object for accessing exec arguments"""
|
|
438
|
+
return Parameter(args)
|