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.
@@ -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
- param_name = param['name'] if isinstance(param, dict) else param
889
-
890
- if param_name in kwargs:
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
- value = self._evaluate(node.value) if node.value else None
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
- # NEW: String interpolation - replace <variable> with scope values
1782
- if isinstance(value, str) and '<' in value and '>' in value:
1783
- value = self._interpolate_string(value)
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
- # NEW: String interpolation
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 - NEW
2864
+ """Replace {variable} and <variable> placeholders with values from scope.
2720
2865
 
2721
- Example: "Hello <name>!" becomes "Hello John!" if name = "John"
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
- return re.sub(pattern, replacer, string)
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):