IncludeCPP 3.4.10__py3-none-any.whl → 3.4.21__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 +1 -1
- includecpp/__init__.pyi +131 -3
- includecpp/cli/commands.py +124 -0
- includecpp/core/cssl/CSSL_DOCUMENTATION.md +1482 -0
- includecpp/core/cssl/__init__.py +6 -6
- includecpp/core/cssl/cssl_builtins.py +243 -5
- includecpp/core/cssl/cssl_parser.py +298 -10
- includecpp/core/cssl/cssl_runtime.py +704 -53
- includecpp/core/cssl/cssl_types.py +403 -2
- includecpp/core/cssl_bridge.py +363 -0
- includecpp/generator/parser.cpp +1 -1
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/METADATA +270 -3
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/RECORD +17 -16
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/WHEEL +0 -0
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/entry_points.txt +0 -0
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/top_level.txt +0 -0
includecpp/core/cssl/__init__.py
CHANGED
|
@@ -14,29 +14,29 @@ Features:
|
|
|
14
14
|
from .cssl_parser import (
|
|
15
15
|
parse_cssl, parse_cssl_program, tokenize_cssl,
|
|
16
16
|
CSSLSyntaxError, CSSLLexer, CSSLParser, ASTNode,
|
|
17
|
-
KEYWORDS, TYPE_GENERICS, INJECTION_HELPERS
|
|
17
|
+
KEYWORDS, TYPE_GENERICS, TYPE_PARAM_FUNCTIONS, INJECTION_HELPERS
|
|
18
18
|
)
|
|
19
19
|
from .cssl_runtime import CSSLRuntime, CSSLRuntimeError, CSSLServiceRunner, run_cssl, run_cssl_file
|
|
20
20
|
from .cssl_types import (
|
|
21
21
|
DataStruct, Shuffled, Iterator, Combo, DataSpace, OpenQuote,
|
|
22
|
-
OpenFind, Parameter, Stack, Vector,
|
|
22
|
+
OpenFind, Parameter, Stack, Vector, Array,
|
|
23
23
|
create_datastruct, create_shuffled, create_iterator,
|
|
24
24
|
create_combo, create_dataspace, create_openquote, create_parameter,
|
|
25
|
-
create_stack, create_vector
|
|
25
|
+
create_stack, create_vector, create_array
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
__all__ = [
|
|
29
29
|
# Parser
|
|
30
30
|
'parse_cssl', 'parse_cssl_program', 'tokenize_cssl',
|
|
31
31
|
'CSSLSyntaxError', 'CSSLLexer', 'CSSLParser', 'ASTNode',
|
|
32
|
-
'KEYWORDS', 'TYPE_GENERICS', 'INJECTION_HELPERS',
|
|
32
|
+
'KEYWORDS', 'TYPE_GENERICS', 'TYPE_PARAM_FUNCTIONS', 'INJECTION_HELPERS',
|
|
33
33
|
# Runtime
|
|
34
34
|
'CSSLRuntime', 'CSSLRuntimeError', 'CSSLServiceRunner',
|
|
35
35
|
'run_cssl', 'run_cssl_file',
|
|
36
36
|
# Data Types
|
|
37
37
|
'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
|
|
38
|
-
'OpenFind', 'Parameter', 'Stack', 'Vector',
|
|
38
|
+
'OpenFind', 'Parameter', 'Stack', 'Vector', 'Array',
|
|
39
39
|
'create_datastruct', 'create_shuffled', 'create_iterator',
|
|
40
40
|
'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter',
|
|
41
|
-
'create_stack', 'create_vector'
|
|
41
|
+
'create_stack', 'create_vector', 'create_array'
|
|
42
42
|
]
|
|
@@ -255,6 +255,7 @@ class CSSLBuiltins:
|
|
|
255
255
|
# CSSL Import System Functions
|
|
256
256
|
self._functions['cso_root'] = self.builtin_cso_root
|
|
257
257
|
self._functions['include'] = self.builtin_include
|
|
258
|
+
self._functions['payload'] = self.builtin_payload
|
|
258
259
|
self._functions['get'] = self.builtin_get
|
|
259
260
|
|
|
260
261
|
# NEW: Extended OS Functions
|
|
@@ -283,6 +284,9 @@ class CSSLBuiltins:
|
|
|
283
284
|
# Print aliases for CSSL
|
|
284
285
|
self._functions['printl'] = self.builtin_println # CSSL uses printl for println
|
|
285
286
|
|
|
287
|
+
# Shared object functions
|
|
288
|
+
self._functions['delete'] = self.builtin_delete # Delete shared object ($Name)
|
|
289
|
+
|
|
286
290
|
def get_function(self, name: str) -> Optional[Callable]:
|
|
287
291
|
"""Get a built-in function by name"""
|
|
288
292
|
return self._functions.get(name)
|
|
@@ -1403,16 +1407,29 @@ class CSSLBuiltins:
|
|
|
1403
1407
|
|
|
1404
1408
|
def builtin_include(self, filepath: str) -> Any:
|
|
1405
1409
|
"""
|
|
1406
|
-
Load and execute a CSSL file, returning its ServiceDefinition
|
|
1410
|
+
Load and execute a CSSL file or .cssl-mod module, returning its ServiceDefinition
|
|
1407
1411
|
Usage: include(cso_root('/services/utils.cssl'))
|
|
1412
|
+
include('modules/math_utils.cssl-mod')
|
|
1413
|
+
include('C:/absolute/path/module.cssl-mod')
|
|
1408
1414
|
Returns: ServiceDefinition with structs, functions, etc.
|
|
1409
1415
|
"""
|
|
1410
1416
|
if not self.runtime:
|
|
1411
1417
|
raise CSSLBuiltinError("include requires runtime context")
|
|
1412
1418
|
|
|
1413
|
-
#
|
|
1414
|
-
|
|
1415
|
-
|
|
1419
|
+
# Normalize path separators (support both / and \)
|
|
1420
|
+
filepath = filepath.replace('\\', '/')
|
|
1421
|
+
|
|
1422
|
+
# Handle absolute paths (Windows: C:/, D:/, etc. and Unix: /)
|
|
1423
|
+
is_absolute = os.path.isabs(filepath) or (len(filepath) > 2 and filepath[1] == ':')
|
|
1424
|
+
|
|
1425
|
+
if not is_absolute:
|
|
1426
|
+
# Try relative to current working directory first
|
|
1427
|
+
cwd_path = os.path.join(os.getcwd(), filepath)
|
|
1428
|
+
if os.path.exists(cwd_path):
|
|
1429
|
+
filepath = cwd_path
|
|
1430
|
+
else:
|
|
1431
|
+
# Fall back to cso_root for CSO service context
|
|
1432
|
+
filepath = self.builtin_cso_root(filepath)
|
|
1416
1433
|
|
|
1417
1434
|
# Check file exists
|
|
1418
1435
|
if not os.path.exists(filepath):
|
|
@@ -1426,10 +1443,17 @@ class CSSLBuiltins:
|
|
|
1426
1443
|
return self.runtime._include_cache[filepath]
|
|
1427
1444
|
|
|
1428
1445
|
try:
|
|
1429
|
-
# Read
|
|
1446
|
+
# Read the file
|
|
1430
1447
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
1431
1448
|
source = f.read()
|
|
1432
1449
|
|
|
1450
|
+
# Check if this is a .cssl-mod file
|
|
1451
|
+
if filepath.endswith('.cssl-mod') or source.startswith('CSSLMOD1'):
|
|
1452
|
+
result = self._load_cssl_module(filepath, source)
|
|
1453
|
+
self.runtime._include_cache[filepath] = result
|
|
1454
|
+
return result
|
|
1455
|
+
|
|
1456
|
+
# Regular CSSL file
|
|
1433
1457
|
from .cssl_parser import parse_cssl
|
|
1434
1458
|
|
|
1435
1459
|
ast = parse_cssl(source)
|
|
@@ -1445,6 +1469,195 @@ class CSSLBuiltins:
|
|
|
1445
1469
|
except Exception as e:
|
|
1446
1470
|
raise CSSLBuiltinError(f"Failed to include '{filepath}': {e}")
|
|
1447
1471
|
|
|
1472
|
+
def _load_cssl_module(self, filepath: str, source: str) -> Any:
|
|
1473
|
+
"""
|
|
1474
|
+
Load a .cssl-mod module file and return a callable module object.
|
|
1475
|
+
Handles Python and C++ modules.
|
|
1476
|
+
"""
|
|
1477
|
+
import base64
|
|
1478
|
+
import pickle
|
|
1479
|
+
|
|
1480
|
+
# Parse the module format: CSSLMOD1\n<base64-encoded-pickle>
|
|
1481
|
+
lines = source.strip().split('\n', 1)
|
|
1482
|
+
if len(lines) < 2 or lines[0] != 'CSSLMOD1':
|
|
1483
|
+
raise CSSLBuiltinError(f"Invalid .cssl-mod format: {filepath}")
|
|
1484
|
+
|
|
1485
|
+
# Decode the module data
|
|
1486
|
+
try:
|
|
1487
|
+
encoded_data = lines[1].strip()
|
|
1488
|
+
module_data = pickle.loads(base64.b64decode(encoded_data))
|
|
1489
|
+
except Exception as e:
|
|
1490
|
+
raise CSSLBuiltinError(f"Failed to decode .cssl-mod: {e}")
|
|
1491
|
+
|
|
1492
|
+
module_name = module_data.get('name', 'unknown')
|
|
1493
|
+
module_type = module_data.get('type', 'python')
|
|
1494
|
+
module_source = module_data.get('source', '')
|
|
1495
|
+
|
|
1496
|
+
if module_type == 'python':
|
|
1497
|
+
return self._execute_python_module(module_name, module_source, filepath)
|
|
1498
|
+
elif module_type == 'cpp':
|
|
1499
|
+
return self._load_cpp_module(module_name, module_source, filepath)
|
|
1500
|
+
else:
|
|
1501
|
+
raise CSSLBuiltinError(f"Unsupported module type: {module_type}")
|
|
1502
|
+
|
|
1503
|
+
def _execute_python_module(self, name: str, source: str, filepath: str) -> Any:
|
|
1504
|
+
"""
|
|
1505
|
+
Execute Python source and return a module-like object with all functions.
|
|
1506
|
+
"""
|
|
1507
|
+
# Create a namespace for the module
|
|
1508
|
+
module_namespace = {
|
|
1509
|
+
'__name__': name,
|
|
1510
|
+
'__file__': filepath,
|
|
1511
|
+
'__builtins__': __builtins__,
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
# Execute the Python source
|
|
1515
|
+
try:
|
|
1516
|
+
exec(source, module_namespace)
|
|
1517
|
+
except Exception as e:
|
|
1518
|
+
raise CSSLBuiltinError(f"Failed to execute Python module '{name}': {e}")
|
|
1519
|
+
|
|
1520
|
+
# Create a callable module wrapper
|
|
1521
|
+
class CSSLModuleWrapper:
|
|
1522
|
+
"""Wrapper that makes Python functions callable from CSSL"""
|
|
1523
|
+
def __init__(self, namespace, mod_name):
|
|
1524
|
+
self._namespace = namespace
|
|
1525
|
+
self._name = mod_name
|
|
1526
|
+
self._functions = {}
|
|
1527
|
+
|
|
1528
|
+
# Extract all callable functions (not dunder methods)
|
|
1529
|
+
for key, value in namespace.items():
|
|
1530
|
+
if callable(value) and not key.startswith('_'):
|
|
1531
|
+
self._functions[key] = value
|
|
1532
|
+
# Also set as attribute for @Module.func() syntax
|
|
1533
|
+
setattr(self, key, value)
|
|
1534
|
+
|
|
1535
|
+
def __getattr__(self, name):
|
|
1536
|
+
if name.startswith('_'):
|
|
1537
|
+
raise AttributeError(f"'{self._name}' has no attribute '{name}'")
|
|
1538
|
+
if name in self._functions:
|
|
1539
|
+
return self._functions[name]
|
|
1540
|
+
if name in self._namespace:
|
|
1541
|
+
return self._namespace[name]
|
|
1542
|
+
raise AttributeError(f"Module '{self._name}' has no function '{name}'")
|
|
1543
|
+
|
|
1544
|
+
def __repr__(self):
|
|
1545
|
+
funcs = list(self._functions.keys())
|
|
1546
|
+
return f"<CSSLModule '{self._name}' functions={funcs}>"
|
|
1547
|
+
|
|
1548
|
+
def __dir__(self):
|
|
1549
|
+
return list(self._functions.keys())
|
|
1550
|
+
|
|
1551
|
+
return CSSLModuleWrapper(module_namespace, name)
|
|
1552
|
+
|
|
1553
|
+
def _load_cpp_module(self, name: str, source: str, filepath: str) -> Any:
|
|
1554
|
+
"""
|
|
1555
|
+
Load a C++ module (stub for future implementation).
|
|
1556
|
+
For now, returns a placeholder with the source available.
|
|
1557
|
+
"""
|
|
1558
|
+
class CppModuleStub:
|
|
1559
|
+
def __init__(self, mod_name, cpp_source):
|
|
1560
|
+
self._name = mod_name
|
|
1561
|
+
self._source = cpp_source
|
|
1562
|
+
|
|
1563
|
+
def __repr__(self):
|
|
1564
|
+
return f"<CppModule '{self._name}' (not compiled)>"
|
|
1565
|
+
|
|
1566
|
+
def compile(self):
|
|
1567
|
+
"""Future: Compile and load the C++ module"""
|
|
1568
|
+
raise NotImplementedError("C++ module compilation not yet implemented")
|
|
1569
|
+
|
|
1570
|
+
return CppModuleStub(name, source)
|
|
1571
|
+
|
|
1572
|
+
def builtin_payload(self, filepath: str) -> None:
|
|
1573
|
+
"""
|
|
1574
|
+
Load a CSSL payload file (.cssl-pl) and execute it in the current scope.
|
|
1575
|
+
|
|
1576
|
+
Payloads are like header files but for CSSL:
|
|
1577
|
+
- Define global variables (accessible via @name)
|
|
1578
|
+
- Define helper functions (globally callable)
|
|
1579
|
+
- Inject code into builtins (like exit() <<== {...})
|
|
1580
|
+
- Set configuration values
|
|
1581
|
+
|
|
1582
|
+
Usage in .cssl file:
|
|
1583
|
+
payload("myconfig.cssl-pl");
|
|
1584
|
+
// Now all globals, functions, and injections are active
|
|
1585
|
+
|
|
1586
|
+
Usage in Python:
|
|
1587
|
+
cssl = CSSL.CsslLang()
|
|
1588
|
+
cssl.code("myhelper", "... cssl code ...") # Creates inline payload
|
|
1589
|
+
cssl.exec('payload("myhelper");') # Loads the inline payload
|
|
1590
|
+
|
|
1591
|
+
.cssl-pl file format:
|
|
1592
|
+
// Variables
|
|
1593
|
+
global version = "1.0.0";
|
|
1594
|
+
global debug = true;
|
|
1595
|
+
|
|
1596
|
+
// Injections
|
|
1597
|
+
exit() <<== {
|
|
1598
|
+
printl("Cleanup...");
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
// Helper functions
|
|
1602
|
+
void log(string msg) {
|
|
1603
|
+
if (@debug) printl("[LOG] " + msg);
|
|
1604
|
+
}
|
|
1605
|
+
"""
|
|
1606
|
+
if not self.runtime:
|
|
1607
|
+
raise CSSLBuiltinError("payload requires runtime context")
|
|
1608
|
+
|
|
1609
|
+
# Normalize path separators
|
|
1610
|
+
filepath = filepath.replace('\\', '/')
|
|
1611
|
+
|
|
1612
|
+
# Check if this is an inline payload (registered via cssl.code())
|
|
1613
|
+
if hasattr(self.runtime, '_inline_payloads') and filepath in self.runtime._inline_payloads:
|
|
1614
|
+
source = self.runtime._inline_payloads[filepath]
|
|
1615
|
+
else:
|
|
1616
|
+
# Handle absolute paths
|
|
1617
|
+
is_absolute = os.path.isabs(filepath) or (len(filepath) > 2 and filepath[1] == ':')
|
|
1618
|
+
|
|
1619
|
+
if not is_absolute:
|
|
1620
|
+
# Try relative to current working directory first
|
|
1621
|
+
cwd_path = os.path.join(os.getcwd(), filepath)
|
|
1622
|
+
if os.path.exists(cwd_path):
|
|
1623
|
+
filepath = cwd_path
|
|
1624
|
+
else:
|
|
1625
|
+
# Fall back to cso_root for CSO service context
|
|
1626
|
+
filepath = self.builtin_cso_root(filepath)
|
|
1627
|
+
|
|
1628
|
+
# Check file exists
|
|
1629
|
+
if not os.path.exists(filepath):
|
|
1630
|
+
raise CSSLBuiltinError(f"Payload file not found: {filepath}")
|
|
1631
|
+
|
|
1632
|
+
# Check payload cache to prevent double loading
|
|
1633
|
+
if not hasattr(self.runtime, '_payload_cache'):
|
|
1634
|
+
self.runtime._payload_cache = set()
|
|
1635
|
+
|
|
1636
|
+
if filepath in self.runtime._payload_cache:
|
|
1637
|
+
return # Already loaded
|
|
1638
|
+
|
|
1639
|
+
# Read the payload file
|
|
1640
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
1641
|
+
source = f.read()
|
|
1642
|
+
|
|
1643
|
+
self.runtime._payload_cache.add(filepath)
|
|
1644
|
+
|
|
1645
|
+
# Parse and execute the payload in current scope
|
|
1646
|
+
# This makes all globals, functions, and injections available
|
|
1647
|
+
try:
|
|
1648
|
+
from .cssl_parser import parse_cssl_program
|
|
1649
|
+
|
|
1650
|
+
ast = parse_cssl_program(source)
|
|
1651
|
+
|
|
1652
|
+
# Execute the payload - this will:
|
|
1653
|
+
# - Register global variables (accessible via @name)
|
|
1654
|
+
# - Define functions in current scope
|
|
1655
|
+
# - Set up any code injections
|
|
1656
|
+
self.runtime._execute_node(ast)
|
|
1657
|
+
|
|
1658
|
+
except Exception as e:
|
|
1659
|
+
raise CSSLBuiltinError(f"Failed to load payload '{filepath}': {e}")
|
|
1660
|
+
|
|
1448
1661
|
def builtin_get(self, source: Any, key: str = None) -> Any:
|
|
1449
1662
|
"""
|
|
1450
1663
|
Get value from module, ServiceDefinition, or dict
|
|
@@ -1614,6 +1827,31 @@ class CSSLBuiltins:
|
|
|
1614
1827
|
# This is handled by the runtime which passes the path
|
|
1615
1828
|
pass
|
|
1616
1829
|
|
|
1830
|
+
def builtin_delete(self, name: str) -> bool:
|
|
1831
|
+
"""
|
|
1832
|
+
Delete a shared object by name.
|
|
1833
|
+
Usage: delete("MyLib") - removes the $MyLib shared object
|
|
1834
|
+
|
|
1835
|
+
Args:
|
|
1836
|
+
name: Name of the shared object (without the $ prefix)
|
|
1837
|
+
|
|
1838
|
+
Returns:
|
|
1839
|
+
True if deleted, False if not found
|
|
1840
|
+
"""
|
|
1841
|
+
from ..cssl_bridge import _live_objects
|
|
1842
|
+
|
|
1843
|
+
# Remove from live objects registry
|
|
1844
|
+
if name in _live_objects:
|
|
1845
|
+
del _live_objects[name]
|
|
1846
|
+
# Also remove from runtime's global scope if present
|
|
1847
|
+
if self.runtime:
|
|
1848
|
+
try:
|
|
1849
|
+
self.runtime.global_scope.delete(f'${name}')
|
|
1850
|
+
except Exception:
|
|
1851
|
+
pass
|
|
1852
|
+
return True
|
|
1853
|
+
return False
|
|
1854
|
+
|
|
1617
1855
|
# ============= CSSL Data Type Constructors =============
|
|
1618
1856
|
|
|
1619
1857
|
def builtin_datastruct(self, element_type: str = 'dynamic') -> Any:
|