IncludeCPP 3.7.1__py3-none-any.whl → 3.7.25__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.
@@ -1,14 +1,24 @@
1
1
  """
2
2
  CSSL Bridge - Python API for CSSL Language
3
3
  Provides CsslLang class for executing CSSL code from Python.
4
+
5
+ v3.8.0 API:
6
+ cssl.run(code, *args) - Execute CSSL code
7
+ cssl.script("cssl", code) - Create typed script
8
+ cssl.makemodule(script, pl) - Bundle main script + payload
9
+ cssl.load(path, name) - Load .cssl/.cssl-pl file
10
+ cssl.execute(name) - Execute loaded script
11
+ cssl.include(path, name) - Register for payload(name)
4
12
  """
5
13
 
14
+ import atexit
6
15
  import os
7
16
  import pickle
8
17
  import random
9
18
  import threading
19
+ import warnings
10
20
  from pathlib import Path
11
- from typing import Any, List, Optional, Callable, Dict
21
+ from typing import Any, List, Optional, Callable, Dict, Union, Tuple
12
22
 
13
23
 
14
24
  def _get_share_directory() -> Path:
@@ -24,6 +34,23 @@ def _get_share_directory() -> Path:
24
34
  return share_dir
25
35
 
26
36
 
37
+ def _cleanup_shared_objects() -> None:
38
+ """Clean up all shared object marker files on process exit."""
39
+ try:
40
+ share_dir = _get_share_directory()
41
+ if share_dir.exists():
42
+ for f in share_dir.glob('*.shareobj*'):
43
+ try:
44
+ f.unlink()
45
+ except Exception:
46
+ pass
47
+ except Exception:
48
+ pass
49
+
50
+ # Register cleanup on process exit
51
+ atexit.register(_cleanup_shared_objects)
52
+
53
+
27
54
  # Global live object registry - holds actual object references for live sharing
28
55
  _live_objects: Dict[str, Any] = {}
29
56
 
@@ -142,6 +169,79 @@ class CSSLModule:
142
169
  return f"<CSSLModule code_len={len(self._code)}>"
143
170
 
144
171
 
172
+ class CSSLScript:
173
+ """
174
+ A typed CSSL script object.
175
+
176
+ Created via cssl.script("cssl", code) or cssl.script("cssl-pl", code).
177
+ Can be executed directly or bundled into a module.
178
+
179
+ Usage:
180
+ main = cssl.script("cssl", '''
181
+ printl("Main script");
182
+ myFunc();
183
+ ''')
184
+
185
+ payload = cssl.script("cssl-pl", '''
186
+ void myFunc() {
187
+ printl("From payload!");
188
+ }
189
+ ''')
190
+
191
+ # Execute directly
192
+ main.run()
193
+
194
+ # Or bundle into module
195
+ mod = cssl.makemodule(main, payload, "mymod")
196
+ """
197
+
198
+ def __init__(self, cssl_instance: 'CsslLang', script_type: str, code: str, params: Tuple = ()):
199
+ """
200
+ Initialize a CSSL script.
201
+
202
+ Args:
203
+ cssl_instance: The parent CsslLang instance
204
+ script_type: "cssl" for main script, "cssl-pl" for payload
205
+ code: The CSSL code
206
+ params: Optional parameters accessible via parameter.get(index)
207
+ """
208
+ if script_type not in ('cssl', 'cssl-pl'):
209
+ raise ValueError(f"Invalid script type '{script_type}'. Must be 'cssl' or 'cssl-pl'")
210
+
211
+ self._cssl = cssl_instance
212
+ self._type = script_type
213
+ self._code = code
214
+ self._params = params
215
+ self._name: Optional[str] = None
216
+
217
+ @property
218
+ def type(self) -> str:
219
+ """Get script type ('cssl' or 'cssl-pl')."""
220
+ return self._type
221
+
222
+ @property
223
+ def code(self) -> str:
224
+ """Get the script code."""
225
+ return self._code
226
+
227
+ @property
228
+ def is_payload(self) -> bool:
229
+ """Check if this is a payload script."""
230
+ return self._type == 'cssl-pl'
231
+
232
+ def run(self, *args) -> Any:
233
+ """Execute this script with optional arguments."""
234
+ all_args = self._params + args
235
+ return self._cssl.run(self._code, *all_args)
236
+
237
+ def __call__(self, *args) -> Any:
238
+ """Allow calling the script directly."""
239
+ return self.run(*args)
240
+
241
+ def __repr__(self) -> str:
242
+ return f"<CSSLScript type='{self._type}' code_len={len(self._code)}>"
243
+
244
+
145
245
  class CSSLFunctionModule:
146
246
  """
147
247
  A CSSL module with accessible functions as methods.
@@ -150,9 +250,11 @@ class CSSLFunctionModule:
150
250
  become callable attributes on this module.
151
251
  """
152
252
 
153
- def __init__(self, cssl_instance: 'CsslLang', code: str):
253
+ def __init__(self, cssl_instance: 'CsslLang', code: str, payload_code: str = None, name: str = None):
154
254
  self._cssl = cssl_instance
155
255
  self._code = code
256
+ self._payload_code = payload_code
257
+ self._name = name
156
258
  self._runtime = None
157
259
  self._functions: Dict[str, Any] = {}
158
260
  self._initialized = False
@@ -167,7 +269,22 @@ class CSSLFunctionModule:
167
269
  # Create a dedicated runtime for this module
168
270
  self._runtime = CSSLRuntime()
169
271
 
170
- # Parse the code
272
+ # If we have a payload, load it first (defines functions/globals for main)
273
+ if self._payload_code:
274
+ payload_ast = parse_cssl_program(self._payload_code)
275
+ for child in payload_ast.children:
276
+ if child.type == 'function':
277
+ func_info = child.value
278
+ func_name = func_info.get('name')
279
+ self._functions[func_name] = child
280
+ self._runtime.scope.set(func_name, child)
281
+ else:
282
+ try:
283
+ self._runtime._execute_node(child)
284
+ except Exception:
285
+ pass
286
+
287
+ # Parse the main code
171
288
  ast = parse_cssl_program(self._code)
172
289
 
173
290
  # Execute to register all function definitions
@@ -184,6 +301,16 @@ class CSSLFunctionModule:
184
301
  except Exception:
185
302
  pass
186
303
 
304
+ # If module has a name, register for payload() access
305
+ if self._name:
306
+ cssl_instance = self._cssl
307
+ runtime = cssl_instance._get_runtime()
308
+ if not hasattr(runtime, '_inline_payloads'):
309
+ runtime._inline_payloads = {}
310
+ # Store combined code for payload() access
311
+ combined = (self._payload_code or '') + '\n' + self._code
312
+ runtime._inline_payloads[self._name] = combined
313
+
187
314
  self._initialized = True
188
315
 
189
316
  def __getattr__(self, name: str) -> Callable:
@@ -224,11 +351,27 @@ class CsslLang:
224
351
  """
225
352
  CSSL Language interface for Python.
226
353
 
227
- Usage:
354
+ v3.8.0 API:
228
355
  from includecpp import CSSL
229
356
  cssl = CSSL.CsslLang()
230
- result = cssl.exec("script.cssl", arg1, arg2)
231
- cssl.T_exec("async_script.cssl", arg1) # Threaded
357
+
358
+ # Execute CSSL code
359
+ result = cssl.run("script.cssl", arg1, arg2)
360
+ result = cssl.run('''printl("Hello");''')
361
+
362
+ # Create typed scripts
363
+ main = cssl.script("cssl", '''printl("Main");''')
364
+ payload = cssl.script("cssl-pl", '''void helper() {}''')
365
+
366
+ # Bundle into module
367
+ mod = cssl.makemodule(main, payload, "mymod")
368
+
369
+ # Load and execute files
370
+ cssl.load("utils.cssl-pl", "utils")
371
+ cssl.execute("utils")
372
+
373
+ # Register for payload() access
374
+ cssl.include("helpers.cssl-pl", "helpers")
232
375
  """
233
376
 
234
377
  def __init__(self, output_callback: Optional[Callable[[str, str], None]] = None):
@@ -241,6 +384,7 @@ class CsslLang:
241
384
  self._output_callback = output_callback
242
385
  self._runtime = None
243
386
  self._threads: List[threading.Thread] = []
387
+ self._loaded_scripts: Dict[str, Dict[str, Any]] = {}
244
388
 
245
389
  def _get_runtime(self):
246
390
  """Lazy load CSSL runtime."""
