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.
- includecpp/__init__.py +1 -1
- includecpp/__init__.pyi +2 -2
- includecpp/cli/commands.py +278 -75
- includecpp/core/cssl/CSSL_DOCUMENTATION.md +27 -8
- includecpp/core/cssl/__init__.py +7 -2
- includecpp/core/cssl/cssl_builtins.py +201 -9
- includecpp/core/cssl/cssl_builtins.pyi +3682 -401
- includecpp/core/cssl/cssl_parser.py +291 -40
- includecpp/core/cssl/cssl_runtime.py +629 -40
- includecpp/core/cssl/cssl_syntax.py +7 -7
- includecpp/core/cssl/cssl_types.py +75 -2
- includecpp/core/cssl_bridge.py +540 -53
- includecpp/vscode/cssl/extension.js +133 -0
- includecpp/vscode/cssl/images/cssl.png +0 -0
- includecpp/vscode/cssl/images/cssl_pl.png +0 -0
- includecpp/vscode/cssl/language-configuration.json +1 -4
- includecpp/vscode/cssl/package.json +117 -11
- includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +213 -29
- {includecpp-3.7.1.dist-info → includecpp-3.7.25.dist-info}/METADATA +2 -2
- {includecpp-3.7.1.dist-info → includecpp-3.7.25.dist-info}/RECORD +24 -21
- {includecpp-3.7.1.dist-info → includecpp-3.7.25.dist-info}/WHEEL +0 -0
- {includecpp-3.7.1.dist-info → includecpp-3.7.25.dist-info}/entry_points.txt +0 -0
- {includecpp-3.7.1.dist-info → includecpp-3.7.25.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.7.1.dist-info → includecpp-3.7.25.dist-info}/top_level.txt +0 -0
includecpp/core/cssl_bridge.py
CHANGED
|
@@ -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
|
-
#
|
|
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
|
-
|
|
354
|
+
v3.8.0 API:
|
|
228
355
|
from includecpp import CSSL
|
|
229
356
|
cssl = CSSL.CsslLang()
|
|
230
|
-
|
|
231
|
-
|
|
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
|
|
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
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
|
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
|
|
497
|
+
def _run_async():
|
|
312
498
|
try:
|
|
313
|
-
result = self.
|
|
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=
|
|
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
|
|
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
|
-
|
|
378
|
-
|
|
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
|
-
|
|
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
|
-
|
|
705
|
+
name: Name of the loaded script
|
|
706
|
+
*args: Arguments to pass to the script
|
|
392
707
|
|
|
393
708
|
Returns:
|
|
394
|
-
|
|
709
|
+
Execution result
|
|
710
|
+
|
|
711
|
+
Usage:
|
|
712
|
+
cssl.load("utils.cssl-pl", "utils")
|
|
713
|
+
result = cssl.execute("utils", arg1, arg2)
|
|
395
714
|
"""
|
|
396
|
-
|
|
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
|
-
|
|
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.
|
|
759
|
-
CSSL.
|
|
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().
|
|
1155
|
+
return get_cssl().run(path_or_code, *args)
|
|
769
1156
|
|
|
770
1157
|
|
|
771
|
-
def
|
|
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.
|
|
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().
|
|
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(
|
|
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
|
-
|
|
841
|
-
|
|
842
|
-
|
|
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
|
-
|
|
847
|
-
|
|
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)
|
|
851
|
-
math_mod.multiply(4, 5) # Returns 20
|
|
1323
|
+
math_mod.add(2, 3) # Returns 5
|
|
852
1324
|
|
|
853
1325
|
Args:
|
|
854
|
-
|
|
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(
|
|
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',
|
|
1354
|
+
'_exec',
|
|
870
1355
|
'T_exec',
|
|
871
|
-
'_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
|
]
|