IncludeCPP 3.7.25__py3-none-any.whl → 3.8.0__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.7.25"
5
+ __version__ = "3.8.0"
6
6
  __all__ = ["CppApi", "CSSL"]
7
7
 
8
8
  # Module-level cache for C++ modules
@@ -7457,11 +7457,24 @@ def cssl():
7457
7457
  pass
7458
7458
 
7459
7459
 
7460
+ @cssl.command(name='run')
7461
+ @click.argument('path', required=False, type=click.Path())
7462
+ @click.option('--code', '-c', type=str, help='Execute code directly')
7463
+ def cssl_run(path, code):
7464
+ """Run/execute CSSL code or file."""
7465
+ _cssl_execute(path, code)
7466
+
7467
+
7460
7468
  @cssl.command(name='exec')
7461
7469
  @click.argument('path', required=False, type=click.Path())
7462
7470
  @click.option('--code', '-c', type=str, help='Execute code directly')
7463
7471
  def cssl_exec(path, code):
7464
- """Execute CSSL code or file."""
7472
+ """Execute CSSL code or file (alias for 'run')."""
7473
+ _cssl_execute(path, code)
7474
+
7475
+
7476
+ def _cssl_execute(path, code):
7477
+ """Internal: Execute CSSL code or file."""
7465
7478
  from pathlib import Path as PathLib
7466
7479
 
7467
7480
  try:
@@ -7923,16 +7936,18 @@ cli.add_command(cssl)
7923
7936
 
7924
7937
  @cli.command()
7925
7938
  @click.option('--force', '-f', is_flag=True, help='Force overwrite existing files')
7939
+ @click.option('--reinstall', '-r', is_flag=True, help='Reinstall extension (removes all versions first)')
7926
7940
  @click.option('--stubs-only', is_flag=True, help='Only update stubs, skip extension files')
7927
- def vscode(force, stubs_only):
7941
+ def vscode(force, reinstall, stubs_only):
7928
7942
  """Initialize or update VSCode configuration for IncludeCPP/CSSL.
7929
7943
 
7930
7944
  Installs CSSL extension globally and sets up project stubs.
7931
7945
 
7932
7946
  \b
7933
7947
  Usage:
7934
- includecpp vscode # Install/update extension + stubs
7935
- includecpp vscode --force # Force reinstall extension
7948
+ includecpp vscode # Install/update extension + stubs
7949
+ includecpp vscode --force # Force reinstall extension
7950
+ includecpp vscode --reinstall # Remove ALL versions & reinstall fresh
7936
7951
  includecpp vscode --stubs-only # Only update stubs
7937
7952
 
7938
7953
  \b
@@ -7999,13 +8014,18 @@ def vscode(force, stubs_only):
7999
8014
  target_dir = global_ext_dir / f'includecpp.cssl-{current_version}'
8000
8015
 
8001
8016
  # Check if already installed with same or older version
8002
- needs_install = force
8017
+ needs_install = force or reinstall
8003
8018
  existing_version = None
8004
8019
 
8005
8020
  # Find existing installations
8006
8021
  for existing in global_ext_dir.glob('includecpp.cssl-*'):
8007
8022
  existing_version = existing.name.split('-')[-1]
8008
- if existing_version != current_version:
8023
+ if reinstall:
8024
+ # --reinstall: Remove ALL versions
8025
+ click.echo(f" Removing version: {existing_version}")
8026
+ shutil.rmtree(existing)
8027
+ needs_install = True
8028
+ elif existing_version != current_version:
8009
8029
  # Remove old version
8010
8030
  click.echo(f" Removing old version: {existing_version}")
8011
8031
  shutil.rmtree(existing)
@@ -205,6 +205,11 @@ class CSSLBuiltins:
205
205
  self._functions['isavailable'] = self.builtin_isavailable
206
206
  self._functions['instance::exists'] = self.builtin_isavailable # Alias
207
207
 
208
+ # Python interop functions
209
+ self._functions['python::pythonize'] = self.builtin_python_pythonize
210
+ self._functions['python::wrap'] = self.builtin_python_pythonize # Alias
211
+ self._functions['python::export'] = self.builtin_python_pythonize # Alias
212
+
208
213
  # Regex functions
209
214
  self._functions['match'] = self.builtin_match
210
215
  self._functions['search'] = self.builtin_search
@@ -2445,6 +2450,211 @@ class CSSLBuiltins:
2445
2450
 
2446
2451
  return None
2447
2452
 
2453
+ # ============= Python Interop Functions =============
2454
+
2455
+ def builtin_python_pythonize(self, cssl_instance: Any) -> Any:
2456
+ """Convert a CSSL class instance to a Python-usable object.
2457
+
2458
+ This allows CSSL classes to be returned and used in Python code
2459
+ with proper attribute access and method calls.
2460
+
2461
+ Usage in CSSL:
2462
+ class Greeter {
2463
+ string name;
2464
+
2465
+ Greeter(string n) {
2466
+ this->name = n;
2467
+ }
2468
+
2469
+ string sayHello() {
2470
+ return "Hello, " + this->name + "!";
2471
+ }
2472
+
2473
+ void setName(string newName) {
2474
+ this->name = newName;
2475
+ }
2476
+
2477
+ string getName() {
2478
+ return this->name;
2479
+ }
2480
+ }
2481
+
2482
+ greeter = new Greeter("World");
2483
+ pyclass = python::pythonize(greeter);
2484
+ parameter.return(pyclass);
2485
+
2486
+ Usage in Python:
2487
+ from includecpp import CSSL
2488
+
2489
+ cssl = CSSL.CsslLang()
2490
+ greeter = cssl.run('''
2491
+ class Greeter { ... }
2492
+ g = new Greeter("World");
2493
+ parameter.return(python::pythonize(g));
2494
+ ''')
2495
+
2496
+ # Now use it like a normal Python object:
2497
+ print(greeter.name) # "World"
2498
+ print(greeter.sayHello()) # "Hello, World!"
2499
+ greeter.setName("Python")
2500
+ print(greeter.getName()) # "Python"
2501
+
2502
+ Args:
2503
+ cssl_instance: A CSSLInstance object (created via 'new ClassName()')
2504
+
2505
+ Returns:
2506
+ PythonizedCSSLInstance - A Python-friendly wrapper
2507
+ """
2508
+ from .cssl_types import CSSLInstance, CSSLClass
2509
+
2510
+ if cssl_instance is None:
2511
+ return None
2512
+
2513
+ # Already pythonized
2514
+ if isinstance(cssl_instance, PythonizedCSSLInstance):
2515
+ return cssl_instance
2516
+
2517
+ # Must be a CSSLInstance
2518
+ if not isinstance(cssl_instance, CSSLInstance):
2519
+ # If it's a dict, wrap it as a simple object
2520
+ if isinstance(cssl_instance, dict):
2521
+ return PythonizedDict(cssl_instance)
2522
+ # Return as-is for primitives
2523
+ return cssl_instance
2524
+
2525
+ return PythonizedCSSLInstance(cssl_instance, self.runtime)
2526
+
2527
+
2528
+ class PythonizedCSSLInstance:
2529
+ """Python wrapper for CSSL class instances.
2530
+
2531
+ Provides Pythonic attribute access and method calling for CSSL objects.
2532
+ """
2533
+
2534
+ def __init__(self, instance: Any, runtime: Any = None):
2535
+ # Use object.__setattr__ to avoid triggering our custom __setattr__
2536
+ object.__setattr__(self, '_cssl_instance', instance)
2537
+ object.__setattr__(self, '_cssl_runtime', runtime)
2538
+ object.__setattr__(self, '_cssl_class_name', instance._class.name if hasattr(instance, '_class') else 'Unknown')
2539
+
2540
+ def __getattr__(self, name: str) -> Any:
2541
+ """Get member or method from CSSL instance."""
2542
+ if name.startswith('_'):
2543
+ raise AttributeError(f"'{self._cssl_class_name}' has no attribute '{name}'")
2544
+
2545
+ instance = object.__getattribute__(self, '_cssl_instance')
2546
+ runtime = object.__getattribute__(self, '_cssl_runtime')
2547
+
2548
+ # Check for member variable first
2549
+ if instance.has_member(name):
2550
+ value = instance.get_member(name)
2551
+ # Recursively pythonize nested CSSL instances
2552
+ from .cssl_types import CSSLInstance
2553
+ if isinstance(value, CSSLInstance):
2554
+ return PythonizedCSSLInstance(value, runtime)
2555
+ return value
2556
+
2557
+ # Check for method
2558
+ method = instance.get_method(name)
2559
+ if method is not None:
2560
+ # Return a callable wrapper for the method
2561
+ return PythonizedMethod(instance, name, method, runtime)
2562
+
2563
+ raise AttributeError(f"'{self._cssl_class_name}' has no attribute '{name}'")
2564
+
2565
+ def __setattr__(self, name: str, value: Any) -> None:
2566
+ """Set member value on CSSL instance."""
2567
+ if name.startswith('_'):
2568
+ object.__setattr__(self, name, value)
2569
+ return
2570
+
2571
+ instance = object.__getattribute__(self, '_cssl_instance')
2572
+ instance.set_member(name, value)
2573
+
2574
+ def __repr__(self) -> str:
2575
+ class_name = object.__getattribute__(self, '_cssl_class_name')
2576
+ instance = object.__getattribute__(self, '_cssl_instance')
2577
+ members = list(instance._members.keys()) if hasattr(instance, '_members') else []
2578
+ return f"<PythonizedCSSL '{class_name}' members={members}>"
2579
+
2580
+ def __dir__(self) -> list:
2581
+ """List available attributes."""
2582
+ instance = object.__getattribute__(self, '_cssl_instance')
2583
+ members = list(instance._members.keys()) if hasattr(instance, '_members') else []
2584
+ methods = list(instance._class.methods.keys()) if hasattr(instance._class, 'methods') else []
2585
+ return members + methods
2586
+
2587
+ def _to_dict(self) -> dict:
2588
+ """Convert to Python dictionary."""
2589
+ instance = object.__getattribute__(self, '_cssl_instance')
2590
+ result = {}
2591
+ for name, value in instance._members.items():
2592
+ from .cssl_types import CSSLInstance
2593
+ if isinstance(value, CSSLInstance):
2594
+ result[name] = PythonizedCSSLInstance(value, None)._to_dict()
2595
+ else:
2596
+ result[name] = value
2597
+ return result
2598
+
2599
+
2600
+ class PythonizedMethod:
2601
+ """Wrapper that makes CSSL methods callable from Python."""
2602
+
2603
+ def __init__(self, instance: Any, method_name: str, method_ast: Any, runtime: Any):
2604
+ self._instance = instance
2605
+ self._method_name = method_name
2606
+ self._method_ast = method_ast
2607
+ self._runtime = runtime
2608
+
2609
+ def __call__(self, *args, **kwargs) -> Any:
2610
+ """Call the CSSL method with arguments."""
2611
+ if self._runtime is None:
2612
+ raise RuntimeError(f"Cannot call method '{self._method_name}' - no runtime available")
2613
+
2614
+ # Execute the method through the runtime
2615
+ # Pass the method AST node, not the method name
2616
+ result = self._runtime._call_method(self._instance, self._method_ast, list(args), kwargs)
2617
+
2618
+ # Pythonize the result if it's a CSSL instance
2619
+ from .cssl_types import CSSLInstance
2620
+ if isinstance(result, CSSLInstance):
2621
+ return PythonizedCSSLInstance(result, self._runtime)
2622
+
2623
+ return result
2624
+
2625
+ def __repr__(self) -> str:
2626
+ return f"<method '{self._method_name}' of '{self._instance._class.name}'>"
2627
+
2628
+
2629
+ class PythonizedDict:
2630
+ """Simple wrapper for dict objects with attribute access."""
2631
+
2632
+ def __init__(self, data: dict):
2633
+ object.__setattr__(self, '_data', data)
2634
+
2635
+ def __getattr__(self, name: str) -> Any:
2636
+ data = object.__getattribute__(self, '_data')
2637
+ if name in data:
2638
+ value = data[name]
2639
+ if isinstance(value, dict):
2640
+ return PythonizedDict(value)
2641
+ return value
2642
+ raise AttributeError(f"No attribute '{name}'")
2643
+
2644
+ def __setattr__(self, name: str, value: Any) -> None:
2645
+ if name.startswith('_'):
2646
+ object.__setattr__(self, name, value)
2647
+ return
2648
+ data = object.__getattribute__(self, '_data')
2649
+ data[name] = value
2650
+
2651
+ def __repr__(self) -> str:
2652
+ data = object.__getattribute__(self, '_data')
2653
+ return f"<PythonizedDict {data}>"
2654
+
2655
+ def _to_dict(self) -> dict:
2656
+ return object.__getattribute__(self, '_data')
2657
+
2448
2658
 
2449
2659
  # Module-level convenience functions
2450
2660
  _default_builtins: Optional[CSSLBuiltins] = None
@@ -716,7 +716,7 @@ class CSSLParser:
716
716
  def _is_type_keyword(self, value: str) -> bool:
717
717
  """Check if a keyword is a type declaration"""
718
718
  return value in ('int', 'string', 'float', 'bool', 'void', 'json', 'array', 'vector', 'stack',
719
- 'list', 'dictionary', 'dict', 'instance', 'map',
719
+ 'list', 'dictionary', 'dict', 'instance', 'map', 'openquote', 'parameter',
720
720
  'dynamic', 'datastruct', 'dataspace', 'shuffled', 'iterator', 'combo', 'structure')
721
721
 
722
722
  def _looks_like_function_declaration(self) -> bool:
@@ -727,14 +727,17 @@ class CSSLParser:
727
727
  - undefined int funcName(...)
728
728
  - vector<string> funcName(...)
729
729
  - undefined void funcName(...)
730
+ - private super virtual meta FuncName(...) <- modifiers without return type
730
731
  """
