IncludeCPP 3.6.0__tar.gz → 3.6.1__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.
Files changed (55) hide show
  1. {includecpp-3.6.0 → includecpp-3.6.1}/IncludeCPP.egg-info/PKG-INFO +1 -1
  2. {includecpp-3.6.0 → includecpp-3.6.1}/PKG-INFO +1 -1
  3. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/__init__.py +1 -1
  4. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/CSSL_DOCUMENTATION.md +89 -13
  5. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_builtins.py +95 -0
  6. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_parser.py +45 -46
  7. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_runtime.py +51 -0
  8. {includecpp-3.6.0 → includecpp-3.6.1}/pyproject.toml +1 -1
  9. {includecpp-3.6.0 → includecpp-3.6.1}/IncludeCPP.egg-info/SOURCES.txt +0 -0
  10. {includecpp-3.6.0 → includecpp-3.6.1}/IncludeCPP.egg-info/dependency_links.txt +0 -0
  11. {includecpp-3.6.0 → includecpp-3.6.1}/IncludeCPP.egg-info/entry_points.txt +0 -0
  12. {includecpp-3.6.0 → includecpp-3.6.1}/IncludeCPP.egg-info/requires.txt +0 -0
  13. {includecpp-3.6.0 → includecpp-3.6.1}/IncludeCPP.egg-info/top_level.txt +0 -0
  14. {includecpp-3.6.0 → includecpp-3.6.1}/LICENSE +0 -0
  15. {includecpp-3.6.0 → includecpp-3.6.1}/MANIFEST.in +0 -0
  16. {includecpp-3.6.0 → includecpp-3.6.1}/README.md +0 -0
  17. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/__init__.pyi +0 -0
  18. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/__main__.py +0 -0
  19. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/cli/__init__.py +0 -0
  20. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/cli/commands.py +0 -0
  21. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/cli/config_parser.py +0 -0
  22. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/__init__.py +0 -0
  23. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/ai_integration.py +0 -0
  24. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/build_manager.py +0 -0
  25. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cpp_api.py +0 -0
  26. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cpp_api.pyi +0 -0
  27. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cppy_converter.py +0 -0
  28. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/__init__.py +0 -0
  29. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_events.py +0 -0
  30. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_modules.py +0 -0
  31. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_syntax.py +0 -0
  32. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl/cssl_types.py +0 -0
  33. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl_bridge.py +0 -0
  34. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/cssl_bridge.pyi +0 -0
  35. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/error_catalog.py +0 -0
  36. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/error_formatter.py +0 -0
  37. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/exceptions.py +0 -0
  38. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/path_discovery.py +0 -0
  39. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/project_ui.py +0 -0
  40. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/core/settings_ui.py +0 -0
  41. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/generator/__init__.py +0 -0
  42. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/generator/parser.cpp +0 -0
  43. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/generator/parser.h +0 -0
  44. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/generator/type_resolver.cpp +0 -0
  45. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/generator/type_resolver.h +0 -0
  46. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/py.typed +0 -0
  47. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/templates/cpp.proj.template +0 -0
  48. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/vscode/__init__.py +0 -0
  49. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/vscode/cssl/__init__.py +0 -0
  50. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/vscode/cssl/language-configuration.json +0 -0
  51. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/vscode/cssl/package.json +0 -0
  52. {includecpp-3.6.0 → includecpp-3.6.1}/includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +0 -0
  53. {includecpp-3.6.0 → includecpp-3.6.1}/requirements.txt +0 -0
  54. {includecpp-3.6.0 → includecpp-3.6.1}/setup.cfg +0 -0
  55. {includecpp-3.6.0 → includecpp-3.6.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.6.0
3
+ Version: 3.6.1
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.6.0
3
+ Version: 3.6.1
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
@@ -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.6.0"
5
+ __version__ = "3.6.1"
6
6
  __all__ = ["CppApi", "CSSL"]
7
7
 
8
8
  # Module-level cache for C++ modules
@@ -1,6 +1,6 @@
1
1
  # CSSL - C-Style Scripting Language
2
2
 
3
- > Version 3.6.0 | A modern scripting language with C++-style syntax and unique features like CodeInfusion and BruteInjection.
3
+ > Version 3.6.1 | A modern scripting language with C++-style syntax and unique features like CodeInfusion and BruteInjection.
4
4
 
5
5
  ---
6
6
 
@@ -17,17 +17,18 @@
17
17
  9. [String Methods](#string-methods)
18
18
  10. [File I/O](#file-io)
19
19
  11. [JSON Functions](#json-functions)
20
- 12. [Live Object Sharing](#live-object-sharing)
21
- 13. [CodeInfusion](#codeinfusion)
22
- 14. [Value Capture](#value-capture)
23
- 15. [BruteInjection](#bruteinjection)
24
- 16. [Filter Syntax](#filter-syntax)
25
- 17. [Module System](#module-system)
26
- 18. [Parameter Bridge](#parameter-bridge)
27
- 19. [Structures](#structures)
28
- 20. [Error Handling](#error-handling)
29
- 21. [CLI Commands](#cli-commands)
30
- 22. [Examples](#examples)
20
+ 12. [Instance Management](#instance-management)
21
+ 13. [Live Object Sharing](#live-object-sharing)
22
+ 14. [CodeInfusion](#codeinfusion)
23
+ 15. [Value Capture](#value-capture)
24
+ 16. [BruteInjection](#bruteinjection)
25
+ 17. [Filter Syntax](#filter-syntax)
26
+ 18. [Module System](#module-system)
27
+ 19. [Parameter Bridge](#parameter-bridge)
28
+ 20. [Structures](#structures)
29
+ 21. [Error Handling](#error-handling)
30
+ 22. [CLI Commands](#cli-commands)
31
+ 23. [Examples](#examples)
31
32
 
32
33
  ---
33
34
 
@@ -1000,6 +1001,81 @@ json merged = json::merge(obj1, obj2, obj3);
1000
1001
 
1001
1002
  ---
1002
1003
 
1004
+ ## Instance Management
1005
+
1006
+ CSSL provides `instance<"name">` syntax and `instance::` namespace for working with shared instances.
1007
+
1008
+ ### Instance Declaration
1009
+
1010
+ ```cssl
1011
+ // Get/create shared instance by name
1012
+ instance<"MyApp"> app;
1013
+
1014
+ // With initialization
1015
+ instance<"tk"> tk = include("tkinter.cssl-mod");
1016
+
1017
+ // Register object as shared instance
1018
+ myModule ==> $AppModule
1019
+ // Or using instance syntax:
1020
+ myModule ==> instance<"AppModule">
1021
+ ```
1022
+
1023
+ ### Instance Introspection
1024
+
1025
+ ```cssl
1026
+ @tk = include("tk.cssl-mod");
1027
+
1028
+ // Get all methods from module
1029
+ stack<string> methods = instance::getMethods(@tk);
1030
+ foreach (m in methods) {
1031
+ printl("Method: " + m);
1032
+ }
1033
+
1034
+ // Get all classes
1035
+ stack<string> classes = instance::getClasses(@tk);
1036
+
1037
+ // Get all variables
1038
+ stack<string> vars = instance::getVars(@tk);
1039
+
1040
+ // Get everything categorized
1041
+ json all = instance::getAll(@tk);
1042
+ printl(all.methods); // ["method1", "method2", ...]
1043
+ printl(all.classes); // ["Class1", "Class2", ...]
1044
+ printl(all.vars); // ["var1", "var2", ...]
1045
+ ```
1046
+
1047
+ ### Dynamic Method Calls
1048
+
1049
+ ```cssl
1050
+ // Call method dynamically by name
1051
+ result = instance::call(@module, "methodName", arg1, arg2);
1052
+
1053
+ // Check if method/attribute exists
1054
+ if (instance::has(@module, "initialize")) {
1055
+ instance::call(@module, "initialize");
1056
+ }
1057
+
1058
+ // Get type name
1059
+ string typeName = instance::type(@module);
1060
+ printl(typeName); // "module"
1061
+ ```
1062
+
1063
+ ### All Instance Functions
1064
+
1065
+ | Function | Description |
1066
+ |----------|-------------|
1067
+ | `instance<"name"> var` | Declare instance variable |
1068
+ | `obj ==> instance<"name">` | Register as shared instance |
1069
+ | `instance::getMethods(obj)` | Get all method names |
1070
+ | `instance::getClasses(obj)` | Get all class names |
1071
+ | `instance::getVars(obj)` | Get all variable names |
1072
+ | `instance::getAll(obj)` | Get categorized dict |
1073
+ | `instance::call(obj, 'name', ...)` | Call method dynamically |
1074
+ | `instance::has(obj, 'name')` | Check if attribute exists |
1075
+ | `instance::type(obj)` | Get type name |
1076
+
1077
+ ---
1078
+
1003
1079
  ## Live Object Sharing
1004
1080
 
1005
1081
  Share Python objects with CSSL. Changes in CSSL reflect back to Python.
@@ -1810,4 +1886,4 @@ print(result) # ["Missing colon after def"]
1810
1886
 
1811
1887
  ---
1812
1888
 
1813
- *CSSL v3.6.0 - Developed as part of IncludeCPP*
1889
+ *CSSL v3.6.1 - Developed as part of IncludeCPP*
@@ -194,6 +194,15 @@ class CSSLBuiltins:
194
194
  self._functions['json::has'] = self.builtin_json_has
195
195
  self._functions['json::merge'] = self.builtin_json_merge
196
196
 
197
+ # Instance introspection functions (instance::getMethods, etc.)
198
+ self._functions['instance::getMethods'] = self.builtin_instance_getMethods
199
+ self._functions['instance::getClasses'] = self.builtin_instance_getClasses
200
+ self._functions['instance::getVars'] = self.builtin_instance_getVars
201
+ self._functions['instance::getAll'] = self.builtin_instance_getAll
202
+ self._functions['instance::call'] = self.builtin_instance_call
203
+ self._functions['instance::has'] = self.builtin_instance_has
204
+ self._functions['instance::type'] = self.builtin_instance_type
205
+
197
206
  # Regex functions
198
207
  self._functions['match'] = self.builtin_match
199
208
  self._functions['search'] = self.builtin_search
@@ -1026,6 +1035,92 @@ class CSSLBuiltins:
1026
1035
  result = deep_merge(result, d)
1027
1036
  return result
1028
1037
 
1038
+ # ============= Instance Introspection Functions =============
1039
+
1040
+ def builtin_instance_getMethods(self, obj: Any) -> list:
1041
+ """Get all methods from an object/module.
1042
+ Usage: instance::getMethods(@module) or instance::getMethods($obj)
1043
+ Returns list of method names.
1044
+ """
1045
+ import inspect
1046
+ methods = []
1047
+ for name in dir(obj):
1048
+ if not name.startswith('_'):
1049
+ attr = getattr(obj, name, None)
1050
+ if callable(attr):
1051
+ methods.append(name)
1052
+ return methods
1053
+
1054
+ def builtin_instance_getClasses(self, obj: Any) -> list:
1055
+ """Get all classes from an object/module.
1056
+ Usage: instance::getClasses(@module)
1057
+ Returns list of class names.
1058
+ """
1059
+ import inspect
1060
+ classes = []
1061
+ for name in dir(obj):
1062
+ if not name.startswith('_'):
1063
+ attr = getattr(obj, name, None)
1064
+ if inspect.isclass(attr):
1065
+ classes.append(name)
1066
+ return classes
1067
+
1068
+ def builtin_instance_getVars(self, obj: Any) -> list:
1069
+ """Get all variables/attributes (non-callable) from an object.
1070
+ Usage: instance::getVars(@module)
1071
+ Returns list of variable names.
1072
+ """
1073
+ vars_list = []
1074
+ for name in dir(obj):
1075
+ if not name.startswith('_'):
1076
+ attr = getattr(obj, name, None)
1077
+ if not callable(attr):
1078
+ vars_list.append(name)
1079
+ return vars_list
1080
+
1081
+ def builtin_instance_getAll(self, obj: Any) -> dict:
1082
+ """Get all attributes from an object, categorized.
1083
+ Usage: instance::getAll(@module)
1084
+ Returns dict with 'methods', 'classes', 'vars' keys.
1085
+ """
1086
+ import inspect
1087
+ result = {
1088
+ 'methods': [],
1089
+ 'classes': [],
1090
+ 'vars': []
1091
+ }
1092
+ for name in dir(obj):
1093
+ if not name.startswith('_'):
1094
+ attr = getattr(obj, name, None)
1095
+ if inspect.isclass(attr):
1096
+ result['classes'].append(name)
1097
+ elif callable(attr):
1098
+ result['methods'].append(name)
1099
+ else:
1100
+ result['vars'].append(name)
1101
+ return result
1102
+
1103
+ def builtin_instance_call(self, obj: Any, method_name: str, *args, **kwargs) -> Any:
1104
+ """Dynamically call a method on an object.
1105
+ Usage: instance::call(@module, 'methodName', arg1, arg2)
1106
+ """
1107
+ method = getattr(obj, method_name, None)
1108
+ if method and callable(method):
1109
+ return method(*args, **kwargs)
1110
+ raise RuntimeError(f"Method '{method_name}' not found on object")
1111
+
1112
+ def builtin_instance_has(self, obj: Any, name: str) -> bool:
1113
+ """Check if object has an attribute.
1114
+ Usage: instance::has(@module, 'methodName')
1115
+ """
1116
+ return hasattr(obj, name)
1117
+
1118
+ def builtin_instance_type(self, obj: Any) -> str:
1119
+ """Get the type name of an object.
1120
+ Usage: instance::type(@module)
1121
+ """
1122
+ return type(obj).__name__
1123
+
1029
1124
  # ============= Regex Functions =============
1030
1125
 
1031
1126
  def builtin_match(self, pattern: str, string: str) -> Optional[dict]:
@@ -898,7 +898,7 @@ class CSSLParser:
898
898
  type_keywords = {'int', 'string', 'float', 'bool', 'dynamic', 'void',
899
899
  'stack', 'vector', 'datastruct', 'dataspace', 'shuffled',
900
900
  'iterator', 'combo', 'array', 'openquote', 'json',
901
- 'list', 'dictionary', 'dict'}
901
+ 'list', 'dictionary', 'dict', 'instance'}
902
902
  if type_name not in type_keywords:
903
903
  return False
904
904
 
@@ -927,11 +927,13 @@ class CSSLParser:
927
927
  # Get type name
928
928
  type_name = self._advance().value # Consume type keyword
929
929
 
930
- # Check for generic type <T>
930
+ # Check for generic type <T> or instance<"name">
931
931
  element_type = None
932
932
  if self._match(TokenType.COMPARE_LT):
933
- # Get element type
934
- if self._check(TokenType.KEYWORD) or self._check(TokenType.IDENTIFIER):
933
+ # For instance<"name">, element_type can be a string literal
934
+ if type_name == 'instance' and self._check(TokenType.STRING):
935
+ element_type = self._advance().value
936
+ elif self._check(TokenType.KEYWORD) or self._check(TokenType.IDENTIFIER):
935
937
  element_type = self._advance().value
936
938
  self._expect(TokenType.COMPARE_GT)
937
939
 
@@ -947,6 +949,14 @@ class CSSLParser:
947
949
 
948
950
  self._match(TokenType.SEMICOLON)
949
951
 
952
+ # For instance<"name">, create a special node type
953
+ if type_name == 'instance':
954
+ return ASTNode('instance_declaration', value={
955
+ 'instance_name': element_type,
956
+ 'name': var_name,
957
+ 'value': value
958
+ })
959
+
950
960
  return ASTNode('typed_declaration', value={
951
961
  'type': type_name,
952
962
  'element_type': element_type,
@@ -1992,14 +2002,10 @@ class CSSLParser:
1992
2002
  # Continue to check for calls, indexing, member access on module refs
1993
2003
  while True:
1994
2004
  if self._match(TokenType.PAREN_START):
1995
- # Function call on module ref: @Module.method()
1996
- args = []
1997
- while not self._check(TokenType.PAREN_END) and not self._is_at_end():
1998
- args.append(self._parse_expression())
1999
- if not self._check(TokenType.PAREN_END):
2000
- self._expect(TokenType.COMMA)
2005
+ # Function call on module ref: @Module.method() - with kwargs support
2006
+ args, kwargs = self._parse_call_arguments()
2001
2007
  self._expect(TokenType.PAREN_END)
2002
- node = ASTNode('call', value={'callee': node, 'args': args})
2008
+ node = ASTNode('call', value={'callee': node, 'args': args, 'kwargs': kwargs})
2003
2009
  elif self._match(TokenType.DOT):
2004
2010
  # Member access: @Module.property
2005
2011
  member = self._advance().value
@@ -2017,31 +2023,23 @@ class CSSLParser:
2017
2023
  # s@<name> self-reference to global struct
2018
2024
  token = self._advance()
2019
2025
  node = ASTNode('self_ref', value=token.value, line=token.line, column=token.column)
2020
- # Check for function call: s@Backend.Loop.Start()
2026
+ # Check for function call: s@Backend.Loop.Start() - with kwargs support
2021
2027
  if self._match(TokenType.PAREN_START):
2022
- args = []
2023
- while not self._check(TokenType.PAREN_END):
2024
- args.append(self._parse_expression())
2025
- if not self._check(TokenType.PAREN_END):
2026
- self._expect(TokenType.COMMA)
2028
+ args, kwargs = self._parse_call_arguments()
2027
2029
  self._expect(TokenType.PAREN_END)
2028
- node = ASTNode('call', value={'callee': node, 'args': args})
2030
+ node = ASTNode('call', value={'callee': node, 'args': args, 'kwargs': kwargs})
2029
2031
  return node
2030
2032
 
2031
2033
  if self._check(TokenType.GLOBAL_REF):
2032
2034
  # r@<name> global variable reference/declaration
2033
2035
  token = self._advance()
2034
2036
  node = ASTNode('global_ref', value=token.value, line=token.line, column=token.column)
2035
- # Check for member access, calls, indexing
2037
+ # Check for member access, calls, indexing - with kwargs support
2036
2038
  while True:
2037
2039
  if self._match(TokenType.PAREN_START):
2038
- args = []
2039
- while not self._check(TokenType.PAREN_END):
2040
- args.append(self._parse_expression())
2041
- if not self._check(TokenType.PAREN_END):
2042
- self._expect(TokenType.COMMA)
2040
+ args, kwargs = self._parse_call_arguments()
2043
2041
  self._expect(TokenType.PAREN_END)
2044
- node = ASTNode('call', value={'callee': node, 'args': args})
2042
+ node = ASTNode('call', value={'callee': node, 'args': args, 'kwargs': kwargs})
2045
2043
  elif self._match(TokenType.DOT):
2046
2044
  member = self._advance().value
2047
2045
  node = ASTNode('member_access', value={'object': node, 'member': member})
@@ -2057,16 +2055,12 @@ class CSSLParser:
2057
2055
  # $<name> shared object reference
2058
2056
  token = self._advance()
2059
2057
  node = ASTNode('shared_ref', value=token.value, line=token.line, column=token.column)
2060
- # Check for member access, calls, indexing
2058
+ # Check for member access, calls, indexing - with kwargs support
2061
2059
  while True:
2062
2060
  if self._match(TokenType.PAREN_START):
2063
- args = []
2064
- while not self._check(TokenType.PAREN_END):
2065
- args.append(self._parse_expression())
2066
- if not self._check(TokenType.PAREN_END):
2067
- self._expect(TokenType.COMMA)
2061
+ args, kwargs = self._parse_call_arguments()
2068
2062
  self._expect(TokenType.PAREN_END)
2069
- node = ASTNode('call', value={'callee': node, 'args': args})
2063
+ node = ASTNode('call', value={'callee': node, 'args': args, 'kwargs': kwargs})
2070
2064
  elif self._match(TokenType.DOT):
2071
2065
  member = self._advance().value
2072
2066
  node = ASTNode('member_access', value={'object': node, 'member': member})
@@ -2082,16 +2076,12 @@ class CSSLParser:
2082
2076
  # %<name> captured reference (captures value at infusion registration time)
2083
2077
  token = self._advance()
2084
2078
  node = ASTNode('captured_ref', value=token.value, line=token.line, column=token.column)
2085
- # Check for member access, calls, indexing
2079
+ # Check for member access, calls, indexing - with kwargs support
2086
2080
  while True:
2087
2081
  if self._match(TokenType.PAREN_START):
2088
- args = []
2089
- while not self._check(TokenType.PAREN_END):
2090
- args.append(self._parse_expression())
2091
- if not self._check(TokenType.PAREN_END):
2092
- self._expect(TokenType.COMMA)
2082
+ args, kwargs = self._parse_call_arguments()
2093
2083
  self._expect(TokenType.PAREN_END)
2094
- node = ASTNode('call', value={'callee': node, 'args': args})
2084
+ node = ASTNode('call', value={'callee': node, 'args': args, 'kwargs': kwargs})
2095
2085
  elif self._match(TokenType.DOT):
2096
2086
  member = self._advance().value
2097
2087
  node = ASTNode('member_access', value={'object': node, 'member': member})
@@ -2160,14 +2150,10 @@ class CSSLParser:
2160
2150
  member = self._advance().value
2161
2151
  node = ASTNode('member_access', value={'object': node, 'member': member})
2162
2152
  elif self._match(TokenType.PAREN_START):
2163
- # Function call
2164
- args = []
2165
- while not self._check(TokenType.PAREN_END):
2166
- args.append(self._parse_expression())
2167
- if not self._check(TokenType.PAREN_END):
2168
- self._expect(TokenType.COMMA)
2153
+ # Function call - use _parse_call_arguments for kwargs support
2154
+ args, kwargs = self._parse_call_arguments()
2169
2155
  self._expect(TokenType.PAREN_END)
2170
- node = ASTNode('call', value={'callee': node, 'args': args})
2156
+ node = ASTNode('call', value={'callee': node, 'args': args, 'kwargs': kwargs})
2171
2157
  elif self._match(TokenType.BRACKET_START):
2172
2158
  # Index access
2173
2159
  index = self._parse_expression()
@@ -2220,6 +2206,19 @@ class CSSLParser:
2220
2206
  namespace_member = self._advance().value
2221
2207
  name = f"{name}::{namespace_member}"
2222
2208
 
2209
+ # Check for instance<"name"> syntax - gets/creates shared instance
2210
+ if name == 'instance' and self._check(TokenType.COMPARE_LT):
2211
+ self._advance() # consume <
2212
+ # Expect string literal for instance name
2213
+ if self._check(TokenType.STRING):
2214
+ instance_name = self._advance().value
2215
+ elif self._check(TokenType.IDENTIFIER):
2216
+ instance_name = self._advance().value
2217
+ else:
2218
+ raise CSSLParserError("Expected instance name (string or identifier)", self._current_line())
2219
+ self._expect(TokenType.COMPARE_GT) # consume >
2220
+ return ASTNode('instance_ref', value=instance_name)
2221
+
2223
2222
  # Check for type generic instantiation: stack<string>, vector<int>, etc.
2224
2223
  # This creates a new instance of the type with the specified element type
2225
2224
  if name in TYPE_GENERICS and self._check(TokenType.COMPARE_LT):
@@ -394,6 +394,9 @@ class CSSLRuntime:
394
394
  elif child.type == 'typed_declaration':
395
395
  # Handle typed variable declaration: type<T> varName = value;
396
396
  result = self._exec_typed_declaration(child)
397
+ elif child.type == 'instance_declaration':
398
+ # Handle instance declaration: instance<"name"> varName;
399
+ result = self._exec_instance_declaration(child)
397
400
  elif child.type in ('assignment', 'expression', 'inject', 'receive', 'flow',
398
401
  'if', 'while', 'for', 'c_for', 'foreach', 'switch', 'try'):
399
402
  result = self._execute_node(child)
@@ -732,6 +735,34 @@ class CSSLRuntime:
732
735
  self.scope.set(var_name, instance)
733
736
  return instance
734
737
 
738
+ def _exec_instance_declaration(self, node: ASTNode) -> Any:
739
+ """Execute instance declaration: instance<"name"> varName;
740
+
741
+ Gets or creates a shared instance by name.
742
+ """
743
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
744
+ decl = node.value
745
+ instance_name = decl.get('instance_name')
746
+ var_name = decl.get('name')
747
+ value_node = decl.get('value')
748
+
749
+ # Get existing shared instance
750
+ instance = None
751
+ if instance_name in _live_objects:
752
+ instance = SharedObjectProxy(instance_name, _live_objects[instance_name])
753
+ elif f'${instance_name}' in self.global_scope:
754
+ instance = self.global_scope.get(f'${instance_name}')
755
+
756
+ # If value is provided, use that and register as shared
757
+ if value_node:
758
+ instance = self._evaluate(value_node)
759
+ # Register in global scope for future access
760
+ self.global_scope.set(f'${instance_name}', instance)
761
+
762
+ # Store in scope
763
+ self.scope.set(var_name, instance)
764
+ return instance
765
+
735
766
  def _exec_global_assignment(self, node: ASTNode) -> Any:
736
767
  """Execute global variable assignment: global Name = value
737
768
 
@@ -1471,6 +1502,12 @@ class CSSLRuntime:
1471
1502
  name = target.value
1472
1503
  _live_objects[name] = final_value
1473
1504
  self.global_scope.set(f'${name}', SharedObjectProxy(name, final_value))
1505
+ elif target.type == 'instance_ref':
1506
+ # value ==> instance<"name"> - create/update shared object
1507
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
1508
+ name = target.value
1509
+ _live_objects[name] = final_value
1510
+ self.global_scope.set(f'${name}', SharedObjectProxy(name, final_value))
1474
1511
  elif target.type == 'member_access':
1475
1512
  self._set_member(target, final_value)
1476
1513
 
@@ -1767,6 +1804,20 @@ class CSSLRuntime:
1767
1804
  return value
1768
1805
  raise CSSLRuntimeError(f"Captured reference '%{name}' not found.")
1769
1806
 
1807
+ if node.type == 'instance_ref':
1808
+ # instance<"name"> - get shared instance by name
1809
+ # Works like $name but with explicit syntax
1810
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
1811
+ name = node.value
1812
+ if name in _live_objects:
1813
+ return SharedObjectProxy(name, _live_objects[name])
1814
+ # Check if stored in runtime's scope
1815
+ scoped_val = self.global_scope.get(f'${name}')
1816
+ if scoped_val is not None:
1817
+ return scoped_val
1818
+ # Return None if instance doesn't exist (can be created via ==>)
1819
+ return None
1820
+
1770
1821
  if node.type == 'type_instantiation':
1771
1822
  # Create new instance of a type: stack<string>, vector<int>, etc.
1772
1823
  type_name = node.value.get('type')
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "IncludeCPP"
7
- version = "3.6.0"
7
+ version = "3.6.1"
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"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes