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 +1 -1
- includecpp/__init__.pyi +4 -1
- includecpp/cli/commands.py +2 -3
- includecpp/core/cssl/__init__.py +6 -4
- includecpp/core/cssl/cssl_parser.py +149 -2
- includecpp/core/cssl/cssl_runtime.py +131 -2
- includecpp/core/cssl/cssl_types.py +121 -7
- includecpp/core/cssl_bridge.py +11 -2
- {includecpp-3.4.8.dist-info → includecpp-3.4.10.dist-info}/METADATA +1 -1
- {includecpp-3.4.8.dist-info → includecpp-3.4.10.dist-info}/RECORD +14 -14
- {includecpp-3.4.8.dist-info → includecpp-3.4.10.dist-info}/WHEEL +0 -0
- {includecpp-3.4.8.dist-info → includecpp-3.4.10.dist-info}/entry_points.txt +0 -0
- {includecpp-3.4.8.dist-info → includecpp-3.4.10.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.4.8.dist-info → includecpp-3.4.10.dist-info}/top_level.txt +0 -0
includecpp/__init__.py
CHANGED
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__
|
includecpp/cli/commands.py
CHANGED
|
@@ -7455,9 +7455,8 @@ def cssl_exec(path, code):
|
|
|
7455
7455
|
try:
|
|
7456
7456
|
result = cssl_lang.exec(source)
|
|
7457
7457
|
|
|
7458
|
-
#
|
|
7459
|
-
|
|
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}")
|
includecpp/core/cssl/__init__.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
429
|
-
|
|
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
|
+
]
|
includecpp/core/cssl_bridge.py
CHANGED
|
@@ -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',
|
|
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,9 +1,9 @@
|
|
|
1
|
-
includecpp/__init__.py,sha256=
|
|
2
|
-
includecpp/__init__.pyi,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
27
|
-
includecpp/core/cssl/cssl_runtime.py,sha256=
|
|
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
|
|
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.
|
|
37
|
-
includecpp-3.4.
|
|
38
|
-
includecpp-3.4.
|
|
39
|
-
includecpp-3.4.
|
|
40
|
-
includecpp-3.4.
|
|
41
|
-
includecpp-3.4.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|