@@ -249,26 +393,48 @@ class CsslLang:
249
393
  self._runtime = CSSLRuntime(output_callback=self._output_callback)
250
394
  return self._runtime
251
395
 
252
- def exec(self, path_or_code: str, *args) -> Any:
396
+ def _detect_type(self, path: str) -> str:
397
+ """Detect script type from file extension."""
398
+ path_obj = Path(path)
399
+ if path_obj.suffix == '.cssl-pl':
400
+ return 'cssl-pl'
401
+ return 'cssl'
402
+
403
+ def run(self, path_or_code: str, *args) -> Any:
253
404
  """
254
405
  Execute CSSL code or file.
255
406
 
407
+ This is the primary method for running CSSL code in v3.8.0+.
408
+
256
409
  Args:
257
410
  path_or_code: Path to .cssl file or CSSL code string
258
- *args: Arguments to pass to the script
411
+ *args: Arguments to pass to the script (accessible via parameter.get())
259
412
 
260
413
  Returns:
261
414
  Execution result. If parameter.return() was called, returns
262
415
  the list of returned values (or single value if only one).
416
+
417
+ Usage:
418
+ cssl.run("script.cssl", "arg1", 42)
419
+ cssl.run('''
420
+ printl("Hello " + parameter.get(0));
421
+ ''', "World")
263
422
  """
264
423
  runtime = self._get_runtime()
265
424
 
266
- # Check if it's a file path
267
- path = Path(path_or_code)
268
- if path.exists() and path.suffix in ('.cssl', '.cssl-mod'):
269
- source = path.read_text(encoding='utf-8')
270
- else:
271
- source = path_or_code
425
+ # Check if it's a file path (not code)
426
+ # Code detection: contains newlines, semicolons, or braces = definitely code
427
+ is_likely_code = '\n' in path_or_code or ';' in path_or_code or '{' in path_or_code
428
+ source = path_or_code
429
+
430
+ if not is_likely_code:
431
+ try:
432
+ path = Path(path_or_code)
433
+ if path.exists() and path.suffix in ('.cssl', '.cssl-mod', '.cssl-pl'):
434
+ source = path.read_text(encoding='utf-8')
435
+ except OSError:
436
+ # Path too long or invalid - treat as code
437
+ pass
272
438
 
273
439
  # Set arguments in runtime scope
274
440
  from .cssl import Parameter
@@ -296,7 +462,27 @@ class CsslLang:
296
462
  raise RuntimeError(error_msg) from e
297
463
  raise RuntimeError(f"CSSL Error:\n{error_msg}") from e
298
464
 