731
732
  saved_pos = self.pos
733
+ has_modifiers = False
732
734
 
733
735
  # Skip modifiers (undefined, open, meta, super, closed, private, virtual)
734
736
  while self._check(TokenType.KEYWORD) and self._is_function_modifier(self._current().value):
735
737
  self._advance()
738
+ has_modifiers = True
736
739
 
737
- # Check for type keyword
740
+ # Check for type keyword (optional if modifiers present)
738
741
  if self._check(TokenType.KEYWORD) and self._is_type_keyword(self._current().value):
739
742
  self._advance()
740
743
 
@@ -756,6 +759,14 @@ class CSSLParser:
756
759
  self.pos = saved_pos
757
760
  return is_func
758
761
 
762
+ # If we have modifiers and the next token is an identifier followed by (
763
+ # This handles: private super virtual meta FuncName()
764
+ elif has_modifiers and self._check(TokenType.IDENTIFIER):
765
+ self._advance()
766
+ is_func = self._check(TokenType.PAREN_START)
767
+ self.pos = saved_pos
768
+ return is_func
769
+
759
770
  self.pos = saved_pos
760
771
  return False
761
772
 
@@ -2186,7 +2186,12 @@ class CSSLRuntime:
2186
2186
 
2187
2187
  if isinstance(target, ASTNode):
2188
2188
  if target.type == 'identifier':
2189
- self.scope.set(target.value, value)
2189
+ # Check if we're in a class method and this is a class member
2190
+ # If so, set the member instead of creating a local variable
2191
+ if self._current_instance is not None and self._current_instance.has_member(target.value):
2192
+ self._current_instance.set_member(target.value, value)
2193
+ else:
2194
+ self.scope.set(target.value, value)
2190
2195
  elif target.type == 'global_ref':
2191
2196
  # r@Name = value - store in promoted globals
2192
2197
  self._promoted_globals[target.value] = value
@@ -2323,6 +2328,16 @@ class CSSLRuntime:
2323
2328
  if node.type == 'identifier':
2324
2329
  name = node.value
2325
2330
  value = self.scope.get(name)
2331
+ # Check if it's a class member in current instance context
2332
+ # This allows accessing members without 'this->' inside methods
2333
+ if value is None and self._current_instance is not None:
2334
+ if self._current_instance.has_member(name):
2335
+ value = self._current_instance.get_member(name)
2336
+ elif self._current_instance.has_method(name):
2337
+ # Return bound method
2338
+ method_node = self._current_instance.get_method(name)
2339
+ instance = self._current_instance
2340
+ value = lambda *args, **kwargs: self._call_method(instance, method_node, list(args), kwargs)
2326
2341
  # Fallback to global scope
2327
2342
  if value is None:
2328
2343
  value = self.global_scope.get(name)
@@ -53,23 +53,23 @@ function activate(context) {
53
53
  // Run the CSSL file using includecpp cssl run
54
54
  const args = ['-m', 'includecpp', 'cssl', 'run', filePath];
55
55
 
56
- const process = spawn(pythonPath, args, {
56
+ const childProcess = spawn(pythonPath, args, {
57
57
  cwd: path.dirname(filePath),
58
58
  env: { ...process.env }
59
59
  });
60
60
 
61
61
  let hasError = false;
62
62
 
63
- process.stdout.on('data', (data) => {
63
+ childProcess.stdout.on('data', (data) => {
64
64
  outputChannel.append(data.toString());
65
65
  });
66
66
 
67
- process.stderr.on('data', (data) => {
67
+ childProcess.stderr.on('data', (data) => {
68
68
  hasError = true;
69
69
  outputChannel.append(data.toString());
70
70
  });
71
71
 
72
- process.on('close', (code) => {
72
+ childProcess.on('close', (code) => {
73
73
  outputChannel.appendLine('');
74
74
  outputChannel.appendLine('─'.repeat(50));
75
75
  if (code === 0) {
@@ -79,7 +79,7 @@ function activate(context) {
79
79
  }
80
80
  });
81
81
 
82
- process.on('error', (err) => {
82
+ childProcess.on('error', (err) => {
83
83
  outputChannel.appendLine(`[CSSL] Error: ${err.message}`);
84
84
  vscode.window.showErrorMessage(`Failed to run CSSL: ${err.message}. Make sure IncludeCPP is installed (pip install includecpp).`);
85
85
  });
@@ -2,7 +2,7 @@
2
2
  "name": "cssl",
3
3
  "displayName": "CSSL Language",
4
4
  "description": "Professional syntax highlighting, snippets, and language support for CSSL scripts (.cssl, .cssl-pl, .cssl-mod)",
5
- "version": "1.3.0",
5
+ "version": "1.3.1",
6
6
  "publisher": "IncludeCPP",
7
7
  "icon": "images/cssl.png",
8
8
  "engines": {
@@ -1076,5 +1076,131 @@
1076
1076
  "}"
1077
1077
  ],
1078
1078
  "description": "Open parameter function"
1079
+ },
1080
+ "Undefined Function": {
1081
+ "prefix": ["undefined", "undef"],
1082
+ "body": [
1083
+ "undefined ${1:void} ${2:FuncName}(${3:params}) {",
1084
+ "\t$0",
1085
+ "}"
1086
+ ],
1087
+ "description": "Function with undefined modifier - suppresses all errors during execution"
1088
+ },
1089
+ "Private Function": {
1090
+ "prefix": "private",
1091
+ "body": [
1092
+ "private ${1:void} ${2:FuncName}(${3:params}) {",
1093
+ "\t$0",
1094
+ "}"
1095
+ ],
1096
+ "description": "Private function - disables all external injections"
1097
+ },
1098
+ "Closed Function": {
1099
+ "prefix": "closed",
1100
+ "body": [
1101
+ "closed ${1:void} ${2:FuncName}(${3:params}) {",
1102
+ "\t$0",
1103
+ "}"
1104
+ ],
1105
+ "description": "Closed function - protects from external injection modifications"
1106
+ },
1107
+ "Virtual Function": {
1108
+ "prefix": "virtual",
1109
+ "body": [
1110
+ "virtual ${1:void} ${2:FuncName}(${3:params}) {",
1111
+ "\t$0",
1112
+ "}"
1113
+ ],
1114
+ "description": "Virtual function - can be overridden in child classes"
1115
+ },
1116
+ "Meta Function": {
1117
+ "prefix": "meta",
1118
+ "body": [
1119
+ "meta ${1:void} ${2:FuncName}(${3:params}) {",
1120
+ "\t$0",
1121
+ "}"
1122
+ ],
1123
+ "description": "Meta function - metaprogramming function for code generation"
1124
+ },
1125
+ "Super Function": {
1126
+ "prefix": "super",
1127
+ "body": [
1128
+ "super ${1:void} ${2:FuncName}(${3:params}) {",
1129
+ "\t$0",
1130
+ "}"
1131
+ ],
1132
+ "description": "Super function - enhanced privileges for system-level operations"
1133
+ },
1134
+ "SQLBased Function": {
1135
+ "prefix": "sqlbased",
1136
+ "body": [
1137
+ "sqlbased ${1:void} ${2:FuncName}(${3:params}) {",
1138
+ "\t$0",
1139
+ "}"
1140
+ ],
1141
+ "description": "SQL-based function - optimized for database operations"
1142
+ },
1143
+ "API Function with Modifiers": {
1144
+ "prefix": ["apifunc", "globalapi"],
1145
+ "body": [
1146
+ "private super virtual meta ${1:GlobalApi}() {",
1147
+ "\tinstance<\"${2:apiName}\"> api;",
1148
+ "\tclass ${3:Api} {",
1149
+ "\t\tdefine ${4:getMethod}() {",
1150
+ "\t\t\t$0",
1151
+ "\t\t}",
1152
+ "\t}",
1153
+ "\t%api +<== new ${3}();",
1154
+ "\treturn %api;",
1155
+ "}"
1156
+ ],
1157
+ "description": "Global API function with full modifiers and instance pattern"
1158
+ },
1159
+ "Combined Modifiers Function": {
1160
+ "prefix": "modfunc",
1161
+ "body": [
1162
+ "${1|undefined,private,closed,virtual,meta,super,sqlbased|} ${2|undefined,private,closed,virtual,meta,super,sqlbased,void,int,string|} ${3:FuncName}(${4:params}) {",
1163
+ "\t$0",
1164
+ "}"
1165
+ ],
1166
+ "description": "Function with selectable modifier combinations"
1167
+ },
1168
+ "Python Pythonize": {
1169
+ "prefix": ["python::pythonize", "pythonize"],
1170
+ "body": "python::pythonize(${1:instance})$0",
1171
+ "description": "Convert CSSL class instance to Python-usable object"
1172
+ },
1173
+ "Return Pythonized Class": {
1174
+ "prefix": "returnpython",
1175
+ "body": [
1176
+ "${1:instance} = new ${2:ClassName}(${3:args});",
1177
+ "pyobj = python::pythonize(${1});",
1178
+ "parameter.return(pyobj);"
1179
+ ],
1180
+ "description": "Create class instance and return as Python object"
1181
+ },
1182
+ "Class with Python Export": {
1183
+ "prefix": "pyclass",
1184
+ "body": [
1185
+ "class ${1:ClassName} {",
1186
+ "\t${2:string} ${3:name};",
1187
+ "",
1188
+ "\t${1}(${4:params}) {",
1189
+ "\t\tthis->${3} = ${5:value};",
1190
+ "\t}",
1191
+ "",
1192
+ "\t${6:string} get${3/(.*)/${1:/capitalize}/}() {",
1193
+ "\t\treturn this->${3};",
1194
+ "\t}",
1195
+ "",
1196
+ "\tvoid set${3/(.*)/${1:/capitalize}/}(${2} newValue) {",
1197
+ "\t\tthis->${3} = newValue;",
1198
+ "\t}",
1199
+ "}",
1200
+ "",
1201
+ "${7:obj} = new ${1}(${8:args});",
1202
+ "parameter.return(python::pythonize(${7}));$0"
1203
+ ],
1204
+ "description": "Create a class and export as Python object"
1079
1205
  }
1080
1206
  }
@@ -319,6 +319,14 @@
319
319
  {
320
320
  "name": "support.function.namespace.combo.cssl",
321
321
  "match": "\\bcombo::(filterdb|blocked|like)\\b"
322
+ },
323
+ {
324
+ "name": "support.function.namespace.python.cssl",
325
+ "match": "\\bpython::(pythonize|wrap|export)\\b"
326
+ },
327
+ {
328
+ "name": "support.function.namespace.filter.cssl",
329
+ "match": "\\bfilter::(register|unregister|list|exists)\\b"
322
330
  }
323
331
  ]
324
332
  },
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.7.25
3
+ Version: 3.8.0
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
@@ -839,7 +839,7 @@ print(math_mod.multiply(4, 5)) # 20
839
839
  cssl = CSSL.CsslLang()
840
840
 
841
841
  # Register code as payload
842
- cssl.code("helpers", '''
842
+ cssl.script(<name>, "helpers", '''
843
843
  global version = "1.0.0";
844
844
  void log(string msg) {
845
845
  printl("[LOG] " + msg);
@@ -847,230 +847,61 @@ cssl.code("helpers", '''
847
847
  ''')
848
848
 
849
849
  # Use in CSSL
850
- cssl.exec('''
851
- payload("helpers");
850
+ cssl.run('''
851
+ payload("<name>"); // use module you declared in cssl.script(<name>, ...)
852
852
  @log("Application started");
853
853
  printl(@version);
854
854
  ''')
855
855
  ```
856
856
 
857
- # Changelog
858
-
859
- ## v3.4.20
860
- - **Documentation:**
861
- - Added complete CSSL language documentation
862
- - Live object sharing with `$name` syntax
863
- - Data types, control flow, functions, injection system
864
- - String methods, modules, and inline payloads
865
-
866
- ## v3.4.19
867
- - **Critical Bug Fixes:**
868
- - Fixed generator raw string literal in parser.cpp (regex pattern with `)"` prematurely terminated)
869
- - Fixed shared object property writes inside loops not persisting to Python
870
- - Added member_access handling in flow operations for shared objects
871
-
872
- ## v3.4.18
873
- - **Bug Fix:**
874
- - Attempted fix for shared object loop writes (partially fixed)
875
-
876
- ## v3.4.17
877
- - **New Feature: Live Object Sharing**
878
- - `cssl.share(instance, name)` - Share Python objects with CSSL
879
- - `$name` syntax for accessing shared objects
880
- - Live bidirectional updates - changes in CSSL reflect in Python
881
- - `delete("name")` builtin for removing shared objects
882
- - Shared object metadata stored in `%APPDATA%/IncludeCPP/shared_objects/`
883
-
884
- ## v3.4.16
885
- - **CSSL Bug Fixes:**
886
- - Fixed `startsWith()` and `endsWith()` parser errors
887
-
888
- ## v3.4.15
889
- - **CSSL Enhancements:**
890
- - Added `elif` keyword support
891
- - Added `range(start, end, step)` with step parameter
892
- - Added `begin()` and `end()` methods to all collection types
893
- - Added `cssl.code(name, code)` for inline payload registration
894
-
895
- ## v3.4.2
896
- - **New Feature: `exec` Command**
897
- - Interactive REPL for quick code testing without creating files
898
- - `includecpp exec py` - Python REPL with IncludeCPP support
899
- - `includecpp exec cpp` - C++ REPL with auto-compilation
900
- - Auto-import modules: `includecpp exec py mymodule`
901
- - Auto-import from plugins: `includecpp exec py plugins/math.cp`
902
- - Import all modules: `includecpp exec py --all`
903
- - Enter code line by line, press ENTER on empty line to execute
904
-
905
- ## v3.4.1
906
- - **Bug Fixes:**
907
- - fix command: Fixed false positives for unused variables (sum, memory_) using word-boundary matching
908
- - CPPY: C++ reserved words (double, int, void, etc.) now properly escaped as Python identifiers
909
- - CPPY: C++ STL functions (accumulate, find, sort, reverse) properly converted to Python equivalents
910
- - CPPY: Member variables with trailing underscore (memory_) now get self. prefix
911
- - CPPY: Private class members now detected for self. prefix conversion
912
- - Plugin: Auto-detect header files from #include directives in source files
913
-
914
- ## v3.4.0
915
- - **CodeMaker Major Update:**
916
- - New Source node type with 8 connection ports for code generation
917
- - Smart code generation: Source nodes generate Python/Plugin files with all connected nodes included
918
- - Right-click on Source node: "Create Python" creates .py in project root
919
- - Right-click on Source node: "Create Plugin" creates .cp, .h, .cpp in plugins/ and include/
920
- - Code options hidden after file generation (prevents duplicates)
921
- - Enhanced description display with background rect in node body
922
- - Arrow key navigation to pan the canvas
923
- - New toolbar buttons: Align H, Align V, Auto-Arrange
924
- - Quick-add buttons: +Source, +Class, +Function
925
- - Properties Panel on the right side for editing selected nodes
926
- - Auto-arrange algorithm for grid layout
927
- - Align horizontal/vertical for selected nodes
928
- - **Bug Fixes:**
929
- - Changelog encoding fixes for Windows console
930
- - CPPY C++ keyword escaping (double, int, etc.)
931
- - CPPY C++ to Python syntax conversion improvements
932
- - CPPY self. prefix for member variables
933
- - Plugin auto-header detection from #include
934
-
935
- ## v3.3.21
936
- - **Encoding Fixes:**
937
- - Replaced Unicode arrow characters with ASCII in changelog (Windows console compatibility)
938
-
939
- ## v3.3.20
940
- - **Bug Fixes:**
941
- - Fixed `QPoint.toPoint()` AttributeError in rubber band selection
942
- - Added UTF-8 encoding to all file read/write operations for cross-platform compatibility
943
- - Fixed bare `except:` clauses to proper `except Exception:` in settings_ui.py
944
-
945
- ## v3.3.19
946
- - **PyQt6 Import Fix:**
947
- - Fixed silent import failure that caused "PyQt6 not installed" error even when installed
948
- - Moved `QUndoStack`, `QUndoCommand`, `QShortcut` from QtWidgets to QtGui (correct location in PyQt6)
949
-
950
- ## v3.3.18
951
- - **CodeMaker Visual Editor (Experimental):**
952
- - Complete rewrite of `project` command with professional-grade UI
953
- - 24 node types across 5 categories (Code Structures, Functions, Data, Organization, Flow)
954
- - Undo/redo system with full command history
955
- - Multi-selection with rubber band and Ctrl+Click
956
- - Copy/paste/duplicate with Ctrl+C/V/D shortcuts
957
- - Node grouping with Ctrl+G
958
- - Code generation for C++ (header/source) and Python
959
- - Search and filter nodes by name and type
960
- - Export to PNG/SVG with transparency support
961
- - Categorized right-click context menus
962
- - Toolbar with common actions
963
- - Cross-platform font detection (Windows/macOS/Linux)
964
- - DPI-aware scaling for high-resolution displays
965
- - **Experimental Feature Gating:**
966
- - `project` command now requires "Enable Experimental Features" in settings
967
- - Consistent gating with `ai` and `cppy` commands
968
-
969
- ## v3.3.16-3.3.17
970
- - **QPen Bug Fixes:**
971
- - Fixed 3 instances of `setPen(Qt.PenStyle.NoPen)` to `setPen(QPen(Qt.PenStyle.NoPen))`
972
- - Proper QPen construction for PyQt6 compatibility
973
-
974
- ## v3.3.15
975
- - **CPPY Converter Major Fixes:**
976
- - Functions returning container now get `std::vector<T>` return type (e.g., shuffle_list)
977
- - `max(items)` / `min(items)` now correctly uses `std::max_element` / `std::min_element`
978
- - Template element parameters (`value`, `item`) now use `const T&` instead of `double`
979
- - Explicit template instantiations now include correct return types and all parameters
980
- - Python docstrings now become C++ comments instead of dangling string literals
981
- - **Unicode Fallback System:**
982
- - AI progress indicators use ASCII fallbacks on Windows terminals
983
- - Fixed encoding errors in changelog display
984
-
985
- ## v3.3.14
986
- - **Experimental Features System:**
987
- - AI and CPPY commands now hidden by default
988
- - Enable via Settings UI: "Enable Experimental Features" checkbox
989
- - Warning about potential bugs documented in README
990
- - **Settings UI Improvements:**
991
- - Added scrollable content area to prevent layout squashing
992
- - New "Experimental" section with orange header
993
- - Better spacing and styling for all elements
994
- - Preserved existing config values on save
995
-
996
- ## v3.3.13
997
- - **Template Support for Generic Functions:**
998
- - Generic container parameters now generate proper C++ templates
999
- - `template<typename T> T getChoice(const std::vector<T>& choices)` instead of invalid `std::vector<auto>`
1000
- - Automatic explicit template instantiations for int, double, std::string
1001
- - **AI Conversion - No pybind11:**
1002
- - AI no longer generates pybind11 code - IncludeCPP handles bindings automatically
1003
- - Clean C++ output in `namespace includecpp`
1004
- - User runs `includecpp plugin` separately to generate bindings
1005
- - **AI Context - Dynamic README:**
1006
- - AI now loads README.md dynamically for accurate IncludeCPP documentation
1007
- - Better understanding of IncludeCPP workflow and patterns
1008
-
1009
- ## v3.3.12
1010
- - **Smart Type Inference:**
1011
- - Parameter types now inferred from common naming patterns (start/end -> int, name/path -> string, etc.)
1012
- - Variable type tracking throughout conversion for accurate string detection
1013
- - Loop variable types inferred from iterables (enumerate, for loops)
1014
- - **String Conversion Fix:**
1015
- - No more `std::to_string()` on already-string variables in f-strings
1016
- - `_is_string_expr()` method for comprehensive string type detection
1017
- - String variables detected by name, type tracking, and method calls
1018
- - **AI Conversion Improvements:**
1019
- - Explicit file extension enforcement (.cpp NOT .cp, .h NOT .hpp)
1020
- - Better --no-h flag handling with clear AI instructions
1021
- - AI can request clarification on unconvertible modules (tkinter, pygame, etc.)
1022
- - User prompted for input when AI needs guidance
1023
-
1024
- ## v3.3.11
1025
- - **CPPY Converter Improvements:**
1026
- - Added `_safe_arg()` and `_safe_get()` for robust bounds checking on all args
1027
- - Added comprehensive try-except handling in `_convert_expr()` with warnings
1028
- - Improved type inference with empty container handling and exception safety
1029
- - Complete string escaping: `\0`, `\f`, `\b`, `\a`, `\v` now properly escaped
1030
- - **New Python Constructs:**
1031
- - Dict comprehensions: `{k: v for k, v in items}` now converts to C++
1032
- - Set comprehensions: `{x for x in items}` now converts to C++
1033
- - Generator expressions: `(x for x in items)` now converts to vector
1034
- - Tuple unpacking: `a, b = func()` now uses C++17 structured bindings
1035
- - **AI Conversion Flags:**
1036
- - New `--think` flag for less context mode
1037
- - New `--think3` flag for maximum context mode
1038
- - New `--websearch` flag for web search in AI conversion
1039
- - Default: `--think2` mode (unchanged behavior)
1040
-
1041
- ## v3.3.10
1042
- - **CPPY Converter seeded RNG fixes:**
1043
- - Fixed `rng = random.Random(seed)` then `rng.randint()` - now properly tracks seeded RNG variables
1044
- - Fixed `random.choices(...)[0]` subscript - returns single element directly without `[0]`
1045
- - Seeded RNG methods (randint, uniform, choice, random) now use the tracked variable with proper C++ distributions
1046
-
1047
- ## v3.3.9
1048
- - **CPPY Converter fixes:**
1049
- - Added f-string (JoinedStr) support - f"text {expr}" now converts to string concatenation
1050
- - Fixed `random.Random(seed).method()` chained calls - now generates proper inline lambda with seeded RNG
1051
- - Fixed `random.choices(items, weights=weights)` keyword argument handling
1052
- - Improved string type detection in f-string expressions
1053
-
1054
- ## v3.3.8
1055
- - **Major rulebased converter improvements:**
1056
- - Added Python `random` module support (randint, uniform, choice, sample, shuffle, gauss, etc.)
1057
- - Added `os` module support (getcwd, path.join, path.exists, listdir, mkdir, etc.)
1058
- - Added `time` module support (sleep, time, perf_counter, monotonic)
1059
- - Added `sys` module support (exit, platform)
1060
- - Added `math` module support (sqrt, pow, sin, cos, log, etc.)
1061
- - Added `re` (regex) module support (match, search, sub, findall)
1062
- - Added `threading` module support (Thread, Lock, Semaphore, etc.)
1063
- - Added `collections` module support (deque, defaultdict, Counter)
1064
- - Added `pathlib.Path` support
1065
- - **Unconvertible code detection:**
1066
- - Automatically detects GUI frameworks (tkinter, PyQt, PySide, pygame) and other unconvertible modules
1067
- - Shows red warning with line numbers when unconvertible code is found
1068
- - New `--force` flag to convert anyway (with `/* UNCONVERTIBLE */` comments)
1069
- - Supports 30+ modules in detection (numpy, pandas, flask, django, etc.)
1070
- - Fixed duplicate file output in `cppy convert --ai`
1071
- - Plugin command now skips inline and underscore-prefixed functions
1072
-
1073
-
1074
- ---
1075
-
1076
- MIT License | v3.4.20 | [GitHub](https://github.com/liliassg/IncludeCPP)
857
+ ## Return CSSL Classes to Python
858
+
859
+ Use `python::pythonize()` to convert CSSL class instances into Python-usable objects:
860
+
861
+ ```python
862
+ from includecpp import CSSL
863
+
864
+ cssl = CSSL.CsslLang()
865
+
866
+ # Create and return a CSSL class as a Python object
867
+ greeter = cssl.run('''
868
+ class Greeter {
869
+ string name;
870
+
871
+ Greeter(string n) {
872
+ this->name = n;
873
+ }
874
+
875
+ string sayHello() {
876
+ return "Hello, " + this->name + "!";
877
+ }
878
+
879
+ void setName(string newName) {
880
+ this->name = newName;
881
+ }
882
+
883
+ string getName() {
884
+ return this->name;
885
+ }
886
+ }
887
+
888
+ instance = new Greeter("World");
889
+ pyclass = python::pythonize(instance);
890
+ parameter.return(pyclass);
891
+ ''')
892
+
893
+ # Now use it like a normal Python object!
894
+ print(greeter.name) # "World"
895
+ print(greeter.sayHello()) # "Hello, World!"
896
+ greeter.setName("Python")
897
+ print(greeter.getName()) # "Python"
898
+ print(greeter.name) # "Python"
899
+ ```
900
+
901
+ ### Aliases
902
+
903
+ - `python::pythonize(instance)` - Main function
904
+ - `python::wrap(instance)` - Alias
905
+ - `python::export(instance)` - Alias
906
+
907
+ All three do the same thing: wrap a CSSL class instance for Python use.
@@ -1,9 +1,9 @@
1
- includecpp/__init__.py,sha256=YgP_G9kl_90bbm_zr9NJq-rDfpM76tC8vfJGNIHBYxY,1673
1
+ includecpp/__init__.py,sha256=cheZCblYfeG2PZg9V8rAeFxzczvL3Ii7cjvuC6lE6Jw,1672
2
2
  includecpp/__init__.pyi,sha256=uSDYlbqd2TinmrdepmE_zvN25jd3Co2cgyPzXgDpopM,7193
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=HDoRuPEPTzxZQcR4rF45GrRVtcw3zDj6cGiwLCZB44Y,349597
6
+ includecpp/cli/commands.py,sha256=R1wZeka7AMUVd61TSTUZ2utjCdorFY3wO_Ahs749iyc,350475
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
@@ -21,12 +21,12 @@ includecpp/core/project_ui.py,sha256=la2EQZKmUkJGuJxnbs09hH1ZhBh9bfndo6okzZsk2dQ
21
21
  includecpp/core/settings_ui.py,sha256=B2SlwgdplF2KiBk5UYf2l8Jjifjd0F-FmBP0DPsVCEQ,11798
22
22
  includecpp/core/cssl/CSSL_DOCUMENTATION.md,sha256=47sUPO-FMq_8_CrJBZFoFBgSO3gSi5zoB1Xp7oeifho,40773
23
23
  includecpp/core/cssl/__init__.py,sha256=scDXRBNK2L6A8qmlpNyaqQj6BFcSfPInBlucdeNfMF0,1975
24
- includecpp/core/cssl/cssl_builtins.py,sha256=r-FX4WQeKxerkepqodIiwhtL_kxxa4PJym_WyWIwA_s,92290
24
+ includecpp/core/cssl/cssl_builtins.py,sha256=B_ggaV4zE1kejphXmo0-_XKFyxU4BWv_g0j_KzHpLJI,100225
25
25
  includecpp/core/cssl/cssl_builtins.pyi,sha256=3ai2V4LyhzPBhAKjRRf0rLVu_bg9ECmTfTkdFKM64iA,127430
26
26
  includecpp/core/cssl/cssl_events.py,sha256=nupIcXW_Vjdud7zCU6hdwkQRQ0MujlPM7Tk2u7eDAiY,21013
27
27
  includecpp/core/cssl/cssl_modules.py,sha256=cUg0-zdymMnWWTsA_BUrW5dx4R04dHpKcUhm-Wfiwwo,103006
28
- includecpp/core/cssl/cssl_parser.py,sha256=fphjjN2MRURMkqi0lFEf6l61xC9IPImlYVjlqonZZHc,117139
29
- includecpp/core/cssl/cssl_runtime.py,sha256=iZgNcKDoTeV50-IsXcsrpuTyDPxEHWyQz5uR3s5UVHg,154613
28
+ includecpp/core/cssl/cssl_parser.py,sha256=WxfqNhsryt5IR7KdDgbHrrYlXS-xBXTsr3YAiGBJZIc,117711
29
+ includecpp/core/cssl/cssl_runtime.py,sha256=LeBZJeiK_XjhJ1QoU1duLxgr6MNb8EenluCRBUtNIyE,155680
30
30
  includecpp/core/cssl/cssl_syntax.py,sha256=bgo3NFehoPTQa5dqwNd_CstkVGVCNYAXbGYUcu5BEN0,16982
31
31
  includecpp/core/cssl/cssl_types.py,sha256=gVjtfxk0Uzfj-H7_LD79oqspFMYDf79ZrRrlZk8eAEs,50647
32
32
  includecpp/generator/__init__.py,sha256=Rsy41bwimaEloD3gDRR_znPfIJzIsCFuWZgCTJBLJlc,62
@@ -37,16 +37,16 @@ includecpp/generator/type_resolver.h,sha256=ZsaxQqcCcKJJApYn7KOp2dLlQ1VFVG_oZDja
37
37
  includecpp/templates/cpp.proj.template,sha256=Iy-L8I4Cl3tIgBMx1Qp5h6gURvkqOAqyodVHuDJ0Luw,359
38
38
  includecpp/vscode/__init__.py,sha256=yLKw-_7MTX1Rx3jLk5JjharJQfFXbwtZVE7YqHpM7yg,39
39
39
  includecpp/vscode/cssl/__init__.py,sha256=rQJAx5X05v-mAwqX1Qb-rbZO219iR73MziFNRUCNUIo,31
40
- includecpp/vscode/cssl/extension.js,sha256=YLFDuKQVdGi15l_vUadD9nlu8mcjzUm_rKj4-oxV-ak,4302
40
+ includecpp/vscode/cssl/extension.js,sha256=FZaKfOpzo2jXtubVCZmnhDZd4eUVHltm5VW_fgNnSkE,4327
41
41
  includecpp/vscode/cssl/language-configuration.json,sha256=61Q00cKI9may5L8YpxMmvfo6PAc-abdJqApfR85DWuw,904
42
- includecpp/vscode/cssl/package.json,sha256=Zu2QoTE0OVCCDUHp1hc7kN2NBbFs60bX-LLGMpXz25M,4853
42
+ includecpp/vscode/cssl/package.json,sha256=kTV4gTigAQ93FIoidjlZW3znKT2_KOXDo2e8evNFTNs,4853
43
43
  includecpp/vscode/cssl/images/cssl.png,sha256=BxAGsnfS0ZzzCvqV6Zb1OAJAZpDUoXlR86MsvUGlSZw,510
44
44
  includecpp/vscode/cssl/images/cssl_pl.png,sha256=z4WMk7g6YCTbUUbSFk343BO6yi_OmNEVYkRenWGydwM,799
45
- includecpp/vscode/cssl/snippets/cssl.snippets.json,sha256=l4SCEPR3CsPxA8HIVLKYY__I979TfKzYWtH1KYIsboo,33062
46
- includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json,sha256=XKRLBOHlCqDDnGPvmNHDQPsIMR1UD9PBaJIlgZOiPqM,21173
47
- includecpp-3.7.25.dist-info/licenses/LICENSE,sha256=fWCsGGsiWZir0UzDd20Hh-3wtRyk1zqUntvtVuAWhvc,1093
48
- includecpp-3.7.25.dist-info/METADATA,sha256=7e3lYqfMjuU6hs9mv5Ol5l7Zpjtr5I_QXp5Mmxh2ftQ,32122
49
- includecpp-3.7.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
- includecpp-3.7.25.dist-info/entry_points.txt,sha256=6A5Mif9gi0139Bf03W5plAb3wnAgbNaEVe1HJoGE-2o,59
51
- includecpp-3.7.25.dist-info/top_level.txt,sha256=RFUaR1KG-M6mCYwP6w4ydP5Cgc8yNbP78jxGAvyjMa8,11
52
- includecpp-3.7.25.dist-info/RECORD,,
45
+ includecpp/vscode/cssl/snippets/cssl.snippets.json,sha256=uV3nHJyQ5f7Pr3FzfbQT2VZOEY3AlGs4wrmqe884jm4,37372
46
+ includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json,sha256=ArCRc_G54kiKGh6WEd4CbmR-SX1X9BOcp3Y0hwZcw44,21543
47
+ includecpp-3.8.0.dist-info/licenses/LICENSE,sha256=fWCsGGsiWZir0UzDd20Hh-3wtRyk1zqUntvtVuAWhvc,1093
48
+ includecpp-3.8.0.dist-info/METADATA,sha256=gnvN0QtGJ_QWGfkyXFKR1kwE4z-8sRz10k3Z3lIMBvs,22510
49
+ includecpp-3.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
+ includecpp-3.8.0.dist-info/entry_points.txt,sha256=6A5Mif9gi0139Bf03W5plAb3wnAgbNaEVe1HJoGE-2o,59
51
+ includecpp-3.8.0.dist-info/top_level.txt,sha256=RFUaR1KG-M6mCYwP6w4ydP5Cgc8yNbP78jxGAvyjMa8,11
52
+ includecpp-3.8.0.dist-info/RECORD,,