IncludeCPP 3.7.1__py3-none-any.whl → 3.7.9__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/cli/commands.py +172 -11
- includecpp/core/cssl/CSSL_DOCUMENTATION.md +27 -8
- includecpp/core/cssl/cssl_parser.py +174 -11
- includecpp/core/cssl/cssl_runtime.py +183 -15
- includecpp/core/cssl_bridge.py +477 -48
- includecpp/vscode/cssl/language-configuration.json +1 -4
- includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +183 -22
- {includecpp-3.7.1.dist-info → includecpp-3.7.9.dist-info}/METADATA +1 -1
- {includecpp-3.7.1.dist-info → includecpp-3.7.9.dist-info}/RECORD +14 -14
- {includecpp-3.7.1.dist-info → includecpp-3.7.9.dist-info}/WHEEL +0 -0
- {includecpp-3.7.1.dist-info → includecpp-3.7.9.dist-info}/entry_points.txt +0 -0
- {includecpp-3.7.1.dist-info → includecpp-3.7.9.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.7.1.dist-info → includecpp-3.7.9.dist-info}/top_level.txt +0 -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
|
|
|
@@ -884,10 +963,20 @@ class CSSLRuntime:
|
|
|
884
963
|
|
|
885
964
|
# Bind parameters - handle both positional and named arguments
|
|
886
965
|
for i, param in enumerate(params):
|
|
887
|
-
# Extract param name from dict format: {'name': 'a', 'type': 'int'}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
966
|
+
# Extract param name and type from dict format: {'name': 'a', 'type': 'int'}
|
|
967
|
+
if isinstance(param, dict):
|
|
968
|
+
param_name = param['name']
|
|
969
|
+
param_type = param.get('type', '')
|
|
970
|
+
else:
|
|
971
|
+
param_name = param
|
|
972
|
+
param_type = ''
|
|
973
|
+
|
|
974
|
+
# Check if this is an 'open' parameter - receives all args as a list
|
|
975
|
+
if param_type == 'open' or param_name == 'Params':
|
|
976
|
+
# 'open Params' receives all arguments as a list
|
|
977
|
+
new_scope.set(param_name, list(args))
|
|
978
|
+
new_scope.set('Params', list(args)) # Also set 'Params' for OpenFind
|
|
979
|
+
elif param_name in kwargs:
|
|
891
980
|
# Named argument takes priority
|
|
892
981
|
new_scope.set(param_name, kwargs[param_name])
|
|
893
982
|
elif i < len(args):
|
|
@@ -1097,8 +1186,20 @@ class CSSLRuntime:
|
|
|
1097
1186
|
return None
|
|
1098
1187
|
|
|
1099
1188
|
def _exec_return(self, node: ASTNode) -> Any:
|
|
1100
|
-
"""Execute return statement
|
|
1101
|
-
|
|
1189
|
+
"""Execute return statement.
|
|
1190
|
+
|
|
1191
|
+
Supports multiple return values for shuffled functions:
|
|
1192
|
+
return a, b, c; // Returns tuple (a, b, c)
|
|
1193
|
+
"""
|
|
1194
|
+
if node.value is None:
|
|
1195
|
+
raise CSSLReturn(None)
|
|
1196
|
+
|
|
1197
|
+
# Check if this is a multiple return value
|
|
1198
|
+
if isinstance(node.value, dict) and node.value.get('multiple'):
|
|
1199
|
+
values = [self._evaluate(v) for v in node.value.get('values', [])]
|
|
1200
|
+
raise CSSLReturn(tuple(values))
|
|
1201
|
+
|
|
1202
|
+
value = self._evaluate(node.value)
|
|
1102
1203
|
raise CSSLReturn(value)
|
|
1103
1204
|
|
|
1104
1205
|
def _exec_break(self, node: ASTNode) -> Any:
|
|
@@ -1725,6 +1826,36 @@ class CSSLRuntime:
|
|
|
1725
1826
|
|
|
1726
1827
|
return value
|
|
1727
1828
|
|
|
1829
|
+
def _exec_tuple_assignment(self, node: ASTNode) -> Any:
|
|
1830
|
+
"""Execute tuple unpacking assignment: a, b, c = shuffled_func()
|
|
1831
|
+
|
|
1832
|
+
Used with shuffled functions that return multiple values.
|
|
1833
|
+
"""
|
|
1834
|
+
targets = node.value.get('targets', [])
|
|
1835
|
+
value = self._evaluate(node.value.get('value'))
|
|
1836
|
+
|
|
1837
|
+
# Convert value to list if it's a tuple or iterable
|
|
1838
|
+
if isinstance(value, (list, tuple)):
|
|
1839
|
+
values = list(value)
|
|
1840
|
+
elif hasattr(value, '__iter__') and not isinstance(value, (str, dict)):
|
|
1841
|
+
values = list(value)
|
|
1842
|
+
else:
|
|
1843
|
+
# Single value - assign to first target only
|
|
1844
|
+
values = [value]
|
|
1845
|
+
|
|
1846
|
+
# Assign values to targets
|
|
1847
|
+
for i, target in enumerate(targets):
|
|
1848
|
+
if i < len(values):
|
|
1849
|
+
var_name = target.value if isinstance(target, ASTNode) else target
|
|
1850
|
+
self.scope.set(var_name, values[i])
|
|
1851
|
+
else:
|
|
1852
|
+
# More targets than values - set to None
|
|
1853
|
+
var_name = target.value if isinstance(target, ASTNode) else target
|
|
1854
|
+
self.scope.set(var_name, None)
|
|
1855
|
+
|
|
1856
|
+
# Assignment statements don't produce a visible result
|
|
1857
|
+
return None
|
|
1858
|
+
|
|
1728
1859
|
def _exec_expression(self, node: ASTNode) -> Any:
|
|
1729
1860
|
"""Execute expression statement"""
|
|
1730
1861
|
return self._evaluate(node.value)
|
|
@@ -1778,9 +1909,12 @@ class CSSLRuntime:
|
|
|
1778
1909
|
|
|
1779
1910
|
if node.type == 'literal':
|
|
1780
1911
|
value = node.value
|
|
1781
|
-
#
|
|
1782
|
-
if isinstance(value, str)
|
|
1783
|
-
|
|
1912
|
+
# String interpolation - replace {var} or <var> with scope values
|
|
1913
|
+
if isinstance(value, str):
|
|
1914
|
+
has_fstring = '{' in value and '}' in value
|
|
1915
|
+
has_legacy = '<' in value and '>' in value
|
|
1916
|
+
if has_fstring or has_legacy:
|
|
1917
|
+
value = self._interpolate_string(value)
|
|
1784
1918
|
return value
|
|
1785
1919
|
|
|
1786
1920
|
# NEW: Type literals (list, dict) - create empty instances
|
|
@@ -1890,9 +2024,11 @@ class CSSLRuntime:
|
|
|
1890
2024
|
return self._eval_this_access(node)
|
|
1891
2025
|
|
|
1892
2026
|
if node.type == 'type_instantiation':
|
|
1893
|
-
# Create new instance of a type: stack<string>, vector<int>, etc.
|
|
2027
|
+
# Create new instance of a type: stack<string>, vector<int>, map<K,V>, etc.
|
|
1894
2028
|
type_name = node.value.get('type')
|
|
1895
2029
|
element_type = node.value.get('element_type', 'dynamic')
|
|
2030
|
+
value_type = node.value.get('value_type') # For map<K, V>
|
|
2031
|
+
init_values = node.value.get('init_values') # For inline init: map<K,V>{...}
|
|
1896
2032
|
|
|
1897
2033
|
if type_name == 'stack':
|
|
1898
2034
|
return Stack(element_type)
|
|
@@ -1916,6 +2052,15 @@ class CSSLRuntime:
|
|
|
1916
2052
|
return List(element_type)
|
|
1917
2053
|
elif type_name in ('dictionary', 'dict'):
|
|
1918
2054
|
return Dictionary(element_type)
|
|
2055
|
+
elif type_name == 'map':
|
|
2056
|
+
# Create Map with key_type and value_type
|
|
2057
|
+
m = Map(element_type, value_type or 'dynamic')
|
|
2058
|
+
# If inline initialization provided, populate the map
|
|
2059
|
+
if init_values:
|
|
2060
|
+
for key, value_node in init_values.items():
|
|
2061
|
+
value = self._evaluate(value_node)
|
|
2062
|
+
m.insert(key, value)
|
|
2063
|
+
return m
|
|
1919
2064
|
else:
|
|
1920
2065
|
return None
|
|
1921
2066
|
|
|
@@ -2714,14 +2859,24 @@ class CSSLRuntime:
|
|
|
2714
2859
|
elif isinstance(obj, dict):
|
|
2715
2860
|
obj[final_attr] = value
|
|
2716
2861
|
|
|
2717
|
-
#
|
|
2862
|
+
# String interpolation (supports both <var> and {var} syntax)
|
|
2718
2863
|
def _interpolate_string(self, string: str) -> str:
|
|
2719
|
-
"""Replace <variable> placeholders with values from scope
|
|
2864
|
+
"""Replace {variable} and <variable> placeholders with values from scope.
|
|
2720
2865
|
|
|
2721
|
-
|
|
2866
|
+
Both syntaxes are supported (variables only, not expressions):
|
|
2867
|
+
"Hello {name}!" -> "Hello John!" (f-string style)
|
|
2868
|
+
"Hello <name>!" -> "Hello John!" (legacy CSSL style)
|
|
2869
|
+
|
|
2870
|
+
Examples:
|
|
2871
|
+
string name = "Alice";
|
|
2872
|
+
int age = 30;
|
|
2873
|
+
printl("Hello {name}, you are {age} years old!");
|
|
2874
|
+
printl("Hello <name>, you are <age> years old!");
|
|
2875
|
+
|
|
2876
|
+
Note: Only simple variable names are supported, not expressions.
|
|
2877
|
+
Use string concatenation for complex expressions.
|
|
2722
2878
|
"""
|
|
2723
2879
|
import re
|
|
2724
|
-
pattern = r'<([A-Za-z_][A-Za-z0-9_]*)>'
|
|
2725
2880
|
|
|
2726
2881
|
def replacer(match):
|
|
2727
2882
|
var_name = match.group(1)
|
|
@@ -2733,10 +2888,23 @@ class CSSLRuntime:
|
|
|
2733
2888
|
# Try modules
|
|
2734
2889
|
if value is None:
|
|
2735
2890
|
value = self._modules.get(var_name)
|
|
2891
|
+
# Try global scope
|
|
2892
|
+
if value is None:
|
|
2893
|
+
value = self.global_scope.get(var_name)
|
|
2736
2894
|
# Return string representation or empty string if None
|
|
2737
2895
|
return str(value) if value is not None else ''
|
|
2738
2896
|
|
|
2739
|
-
|
|
2897
|
+
# Support both {var} and <var> syntax - simple variable names only
|
|
2898
|
+
# Pattern: {identifier} or <identifier>
|
|
2899
|
+
patterns = [
|
|
2900
|
+
r'\{([A-Za-z_][A-Za-z0-9_]*)\}', # {name} f-string style
|
|
2901
|
+
r'<([A-Za-z_][A-Za-z0-9_]*)>', # <name> legacy CSSL style
|
|
2902
|
+
]
|
|
2903
|
+
|
|
2904
|
+
result = string
|
|
2905
|
+
for pattern in patterns:
|
|
2906
|
+
result = re.sub(pattern, replacer, result)
|
|
2907
|
+
return result
|
|
2740
2908
|
|
|
2741
2909
|
# NEW: Promote variable to global scope via global()
|
|
2742
2910
|
def promote_to_global(self, s_ref_name: str):
|