IncludeCPP 3.7.2__tar.gz → 3.7.4__tar.gz
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-3.7.2 → includecpp-3.7.4}/IncludeCPP.egg-info/PKG-INFO +1 -1
- {includecpp-3.7.2 → includecpp-3.7.4}/PKG-INFO +1 -1
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/__init__.py +1 -1
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_parser.py +109 -4
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_runtime.py +125 -9
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl_bridge.py +477 -48
- {includecpp-3.7.2 → includecpp-3.7.4}/pyproject.toml +1 -1
- {includecpp-3.7.2 → includecpp-3.7.4}/setup.py +1 -1
- {includecpp-3.7.2 → includecpp-3.7.4}/IncludeCPP.egg-info/SOURCES.txt +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/IncludeCPP.egg-info/dependency_links.txt +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/IncludeCPP.egg-info/entry_points.txt +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/IncludeCPP.egg-info/requires.txt +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/IncludeCPP.egg-info/top_level.txt +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/LICENSE +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/MANIFEST.in +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/README.md +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/__init__.pyi +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/__main__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/cli/__init__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/cli/commands.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/cli/config_parser.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/__init__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/ai_integration.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/build_manager.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cpp_api.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cpp_api.pyi +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cppy_converter.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/CSSL_DOCUMENTATION.md +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/__init__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_builtins.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_builtins.pyi +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_events.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_modules.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_syntax.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl/cssl_types.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/cssl_bridge.pyi +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/error_catalog.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/error_formatter.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/exceptions.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/path_discovery.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/project_ui.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/core/settings_ui.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/generator/__init__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/generator/parser.cpp +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/generator/parser.h +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/generator/type_resolver.cpp +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/generator/type_resolver.h +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/py.typed +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/templates/cpp.proj.template +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/vscode/__init__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/vscode/cssl/__init__.py +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/vscode/cssl/language-configuration.json +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/vscode/cssl/package.json +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/vscode/cssl/snippets/cssl.snippets.json +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/requirements.txt +0 -0
- {includecpp-3.7.2 → includecpp-3.7.4}/setup.cfg +0 -0
|
@@ -108,6 +108,8 @@ class TokenType(Enum):
|
|
|
108
108
|
COMMENT = auto()
|
|
109
109
|
NEWLINE = auto()
|
|
110
110
|
EOF = auto()
|
|
111
|
+
# Super-functions for .cssl-pl payload files (v3.8.0)
|
|
112
|
+
SUPER_FUNC = auto() # #$run(), #$exec(), #$printl() - pre-execution hooks
|
|
111
113
|
|
|
112
114
|
|
|
113
115
|
KEYWORDS = {
|
|
@@ -212,9 +214,14 @@ class CSSLLexer:
|
|
|
212
214
|
|
|
213
215
|
char = self.source[self.pos]
|
|
214
216
|
|
|
215
|
-
# Comments
|
|
217
|
+
# Super-functions (#$) or Comments (# and // style)
|
|
216
218
|
if char == '#':
|
|
217
|
-
self.
|
|
219
|
+
if self._peek(1) == '$':
|
|
220
|
+
# Super-function: #$run(), #$exec(), #$printl()
|
|
221
|
+
self._read_super_function()
|
|
222
|
+
else:
|
|
223
|
+
# Regular comment
|
|
224
|
+
self._skip_comment()
|
|
218
225
|
elif char == '/' and self._peek(1) == '/':
|
|
219
226
|
# C-style // comment - NEW
|
|
220
227
|
self._skip_comment()
|
|
@@ -446,6 +453,31 @@ class CSSLLexer:
|
|
|
446
453
|
else:
|
|
447
454
|
self._add_token(TokenType.IDENTIFIER, value)
|
|
448
455
|
|
|
456
|
+
def _read_super_function(self):
|
|
457
|
+
"""Read #$<name>(...) super-function call for .cssl-pl payloads.
|
|
458
|
+
|
|
459
|
+
Super-functions are pre-execution hooks that run when a payload is loaded.
|
|
460
|
+
Valid super-functions: #$run(), #$exec(), #$printl()
|
|
461
|
+
|
|
462
|
+
Syntax:
|
|
463
|
+
#$run(initFunction); // Call a function at load time
|
|
464
|
+
#$exec(setup()); // Execute expression at load time
|
|
465
|
+
#$printl("Payload loaded"); // Print at load time
|
|
466
|
+
"""
|
|
467
|
+
start = self.pos
|
|
468
|
+
self._advance() # skip '#'
|
|
469
|
+
self._advance() # skip '$'
|
|
470
|
+
|
|
471
|
+
# Read the super-function name (run, exec, printl, etc.)
|
|
472
|
+
name_start = self.pos
|
|
473
|
+
while self.pos < len(self.source) and (self.source[self.pos].isalnum() or self.source[self.pos] == '_'):
|
|
474
|
+
self._advance()
|
|
475
|
+
func_name = self.source[name_start:self.pos]
|
|
476
|
+
|
|
477
|
+
# Store as #$<name> token value
|
|
478
|
+
value = f'#${func_name}'
|
|
479
|
+
self._add_token(TokenType.SUPER_FUNC, value)
|
|
480
|
+
|
|
449
481
|
def _read_self_ref(self):
|
|
450
482
|
"""Read s@<name> or s@<name>.<member>... self-reference"""
|
|
451
483
|
start = self.pos
|
|
@@ -1377,6 +1409,9 @@ class CSSLParser:
|
|
|
1377
1409
|
elif self._looks_like_function_declaration():
|
|
1378
1410
|
# Nested typed function (e.g., void Level2() { ... })
|
|
1379
1411
|
return self._parse_typed_function()
|
|
1412
|
+
elif self._check(TokenType.SUPER_FUNC):
|
|
1413
|
+
# Super-function for .cssl-pl payload files
|
|
1414
|
+
return self._parse_super_function()
|
|
1380
1415
|
elif (self._check(TokenType.IDENTIFIER) or self._check(TokenType.AT) or
|
|
1381
1416
|
self._check(TokenType.CAPTURED_REF) or self._check(TokenType.SHARED_REF) or
|
|
1382
1417
|
self._check(TokenType.GLOBAL_REF) or self._check(TokenType.SELF_REF) or
|
|
@@ -1728,6 +1763,31 @@ class CSSLParser:
|
|
|
1728
1763
|
self._match(TokenType.SEMICOLON)
|
|
1729
1764
|
return ASTNode('return', value=value)
|
|
1730
1765
|
|
|
1766
|
+
def _parse_super_function(self) -> ASTNode:
|
|
1767
|
+
"""Parse super-function for .cssl-pl payload files.
|
|
1768
|
+
|
|
1769
|
+
Syntax:
|
|
1770
|
+
#$run(initFunction); // Call function at load time
|
|
1771
|
+
#$exec(setup()); // Execute expression at load time
|
|
1772
|
+
#$printl("Payload loaded"); // Print at load time
|
|
1773
|
+
|
|
1774
|
+
These are pre-execution hooks that run when payload() loads the file.
|
|
1775
|
+
"""
|
|
1776
|
+
token = self._advance() # Get the SUPER_FUNC token
|
|
1777
|
+
super_name = token.value # e.g., "#$run", "#$exec", "#$printl"
|
|
1778
|
+
|
|
1779
|
+
# Parse the arguments
|
|
1780
|
+
self._expect(TokenType.PAREN_START)
|
|
1781
|
+
args = []
|
|
1782
|
+
if not self._check(TokenType.PAREN_END):
|
|
1783
|
+
args.append(self._parse_expression())
|
|
1784
|
+
while self._match(TokenType.COMMA):
|
|
1785
|
+
args.append(self._parse_expression())
|
|
1786
|
+
self._expect(TokenType.PAREN_END)
|
|
1787
|
+
self._match(TokenType.SEMICOLON)
|
|
1788
|
+
|
|
1789
|
+
return ASTNode('super_func', value={'name': super_name, 'args': args})
|
|
1790
|
+
|
|
1731
1791
|
def _parse_try(self) -> ASTNode:
|
|
1732
1792
|
node = ASTNode('try', children=[])
|
|
1733
1793
|
|
|
@@ -2335,17 +2395,62 @@ class CSSLParser:
|
|
|
2335
2395
|
self._expect(TokenType.COMPARE_GT) # consume >
|
|
2336
2396
|
return ASTNode('instance_ref', value=instance_name)
|
|
2337
2397
|
|
|
2338
|
-
# Check for type generic instantiation: stack<string>, vector<int>, etc.
|
|
2398
|
+
# Check for type generic instantiation: stack<string>, vector<int>, map<string, int>, etc.
|
|
2339
2399
|
# This creates a new instance of the type with the specified element type
|
|
2340
2400
|
if name in TYPE_GENERICS and self._check(TokenType.COMPARE_LT):
|
|
2341
2401
|
self._advance() # consume <
|
|
2342
2402
|
element_type = 'dynamic'
|
|
2403
|
+
value_type = None # For map<K, V>
|
|
2404
|
+
|
|
2343
2405
|
if self._check(TokenType.KEYWORD) or self._check(TokenType.IDENTIFIER):
|
|
2344
2406
|
element_type = self._advance().value
|
|
2407
|
+
|
|
2408
|
+
# Check for second type parameter (map<K, V>)
|
|
2409
|
+
if name == 'map' and self._check(TokenType.COMMA):
|
|
2410
|
+
self._advance() # consume ,
|
|
2411
|
+
if self._check(TokenType.KEYWORD) or self._check(TokenType.IDENTIFIER):
|
|
2412
|
+
value_type = self._advance().value
|
|
2413
|
+
else:
|
|
2414
|
+
value_type = 'dynamic'
|
|
2415
|
+
|
|
2345
2416
|
self._expect(TokenType.COMPARE_GT) # consume >
|
|
2417
|
+
|
|
2418
|
+
# Check for inline initialization: map<K,V>{"key": "value", ...}
|
|
2419
|
+
init_values = None
|
|
2420
|
+
if self._check(TokenType.BLOCK_START):
|
|
2421
|
+
self._advance() # consume {
|
|
2422
|
+
init_values = {}
|
|
2423
|
+
|
|
2424
|
+
while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
|
|
2425
|
+
# Parse key
|
|
2426
|
+
if self._check(TokenType.STRING):
|
|
2427
|
+
key = self._advance().value
|
|
2428
|
+
elif self._check(TokenType.IDENTIFIER):
|
|
2429
|
+
key = self._advance().value
|
|
2430
|
+
else:
|
|
2431
|
+
key = str(self._parse_expression().value) if hasattr(self._parse_expression(), 'value') else 'key'
|
|
2432
|
+
|
|
2433
|
+
# Expect : or =
|
|
2434
|
+
if self._check(TokenType.COLON):
|
|
2435
|
+
self._advance()
|
|
2436
|
+
elif self._check(TokenType.EQUALS):
|
|
2437
|
+
self._advance()
|
|
2438
|
+
|
|
2439
|
+
# Parse value
|
|
2440
|
+
value = self._parse_expression()
|
|
2441
|
+
init_values[key] = value
|
|
2442
|
+
|
|
2443
|
+
# Optional comma
|
|
2444
|
+
if self._check(TokenType.COMMA):
|
|
2445
|
+
self._advance()
|
|
2446
|
+
|
|
2447
|
+
self._expect(TokenType.BLOCK_END) # consume }
|
|
2448
|
+
|
|
2346
2449
|
return ASTNode('type_instantiation', value={
|
|
2347
2450
|
'type': name,
|
|
2348
|
-
'element_type': element_type
|
|
2451
|
+
'element_type': element_type,
|
|
2452
|
+
'value_type': value_type,
|
|
2453
|
+
'init_values': init_values
|
|
2349
2454
|
})
|
|
2350
2455
|
|
|
2351
2456
|
# Check for type-parameterized function call: OpenFind<string>(0)
|
|
@@ -401,6 +401,9 @@ class CSSLRuntime:
|
|
|
401
401
|
elif child.type == 'instance_declaration':
|
|
402
402
|
# Handle instance declaration: instance<"name"> varName;
|
|
403
403
|
result = self._exec_instance_declaration(child)
|
|
404
|
+
elif child.type == 'super_func':
|
|
405
|
+
# Super-function for .cssl-pl payload files (#$run, #$exec, #$printl)
|
|
406
|
+
result = self._exec_super_func(child)
|
|
404
407
|
elif child.type in ('assignment', 'expression', 'inject', 'receive', 'flow',
|
|
405
408
|
'if', 'while', 'for', 'c_for', 'foreach', 'switch', 'try'):
|
|
406
409
|
result = self._execute_node(child)
|
|
@@ -820,6 +823,82 @@ class CSSLRuntime:
|
|
|
820
823
|
self.scope.set(var_name, instance)
|
|
821
824
|
return instance
|
|
822
825
|
|
|
826
|
+
def _exec_super_func(self, node: ASTNode) -> Any:
|
|
827
|
+
"""Execute super-function for .cssl-pl payload files.
|
|
828
|
+
|
|
829
|
+
Super-functions are pre-execution hooks that run when payload() loads a file.
|
|
830
|
+
|
|
831
|
+
Supported super-functions:
|
|
832
|
+
#$run(funcName) - Call a function defined in the payload
|
|
833
|
+
#$exec(expression) - Execute an expression immediately
|
|
834
|
+
#$printl(message) - Print a message during load
|
|
835
|
+
|
|
836
|
+
Example .cssl-pl file:
|
|
837
|
+
void initDatabase() {
|
|
838
|
+
printl("DB initialized");
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
#$run(initDatabase); // Calls initDatabase when payload loads
|
|
842
|
+
#$printl("Payload loaded"); // Prints during load
|
|
843
|
+
"""
|
|
844
|
+
super_info = node.value
|
|
845
|
+
super_name = super_info.get('name', '') # e.g., "#$run", "#$exec", "#$printl"
|
|
846
|
+
args = super_info.get('args', [])
|
|
847
|
+
|
|
848
|
+
# Extract the function name part (after #$)
|
|
849
|
+
if super_name.startswith('#$'):
|
|
850
|
+
func_type = super_name[2:] # "run", "exec", "printl"
|
|
851
|
+
else:
|
|
852
|
+
func_type = super_name
|
|
853
|
+
|
|
854
|
+
if func_type == 'run':
|
|
855
|
+
# #$run(funcName) - Call a function by name
|
|
856
|
+
if args:
|
|
857
|
+
func_ref = args[0]
|
|
858
|
+
if isinstance(func_ref, ASTNode):
|
|
859
|
+
if func_ref.type == 'identifier':
|
|
860
|
+
func_name = func_ref.value
|
|
861
|
+
elif func_ref.type == 'call':
|
|
862
|
+
# Direct call like #$run(setup())
|
|
863
|
+
return self._eval_call(func_ref)
|
|
864
|
+
else:
|
|
865
|
+
func_name = self._evaluate(func_ref)
|
|
866
|
+
else:
|
|
867
|
+
func_name = str(func_ref)
|
|
868
|
+
|
|
869
|
+
# Look up and call the function
|
|
870
|
+
func_node = self.scope.get(func_name)
|
|
871
|
+
if func_node and isinstance(func_node, ASTNode) and func_node.type == 'function':
|
|
872
|
+
return self._call_function(func_node, [])
|
|
873
|
+
else:
|
|
874
|
+
raise CSSLRuntimeError(f"#$run: Function '{func_name}' not found", node.line)
|
|
875
|
+
|
|
876
|
+
elif func_type == 'exec':
|
|
877
|
+
# #$exec(expression) - Execute an expression
|
|
878
|
+
if args:
|
|
879
|
+
return self._evaluate(args[0])
|
|
880
|
+
|
|
881
|
+
elif func_type == 'printl':
|
|
882
|
+
# #$printl(message) - Print a message
|
|
883
|
+
if args:
|
|
884
|
+
msg = self._evaluate(args[0])
|
|
885
|
+
print(str(msg))
|
|
886
|
+
self.output_buffer.append(str(msg))
|
|
887
|
+
return None
|
|
888
|
+
|
|
889
|
+
elif func_type == 'print':
|
|
890
|
+
# #$print(message) - Print without newline
|
|
891
|
+
if args:
|
|
892
|
+
msg = self._evaluate(args[0])
|
|
893
|
+
print(str(msg), end='')
|
|
894
|
+
self.output_buffer.append(str(msg))
|
|
895
|
+
return None
|
|
896
|
+
|
|
897
|
+
else:
|
|
898
|
+
raise CSSLRuntimeError(f"Unknown super-function: {super_name}", node.line)
|
|
899
|
+
|
|
900
|
+
return None
|
|
901
|
+
|
|
823
902
|
def _exec_global_assignment(self, node: ASTNode) -> Any:
|
|
824
903
|
"""Execute global variable assignment: global Name = value
|
|
825
904
|
|
|
@@ -1778,9 +1857,12 @@ class CSSLRuntime:
|
|
|
1778
1857
|
|
|
1779
1858
|
if node.type == 'literal':
|
|
1780
1859
|
value = node.value
|
|
1781
|
-
#
|
|
1782
|
-
if isinstance(value, str)
|
|
1783
|
-
|
|
1860
|
+
# String interpolation - replace {var} or <var> with scope values
|
|
1861
|
+
if isinstance(value, str):
|
|
1862
|
+
has_fstring = '{' in value and '}' in value
|
|
1863
|
+
has_legacy = '<' in value and '>' in value
|
|
1864
|
+
if has_fstring or has_legacy:
|
|
1865
|
+
value = self._interpolate_string(value)
|
|
1784
1866
|
return value
|
|
1785
1867
|
|
|
1786
1868
|
# NEW: Type literals (list, dict) - create empty instances
|
|
@@ -1890,9 +1972,11 @@ class CSSLRuntime:
|
|
|
1890
1972
|
return self._eval_this_access(node)
|
|
1891
1973
|
|
|
1892
1974
|
if node.type == 'type_instantiation':
|
|
1893
|
-
# Create new instance of a type: stack<string>, vector<int>, etc.
|
|
1975
|
+
# Create new instance of a type: stack<string>, vector<int>, map<K,V>, etc.
|
|
1894
1976
|
type_name = node.value.get('type')
|
|
1895
1977
|
element_type = node.value.get('element_type', 'dynamic')
|
|
1978
|
+
value_type = node.value.get('value_type') # For map<K, V>
|
|
1979
|
+
init_values = node.value.get('init_values') # For inline init: map<K,V>{...}
|
|
1896
1980
|
|
|
1897
1981
|
if type_name == 'stack':
|
|
1898
1982
|
return Stack(element_type)
|
|
@@ -1916,6 +2000,15 @@ class CSSLRuntime:
|
|
|
1916
2000
|
return List(element_type)
|
|
1917
2001
|
elif type_name in ('dictionary', 'dict'):
|
|
1918
2002
|
return Dictionary(element_type)
|
|
2003
|
+
elif type_name == 'map':
|
|
2004
|
+
# Create Map with key_type and value_type
|
|
2005
|
+
m = Map(element_type, value_type or 'dynamic')
|
|
2006
|
+
# If inline initialization provided, populate the map
|
|
2007
|
+
if init_values:
|
|
2008
|
+
for key, value_node in init_values.items():
|
|
2009
|
+
value = self._evaluate(value_node)
|
|
2010
|
+
m.insert(key, value)
|
|
2011
|
+
return m
|
|
1919
2012
|
else:
|
|
1920
2013
|
return None
|
|
1921
2014
|
|
|
@@ -2714,14 +2807,24 @@ class CSSLRuntime:
|
|
|
2714
2807
|
elif isinstance(obj, dict):
|
|
2715
2808
|
obj[final_attr] = value
|
|
2716
2809
|
|
|
2717
|
-
#
|
|
2810
|
+
# String interpolation (supports both <var> and {var} syntax)
|
|
2718
2811
|
def _interpolate_string(self, string: str) -> str:
|
|
2719
|
-
"""Replace <variable> placeholders with values from scope
|
|
2812
|
+
"""Replace {variable} and <variable> placeholders with values from scope.
|
|
2813
|
+
|
|
2814
|
+
Both syntaxes are supported (variables only, not expressions):
|
|
2815
|
+
"Hello {name}!" -> "Hello John!" (f-string style)
|
|
2816
|
+
"Hello <name>!" -> "Hello John!" (legacy CSSL style)
|
|
2817
|
+
|
|
2818
|
+
Examples:
|
|
2819
|
+
string name = "Alice";
|
|
2820
|
+
int age = 30;
|
|
2821
|
+
printl("Hello {name}, you are {age} years old!");
|
|
2822
|
+
printl("Hello <name>, you are <age> years old!");
|
|
2720
2823
|
|
|
2721
|
-
|
|
2824
|
+
Note: Only simple variable names are supported, not expressions.
|
|
2825
|
+
Use string concatenation for complex expressions.
|
|
2722
2826
|
"""
|
|
2723
2827
|
import re
|
|
2724
|
-
pattern = r'<([A-Za-z_][A-Za-z0-9_]*)>'
|
|
2725
2828
|
|
|
2726
2829
|
def replacer(match):
|
|
2727
2830
|
var_name = match.group(1)
|
|
@@ -2733,10 +2836,23 @@ class CSSLRuntime:
|
|
|
2733
2836
|
# Try modules
|
|
2734
2837
|
if value is None:
|
|
2735
2838
|
value = self._modules.get(var_name)
|
|
2839
|
+
# Try global scope
|
|
2840
|
+
if value is None:
|
|
2841
|
+
value = self.global_scope.get(var_name)
|
|
2736
2842
|
# Return string representation or empty string if None
|
|
2737
2843
|
return str(value) if value is not None else ''
|
|
2738
2844
|
|
|
2739
|
-
|
|
2845
|
+
# Support both {var} and <var> syntax - simple variable names only
|
|
2846
|
+
# Pattern: {identifier} or <identifier>
|
|
2847
|
+
patterns = [
|
|
2848
|
+
r'\{([A-Za-z_][A-Za-z0-9_]*)\}', # {name} f-string style
|
|
2849
|
+
r'<([A-Za-z_][A-Za-z0-9_]*)>', # <name> legacy CSSL style
|
|
2850
|
+
]
|
|
2851
|
+
|
|
2852
|
+
result = string
|
|
2853
|
+
for pattern in patterns:
|
|
2854
|
+
result = re.sub(pattern, replacer, result)
|
|
2855
|
+
return result
|
|
2740
2856
|
|
|
2741
2857
|
# NEW: Promote variable to global scope via global()
|
|
2742
2858
|
def promote_to_global(self, s_ref_name: str):
|
|
@@ -1,14 +1,23 @@
|
|
|
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
|
|
|
6
14
|
import os
|
|
7
15
|
import pickle
|
|
8
16
|
import random
|
|
9
17
|
import threading
|
|
18
|
+
import warnings
|
|
10
19
|
from pathlib import Path
|
|
11
|
-
from typing import Any, List, Optional, Callable, Dict
|
|
20
|
+
from typing import Any, List, Optional, Callable, Dict, Union, Tuple
|
|
12
21
|
|
|
13
22
|
|
|
14
23
|
def _get_share_directory() -> Path:
|
|
@@ -142,6 +151,79 @@ class CSSLModule:
|
|
|
142
151
|
return f"<CSSLModule code_len={len(self._code)}>"
|
|
143
152
|
|
|
144
153
|
|
|
154
|
+
class CSSLScript:
|
|
155
|
+
"""
|
|
156
|
+
A typed CSSL script object.
|
|
157
|
+
|
|
158
|
+
Created via cssl.script("cssl", code) or cssl.script("cssl-pl", code).
|
|
159
|
+
Can be executed directly or bundled into a module.
|
|
160
|
+
|
|
161
|
+
Usage:
|
|
162
|
+
main = cssl.script("cssl", '''
|
|
163
|
+
printl("Main script");
|
|
164
|
+
myFunc();
|
|
165
|
+
''')
|
|
166
|
+
|
|
167
|
+
payload = cssl.script("cssl-pl", '''
|
|
168
|
+
void myFunc() {
|
|
169
|
+
printl("From payload!");
|
|
170
|
+
}
|
|
171
|
+
''')
|
|
172
|
+
|
|
173
|
+
# Execute directly
|
|
174
|
+
main.run()
|
|
175
|
+
|
|
176
|
+
# Or bundle into module
|
|
177
|
+
mod = cssl.makemodule(main, payload, "mymod")
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
def __init__(self, cssl_instance: 'CsslLang', script_type: str, code: str, params: Tuple = ()):
|
|
181
|
+
"""
|
|
182
|
+
Initialize a CSSL script.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
cssl_instance: The parent CsslLang instance
|
|
186
|
+
script_type: "cssl" for main script, "cssl-pl" for payload
|
|
187
|
+
code: The CSSL code
|
|
188
|
+
params: Optional parameters accessible via parameter.get(index)
|
|
189
|
+
"""
|
|
190
|
+
if script_type not in ('cssl', 'cssl-pl'):
|
|
191
|
+
raise ValueError(f"Invalid script type '{script_type}'. Must be 'cssl' or 'cssl-pl'")
|
|
192
|
+
|
|
193
|
+
self._cssl = cssl_instance
|
|
194
|
+
self._type = script_type
|
|
195
|
+
self._code = code
|
|
196
|
+
self._params = params
|
|
197
|
+
self._name: Optional[str] = None
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def type(self) -> str:
|
|
201
|
+
"""Get script type ('cssl' or 'cssl-pl')."""
|
|
202
|
+
return self._type
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def code(self) -> str:
|
|
206
|
+
"""Get the script code."""
|
|
207
|
+
return self._code
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def is_payload(self) -> bool:
|
|
211
|
+
"""Check if this is a payload script."""
|
|
212
|
+
return self._type == 'cssl-pl'
|
|
213
|
+
|
|
214
|
+
def run(self, *args) -> Any:
|
|
215
|
+
"""Execute this script with optional arguments."""
|
|
216
|
+
all_args = self._params + args
|
|
217
|
+
return self._cssl.run(self._code, *all_args)
|
|
218
|
+
|
|
219
|
+
def __call__(self, *args) -> Any:
|
|
220
|
+
"""Allow calling the script directly."""
|
|
221
|
+
return self.run(*args)
|
|
222
|
+
|
|
223
|
+
def __repr__(self) -> str:
|
|
224
|
+
return f"<CSSLScript type='{self._type}' code_len={len(self._code)}>"
|
|
225
|
+
|
|
226
|
+
|
|
145
227
|
class CSSLFunctionModule:
|
|
146
228
|
"""
|
|
147
229
|
A CSSL module with accessible functions as methods.
|
|
@@ -150,9 +232,11 @@ class CSSLFunctionModule:
|
|
|
150
232
|
become callable attributes on this module.
|
|
151
233
|
"""
|
|
152
234
|
|
|
153
|
-
def __init__(self, cssl_instance: 'CsslLang', code: str):
|
|
235
|
+
def __init__(self, cssl_instance: 'CsslLang', code: str, payload_code: str = None, name: str = None):
|
|
154
236
|
self._cssl = cssl_instance
|
|
155
237
|
self._code = code
|
|
238
|
+
self._payload_code = payload_code
|
|
239
|
+
self._name = name
|
|
156
240
|
self._runtime = None
|
|
157
241
|
self._functions: Dict[str, Any] = {}
|
|
158
242
|
self._initialized = False
|
|
@@ -167,7 +251,22 @@ class CSSLFunctionModule:
|
|
|
167
251
|
# Create a dedicated runtime for this module
|
|
168
252
|
self._runtime = CSSLRuntime()
|
|
169
253
|
|
|
170
|
-
#
|
|
254
|
+
# If we have a payload, load it first (defines functions/globals for main)
|
|
255
|
+
if self._payload_code:
|
|
256
|
+
payload_ast = parse_cssl_program(self._payload_code)
|
|
257
|
+
for child in payload_ast.children:
|
|
258
|
+
if child.type == 'function':
|
|
259
|
+
func_info = child.value
|
|
260
|
+
func_name = func_info.get('name')
|
|
261
|
+
self._functions[func_name] = child
|
|
262
|
+
self._runtime.scope.set(func_name, child)
|
|
263
|
+
else:
|
|
264
|
+
try:
|
|
265
|
+
self._runtime._execute_node(child)
|
|
266
|
+
except Exception:
|
|
267
|
+
pass
|
|
268
|
+
|
|
269
|
+
# Parse the main code
|
|
171
270
|
ast = parse_cssl_program(self._code)
|
|
172
271
|
|
|
173
272
|
# Execute to register all function definitions
|
|
@@ -184,6 +283,16 @@ class CSSLFunctionModule:
|
|
|
184
283
|
except Exception:
|
|
185
284
|
pass
|
|
186
285
|
|
|
286
|
+
# If module has a name, register for payload() access
|
|
287
|
+
if self._name:
|
|
288
|
+
cssl_instance = self._cssl
|
|
289
|
+
runtime = cssl_instance._get_runtime()
|
|
290
|
+
if not hasattr(runtime, '_inline_payloads'):
|
|
291
|
+
runtime._inline_payloads = {}
|
|
292
|
+
# Store combined code for payload() access
|
|
293
|
+
combined = (self._payload_code or '') + '\n' + self._code
|
|
294
|
+
runtime._inline_payloads[self._name] = combined
|
|
295
|
+
|
|
187
296
|
self._initialized = True
|
|
188
297
|
|
|
189
298
|
def __getattr__(self, name: str) -> Callable:
|
|
@@ -224,11 +333,27 @@ class CsslLang:
|
|
|
224
333
|
"""
|
|
225
334
|
CSSL Language interface for Python.
|
|
226
335
|
|
|
227
|
-
|
|
336
|
+
v3.8.0 API:
|
|
228
337
|
from includecpp import CSSL
|
|
229
338
|
cssl = CSSL.CsslLang()
|
|
230
|
-
|
|
231
|
-
|
|
339
|
+
|
|
340
|
+
# Execute CSSL code
|
|
341
|
+
result = cssl.run("script.cssl", arg1, arg2)
|
|
342
|
+
result = cssl.run('''printl("Hello");''')
|
|
343
|
+
|
|
344
|
+
# Create typed scripts
|
|
345
|
+
main = cssl.script("cssl", '''printl("Main");''')
|
|
346
|
+
payload = cssl.script("cssl-pl", '''void helper() {}''')
|
|
347
|
+
|
|
348
|
+
# Bundle into module
|
|
349
|
+
mod = cssl.makemodule(main, payload, "mymod")
|
|
350
|
+
|
|
351
|
+
# Load and execute files
|
|
352
|
+
cssl.load("utils.cssl-pl", "utils")
|
|
353
|
+
cssl.execute("utils")
|
|
354
|
+
|
|
355
|
+
# Register for payload() access
|
|
356
|
+
cssl.include("helpers.cssl-pl", "helpers")
|
|
232
357
|
"""
|
|
233
358
|
|
|
234
359
|
def __init__(self, output_callback: Optional[Callable[[str, str], None]] = None):
|
|
@@ -241,6 +366,7 @@ class CsslLang:
|
|
|
241
366
|
self._output_callback = output_callback
|
|
242
367
|
self._runtime = None
|
|
243
368
|
self._threads: List[threading.Thread] = []
|
|
369
|
+
self._loaded_scripts: Dict[str, Dict[str, Any]] = {}
|
|
244
370
|
|
|
245
371
|
def _get_runtime(self):
|
|
246
372
|
"""Lazy load CSSL runtime."""
|
|
@@ -249,23 +375,38 @@ class CsslLang:
|
|
|
249
375
|
self._runtime = CSSLRuntime(output_callback=self._output_callback)
|
|
250
376
|
return self._runtime
|
|
251
377
|
|
|
252
|
-
def
|
|
378
|
+
def _detect_type(self, path: str) -> str:
|
|
379
|
+
"""Detect script type from file extension."""
|
|
380
|
+
path_obj = Path(path)
|
|
381
|
+
if path_obj.suffix == '.cssl-pl':
|
|
382
|
+
return 'cssl-pl'
|
|
383
|
+
return 'cssl'
|
|
384
|
+
|
|
385
|
+
def run(self, path_or_code: str, *args) -> Any:
|
|
253
386
|
"""
|
|
254
387
|
Execute CSSL code or file.
|
|
255
388
|
|
|
389
|
+
This is the primary method for running CSSL code in v3.8.0+.
|
|
390
|
+
|
|
256
391
|
Args:
|
|
257
392
|
path_or_code: Path to .cssl file or CSSL code string
|
|
258
|
-
*args: Arguments to pass to the script
|
|
393
|
+
*args: Arguments to pass to the script (accessible via parameter.get())
|
|
259
394
|
|
|
260
395
|
Returns:
|
|
261
396
|
Execution result. If parameter.return() was called, returns
|
|
262
397
|
the list of returned values (or single value if only one).
|
|
398
|
+
|
|
399
|
+
Usage:
|
|
400
|
+
cssl.run("script.cssl", "arg1", 42)
|
|
401
|
+
cssl.run('''
|
|
402
|
+
printl("Hello " + parameter.get(0));
|
|
403
|
+
''', "World")
|
|
263
404
|
"""
|
|
264
405
|
runtime = self._get_runtime()
|
|
265
406
|
|
|
266
407
|
# Check if it's a file path
|
|
267
408
|
path = Path(path_or_code)
|
|
268
|
-
if path.exists() and path.suffix in ('.cssl', '.cssl-mod'):
|
|
409
|
+
if path.exists() and path.suffix in ('.cssl', '.cssl-mod', '.cssl-pl'):
|
|
269
410
|
source = path.read_text(encoding='utf-8')
|
|
270
411
|
else:
|
|
271
412
|
source = path_or_code
|
|
@@ -296,7 +437,27 @@ class CsslLang:
|
|
|
296
437
|
raise RuntimeError(error_msg) from e
|
|
297
438
|
raise RuntimeError(f"CSSL Error:\n{error_msg}") from e
|
|
298
439
|
|
|
299
|
-
def
|
|
440
|
+
def exec(self, path_or_code: str, *args) -> Any:
|
|
441
|
+
"""
|
|
442
|
+
Execute CSSL code or file.
|
|
443
|
+
|
|
444
|
+
DEPRECATED: Use run() instead. This method is kept for backwards compatibility.
|
|
445
|
+
|
|
446
|
+
Args:
|
|
447
|
+
path_or_code: Path to .cssl file or CSSL code string
|
|
448
|
+
*args: Arguments to pass to the script
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
Execution result
|
|
452
|
+
"""
|
|
453
|
+
warnings.warn(
|
|
454
|
+
"exec() is deprecated, use run() instead",
|
|
455
|
+
DeprecationWarning,
|
|
456
|
+
stacklevel=2
|
|
457
|
+
)
|
|
458
|
+
return self.run(path_or_code, *args)
|
|
459
|
+
|
|
460
|
+
def T_run(self, path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
|
|
300
461
|
"""
|
|
301
462
|
Execute CSSL code asynchronously in a thread.
|
|
302
463
|
|
|
@@ -308,20 +469,33 @@ class CsslLang:
|
|
|
308
469
|
Returns:
|
|
309
470
|
Thread object
|
|
310
471
|
"""
|
|
311
|
-
def
|
|
472
|
+
def _run_async():
|
|
312
473
|
try:
|
|
313
|
-
result = self.
|
|
474
|
+
result = self.run(path_or_code, *args)
|
|
314
475
|
if callback:
|
|
315
476
|
callback(result)
|
|
316
477
|
except Exception as e:
|
|
317
478
|
if callback:
|
|
318
479
|
callback(e)
|
|
319
480
|
|
|
320
|
-
thread = threading.Thread(target=
|
|
481
|
+
thread = threading.Thread(target=_run_async, daemon=True)
|
|
321
482
|
thread.start()
|
|
322
483
|
self._threads.append(thread)
|
|
323
484
|
return thread
|
|
324
485
|
|
|
486
|
+
def T_exec(self, path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
|
|
487
|
+
"""
|
|
488
|
+
Execute CSSL code asynchronously in a thread.
|
|
489
|
+
|
|
490
|
+
DEPRECATED: Use T_run() instead.
|
|
491
|
+
"""
|
|
492
|
+
warnings.warn(
|
|
493
|
+
"T_exec() is deprecated, use T_run() instead",
|
|
494
|
+
DeprecationWarning,
|
|
495
|
+
stacklevel=2
|
|
496
|
+
)
|
|
497
|
+
return self.T_run(path_or_code, *args, callback=callback)
|
|
498
|
+
|
|
325
499
|
def wait_all(self, timeout: Optional[float] = None):
|
|
326
500
|
"""Wait for all async executions to complete."""
|
|
327
501
|
for thread in self._threads:
|
|
@@ -368,32 +542,185 @@ class CsslLang:
|
|
|
368
542
|
"""
|
|
369
543
|
return CSSLModule(self, code)
|
|
370
544
|
|
|
371
|
-
def
|
|
545
|
+
def script(self, script_type: str, code: str, *params) -> 'CSSLScript':
|
|
546
|
+
"""
|
|
547
|
+
Create a typed CSSL script.
|
|
548
|
+
|
|
549
|
+
Args:
|
|
550
|
+
script_type: "cssl" for main script, "cssl-pl" for payload
|
|
551
|
+
code: The CSSL code
|
|
552
|
+
*params: Optional parameters accessible via parameter.get(index)
|
|
553
|
+
|
|
554
|
+
Returns:
|
|
555
|
+
CSSLScript object that can be executed or bundled
|
|
556
|
+
|
|
557
|
+
Usage:
|
|
558
|
+
main = cssl.script("cssl", '''
|
|
559
|
+
printl("Main script running");
|
|
560
|
+
helper();
|
|
561
|
+
''')
|
|
562
|
+
|
|
563
|
+
payload = cssl.script("cssl-pl", '''
|
|
564
|
+
void helper() {
|
|
565
|
+
printl("Helper called!");
|
|
566
|
+
}
|
|
567
|
+
''')
|
|
568
|
+
|
|
569
|
+
# Execute directly
|
|
570
|
+
main.run()
|
|
571
|
+
|
|
572
|
+
# Or bundle into module
|
|
573
|
+
mod = cssl.makemodule(main, payload, "mymod")
|
|
574
|
+
"""
|
|
575
|
+
return CSSLScript(self, script_type, code, params)
|
|
576
|
+
|
|
577
|
+
def makemodule(
|
|
578
|
+
self,
|
|
579
|
+
main_script: Union[str, 'CSSLScript'],
|
|
580
|
+
payload_script: Union[str, 'CSSLScript', None] = None,
|
|
581
|
+
name: str = None
|
|
582
|
+
) -> 'CSSLFunctionModule':
|
|
372
583
|
"""
|
|
373
584
|
Create a CSSL module with accessible functions.
|
|
374
585
|
|
|
375
586
|
Functions defined in the code become methods on the returned module.
|
|
587
|
+
Optionally registers the module for payload() access in other scripts.
|
|
376
588
|
|
|
377
|
-
|
|
378
|
-
|
|
589
|
+
Args:
|
|
590
|
+
main_script: Main CSSL code (string or CSSLScript)
|
|
591
|
+
payload_script: Optional payload code (string or CSSLScript)
|
|
592
|
+
name: Optional name to register for payload(name) access
|
|
593
|
+
|
|
594
|
+
Returns:
|
|
595
|
+
CSSLFunctionModule - module with callable function attributes
|
|
596
|
+
|
|
597
|
+
Usage (v3.8.0 - with CSSLScript objects):
|
|
598
|
+
main = cssl.script("cssl", '''
|
|
599
|
+
printl("Main");
|
|
600
|
+
helper();
|
|
601
|
+
''')
|
|
602
|
+
payload = cssl.script("cssl-pl", '''
|
|
603
|
+
void helper() { printl("Helper!"); }
|
|
604
|
+
''')
|
|
605
|
+
mod = cssl.makemodule(main, payload, "mymod")
|
|
606
|
+
mod.helper() # Direct call
|
|
607
|
+
|
|
608
|
+
# Also available in other scripts:
|
|
609
|
+
cssl.run('''
|
|
610
|
+
payload("mymod");
|
|
611
|
+
helper(); // Works!
|
|
612
|
+
''')
|
|
613
|
+
|
|
614
|
+
Usage (legacy - code string):
|
|
615
|
+
module = cssl.makemodule('''
|
|
379
616
|
string greet(string name) {
|
|
380
617
|
return "Hello, " + name + "!";
|
|
381
618
|
}
|
|
382
|
-
|
|
383
|
-
int add(int a, int b) {
|
|
384
|
-
return a + b;
|
|
385
|
-
}
|
|
386
619
|
''')
|
|
387
620
|
module.greet("World") # Returns "Hello, World!"
|
|
388
|
-
|
|
621
|
+
"""
|
|
622
|
+
# Extract code from CSSLScript objects if provided
|
|
623
|
+
if isinstance(main_script, CSSLScript):
|
|
624
|
+
main_code = main_script.code
|
|
625
|
+
else:
|
|
626
|
+
main_code = main_script
|
|
627
|
+
|
|
628
|
+
payload_code = None
|
|
629
|
+
if payload_script is not None:
|
|
630
|
+
if isinstance(payload_script, CSSLScript):
|
|
631
|
+
payload_code = payload_script.code
|
|
632
|
+
else:
|
|
633
|
+
payload_code = payload_script
|
|
634
|
+
|
|
635
|
+
return CSSLFunctionModule(self, main_code, payload_code, name)
|
|
636
|
+
|
|
637
|
+
def load(self, path: str, name: str) -> None:
|
|
638
|
+
"""
|
|
639
|
+
Load a .cssl or .cssl-pl file and register by name.
|
|
640
|
+
|
|
641
|
+
The file becomes accessible for execute(name) or payload(name).
|
|
642
|
+
|
|
643
|
+
Args:
|
|
644
|
+
path: Path to the .cssl or .cssl-pl file
|
|
645
|
+
name: Name to register the script under
|
|
646
|
+
|
|
647
|
+
Usage:
|
|
648
|
+
cssl.load("utils.cssl-pl", "utils")
|
|
649
|
+
cssl.execute("utils") # Run it
|
|
650
|
+
|
|
651
|
+
# Or in CSSL code:
|
|
652
|
+
cssl.run('''
|
|
653
|
+
payload("utils"); // Loads the registered file
|
|
654
|
+
''')
|
|
655
|
+
"""
|
|
656
|
+
path_obj = Path(path)
|
|
657
|
+
if not path_obj.exists():
|
|
658
|
+
raise FileNotFoundError(f"CSSL file not found: {path}")
|
|
659
|
+
|
|
660
|
+
script_type = self._detect_type(path)
|
|
661
|
+
code = path_obj.read_text(encoding='utf-8')
|
|
662
|
+
|
|
663
|
+
self._loaded_scripts[name] = {
|
|
664
|
+
'path': str(path_obj.absolute()),
|
|
665
|
+
'type': script_type,
|
|
666
|
+
'code': code
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
# Also register for payload() access
|
|
670
|
+
runtime = self._get_runtime()
|
|
671
|
+
if not hasattr(runtime, '_inline_payloads'):
|
|
672
|
+
runtime._inline_payloads = {}
|
|
673
|
+
runtime._inline_payloads[name] = code
|
|
674
|
+
|
|
675
|
+
def execute(self, name: str, *args) -> Any:
|
|
676
|
+
"""
|
|
677
|
+
Execute a previously loaded script by name.
|
|
389
678
|
|
|
390
679
|
Args:
|
|
391
|
-
|
|
680
|
+
name: Name of the loaded script
|
|
681
|
+
*args: Arguments to pass to the script
|
|
392
682
|
|
|
393
683
|
Returns:
|
|
394
|
-
|
|
684
|
+
Execution result
|
|
685
|
+
|
|
686
|
+
Usage:
|
|
687
|
+
cssl.load("utils.cssl-pl", "utils")
|
|
688
|
+
result = cssl.execute("utils", arg1, arg2)
|
|
395
689
|
"""
|
|
396
|
-
|
|
690
|
+
if name not in self._loaded_scripts:
|
|
691
|
+
raise KeyError(f"No script loaded with name '{name}'. Use load() first.")
|
|
692
|
+
|
|
693
|
+
script_info = self._loaded_scripts[name]
|
|
694
|
+
return self.run(script_info['code'], *args)
|
|
695
|
+
|
|
696
|
+
def include(self, path: str, name: str) -> None:
|
|
697
|
+
"""
|
|
698
|
+
Register a file to be accessible via payload(name) or include(name) in CSSL.
|
|
699
|
+
|
|
700
|
+
Unlike load(), this doesn't store the script for execute() - it only
|
|
701
|
+
makes it available for payload() calls within CSSL code.
|
|
702
|
+
|
|
703
|
+
Args:
|
|
704
|
+
path: Path to the .cssl or .cssl-pl file
|
|
705
|
+
name: Name for payload() access
|
|
706
|
+
|
|
707
|
+
Usage:
|
|
708
|
+
cssl.include("helpers.cssl-pl", "helpers")
|
|
709
|
+
cssl.run('''
|
|
710
|
+
payload("helpers");
|
|
711
|
+
// Functions from helpers are now available
|
|
712
|
+
''')
|
|
713
|
+
"""
|
|
714
|
+
path_obj = Path(path)
|
|
715
|
+
if not path_obj.exists():
|
|
716
|
+
raise FileNotFoundError(f"CSSL file not found: {path}")
|
|
717
|
+
|
|
718
|
+
code = path_obj.read_text(encoding='utf-8')
|
|
719
|
+
|
|
720
|
+
runtime = self._get_runtime()
|
|
721
|
+
if not hasattr(runtime, '_inline_payloads'):
|
|
722
|
+
runtime._inline_payloads = {}
|
|
723
|
+
runtime._inline_payloads[name] = code
|
|
397
724
|
|
|
398
725
|
def code(self, name: str, code: str) -> None:
|
|
399
726
|
"""
|
|
@@ -748,15 +1075,18 @@ def get_cssl() -> CsslLang:
|
|
|
748
1075
|
return _default_instance
|
|
749
1076
|
|
|
750
1077
|
|
|
751
|
-
# Module-level convenience functions
|
|
752
|
-
|
|
1078
|
+
# Module-level convenience functions (v3.8.0 API)
|
|
1079
|
+
|
|
1080
|
+
def run(path_or_code: str, *args) -> Any:
|
|
753
1081
|
"""
|
|
754
1082
|
Execute CSSL code or file.
|
|
755
1083
|
|
|
1084
|
+
This is the primary method for running CSSL code in v3.8.0+.
|
|
1085
|
+
|
|
756
1086
|
Usage:
|
|
757
1087
|
from includecpp import CSSL
|
|
758
|
-
CSSL.
|
|
759
|
-
CSSL.
|
|
1088
|
+
CSSL.run("script.cssl", arg1, arg2)
|
|
1089
|
+
CSSL.run("printl('Hello World');")
|
|
760
1090
|
|
|
761
1091
|
Args:
|
|
762
1092
|
path_or_code: Path to .cssl file or CSSL code string
|
|
@@ -765,16 +1095,30 @@ def exec(path_or_code: str, *args) -> Any:
|
|
|
765
1095
|
Returns:
|
|
766
1096
|
Execution result
|
|
767
1097
|
"""
|
|
768
|
-
return get_cssl().
|
|
1098
|
+
return get_cssl().run(path_or_code, *args)
|
|
769
1099
|
|
|
770
1100
|
|
|
771
|
-
def
|
|
1101
|
+
def exec(path_or_code: str, *args) -> Any:
|
|
1102
|
+
"""
|
|
1103
|
+
Execute CSSL code or file.
|
|
1104
|
+
|
|
1105
|
+
DEPRECATED: Use run() instead.
|
|
1106
|
+
"""
|
|
1107
|
+
warnings.warn(
|
|
1108
|
+
"exec() is deprecated, use run() instead",
|
|
1109
|
+
DeprecationWarning,
|
|
1110
|
+
stacklevel=2
|
|
1111
|
+
)
|
|
1112
|
+
return get_cssl().run(path_or_code, *args)
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
def T_run(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
|
|
772
1116
|
"""
|
|
773
1117
|
Execute CSSL code asynchronously in a thread.
|
|
774
1118
|
|
|
775
1119
|
Usage:
|
|
776
1120
|
from includecpp import CSSL
|
|
777
|
-
CSSL.
|
|
1121
|
+
CSSL.T_run("async_script.cssl", arg1, callback=on_done)
|
|
778
1122
|
|
|
779
1123
|
Args:
|
|
780
1124
|
path_or_code: Path to .cssl file or CSSL code string
|
|
@@ -784,7 +1128,75 @@ def T_exec(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] =
|
|
|
784
1128
|
Returns:
|
|
785
1129
|
Thread object
|
|
786
1130
|
"""
|
|
787
|
-
return get_cssl().
|
|
1131
|
+
return get_cssl().T_run(path_or_code, *args, callback=callback)
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
def T_exec(path_or_code: str, *args, callback: Optional[Callable[[Any], None]] = None) -> threading.Thread:
|
|
1135
|
+
"""
|
|
1136
|
+
Execute CSSL code asynchronously in a thread.
|
|
1137
|
+
|
|
1138
|
+
DEPRECATED: Use T_run() instead.
|
|
1139
|
+
"""
|
|
1140
|
+
warnings.warn(
|
|
1141
|
+
"T_exec() is deprecated, use T_run() instead",
|
|
1142
|
+
DeprecationWarning,
|
|
1143
|
+
stacklevel=2
|
|
1144
|
+
)
|
|
1145
|
+
return get_cssl().T_run(path_or_code, *args, callback=callback)
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
def script(script_type: str, code: str, *params) -> CSSLScript:
|
|
1149
|
+
"""
|
|
1150
|
+
Create a typed CSSL script.
|
|
1151
|
+
|
|
1152
|
+
Usage:
|
|
1153
|
+
from includecpp import CSSL
|
|
1154
|
+
main = CSSL.script("cssl", '''printl("Main");''')
|
|
1155
|
+
payload = CSSL.script("cssl-pl", '''void helper() {}''')
|
|
1156
|
+
mod = CSSL.makemodule(main, payload, "mymod")
|
|
1157
|
+
|
|
1158
|
+
Args:
|
|
1159
|
+
script_type: "cssl" for main script, "cssl-pl" for payload
|
|
1160
|
+
code: The CSSL code
|
|
1161
|
+
*params: Optional parameters
|
|
1162
|
+
|
|
1163
|
+
Returns:
|
|
1164
|
+
CSSLScript object
|
|
1165
|
+
"""
|
|
1166
|
+
return get_cssl().script(script_type, code, *params)
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
def load(path: str, name: str) -> None:
|
|
1170
|
+
"""
|
|
1171
|
+
Load a .cssl or .cssl-pl file and register by name.
|
|
1172
|
+
|
|
1173
|
+
Usage:
|
|
1174
|
+
CSSL.load("utils.cssl-pl", "utils")
|
|
1175
|
+
CSSL.execute("utils")
|
|
1176
|
+
"""
|
|
1177
|
+
return get_cssl().load(path, name)
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
def execute(name: str, *args) -> Any:
|
|
1181
|
+
"""
|
|
1182
|
+
Execute a previously loaded script by name.
|
|
1183
|
+
|
|
1184
|
+
Usage:
|
|
1185
|
+
CSSL.load("utils.cssl-pl", "utils")
|
|
1186
|
+
result = CSSL.execute("utils", arg1, arg2)
|
|
1187
|
+
"""
|
|
1188
|
+
return get_cssl().execute(name, *args)
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
def include(path: str, name: str) -> None:
|
|
1192
|
+
"""
|
|
1193
|
+
Register a file for payload(name) access in CSSL.
|
|
1194
|
+
|
|
1195
|
+
Usage:
|
|
1196
|
+
CSSL.include("helpers.cssl-pl", "helpers")
|
|
1197
|
+
CSSL.run('payload("helpers");')
|
|
1198
|
+
"""
|
|
1199
|
+
return get_cssl().include(path, name)
|
|
788
1200
|
|
|
789
1201
|
|
|
790
1202
|
def set_global(name: str, value: Any) -> None:
|
|
@@ -808,7 +1220,9 @@ def clear_output() -> None:
|
|
|
808
1220
|
|
|
809
1221
|
|
|
810
1222
|
# Aliases to avoid conflict with Python builtin exec
|
|
1223
|
+
_run = run
|
|
811
1224
|
_exec = exec
|
|
1225
|
+
_T_run = T_run
|
|
812
1226
|
_T_exec = T_exec
|
|
813
1227
|
|
|
814
1228
|
|
|
@@ -832,43 +1246,58 @@ def module(code: str) -> CSSLModule:
|
|
|
832
1246
|
return get_cssl().module(code)
|
|
833
1247
|
|
|
834
1248
|
|
|
835
|
-
def makemodule(
|
|
1249
|
+
def makemodule(
|
|
1250
|
+
main_script: Union[str, CSSLScript],
|
|
1251
|
+
payload_script: Union[str, CSSLScript, None] = None,
|
|
1252
|
+
name: str = None
|
|
1253
|
+
) -> CSSLFunctionModule:
|
|
836
1254
|
"""
|
|
837
1255
|
Create a CSSL module with accessible functions.
|
|
838
1256
|
|
|
839
|
-
Usage:
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
return a + b;
|
|
844
|
-
}
|
|
1257
|
+
Usage (v3.8.0 - with CSSLScript):
|
|
1258
|
+
main = CSSL.script("cssl", '''printl("Main");''')
|
|
1259
|
+
payload = CSSL.script("cssl-pl", '''void helper() {}''')
|
|
1260
|
+
mod = CSSL.makemodule(main, payload, "mymod")
|
|
845
1261
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
}
|
|
1262
|
+
Usage (legacy - code string):
|
|
1263
|
+
math_mod = CSSL.makemodule('''
|
|
1264
|
+
int add(int a, int b) { return a + b; }
|
|
849
1265
|
''')
|
|
850
|
-
math_mod.add(2, 3)
|
|
851
|
-
math_mod.multiply(4, 5) # Returns 20
|
|
1266
|
+
math_mod.add(2, 3) # Returns 5
|
|
852
1267
|
|
|
853
1268
|
Args:
|
|
854
|
-
|
|
1269
|
+
main_script: Main CSSL code (string or CSSLScript)
|
|
1270
|
+
payload_script: Optional payload code (string or CSSLScript)
|
|
1271
|
+
name: Optional name to register for payload(name) access
|
|
855
1272
|
|
|
856
1273
|
Returns:
|
|
857
1274
|
CSSLFunctionModule - module with callable function attributes
|
|
858
1275
|
"""
|
|
859
|
-
return get_cssl().makemodule(
|
|
1276
|
+
return get_cssl().makemodule(main_script, payload_script, name)
|
|
860
1277
|
|
|
861
1278
|
|
|
862
1279
|
# Export all
|
|
863
1280
|
__all__ = [
|
|
864
1281
|
'CsslLang',
|
|
865
1282
|
'CSSLModule',
|
|
1283
|
+
'CSSLScript',
|
|
866
1284
|
'CSSLFunctionModule',
|
|
867
1285
|
'get_cssl',
|
|
1286
|
+
# v3.8.0 primary API
|
|
1287
|
+
'run',
|
|
1288
|
+
'_run',
|
|
1289
|
+
'T_run',
|
|
1290
|
+
'_T_run',
|
|
1291
|
+
'script',
|
|
1292
|
+
'load',
|
|
1293
|
+
'execute',
|
|
1294
|
+
'include',
|
|
1295
|
+
# Legacy (deprecated)
|
|
868
1296
|
'exec',
|
|
869
|
-
'_exec',
|
|
1297
|
+
'_exec',
|
|
870
1298
|
'T_exec',
|
|
871
|
-
'_T_exec',
|
|
1299
|
+
'_T_exec',
|
|
1300
|
+
# Other
|
|
872
1301
|
'set_global',
|
|
873
1302
|
'get_global',
|
|
874
1303
|
'get_output',
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "IncludeCPP"
|
|
7
|
-
version = "3.7.
|
|
7
|
+
version = "3.7.4"
|
|
8
8
|
description = "Professional C++ Python bindings with type-generic templates, pystubs and native threading"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -6,7 +6,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name="IncludeCPP",
|
|
9
|
-
version="3.7.
|
|
9
|
+
version="3.7.4",
|
|
10
10
|
author="Lilias Hatterscheidt",
|
|
11
11
|
author_email="lilias@includecpp.dev",
|
|
12
12
|
description="Professional C++ Python bindings with type-generic templates and native threading",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|