299
- def T_exec(self, path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
465
+ def exec(self, path_or_code: str, *args) -> Any:
466
+ """
467
+ Execute CSSL code or file.
468
+
469
+ DEPRECATED: Use run() instead. This method is kept for backwards compatibility.
470
+
471
+ Args:
472
+ path_or_code: Path to .cssl file or CSSL code string
473
+ *args: Arguments to pass to the script
474
+
475
+ Returns:
476
+ Execution result
477
+ """
478
+ warnings.warn(
479
+ "exec() is deprecated, use run() instead",
480
+ DeprecationWarning,
481
+ stacklevel=2
482
+ )
483
+ return self.run(path_or_code, *args)
484
+
485
+ def T_run(self, path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
300
486
  """
301
487
  Execute CSSL code asynchronously in a thread.
302
488
 
@@ -308,20 +494,33 @@ class CsslLang:
308
494
  Returns:
309
495
  Thread object
310
496
  """
311
- def _run():
497
+ def _run_async():
312
498
  try:
313
- result = self.exec(path_or_code, *args)
499
+ result = self.run(path_or_code, *args)
314
500
  if callback:
315
501
  callback(result)
316
502
  except Exception as e:
317
503
  if callback:
318
504
  callback(e)
319
505
 
320
- thread = threading.Thread(target=_run, daemon=True)
506
+ thread = threading.Thread(target=_run_async, daemon=True)
321
507
  thread.start()
322
508
  self._threads.append(thread)
323
509
  return thread
324
510
 
511
+ def T_exec(self, path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
512
+ """
513
+ Execute CSSL code asynchronously in a thread.
514
+
515
+ DEPRECATED: Use T_run() instead.
516
+ """
517
+ warnings.warn(
518
+ "T_exec() is deprecated, use T_run() instead",
519
+ DeprecationWarning,
520
+ stacklevel=2
521
+ )
522
+ return self.T_run(path_or_code, *args, callback=callback)
523
+
325
524
  def wait_all(self, timeout: Optional[float] = None):
326
525
  """Wait for all async executions to complete."""
327
526
  for thread in self._threads:
@@ -368,32 +567,185 @@ class CsslLang:
368
567
  """
369
568
  return CSSLModule(self, code)
370
569
 
371
- def makemodule(self, code: str) -> 'CSSLFunctionModule':
570
+ def script(self, script_type: str, code: str, *params) -> 'CSSLScript':
571
+ """
572
+ Create a typed CSSL script.
573
+
574
+ Args:
575
+ script_type: "cssl" for main script, "cssl-pl" for payload
576
+ code: The CSSL code
577
+ *params: Optional parameters accessible via parameter.get(index)
578
+
579
+ Returns:
580
+ CSSLScript object that can be executed or bundled
581
+
582
+ Usage:
583
+ main = cssl.script("cssl", '''
584
+ printl("Main script running");
585
+ helper();
586
+ ''')
587
+
588
+ payload = cssl.script("cssl-pl", '''
589
+ void helper() {
590
+ printl("Helper called!");
591
+ }
592
+ ''')
593
+
594
+ # Execute directly
595
+ main.run()
596
+
597
+ # Or bundle into module
598
+ mod = cssl.makemodule(main, payload, "mymod")
599
+ """
600
+ return CSSLScript(self, script_type, code, params)
601
+
602
+ def makemodule(
603
+ self,
604
+ main_script: Union[str, 'CSSLScript'],
605
+ payload_script: Union[str, 'CSSLScript', None] = None,
606
+ name: str = None
607
+ ) -> 'CSSLFunctionModule':
372
608
  """
373
609
  Create a CSSL module with accessible functions.
374
610
 
375
611
  Functions defined in the code become methods on the returned module.
612
+ Optionally registers the module for payload() access in other scripts.
376
613
 
377
- Usage:
378
- module = CSSL.makemodule('''
614
+ Args:
615
+ main_script: Main CSSL code (string or CSSLScript)
616
+ payload_script: Optional payload code (string or CSSLScript)
617
+ name: Optional name to register for payload(name) access
618
+
619
+ Returns:
620
+ CSSLFunctionModule - module with callable function attributes
621
+
622
+ Usage (v3.8.0 - with CSSLScript objects):
623
+ main = cssl.script("cssl", '''
624
+ printl("Main");
625
+ helper();
626
+ ''')
627
+ payload = cssl.script("cssl-pl", '''
628
+ void helper() { printl("Helper!"); }
629
+ ''')
630
+ mod = cssl.makemodule(main, payload, "mymod")
631
+ mod.helper() # Direct call
632
+
633
+ # Also available in other scripts:
634
+ cssl.run('''
635
+ payload("mymod");
636
+ helper(); // Works!
637
+ ''')
638
+
639
+ Usage (legacy - code string):
640
+ module = cssl.makemodule('''
379
641
  string greet(string name) {
380
642
  return "Hello, " + name + "!";
381
643
  }
382
-
383
- int add(int a, int b) {
384
- return a + b;
385
- }
386
644
  ''')
387
645
  module.greet("World") # Returns "Hello, World!"
388
- module.add(2, 3) # Returns 5
646
+ """
647
+ # Extract code from CSSLScript objects if provided
648
+ if isinstance(main_script, CSSLScript):
649
+ main_code = main_script.code
650
+ else:
651
+ main_code = main_script
652
+
653
+ payload_code = None
654
+ if payload_script is not None:
655
+ if isinstance(payload_script, CSSLScript):
656
+ payload_code = payload_script.code
657
+ else:
658
+ payload_code = payload_script
659
+
660
+ return CSSLFunctionModule(self, main_code, payload_code, name)
661
+
662
+ def load(self, path: str, name: str) -> None:
663
+ """
664
+ Load a .cssl or .cssl-pl file and register by name.
665
+
666
+ The file becomes accessible for execute(name) or payload(name).
667
+
668
+ Args:
669
+ path: Path to the .cssl or .cssl-pl file
670
+ name: Name to register the script under
671
+
672
+ Usage:
673
+ cssl.load("utils.cssl-pl", "utils")
674
+ cssl.execute("utils") # Run it
675
+
676
+ # Or in CSSL code:
677
+ cssl.run('''
678
+ payload("utils"); // Loads the registered file
679
+ ''')
680
+ """
681
+ path_obj = Path(path)
682
+ if not path_obj.exists():
683
+ raise FileNotFoundError(f"CSSL file not found: {path}")
684
+
685
+ script_type = self._detect_type(path)
686
+ code = path_obj.read_text(encoding='utf-8')
687
+
688
+ self._loaded_scripts[name] = {
689
+ 'path': str(path_obj.absolute()),
690
+ 'type': script_type,
691
+ 'code': code
692
+ }
693
+
694
+ # Also register for payload() access
695
+ runtime = self._get_runtime()
696
+ if not hasattr(runtime, '_inline_payloads'):
697
+ runtime._inline_payloads = {}
698
+ runtime._inline_payloads[name] = code
699
+
700
+ def execute(self, name: str, *args) -> Any:
701
+ """
702
+ Execute a previously loaded script by name.
389
703
 
390
704
  Args:
391
- code: CSSL code string with function definitions
705
+ name: Name of the loaded script
706
+ *args: Arguments to pass to the script
392
707
 
393
708
  Returns:
394
- CSSLFunctionModule - module with callable function attributes
709
+ Execution result
710
+
711
+ Usage:
712
+ cssl.load("utils.cssl-pl", "utils")
713
+ result = cssl.execute("utils", arg1, arg2)
395
714
  """
396
- return CSSLFunctionModule(self, code)
715
+ if name not in self._loaded_scripts:
716
+ raise KeyError(f"No script loaded with name '{name}'. Use load() first.")
717
+
718
+ script_info = self._loaded_scripts[name]
719
+ return self.run(script_info['code'], *args)
720
+
721
+ def include(self, path: str, name: str) -> None:
722
+ """
723
+ Register a file to be accessible via payload(name) or include(name) in CSSL.
724
+
725
+ Unlike load(), this doesn't store the script for execute() - it only
726
+ makes it available for payload() calls within CSSL code.
727
+
728
+ Args:
729
+ path: Path to the .cssl or .cssl-pl file
730
+ name: Name for payload() access
731
+
732
+ Usage:
733
+ cssl.include("helpers.cssl-pl", "helpers")
734
+ cssl.run('''
735
+ payload("helpers");
736
+ // Functions from helpers are now available
737
+ ''')
738
+ """
739
+ path_obj = Path(path)
740
+ if not path_obj.exists():
741
+ raise FileNotFoundError(f"CSSL file not found: {path}")
742
+
743
+ code = path_obj.read_text(encoding='utf-8')
744
+
745
+ runtime = self._get_runtime()
746
+ if not hasattr(runtime, '_inline_payloads'):
747
+ runtime._inline_payloads = {}
748
+ runtime._inline_payloads[name] = code
397
749
 
398
750
  def code(self, name: str, code: str) -> None:
399
751
  """
@@ -737,6 +1089,38 @@ def shared(name: str) -> Optional[Any]:
737
1089
  return get_shared(name)
738
1090
 
739
1091
 
1092
+ def cleanup_shared() -> int:
1093
+ """
1094
+ Manually clean up all shared object marker files.
1095
+
1096
+ Call this to remove stale .shareobj files from %APPDATA%/IncludeCPP/shared_objects/
1097
+ that may have accumulated from previous sessions.
1098
+
1099
+ Returns:
1100
+ Number of files deleted
1101
+ """
1102
+ global _live_objects, _global_shared_objects
1103
+
1104
+ count = 0
1105
+ try:
1106
+ share_dir = _get_share_directory()
1107
+ if share_dir.exists():
1108
+ for f in share_dir.glob('*.shareobj*'):
1109
+ try:
1110
+ f.unlink()
1111
+ count += 1
1112
+ except Exception:
1113
+ pass
1114
+ except Exception:
1115
+ pass
1116
+
1117
+ # Clear in-memory registries
1118
+ _live_objects.clear()
1119
+ _global_shared_objects.clear()
1120
+
1121
+ return count
1122
+
1123
+
740
1124
  # Singleton for convenience
741
1125
  _default_instance: Optional[CsslLang] = None
742
1126
 
@@ -748,15 +1132,18 @@ def get_cssl() -> CsslLang:
748
1132
  return _default_instance
749
1133
 
750
1134
 
751
- # Module-level convenience functions
752
- def exec(path_or_code: str, *args) -> Any:
1135
+ # Module-level convenience functions (v3.8.0 API)
1136
+
1137
+ def run(path_or_code: str, *args) -> Any:
753
1138
  """
754
1139
  Execute CSSL code or file.
755
1140
 
1141
+ This is the primary method for running CSSL code in v3.8.0+.
1142
+
756
1143
  Usage:
757
1144
  from includecpp import CSSL
758
- CSSL.exec("script.cssl", arg1, arg2)
759
- CSSL.exec("printl('Hello World');")
1145
+ CSSL.run("script.cssl", arg1, arg2)
1146
+ CSSL.run("printl('Hello World');")
760
1147
 
761
1148
  Args:
762
1149
  path_or_code: Path to .cssl file or CSSL code string
@@ -765,16 +1152,30 @@ def exec(path_or_code: str, *args) -> Any:
765
1152
  Returns:
766
1153
  Execution result
767
1154
  """
768
- return get_cssl().exec(path_or_code, *args)
1155
+ return get_cssl().run(path_or_code, *args)
769
1156
 
770
1157
 
771
- def T_exec(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
1158
+ def exec(path_or_code: str, *args) -> Any:
1159
+ """
1160
+ Execute CSSL code or file.
1161
+
1162
+ DEPRECATED: Use run() instead.
1163
+ """
1164
+ warnings.warn(
1165
+ "exec() is deprecated, use run() instead",
1166
+ DeprecationWarning,
1167
+ stacklevel=2
1168
+ )
1169
+ return get_cssl().run(path_or_code, *args)
1170
+
1171
+
1172
+ def T_run(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
772
1173
  """
773
1174
  Execute CSSL code asynchronously in a thread.
774
1175
 
775
1176
  Usage:
776
1177
  from includecpp import CSSL
777
- CSSL.T_exec("async_script.cssl", arg1, callback=on_done)
1178
+ CSSL.T_run("async_script.cssl", arg1, callback=on_done)
778
1179
 
779
1180
  Args:
780
1181
  path_or_code: Path to .cssl file or CSSL code string
@@ -784,7 +1185,75 @@ def T_exec(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] =
784
1185
  Returns:
785
1186
  Thread object
786
1187
  """
787
- return get_cssl().T_exec(path_or_code, *args, callback=callback)
1188
+ return get_cssl().T_run(path_or_code, *args, callback=callback)
1189
+
1190
+
1191
+ def T_exec(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
1192
+ """
1193
+ Execute CSSL code asynchronously in a thread.
1194
+
1195
+ DEPRECATED: Use T_run() instead.
1196
+ """
1197
+ warnings.warn(
1198
+ "T_exec() is deprecated, use T_run() instead",
1199
+ DeprecationWarning,
1200
+ stacklevel=2
1201
+ )
1202
+ return get_cssl().T_run(path_or_code, *args, callback=callback)
1203
+
1204
+
1205
+ def script(script_type: str, code: str, *params) -> CSSLScript:
1206
+ """
1207
+ Create a typed CSSL script.
1208
+
1209
+ Usage:
1210
+ from includecpp import CSSL
1211
+ main = CSSL.script("cssl", '''printl("Main");''')
1212
+ payload = CSSL.script("cssl-pl", '''void helper() {}''')
1213
+ mod = CSSL.makemodule(main, payload, "mymod")
1214
+
1215
+ Args:
1216
+ script_type: "cssl" for main script, "cssl-pl" for payload
1217
+ code: The CSSL code
1218
+ *params: Optional parameters
1219
+
1220
+ Returns:
1221
+ CSSLScript object
1222
+ """
1223
+ return get_cssl().script(script_type, code, *params)
1224
+
1225
+
1226
+ def load(path: str, name: str) -> None:
1227
+ """
1228
+ Load a .cssl or .cssl-pl file and register by name.
1229
+
1230
+ Usage:
1231
+ CSSL.load("utils.cssl-pl", "utils")
1232
+ CSSL.execute("utils")
1233
+ """
1234
+ return get_cssl().load(path, name)
1235
+
1236
+
1237
+ def execute(name: str, *args) -> Any:
1238
+ """
1239
+ Execute a previously loaded script by name.
1240
+
1241
+ Usage:
1242
+ CSSL.load("utils.cssl-pl", "utils")
1243
+ result = CSSL.execute("utils", arg1, arg2)
1244
+ """
1245
+ return get_cssl().execute(name, *args)
1246
+
1247
+
1248
+ def include(path: str, name: str) -> None:
1249
+ """
1250
+ Register a file for payload(name) access in CSSL.
1251
+
1252
+ Usage:
1253
+ CSSL.include("helpers.cssl-pl", "helpers")
1254
+ CSSL.run('payload("helpers");')
1255
+ """
1256
+ return get_cssl().include(path, name)
788
1257
 
789
1258
 
790
1259
  def set_global(name: str, value: Any) -> None:
@@ -808,7 +1277,9 @@ def clear_output() -> None:
808
1277
 
809
1278
 
810
1279
  # Aliases to avoid conflict with Python builtin exec
1280
+ _run = run
811
1281
  _exec = exec
1282
+ _T_run = T_run
812
1283
  _T_exec = T_exec
813
1284
 
814
1285
 
@@ -832,43 +1303,58 @@ def module(code: str) -> CSSLModule:
832
1303
  return get_cssl().module(code)
833
1304
 
834
1305
 
835
- def makemodule(code: str) -> CSSLFunctionModule:
1306
+ def makemodule(
1307
+ main_script: Union[str, CSSLScript],
1308
+ payload_script: Union[str, CSSLScript, None] = None,
1309
+ name: str = None
1310
+ ) -> CSSLFunctionModule:
836
1311
  """
837
1312
  Create a CSSL module with accessible functions.
838
1313
 
839
- Usage:
840
- from includecpp import CSSL
841
- math_mod = CSSL.makemodule('''
842
- int add(int a, int b) {
843
- return a + b;
844
- }
1314
+ Usage (v3.8.0 - with CSSLScript):
1315
+ main = CSSL.script("cssl", '''printl("Main");''')
1316
+ payload = CSSL.script("cssl-pl", '''void helper() {}''')
1317
+ mod = CSSL.makemodule(main, payload, "mymod")
845
1318
 
846
- int multiply(int a, int b) {
847
- return a * b;
848
- }
1319
+ Usage (legacy - code string):
1320
+ math_mod = CSSL.makemodule('''
1321
+ int add(int a, int b) { return a + b; }
849
1322
  ''')
850
- math_mod.add(2, 3) # Returns 5
851
- math_mod.multiply(4, 5) # Returns 20
1323
+ math_mod.add(2, 3) # Returns 5
852
1324
 
853
1325
  Args:
854
- code: CSSL code string with function definitions
1326
+ main_script: Main CSSL code (string or CSSLScript)
1327
+ payload_script: Optional payload code (string or CSSLScript)
1328
+ name: Optional name to register for payload(name) access
855
1329
 
856
1330
  Returns:
857
1331
  CSSLFunctionModule - module with callable function attributes
858
1332
  """
859
- return get_cssl().makemodule(code)
1333
+ return get_cssl().makemodule(main_script, payload_script, name)
860
1334
 
861
1335
 
862
1336
  # Export all
863
1337
  __all__ = [
864
1338
  'CsslLang',
865
1339
  'CSSLModule',
1340
+ 'CSSLScript',
866
1341
  'CSSLFunctionModule',
867
1342
  'get_cssl',
1343
+ # v3.8.0 primary API
1344
+ 'run',
1345
+ '_run',
1346
+ 'T_run',
1347
+ '_T_run',
1348
+ 'script',
1349
+ 'load',
1350
+ 'execute',
1351
+ 'include',
1352
+ # Legacy (deprecated)
868
1353
  'exec',
869
- '_exec', # Alias for exec (avoids Python builtin conflict)
1354
+ '_exec',
870
1355
  'T_exec',
871
- '_T_exec', # Alias for T_exec
1356
+ '_T_exec',
1357
+ # Other
872
1358
  'set_global',
873
1359
  'get_global',
874
1360
  'get_output',
@@ -879,4 +1365,5 @@ __all__ = [
879
1365
  'unshare',
880
1366
  'shared',
881
1367
  'get_shared',
1368
+ 'cleanup_shared',
882
1369
  ]