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.
@@ -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
- # Resolve relative paths
1414
- if not os.path.isabs(filepath):
1415
- filepath = self.builtin_cso_root(filepath)
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 and parse the file
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: