IncludeCPP 3.4.8__py3-none-any.whl → 3.4.10__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 CHANGED
@@ -2,7 +2,7 @@ from .core.cpp_api import CppApi
2
2
  from .core import cssl_bridge as CSSL
3
3
  import warnings
4
4
 
5
- __version__ = "3.4.8"
5
+ __version__ = "3.4.10"
6
6
  __all__ = ["CppApi", "CSSL"]
7
7
 
8
8
  # Module-level cache for C++ modules
includecpp/__init__.pyi CHANGED
@@ -11,6 +11,9 @@ try:
11
11
  except ImportError:
12
12
  pass # Generated during rebuild
13
13
 
14
+ # CSSL module - CSO Service Script Language
15
+ from .core import cssl_bridge as CSSL
16
+
14
17
  __version__: str
15
18
 
16
19
  # Dynamic module access via: from includecpp import <module_name>
@@ -121,4 +124,4 @@ class CppApi:
121
124
  """List all available modules."""
122
125
  ...
123
126
 
124
- __all__: List[str]
127
+ __all__: List[str] # Includes: CppApi, CSSL, __version__
@@ -7455,9 +7455,8 @@ def cssl_exec(path, code):
7455
7455
  try:
7456
7456
  result = cssl_lang.exec(source)
7457
7457
 
7458
- # Print output buffer
7459
- for line in cssl_lang.get_output():
7460
- click.echo(line)
7458
+ # Output is already printed to stdout during execution via runtime.output()
7459
+ # No need to print buffer again - this was causing double output
7461
7460
 
7462
7461
  if result is not None:
7463
7462
  click.echo(f"Result: {result}")
@@ -19,9 +19,10 @@ from .cssl_parser import (
19
19
  from .cssl_runtime import CSSLRuntime, CSSLRuntimeError, CSSLServiceRunner, run_cssl, run_cssl_file
20
20
  from .cssl_types import (
21
21
  DataStruct, Shuffled, Iterator, Combo, DataSpace, OpenQuote,
22
- OpenFind, Parameter,
22
+ OpenFind, Parameter, Stack, Vector,
23
23
  create_datastruct, create_shuffled, create_iterator,
24
- create_combo, create_dataspace, create_openquote, create_parameter
24
+ create_combo, create_dataspace, create_openquote, create_parameter,
25
+ create_stack, create_vector
25
26
  )
26
27
 
27
28
  __all__ = [
@@ -34,7 +35,8 @@ __all__ = [
34
35
  'run_cssl', 'run_cssl_file',
35
36
  # Data Types
36
37
  'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
37
- 'OpenFind', 'Parameter',
38
+ 'OpenFind', 'Parameter', 'Stack', 'Vector',
38
39
  'create_datastruct', 'create_shuffled', 'create_iterator',
39
- 'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter'
40
+ 'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter',
41
+ 'create_stack', 'create_vector'
40
42
  ]
@@ -679,6 +679,44 @@ class CSSLParser:
679
679
  self.pos = saved_pos
680
680
  return False
681
681
 
682
+ def _looks_like_typed_variable(self) -> bool:
683
+ """Check if current position looks like a typed variable declaration.
684
+
685
+ Patterns:
686
+ - int x;
687
+ - stack<string> myStack;
688
+ - vector<int> nums = [1,2,3];
689
+
690
+ Distinguishes from function declarations by checking for '(' after identifier.
691
+ """
692
+ saved_pos = self.pos
693
+
694
+ # Check for type keyword
695
+ if self._check(TokenType.KEYWORD) and self._is_type_keyword(self._current().value):
696
+ self._advance()
697
+
698
+ # Skip generic type parameters <T>
699
+ if self._check(TokenType.COMPARE_LT):
700
+ depth = 1
701
+ self._advance()
702
+ while depth > 0 and not self._is_at_end():
703
+ if self._check(TokenType.COMPARE_LT):
704
+ depth += 1
705
+ elif self._check(TokenType.COMPARE_GT):
706
+ depth -= 1
707
+ self._advance()
708
+
709
+ # Check for identifier NOT followed by ( (that would be a function)
710
+ if self._check(TokenType.IDENTIFIER):
711
+ self._advance()
712
+ # If followed by '(' it's a function, not a variable
713
+ is_var = not self._check(TokenType.PAREN_START)
714
+ self.pos = saved_pos
715
+ return is_var
716
+
717
+ self.pos = saved_pos
718
+ return False
719
+
682
720
  def _parse_typed_function(self) -> ASTNode:
683
721
  """Parse C-style typed function declaration.
684
722
 
@@ -800,6 +838,78 @@ class CSSLParser:
800
838
  self._expect(TokenType.BLOCK_END)
801
839
  return node
802
840
 
841
+ def _looks_like_typed_variable(self) -> bool:
842
+ """Check if current position looks like a typed variable declaration:
843
+ type_name varName; or type_name<T> varName; or type_name varName = value;
844
+ """
845
+ # Save position
846
+ saved_pos = self.pos
847
+
848
+ # Must start with a type keyword (int, string, stack, vector, etc.)
849
+ if not self._check(TokenType.KEYWORD):
850
+ return False
851
+
852
+ type_name = self._current().value
853
+
854
+ # Skip known type keywords
855
+ type_keywords = {'int', 'string', 'float', 'bool', 'dynamic', 'void',
856
+ 'stack', 'vector', 'datastruct', 'dataspace', 'shuffled',
857
+ 'iterator', 'combo', 'array', 'openquote', 'json'}
858
+ if type_name not in type_keywords:
859
+ return False
860
+
861
+ self._advance()
862
+
863
+ # Check for optional generic <T>
864
+ if self._match(TokenType.COMPARE_LT):
865
+ # Skip until >
866
+ depth = 1
867
+ while depth > 0 and not self._is_at_end():
868
+ if self._check(TokenType.COMPARE_LT):
869
+ depth += 1
870
+ elif self._check(TokenType.COMPARE_GT):
871
+ depth -= 1
872
+ self._advance()
873
+
874
+ # Next should be an identifier (variable name), not '(' (function) or ';'
875
+ result = self._check(TokenType.IDENTIFIER)
876
+
877
+ # Restore position
878
+ self.pos = saved_pos
879
+ return result
880
+
881
+ def _parse_typed_variable(self) -> Optional[ASTNode]:
882
+ """Parse a typed variable declaration: type varName; or type<T> varName = value;"""
883
+ # Get type name
884
+ type_name = self._advance().value # Consume type keyword
885
+
886
+ # Check for generic type <T>
887
+ element_type = None
888
+ if self._match(TokenType.COMPARE_LT):
889
+ # Get element type
890
+ if self._check(TokenType.KEYWORD) or self._check(TokenType.IDENTIFIER):
891
+ element_type = self._advance().value
892
+ self._expect(TokenType.COMPARE_GT)
893
+
894
+ # Get variable name
895
+ if not self._check(TokenType.IDENTIFIER):
896
+ return None
897
+ var_name = self._advance().value
898
+
899
+ # Check for assignment or just declaration
900
+ value = None
901
+ if self._match(TokenType.EQUALS):
902
+ value = self._parse_expression()
903
+
904
+ self._match(TokenType.SEMICOLON)
905
+
906
+ return ASTNode('typed_declaration', value={
907
+ 'type': type_name,
908
+ 'element_type': element_type,
909
+ 'name': var_name,
910
+ 'value': value
911
+ })
912
+
803
913
  def parse_program(self) -> ASTNode:
804
914
  """Parse a standalone program (no service wrapper)"""
805
915
  root = ASTNode('program', children=[])
@@ -812,6 +922,11 @@ class CSSLParser:
812
922
  # Check for C-style typed function declarations
813
923
  elif self._looks_like_function_declaration():
814
924
  root.children.append(self._parse_typed_function())
925
+ # Check for typed variable declarations (int x;, stack<string> s;)
926
+ elif self._looks_like_typed_variable():
927
+ decl = self._parse_typed_variable()
928
+ if decl:
929
+ root.children.append(decl)
815
930
  # Handle service blocks
816
931
  elif self._match_keyword('service-init'):
817
932
  root.children.append(self._parse_service_init())
@@ -827,11 +942,15 @@ class CSSLParser:
827
942
  elif self._match_keyword('global'):
828
943
  stmt = self._parse_expression_statement()
829
944
  if stmt:
830
- root.children.append(stmt)
945
+ # Wrap in global_assignment to mark as global variable
946
+ global_stmt = ASTNode('global_assignment', value=stmt)
947
+ root.children.append(global_stmt)
831
948
  elif self._check(TokenType.GLOBAL_REF):
832
949
  stmt = self._parse_expression_statement()
833
950
  if stmt:
834
- root.children.append(stmt)
951
+ # Wrap in global_assignment to mark as global variable (same as 'global' keyword)
952
+ global_stmt = ASTNode('global_assignment', value=stmt)
953
+ root.children.append(global_stmt)
835
954
  # Handle statements
836
955
  elif self._check(TokenType.IDENTIFIER) or self._check(TokenType.AT) or self._check(TokenType.SELF_REF):
837
956
  stmt = self._parse_expression_statement()
@@ -1143,6 +1262,9 @@ class CSSLParser:
1143
1262
  elif self._match_keyword('define'):
1144
1263
  # Nested define function
1145
1264
  return self._parse_define()
1265
+ elif self._looks_like_typed_variable():
1266
+ # Typed variable declaration (e.g., stack<string> myStack;)
1267
+ return self._parse_typed_variable()
1146
1268
  elif self._looks_like_function_declaration():
1147
1269
  # Nested typed function (e.g., void Level2() { ... })
1148
1270
  return self._parse_typed_function()
@@ -1640,6 +1762,31 @@ class CSSLParser:
1640
1762
  node = ASTNode('call', value={'callee': node, 'args': args})
1641
1763
  return node
1642
1764
 
1765
+ if self._check(TokenType.GLOBAL_REF):
1766
+ # r@<name> global variable reference/declaration
1767
+ token = self._advance()
1768
+ node = ASTNode('global_ref', value=token.value, line=token.line, column=token.column)
1769
+ # Check for member access, calls, indexing
1770
+ while True:
1771
+ if self._match(TokenType.PAREN_START):
1772
+ args = []
1773
+ while not self._check(TokenType.PAREN_END):
1774
+ args.append(self._parse_expression())
1775
+ if not self._check(TokenType.PAREN_END):
1776
+ self._expect(TokenType.COMMA)
1777
+ self._expect(TokenType.PAREN_END)
1778
+ node = ASTNode('call', value={'callee': node, 'args': args})
1779
+ elif self._match(TokenType.DOT):
1780
+ member = self._advance().value
1781
+ node = ASTNode('member_access', value={'object': node, 'member': member})
1782
+ elif self._match(TokenType.BRACKET_START):
1783
+ index = self._parse_expression()
1784
+ self._expect(TokenType.BRACKET_END)
1785
+ node = ASTNode('index_access', value={'object': node, 'index': index})
1786
+ else:
1787
+ break
1788
+ return node
1789
+
1643
1790
  if self._check(TokenType.NUMBER):
1644
1791
  return ASTNode('literal', value=self._advance().value)
1645
1792
 
@@ -12,7 +12,10 @@ from .cssl_parser import ASTNode, parse_cssl, parse_cssl_program, CSSLSyntaxErro
12
12
  from .cssl_events import CSSLEventManager, EventType, EventData, get_event_manager
13
13
  from .cssl_builtins import CSSLBuiltins
14
14
  from .cssl_modules import get_module_registry, get_standard_module
15
- from .cssl_types import Parameter, DataStruct, Shuffled, Iterator, Combo
15
+ from .cssl_types import (
16
+ Parameter, DataStruct, Shuffled, Iterator, Combo,
17
+ Stack, Vector, DataSpace, OpenQuote
18
+ )
16
19
 
17
20
 
18
21
  class CSSLRuntimeError(Exception):
@@ -291,6 +294,12 @@ class CSSLRuntime:
291
294
  self._exec_struct(child)
292
295
  elif child.type == 'function':
293
296
  self._exec_function(child)
297
+ elif child.type == 'global_assignment':
298
+ # Handle global variable declaration: global Name = value
299
+ result = self._exec_global_assignment(child)
300
+ elif child.type == 'typed_declaration':
301
+ # Handle typed variable declaration: type<T> varName = value;
302
+ result = self._exec_typed_declaration(child)
294
303
  elif child.type in ('assignment', 'expression', 'inject', 'receive', 'flow',
295
304
  'if', 'while', 'for', 'foreach', 'switch', 'try'):
296
305
  result = self._execute_node(child)
@@ -564,6 +573,103 @@ class CSSLRuntime:
564
573
  self.scope.set(func_name, node)
565
574
  return None
566
575
 
576
+ def _exec_typed_declaration(self, node: ASTNode) -> Any:
577
+ """Execute typed variable declaration: type<T> varName = value;
578
+
579
+ Creates appropriate type instances for stack, vector, datastruct, etc.
580
+ """
581
+ decl = node.value
582
+ type_name = decl.get('type')
583
+ element_type = decl.get('element_type', 'dynamic')
584
+ var_name = decl.get('name')
585
+ value_node = decl.get('value')
586
+
587
+ # Create the appropriate type instance
588
+ if type_name == 'stack':
589
+ instance = Stack(element_type)
590
+ elif type_name == 'vector':
591
+ instance = Vector(element_type)
592
+ elif type_name == 'datastruct':
593
+ instance = DataStruct(element_type)
594
+ elif type_name == 'shuffled':
595
+ instance = Shuffled(element_type)
596
+ elif type_name == 'iterator':
597
+ instance = Iterator(element_type)
598
+ elif type_name == 'combo':
599
+ instance = Combo(element_type)
600
+ elif type_name == 'dataspace':
601
+ instance = DataSpace(element_type)
602
+ elif type_name == 'openquote':
603
+ instance = OpenQuote()
604
+ elif type_name in ('int', 'integer'):
605
+ instance = 0 if value_node is None else self._evaluate(value_node)
606
+ elif type_name in ('string', 'str'):
607
+ instance = "" if value_node is None else self._evaluate(value_node)
608
+ elif type_name in ('float', 'double'):
609
+ instance = 0.0 if value_node is None else self._evaluate(value_node)
610
+ elif type_name == 'bool':
611
+ instance = False if value_node is None else self._evaluate(value_node)
612
+ elif type_name == 'dynamic':
613
+ instance = None if value_node is None else self._evaluate(value_node)
614
+ elif type_name == 'json':
615
+ instance = {} if value_node is None else self._evaluate(value_node)
616
+ elif type_name == 'array':
617
+ instance = [] if value_node is None else self._evaluate(value_node)
618
+ else:
619
+ # Default: evaluate the value or set to None
620
+ instance = self._evaluate(value_node) if value_node else None
621
+
622
+ # If there's an explicit value, use it instead
623
+ if value_node and type_name not in ('int', 'integer', 'string', 'str', 'float', 'double', 'bool', 'dynamic', 'json', 'array'):
624
+ # For container types, the value might be initialization data
625
+ init_value = self._evaluate(value_node)
626
+ if isinstance(init_value, (list, tuple)):
627
+ instance.extend(init_value)
628
+ elif init_value is not None:
629
+ if hasattr(instance, 'append'):
630
+ instance.append(init_value)
631
+
632
+ # Store in scope
633
+ self.scope.set(var_name, instance)
634
+ return instance
635
+
636
+ def _exec_global_assignment(self, node: ASTNode) -> Any:
637
+ """Execute global variable assignment: global Name = value
638
+
639
+ Stores the value in _promoted_globals so it can be accessed via @Name
640
+ """
641
+ inner = node.value # The wrapped assignment/expression node
642
+
643
+ if inner is None:
644
+ return None
645
+
646
+ # Handle assignment node: global Name = value
647
+ if inner.type == 'assignment':
648
+ target = inner.value.get('target')
649
+ value = self._evaluate(inner.value.get('value'))
650
+
651
+ # Get variable name from target
652
+ if isinstance(target, ASTNode) and target.type == 'identifier':
653
+ var_name = target.value
654
+ elif isinstance(target, str):
655
+ var_name = target
656
+ else:
657
+ var_name = str(target)
658
+
659
+ # Store in promoted globals for @Name access
660
+ self._promoted_globals[var_name] = value
661
+ # Also store in global scope for regular access
662
+ self.global_scope.set(var_name, value)
663
+ return value
664
+
665
+ # Handle expression that results in assignment
666
+ elif inner.type == 'expression':
667
+ result = self._evaluate(inner.value)
668
+ return result
669
+
670
+ # Fallback: execute normally
671
+ return self._execute_node(inner)
672
+
567
673
  def _call_function(self, func_node: ASTNode, args: List[Any]) -> Any:
568
674
  """Call a function node with arguments"""
569
675
  func_info = func_node.value
@@ -1094,6 +1200,10 @@ class CSSLRuntime:
1094
1200
  if isinstance(target, ASTNode):
1095
1201
  if target.type == 'identifier':
1096
1202
  self.scope.set(target.value, value)
1203
+ elif target.type == 'global_ref':
1204
+ # r@Name = value - store in promoted globals
1205
+ self._promoted_globals[target.value] = value
1206
+ self.global_scope.set(target.value, value)
1097
1207
  elif target.type == 'member_access':
1098
1208
  self._set_member(target, value)
1099
1209
  elif target.type == 'index_access':
@@ -1177,12 +1287,26 @@ class CSSLRuntime:
1177
1287
  return value
1178
1288
 
1179
1289
  if node.type == 'module_ref':
1180
- return self.get_module(node.value)
1290
+ # Check modules first, then promoted globals, then scope
1291
+ value = self.get_module(node.value)
1292
+ if value is None:
1293
+ value = self._promoted_globals.get(node.value)
1294
+ if value is None:
1295
+ value = self.global_scope.get(node.value)
1296
+ return value
1181
1297
 
1182
1298
  if node.type == 'self_ref':
1183
1299
  # s@<name> reference to global struct
1184
1300
  return self.get_global_struct(node.value)
1185
1301
 
1302
+ if node.type == 'global_ref':
1303
+ # r@<name> global variable reference
1304
+ # Check promoted globals first, then global scope
1305
+ value = self._promoted_globals.get(node.value)
1306
+ if value is None:
1307
+ value = self.global_scope.get(node.value)
1308
+ return value
1309
+
1186
1310
  if node.type == 'binary':
1187
1311
  return self._eval_binary(node)
1188
1312
 
@@ -1290,6 +1414,11 @@ class CSSLRuntime:
1290
1414
  if obj is None:
1291
1415
  return None
1292
1416
 
1417
+ # Special handling for Parameter.return() -> Parameter.return_()
1418
+ # since 'return' is a Python keyword
1419
+ if isinstance(obj, Parameter) and member == 'return':
1420
+ member = 'return_'
1421
+
1293
1422
  if hasattr(obj, member):
1294
1423
  return getattr(obj, member)
1295
1424
 
@@ -65,6 +65,90 @@ class DataStruct(list):
65
65
  return None
66
66
 
67
67
 
68
+ class Stack(list):
69
+ """Stack data structure (LIFO).
70
+
71
+ Standard stack with push/pop operations.
72
+
73
+ Usage:
74
+ stack<string> myStack;
75
+ myStack.push("Item1");
76
+ myStack.push("Item2");
77
+ item = myStack.pop(); # Returns "Item2"
78
+ """
79
+
80
+ def __init__(self, element_type: str = 'dynamic'):
81
+ super().__init__()
82
+ self._element_type = element_type
83
+
84
+ def push(self, item: Any) -> 'Stack':
85
+ """Push item onto stack"""
86
+ self.append(item)
87
+ return self
88
+
89
+ def peek(self) -> Any:
90
+ """View top item without removing"""
91
+ return self[-1] if self else None
92
+
93
+ def is_empty(self) -> bool:
94
+ """Check if stack is empty"""
95
+ return len(self) == 0
96
+
97
+ def size(self) -> int:
98
+ """Return stack size"""
99
+ return len(self)
100
+
101
+
102
+ class Vector(list):
103
+ """Dynamic array (vector) data structure.
104
+
105
+ Resizable array with efficient random access.
106
+
107
+ Usage:
108
+ vector<int> myVector;
109
+ myVector.push(1);
110
+ myVector.push(2);
111
+ myVector.at(0); # Returns 1
112
+ """
113
+
114
+ def __init__(self, element_type: str = 'dynamic'):
115
+ super().__init__()
116
+ self._element_type = element_type
117
+
118
+ def push(self, item: Any) -> 'Vector':
119
+ """Add item to end"""
120
+ self.append(item)
121
+ return self
122
+
123
+ def at(self, index: int) -> Any:
124
+ """Get item at index"""
125
+ if 0 <= index < len(self):
126
+ return self[index]
127
+ return None
128
+
129
+ def set(self, index: int, value: Any) -> 'Vector':
130
+ """Set item at index"""
131
+ if 0 <= index < len(self):
132
+ self[index] = value
133
+ return self
134
+
135
+ def size(self) -> int:
136
+ """Return vector size"""
137
+ return len(self)
138
+
139
+ def empty(self) -> bool:
140
+ """Check if vector is empty"""
141
+ return len(self) == 0
142
+
143
+ def front(self) -> Any:
144
+ """Get first element"""
145
+ return self[0] if self else None
146
+
147
+ def back(self) -> Any:
148
+ """Get last element"""
149
+ return self[-1] if self else None
150
+
151
+
68
152
  class Shuffled(list):
69
153
  """Unorganized fast storage for multiple returns.
70
154
 
@@ -356,10 +440,13 @@ class Parameter:
356
440
  parameter.get(1) # Get second argument
357
441
  parameter.count() # Get total argument count
358
442
  parameter.all() # Get all arguments as list
443
+ parameter.return(value) # Yield a return value (generator-like)
444
+ parameter.returns() # Get all yielded return values
359
445
  """
360
446
 
361
447
  def __init__(self, args: List[Any] = None):
362
448
  self._args = args if args is not None else []
449
+ self._returns: List[Any] = []
363
450
 
364
451
  def get(self, index: int, default: Any = None) -> Any:
365
452
  """Get argument at index, returns default if not found"""
@@ -379,6 +466,27 @@ class Parameter:
379
466
  """Check if argument exists at index"""
380
467
  return 0 <= index < len(self._args)
381
468
 
469
+ # Using 'return_' to avoid Python keyword conflict
470
+ def return_(self, value: Any) -> None:
471
+ """Yield a return value (generator-like behavior).
472
+
473
+ Multiple calls accumulate values that can be retrieved via returns().
474
+ The CSSL runtime will collect these as the exec() return value.
475
+ """
476
+ self._returns.append(value)
477
+
478
+ def returns(self) -> List[Any]:
479
+ """Get all yielded return values"""
480
+ return list(self._returns)
481
+
482
+ def clear_returns(self) -> None:
483
+ """Clear all yielded return values"""
484
+ self._returns.clear()
485
+
486
+ def has_returns(self) -> bool:
487
+ """Check if any values have been returned"""
488
+ return len(self._returns) > 0
489
+
382
490
  def __iter__(self):
383
491
  return iter(self._args)
384
492
 
@@ -424,15 +532,21 @@ def create_dataspace(space_type: str = 'dynamic') -> DataSpace:
424
532
  def create_openquote(db_ref: Any = None) -> OpenQuote:
425
533
  return OpenQuote(db_ref)
426
534
 
535
+ def create_stack(element_type: str = 'dynamic') -> Stack:
536
+ return Stack(element_type)
427
537
 
428
- __all__ = [
429
- 'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
430
- 'OpenFind', 'Parameter',
431
- 'create_datastruct', 'create_shuffled', 'create_iterator',
432
- 'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter'
433
- ]
434
-
538
+ def create_vector(element_type: str = 'dynamic') -> Vector:
539
+ return Vector(element_type)
435
540
 
436
541
  def create_parameter(args: List[Any] = None) -> Parameter:
437
542
  """Create a Parameter object for accessing exec arguments"""
438
543
  return Parameter(args)
544
+
545
+
546
+ __all__ = [
547
+ 'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
548
+ 'OpenFind', 'Parameter', 'Stack', 'Vector',
549
+ 'create_datastruct', 'create_shuffled', 'create_iterator',
550
+ 'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter',
551
+ 'create_stack', 'create_vector'
552
+ ]
@@ -144,7 +144,8 @@ class CsslLang:
144
144
  *args: Arguments to pass to the script
145
145
 
146
146
  Returns:
147
- Execution result
147
+ Execution result. If parameter.return() was called, returns
148
+ the list of returned values (or single value if only one).
148
149
  """
149
150
  runtime = self._get_runtime()
150
151
 
@@ -157,13 +158,21 @@ class CsslLang:
157
158
 
158
159
  # Set arguments in runtime scope
159
160
  from .cssl import Parameter
161
+ param = Parameter(list(args))
160
162
  runtime.global_scope.set('args', list(args))
161
163
  runtime.global_scope.set('argc', len(args))
162
- runtime.global_scope.set('parameter', Parameter(list(args)))
164
+ runtime.global_scope.set('parameter', param)
163
165
 
164
166
  # Execute as standalone program
165
167
  try:
166
168
  result = runtime.execute_program(source)
169
+
170
+ # Check if parameter.return() was used (generator-like returns)
171
+ if param.has_returns():
172
+ returns = param.returns()
173
+ # Return single value if only one, else return list
174
+ return returns[0] if len(returns) == 1 else returns
175
+
167
176
  return result
168
177
  except Exception as e:
169
178
  raise RuntimeError(f"CSSL Error: {e}") from e
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.4.8
3
+ Version: 3.4.10
4
4
  Summary: Professional C++ Python bindings with type-generic templates, pystubs and native threading
5
5
  Home-page: https://github.com/liliassg/IncludeCPP
6
6
  Author: Lilias Hatterscheidt
@@ -1,9 +1,9 @@
1
- includecpp/__init__.py,sha256=JTm6AEIeXuM8WBahVIQD_rsuZg0rVRpdDumCb5xmRkk,1672
2
- includecpp/__init__.pyi,sha256=gNfQTFiM0z-Z2xazX7Hk5ULtW44lEU2j6hGEipcipMY,3637
1
+ includecpp/__init__.py,sha256=ADg4AjowwcXWGRAZLfuz0f494MvuL2vD7Ry4-LtbIBg,1673
2
+ includecpp/__init__.pyi,sha256=SBHwNvqWSUj0c_oS0uVGoOv25uYUOYtORFMxKiN0pkY,3762
3
3
  includecpp/__main__.py,sha256=d6QK0PkvUe1ENofpmHRAg3bwNbZr8PiRscfI3-WRfVg,72
4
4
  includecpp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  includecpp/cli/__init__.py,sha256=Yda-4a5QJb_tKu35YQNfc5lu-LewTsM5abqNNkzS47M,113
6
- includecpp/cli/commands.py,sha256=90-L9iy4qIvyZR5KlMPSI5YNN7cb_1e6D5p-MTPkYJo,316845
6
+ includecpp/cli/commands.py,sha256=7ozSW7IyUaCoSY1tC0-ieV1TYNP37g7kSoG16XmOkZY,316898
7
7
  includecpp/cli/config_parser.py,sha256=KveeYUg2TA9sC5hKVzYYfgdNm2WfLG5y7_yxgBWn9yM,4886
8
8
  includecpp/core/__init__.py,sha256=L1bT6oikTjdto-6Px7DpjePtM07ymo3Bnov1saZzsGg,390
9
9
  includecpp/core/ai_integration.py,sha256=PW6yFDqdXjfchpfKTKg59AOLhLry9kqJEGf_65BztrY,87603
@@ -11,7 +11,7 @@ includecpp/core/build_manager.py,sha256=uLuYsuiC6OsOGaU5wAJfl4M3IbdnIDgogfMd8VsV
11
11
  includecpp/core/cpp_api.py,sha256=8y_B1L18rhSBZln654xPPzqO2PdvAlLpJrfEjzl7Wnc,14039
12
12
  includecpp/core/cpp_api.pyi,sha256=IEiaKqaPItnn6rjL7aK32D3o9FYmRYCgCZbqiQNUwdc,3496
13
13
  includecpp/core/cppy_converter.py,sha256=b7yqu-aoa0wShNY0GvQT67TnNhYya4GyYmG7oDdqDV4,156686
14
- includecpp/core/cssl_bridge.py,sha256=PRpXXGj4LfAbeNcFeL5XeCU6wiyavRaxBs5RfR8dYnU,12198
14
+ includecpp/core/cssl_bridge.py,sha256=HpnMbX4lnGCuQq8ZjnvLSfqd-wrobMF5szhQM4T2RGI,12635
15
15
  includecpp/core/cssl_bridge.pyi,sha256=Q4zjc2Kf2wPJPnfgHS-koPEon3Kty6o3mCvp9E5Q8tE,7635
16
16
  includecpp/core/error_catalog.py,sha256=VS3N-P0yEbiHimsDPtcaYfrUb7mXQ-7pqw18PtSngaU,33869
17
17
  includecpp/core/error_formatter.py,sha256=7-MzRIT8cM4uODxy0IZ9pu7pqR4Pq2I8Si0QQZHjmVc,39239
@@ -19,23 +19,23 @@ includecpp/core/exceptions.py,sha256=szeF4qdzi_q8hBBZi7mJxkliyQ0crplkLYe0ymlBGtk
19
19
  includecpp/core/path_discovery.py,sha256=jI0oSq6Hsd4LKXmU4dOiGSrXcEO_KWMXfQ5_ylBmXvU,2561
20
20
  includecpp/core/project_ui.py,sha256=la2EQZKmUkJGuJxnbs09hH1ZhBh9bfndo6okzZsk2dQ,141134
21
21
  includecpp/core/settings_ui.py,sha256=B2SlwgdplF2KiBk5UYf2l8Jjifjd0F-FmBP0DPsVCEQ,11798
22
- includecpp/core/cssl/__init__.py,sha256=YrlKTifbmdjofU7yGsRPSXw3rwFvTDb2Ic1kq6C3cD0,1613
22
+ includecpp/core/cssl/__init__.py,sha256=Z63V6GjWMyd61WpdoAd-hA_ZB3kgIw2RvA-RR35WBEc,1719
23
23
  includecpp/core/cssl/cssl_builtins.py,sha256=PDz4FoWqNdGjBTBLKJ2fc8SqFKpprSey_9gZxV19tIE,61896
24
24
  includecpp/core/cssl/cssl_events.py,sha256=nupIcXW_Vjdud7zCU6hdwkQRQ0MujlPM7Tk2u7eDAiY,21013
25
25
  includecpp/core/cssl/cssl_modules.py,sha256=cUg0-zdymMnWWTsA_BUrW5dx4R04dHpKcUhm-Wfiwwo,103006
26
- includecpp/core/cssl/cssl_parser.py,sha256=T7CfbhdqmxtQEw0BjPZ5kUUsWFBcEsSHGppxl8K_Fj4,73112
27
- includecpp/core/cssl/cssl_runtime.py,sha256=VjncRlNDuZWrEKdqpKB7RyLEBucJAzIOb71EUI-6jRM,60945
26
+ includecpp/core/cssl/cssl_parser.py,sha256=B52QW-Cc9GBmoJGlqNlmEBq1-3cHcztVbUWNR4KuTH4,79259
27
+ includecpp/core/cssl/cssl_runtime.py,sha256=zvhWTGIkjTxKuQBjouGO6T7miyfSL1vGCXa3RQ7v60c,66626
28
28
  includecpp/core/cssl/cssl_syntax.py,sha256=vgI-dgj6gs9cOHwNRff6JbwZZYW_fYutnwCkznlgZiE,17006
29
- includecpp/core/cssl/cssl_types.py,sha256=G27Gk_xLHvIaAez8P-D8-cEGvGkKf5_acDdQmV3FWs8,14490
29
+ includecpp/core/cssl/cssl_types.py,sha256=-4kevtcUSqjCX9v6TzA_eHW3ZqaeKjEAIc92dGIAodc,17765
30
30
  includecpp/generator/__init__.py,sha256=Rsy41bwimaEloD3gDRR_znPfIJzIsCFuWZgCTJBLJlc,62
31
31
  includecpp/generator/parser.cpp,sha256=CxVpsBDb22yDaVqp0ljh7dFKBTGlUj65apUGtPRMu0s,76829
32
32
  includecpp/generator/parser.h,sha256=EDm0b-pEesIIIQQ2PvH5h2qwlqJU9BH8SiMV7MWbsTo,11073
33
33
  includecpp/generator/type_resolver.cpp,sha256=MmFK_4HXd1wqxALDiDyXVuU397SXoQL_o5zb_8N8Hzs,12346
34
34
  includecpp/generator/type_resolver.h,sha256=ZsaxQqcCcKJJApYn7KOp2dLlQ1VFVG_oZDjaK5LhBSg,2590
35
35
  includecpp/templates/cpp.proj.template,sha256=Iy-L8I4Cl3tIgBMx1Qp5h6gURvkqOAqyodVHuDJ0Luw,359
36
- includecpp-3.4.8.dist-info/licenses/LICENSE,sha256=fWCsGGsiWZir0UzDd20Hh-3wtRyk1zqUntvtVuAWhvc,1093
37
- includecpp-3.4.8.dist-info/METADATA,sha256=906TSNdXml6v_XL747RrNER-_Ibf-QzS9RDbnr3NbfQ,26654
38
- includecpp-3.4.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
- includecpp-3.4.8.dist-info/entry_points.txt,sha256=6A5Mif9gi0139Bf03W5plAb3wnAgbNaEVe1HJoGE-2o,59
40
- includecpp-3.4.8.dist-info/top_level.txt,sha256=RFUaR1KG-M6mCYwP6w4ydP5Cgc8yNbP78jxGAvyjMa8,11
41
- includecpp-3.4.8.dist-info/RECORD,,
36
+ includecpp-3.4.10.dist-info/licenses/LICENSE,sha256=fWCsGGsiWZir0UzDd20Hh-3wtRyk1zqUntvtVuAWhvc,1093
37
+ includecpp-3.4.10.dist-info/METADATA,sha256=Pu0j0edS2IRiuGTQA6nIAhYDgBsbq3oddp6TMnDdn1E,26655
38
+ includecpp-3.4.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
+ includecpp-3.4.10.dist-info/entry_points.txt,sha256=6A5Mif9gi0139Bf03W5plAb3wnAgbNaEVe1HJoGE-2o,59
40
+ includecpp-3.4.10.dist-info/top_level.txt,sha256=RFUaR1KG-M6mCYwP6w4ydP5Cgc8yNbP78jxGAvyjMa8,11
41
+ includecpp-3.4.10.dist-info/RECORD,,