IncludeCPP 3.7.5__tar.gz → 3.7.11__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 (60) hide show
  1. {includecpp-3.7.5 → includecpp-3.7.11}/IncludeCPP.egg-info/PKG-INFO +1 -1
  2. {includecpp-3.7.5 → includecpp-3.7.11}/IncludeCPP.egg-info/SOURCES.txt +4 -0
  3. {includecpp-3.7.5 → includecpp-3.7.11}/PKG-INFO +1 -1
  4. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/__init__.py +1 -1
  5. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/cli/commands.py +219 -129
  6. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/CSSL_DOCUMENTATION.md +27 -8
  7. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_parser.py +42 -3
  8. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_runtime.py +44 -2
  9. includecpp-3.7.11/includecpp/vscode/cssl/images/cssl.png +0 -0
  10. includecpp-3.7.11/includecpp/vscode/cssl/images/cssl_pl.png +0 -0
  11. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/vscode/cssl/language-configuration.json +1 -4
  12. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/vscode/cssl/package.json +24 -5
  13. includecpp-3.7.11/includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +527 -0
  14. {includecpp-3.7.5 → includecpp-3.7.11}/pyproject.toml +3 -2
  15. includecpp-3.7.5/includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +0 -341
  16. {includecpp-3.7.5 → includecpp-3.7.11}/IncludeCPP.egg-info/dependency_links.txt +0 -0
  17. {includecpp-3.7.5 → includecpp-3.7.11}/IncludeCPP.egg-info/entry_points.txt +0 -0
  18. {includecpp-3.7.5 → includecpp-3.7.11}/IncludeCPP.egg-info/requires.txt +0 -0
  19. {includecpp-3.7.5 → includecpp-3.7.11}/IncludeCPP.egg-info/top_level.txt +0 -0
  20. {includecpp-3.7.5 → includecpp-3.7.11}/LICENSE +0 -0
  21. {includecpp-3.7.5 → includecpp-3.7.11}/MANIFEST.in +0 -0
  22. {includecpp-3.7.5 → includecpp-3.7.11}/README.md +0 -0
  23. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/__init__.pyi +0 -0
  24. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/__main__.py +0 -0
  25. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/cli/__init__.py +0 -0
  26. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/cli/config_parser.py +0 -0
  27. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/__init__.py +0 -0
  28. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/ai_integration.py +0 -0
  29. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/build_manager.py +0 -0
  30. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cpp_api.py +0 -0
  31. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cpp_api.pyi +0 -0
  32. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cppy_converter.py +0 -0
  33. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/__init__.py +0 -0
  34. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_builtins.py +0 -0
  35. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_builtins.pyi +0 -0
  36. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_events.py +0 -0
  37. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_modules.py +0 -0
  38. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_syntax.py +0 -0
  39. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl/cssl_types.py +0 -0
  40. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl_bridge.py +0 -0
  41. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/cssl_bridge.pyi +0 -0
  42. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/error_catalog.py +0 -0
  43. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/error_formatter.py +0 -0
  44. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/exceptions.py +0 -0
  45. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/path_discovery.py +0 -0
  46. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/project_ui.py +0 -0
  47. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/core/settings_ui.py +0 -0
  48. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/generator/__init__.py +0 -0
  49. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/generator/parser.cpp +0 -0
  50. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/generator/parser.h +0 -0
  51. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/generator/type_resolver.cpp +0 -0
  52. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/generator/type_resolver.h +0 -0
  53. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/py.typed +0 -0
  54. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/templates/cpp.proj.template +0 -0
  55. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/vscode/__init__.py +0 -0
  56. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/vscode/cssl/__init__.py +0 -0
  57. {includecpp-3.7.5 → includecpp-3.7.11}/includecpp/vscode/cssl/snippets/cssl.snippets.json +0 -0
  58. {includecpp-3.7.5 → includecpp-3.7.11}/requirements.txt +0 -0
  59. {includecpp-3.7.5 → includecpp-3.7.11}/setup.cfg +0 -0
  60. {includecpp-3.7.5 → includecpp-3.7.11}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.7.5
3
+ Version: 3.7.11
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
@@ -45,6 +45,8 @@ setup.py
45
45
  ./includecpp/vscode/cssl/__init__.py
46
46
  ./includecpp/vscode/cssl/language-configuration.json
47
47
  ./includecpp/vscode/cssl/package.json
48
+ ./includecpp/vscode/cssl/images/cssl.png
49
+ ./includecpp/vscode/cssl/images/cssl_pl.png
48
50
  ./includecpp/vscode/cssl/snippets/cssl.snippets.json
49
51
  ./includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json
50
52
  IncludeCPP.egg-info/PKG-INFO
@@ -94,5 +96,7 @@ includecpp/vscode/__init__.py
94
96
  includecpp/vscode/cssl/__init__.py
95
97
  includecpp/vscode/cssl/language-configuration.json
96
98
  includecpp/vscode/cssl/package.json
99
+ includecpp/vscode/cssl/images/cssl.png
100
+ includecpp/vscode/cssl/images/cssl_pl.png
97
101
  includecpp/vscode/cssl/snippets/cssl.snippets.json
98
102
  includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IncludeCPP
3
- Version: 3.7.5
3
+ Version: 3.7.11
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.7.5"
5
+ __version__ = "3.7.11"
6
6
  __all__ = ["CppApi", "CSSL"]
7
7
 
8
8
  # Module-level cache for C++ modules
@@ -1193,7 +1193,7 @@ def build(ctx, clean, keep, verbose, no_incremental, incremental, parallel, jobs
1193
1193
  @cli.command()
1194
1194
  @click.argument('module_name')
1195
1195
  def add(module_name):
1196
- """Create a new module template."""
1196
+ """Create a new module template with sample C++ code."""
1197
1197
  plugins_dir = Path("plugins")
1198
1198
  if not plugins_dir.exists():
1199
1199
  click.echo("Error: plugins/ directory not found")
@@ -1204,6 +1204,7 @@ def add(module_name):
1204
1204
  click.echo(f"Module {module_name} already exists")
1205
1205
  return
1206
1206
 
1207
+ # Create .cp config file
1207
1208
  template = f"""SOURCE(include/{module_name}.cpp) {module_name}
1208
1209
 
1209
1210
  PUBLIC(
@@ -1215,7 +1216,41 @@ PUBLIC(
1215
1216
  f.write(template)
1216
1217
 
1217
1218
  click.echo(f"Created {cp_file}")
1218
- click.echo(f"Now create include/{module_name}.cpp with your C++ code")
1219
+
1220
+ # Create include/ directory if it doesn't exist
1221
+ include_dir = Path("include")
1222
+ include_dir.mkdir(exist_ok=True)
1223
+
1224
+ # Create .cpp file with sample code
1225
+ cpp_file = include_dir / f"{module_name}.cpp"
1226
+ if not cpp_file.exists():
1227
+ cpp_template = f"""#include <string>
1228
+ #include <vector>
1229
+
1230
+ namespace includecpp {{
1231
+
1232
+ // Example function - returns a greeting
1233
+ std::string example_function(const std::string& name) {{
1234
+ return "Hello, " + name + "!";
1235
+ }}
1236
+
1237
+ // Add more functions here...
1238
+ // int add(int a, int b) {{ return a + b; }}
1239
+ // std::vector<int> range(int n) {{ ... }}
1240
+
1241
+ }} // namespace includecpp
1242
+ """
1243
+ with open(cpp_file, 'w', encoding='utf-8') as f:
1244
+ f.write(cpp_template)
1245
+
1246
+ click.echo(f"Created {cpp_file}")
1247
+ else:
1248
+ click.echo(f"Note: {cpp_file} already exists, skipped")
1249
+
1250
+ click.echo(f"\nNext steps:")
1251
+ click.echo(f" 1. Edit include/{module_name}.cpp to add your functions")
1252
+ click.echo(f" 2. Update plugins/{module_name}.cp to expose functions")
1253
+ click.echo(f" 3. Run: includecpp rebuild")
1219
1254
 
1220
1255
  @cli.command('list')
1221
1256
  def list_modules():
@@ -7480,13 +7515,12 @@ def cssl_exec(path, code):
7480
7515
  # Execute
7481
7516
  click.secho("--- Output ---", fg='green')
7482
7517
  try:
7483
- result = cssl_lang.exec(source)
7518
+ result = cssl_lang.run(source)
7484
7519
 
7485
7520
  # Output is already printed to stdout during execution via runtime.output()
7486
- # No need to print buffer again - this was causing double output
7487
-
7488
- if result is not None:
7489
- click.echo(f"Result: {result}")
7521
+ # Don't print "Result:" automatically - users should use printl() for output
7522
+ # This prevents unwanted output for function calls like: Function();
7523
+ pass
7490
7524
 
7491
7525
  except Exception as e:
7492
7526
  click.secho(f"CSSL Error: {e}", fg='red')
@@ -7595,75 +7629,95 @@ def cssl_doc(search, list_sections):
7595
7629
  click.secho("=" * 50, fg='cyan')
7596
7630
  click.echo()
7597
7631
 
7598
- # Split into sections (## headers)
7599
- sections = re.split(r'(?=^## )', content, flags=re.MULTILINE)
7600
-
7601
- found_sections = []
7602
- for section in sections:
7603
- if search.lower() in section.lower():
7604
- found_sections.append(section)
7605
-
7606
- if found_sections:
7607
- # Also find specific lines with the search term
7608
- all_lines = content.split('\n')
7609
- matching_lines = []
7610
- for i, line in enumerate(all_lines):
7611
- if search.lower() in line.lower():
7612
- # Get context (2 lines before and after)
7613
- start = max(0, i - 2)
7614
- end = min(len(all_lines), i + 3)
7615
- context = '\n'.join(all_lines[start:end])
7616
- if context not in matching_lines:
7617
- matching_lines.append((i + 1, context))
7618
-
7619
- # Show summary
7620
- click.secho(f"Found in {len(found_sections)} section(s):", fg='green')
7621
- for section in found_sections:
7622
- # Extract section title
7623
- title_match = re.match(r'^##\s+(.+)$', section, re.MULTILINE)
7624
- if title_match:
7625
- click.echo(f" - {title_match.group(1)}")
7632
+ # Split into subsections (### headers) for focused results
7633
+ subsections = re.split(r'(?=^### )', content, flags=re.MULTILINE)
7626
7634
 
7627
- click.echo()
7635
+ # Also split into main sections (## headers)
7636
+ main_sections = re.split(r'(?=^## )', content, flags=re.MULTILINE)
7628
7637
 
7629
- # Show matching contexts with highlighting
7630
- click.secho("Matching content:", fg='yellow', bold=True)
7631
- click.secho("-" * 50, fg='yellow')
7638
+ # Find matching subsections (### level) - most focused
7639
+ matching_subsections = []
7640
+ for subsection in subsections:
7641
+ if search.lower() in subsection.lower():
7642
+ # Extract title
7643
+ title_match = re.match(r'^###\s+(.+)$', subsection, re.MULTILINE)
7644
+ if title_match:
7645
+ # Trim subsection to just the content until next ### or ##
7646
+ lines = subsection.split('\n')
7647
+ trimmed_lines = []
7648
+ for line in lines:
7649
+ if line.startswith('## ') and not line.startswith('### '):
7650
+ break
7651
+ trimmed_lines.append(line)
7652
+ matching_subsections.append((title_match.group(1), '\n'.join(trimmed_lines)))
7653
+
7654
+ if matching_subsections:
7655
+ click.secho(f"Found {len(matching_subsections)} matching subsection(s):", fg='green')
7656
+ click.echo()
7632
7657
 
7633
- for line_num, context in matching_lines[:15]: # Limit to 15 matches
7634
- click.echo(f"\nLine {line_num}:")
7635
- # Highlight the search term
7658
+ # Show focused subsections (limit output)
7659
+ for title, sub_content in matching_subsections[:5]:
7660
+ click.secho(f"### {title}", fg='yellow', bold=True)
7661
+ # Highlight search term in content
7636
7662
  highlighted = re.sub(
7637
7663
  f'({re.escape(search)})',
7638
7664
  click.style(r'\1', fg='green', bold=True),
7639
- context,
7665
+ sub_content,
7640
7666
  flags=re.IGNORECASE
7641
7667
  )
7642
- click.echo(highlighted)
7643
- click.echo("-" * 30)
7644
-
7645
- if len(matching_lines) > 15:
7646
- click.echo(f"\n... and {len(matching_lines) - 15} more matches")
7647
-
7648
- # Offer to show full sections
7649
- click.echo()
7650
- click.secho("Full sections containing your search:", fg='cyan')
7651
- click.echo("(Scroll or pipe to a file for full content)")
7652
- click.echo()
7653
-
7654
- for section in found_sections:
7655
- click.echo(section)
7668
+ # Limit lines per subsection
7669
+ lines = highlighted.split('\n')
7670
+ if len(lines) > 30:
7671
+ click.echo('\n'.join(lines[:30]))
7672
+ click.secho(f" ... ({len(lines) - 30} more lines)", fg='cyan')
7673
+ else:
7674
+ click.echo(highlighted)
7675
+ click.echo()
7676
+ click.secho("-" * 40, fg='cyan')
7656
7677
  click.echo()
7657
7678
 
7679
+ if len(matching_subsections) > 5:
7680
+ click.secho(f"... and {len(matching_subsections) - 5} more subsections", fg='cyan')
7681
+ click.echo("Use --list to see all sections")
7658
7682
  else:
7659
- click.secho(f"No matches found for '{search}'", fg='yellow')
7660
- click.echo()
7661
- click.echo("Try searching for:")
7662
- click.echo(" - Keywords: class, function, define, open, global")
7663
- click.echo(" - Syntax: $, @, ::, this->, <<==, <==")
7664
- click.echo(" - Types: string, int, stack, vector, map, json")
7665
- click.echo()
7666
- click.echo("Or use: includecpp cssl doc --list")
7683
+ # Fall back to main section search (## level)
7684
+ found_sections = []
7685
+ for section in main_sections:
7686
+ if search.lower() in section.lower():
7687
+ title_match = re.match(r'^##\s+(.+)$', section, re.MULTILINE)
7688
+ if title_match:
7689
+ found_sections.append((title_match.group(1), section))
7690
+
7691
+ if found_sections:
7692
+ click.secho(f"Found in {len(found_sections)} section(s):", fg='green')
7693
+ for title, _ in found_sections:
7694
+ click.echo(f" - {title}")
7695
+ click.echo()
7696
+
7697
+ # Show first matching section, trimmed
7698
+ title, section = found_sections[0]
7699
+ click.secho(f"## {title}", fg='yellow', bold=True)
7700
+ highlighted = re.sub(
7701
+ f'({re.escape(search)})',
7702
+ click.style(r'\1', fg='green', bold=True),
7703
+ section,
7704
+ flags=re.IGNORECASE
7705
+ )
7706
+ lines = highlighted.split('\n')
7707
+ if len(lines) > 40:
7708
+ click.echo('\n'.join(lines[:40]))
7709
+ click.secho(f"\n... ({len(lines) - 40} more lines in this section)", fg='cyan')
7710
+ else:
7711
+ click.echo(highlighted)
7712
+ else:
7713
+ click.secho(f"No matches found for '{search}'", fg='yellow')
7714
+ click.echo()
7715
+ click.echo("Try searching for:")
7716
+ click.echo(" - Keywords: class, function, define, open, global, shuffled")
7717
+ click.echo(" - Syntax: $, @, ::, this->, <<==, <==, #$")
7718
+ click.echo(" - Types: string, int, stack, vector, map, json")
7719
+ click.echo()
7720
+ click.echo("Or use: includecpp cssl doc --list")
7667
7721
  else:
7668
7722
  # Full documentation mode
7669
7723
  click.echo_via_pager(content)
@@ -7804,26 +7858,46 @@ def cssl_vscode():
7804
7858
  click.secho("CSSL extension files not found in package.", fg='red')
7805
7859
  return
7806
7860
 
7807
- # Install extension
7808
- target_dir = vscode_ext_dir / 'includecpp.cssl-1.0.0'
7861
+ # Get version from package.json
7862
+ pkg_json = source_ext_dir / 'package.json'
7863
+ current_version = "1.1.0"
7864
+ if pkg_json.exists():
7865
+ try:
7866
+ pkg_data = json.loads(pkg_json.read_text(encoding='utf-8'))
7867
+ current_version = pkg_data.get('version', '1.1.0')
7868
+ except:
7869
+ pass
7870
+
7871
+ target_dir = vscode_ext_dir / f'includecpp.cssl-{current_version}'
7809
7872
 
7810
7873
  try:
7874
+ # Check for existing installations
7875
+ existing_version = None
7876
+ for existing in vscode_ext_dir.glob('includecpp.cssl-*'):
7877
+ existing_version = existing.name.split('-')[-1]
7878
+ if existing_version != current_version:
7879
+ click.echo(f"Removing old version: {existing_version}")
7880
+ shutil.rmtree(existing)
7881
+
7811
7882
  if target_dir.exists():
7812
7883
  shutil.rmtree(target_dir)
7813
7884
 
7814
7885
  shutil.copytree(source_ext_dir, target_dir)
7815
7886
 
7816
- click.secho("CSSL VSCode extension installed!", fg='green', bold=True)
7887
+ if existing_version and existing_version != current_version:
7888
+ click.secho(f"CSSL extension updated: v{existing_version} -> v{current_version}", fg='green', bold=True)
7889
+ else:
7890
+ click.secho(f"CSSL VSCode extension installed! (v{current_version})", fg='green', bold=True)
7817
7891
  click.echo()
7818
7892
  click.echo(f"Installed to: {target_dir}")
7819
7893
  click.echo()
7820
7894
  click.echo("Features:")
7821
7895
  click.echo(" - Syntax highlighting for .cssl, .cssl-pl, .cssl-mod files")
7822
- click.echo(" - BruteInjection operators: <==, ==>, <<==, +<==, etc.")
7823
- click.echo(" - Type highlighting: int, string, stack<T>, datastruct<T>")
7896
+ click.echo(" - OOP support: class, constructor, this->member")
7897
+ click.echo(" - Injection operators: <== (brute), <<== (infuse)")
7898
+ click.echo(" - Type highlighting: int, string, stack<T>, instance<>")
7824
7899
  click.echo(" - Global references: @Name, r@Name, s@Name")
7825
7900
  click.echo(" - Shared objects: $Name")
7826
- click.echo(" - Filter helpers: string::contains, json::key, etc.")
7827
7901
  click.echo()
7828
7902
  click.secho("Restart VSCode to activate the extension.", fg='yellow')
7829
7903
 
@@ -7847,35 +7921,28 @@ cli.add_command(cssl)
7847
7921
  def vscode(force, stubs_only):
7848
7922
  """Initialize or update VSCode configuration for IncludeCPP/CSSL.
7849
7923
 
7850
- Sets up .vscode folder with:
7851
- - CSSL language support (syntax highlighting, snippets)
7852
- - Type stubs for builtins (.pyi files)
7853
- - Auto-generated stubs for your plugins and modules
7924
+ Installs CSSL extension globally and sets up project stubs.
7854
7925
 
7855
7926
  \b
7856
7927
  Usage:
7857
- includecpp vscode # Initialize .vscode
7858
- includecpp vscode --force # Force overwrite existing
7928
+ includecpp vscode # Install/update extension + stubs
7929
+ includecpp vscode --force # Force reinstall extension
7859
7930
  includecpp vscode --stubs-only # Only update stubs
7860
7931
 
7861
7932
  \b
7862
- What it creates:
7863
- .vscode/
7864
- settings.json - VSCode settings for CSSL
7865
- cssl/ - CSSL language extension
7866
- stubs/ - Type stubs for IDE support
7867
- cssl_builtins.pyi - CSSL builtin functions
7868
- plugins/ - Stubs for your .cp plugins
7869
- modules/ - Stubs for your modules
7933
+ What it does:
7934
+ 1. Installs CSSL extension globally (~/.vscode/extensions/)
7935
+ 2. Creates .vscode/settings.json with file associations
7936
+ 3. Creates .vscode/stubs/ with type hints for IDE support
7870
7937
  """
7871
7938
  from pathlib import Path as PathLib
7939
+ import os
7872
7940
 
7873
7941
  cwd = PathLib.cwd()
7874
7942
  vscode_dir = cwd / '.vscode'
7875
7943
  stubs_dir = vscode_dir / 'stubs'
7876
7944
  plugins_stubs_dir = stubs_dir / 'plugins'
7877
7945
  modules_stubs_dir = stubs_dir / 'modules'
7878
- cssl_ext_dir = vscode_dir / 'cssl'
7879
7946
 
7880
7947
  # Create directories
7881
7948
  vscode_dir.mkdir(exist_ok=True)
@@ -7891,56 +7958,79 @@ def vscode(force, stubs_only):
7891
7958
  updated_count = 0
7892
7959
  created_count = 0
7893
7960
 
7894
- # 1. Copy CSSL extension files (unless stubs-only)
7961
+ # 1. Install CSSL extension GLOBALLY (unless stubs-only)
7895
7962
  if not stubs_only:
7896
- click.secho("Setting up CSSL language support...", fg='yellow')
7963
+ click.secho("Installing CSSL extension globally...", fg='yellow')
7897
7964
 
7898
7965
  # Find source extension directory
7899
7966
  source_ext_dir = PathLib(__file__).parent.parent / 'vscode' / 'cssl'
7900
7967
 
7901
7968
  if source_ext_dir.exists():
7902
- cssl_ext_dir.mkdir(exist_ok=True)
7903
-
7904
- # Copy extension files
7905
- ext_files = [
7906
- 'language-configuration.json',
7907
- 'package.json',
7908
- ]
7909
-
7910
- for fname in ext_files:
7911
- src = source_ext_dir / fname
7912
- dst = cssl_ext_dir / fname
7913
- if src.exists():
7914
- if not dst.exists() or force:
7915
- shutil.copy2(src, dst)
7916
- created_count += 1
7917
- click.echo(f" Created: .vscode/cssl/{fname}")
7918
-
7919
- # Copy syntaxes folder
7920
- syntaxes_src = source_ext_dir / 'syntaxes'
7921
- syntaxes_dst = cssl_ext_dir / 'syntaxes'
7922
- if syntaxes_src.exists():
7923
- syntaxes_dst.mkdir(exist_ok=True)
7924
- for f in syntaxes_src.glob('*.json'):
7925
- dst = syntaxes_dst / f.name
7926
- if not dst.exists() or force:
7927
- shutil.copy2(f, dst)
7928
- created_count += 1
7929
- click.echo(f" Created: .vscode/cssl/syntaxes/{f.name}")
7930
-
7931
- # Copy snippets folder
7932
- snippets_src = source_ext_dir / 'snippets'
7933
- snippets_dst = cssl_ext_dir / 'snippets'
7934
- if snippets_src.exists():
7935
- snippets_dst.mkdir(exist_ok=True)
7936
- for f in snippets_src.glob('*.json'):
7937
- dst = snippets_dst / f.name
7938
- if not dst.exists() or force:
7939
- shutil.copy2(f, dst)
7940
- created_count += 1
7941
- click.echo(f" Created: .vscode/cssl/snippets/{f.name}")
7969
+ # Get version from package.json
7970
+ pkg_json = source_ext_dir / 'package.json'
7971
+ current_version = "1.1.0"
7972
+ if pkg_json.exists():
7973
+ try:
7974
+ pkg_data = json.loads(pkg_json.read_text(encoding='utf-8'))
7975
+ current_version = pkg_data.get('version', '1.1.0')
7976
+ except:
7977
+ pass
7978
+
7979
+ # Find global VSCode extensions directory
7980
+ if os.name == 'nt': # Windows
7981
+ global_ext_dir = PathLib(os.environ.get('USERPROFILE', '')) / '.vscode' / 'extensions'
7982
+ else: # Linux/Mac
7983
+ global_ext_dir = PathLib.home() / '.vscode' / 'extensions'
7984
+
7985
+ if not global_ext_dir.exists():
7986
+ # Try VSCode Insiders
7987
+ if os.name == 'nt':
7988
+ global_ext_dir = PathLib(os.environ.get('USERPROFILE', '')) / '.vscode-insiders' / 'extensions'
7989
+ else:
7990
+ global_ext_dir = PathLib.home() / '.vscode-insiders' / 'extensions'
7991
+
7992
+ if global_ext_dir.exists():
7993
+ target_dir = global_ext_dir / f'includecpp.cssl-{current_version}'
7994
+
7995
+ # Check if already installed with same or older version
7996
+ needs_install = force
7997
+ existing_version = None
7998
+
7999
+ # Find existing installations
8000
+ for existing in global_ext_dir.glob('includecpp.cssl-*'):
8001
+ existing_version = existing.name.split('-')[-1]
8002
+ if existing_version != current_version:
8003
+ # Remove old version
8004
+ click.echo(f" Removing old version: {existing_version}")
8005
+ shutil.rmtree(existing)
8006
+ needs_install = True
8007
+ elif not force:
8008
+ click.echo(f" Already installed: v{current_version}")
8009
+ needs_install = False
8010
+
8011
+ if not target_dir.exists():
8012
+ needs_install = True
8013
+
8014
+ if needs_install:
8015
+ # Remove target if exists (force reinstall)
8016
+ if target_dir.exists():
8017
+ shutil.rmtree(target_dir)
8018
+
8019
+ # Copy extension to global directory
8020
+ shutil.copytree(source_ext_dir, target_dir)
8021
+ created_count += 1
8022
+
8023
+ if existing_version and existing_version != current_version:
8024
+ click.secho(f" Updated: v{existing_version} -> v{current_version}", fg='green')
8025
+ else:
8026
+ click.secho(f" Installed: v{current_version}", fg='green')
7942
8027
 
7943
- click.secho(" CSSL extension configured", fg='green')
8028
+ click.echo(f" Location: {target_dir}")
8029
+ click.echo()
8030
+ click.secho(" Restart VSCode to activate the extension!", fg='yellow', bold=True)
8031
+ else:
8032
+ click.secho(" VSCode extensions directory not found.", fg='red')
8033
+ click.echo(" Make sure VSCode is installed.")
7944
8034
  else:
7945
8035
  click.secho(" Warning: CSSL extension source not found", fg='yellow')
7946
8036
 
@@ -1,6 +1,6 @@
1
1
  # CSSL - C-Style Scripting Language
2
2
 
3
- > Version 3.7.2 | A modern scripting language with C++-style syntax and unique features like CodeInfusion and BruteInjection.
3
+ > Version 3.7.6 | A modern scripting language with C++-style syntax and unique features like CodeInfusion and BruteInjection.
4
4
 
5
5
  ---
6
6
 
@@ -41,22 +41,25 @@
41
41
  ```python
42
42
  from includecpp import CSSL
43
43
 
44
- # Initialize CSSL
45
- CSSL.CsslLang()
46
-
47
- # Execute code
48
- CSSL.exec("""
44
+ # Execute code (v3.7.6+: use run() instead of exec())
45
+ CSSL.run("""
49
46
  printl("Hello CSSL!");
50
47
  """)
51
48
 
52
49
  # With parameters and return value
53
- result = CSSL.exec("""
50
+ result = CSSL.run("""
54
51
  string name = parameter.get(0);
55
52
  printl("Hello " + name);
56
53
  parameter.return(true);
57
54
  """, "World")
58
55
 
59
56
  print(result) # True
57
+
58
+ # Create typed scripts and modules (v3.7.6+)
59
+ main = CSSL.script("cssl", '''printl("Main");''')
60
+ payload = CSSL.script("cssl-pl", '''void helper() { printl("Helper!"); }''')
61
+ mod = CSSL.makemodule(main, payload, "mymod")
62
+ mod.helper() # Call function directly
60
63
  ```
61
64
 
62
65
  ### CLI Execution
@@ -701,12 +704,24 @@ super void forceRun() {
701
704
 
702
705
  ### shuffled
703
706
 
704
- Allows multiple return values.
707
+ Allows multiple return values with tuple unpacking.
705
708
 
706
709
  ```cssl
707
710
  shuffled string getNames() {
708
711
  return "Alice", "Bob", "Charlie";
709
712
  }
713
+
714
+ // Tuple unpacking (v3.7.6+)
715
+ a, b, c = getNames();
716
+ printl(a); // "Alice"
717
+ printl(b); // "Bob"
718
+ printl(c); // "Charlie"
719
+
720
+ // Works with any types
721
+ shuffled getValues() {
722
+ return "text", 42, true;
723
+ }
724
+ name, num, flag = getValues();
710
725
  ```
711
726
 
712
727
  ---
@@ -1143,6 +1158,10 @@ print(stats.total) # 50 - Persisted!
1143
1158
 
1144
1159
  CodeInfusion enables modifying functions at runtime.
1145
1160
 
1161
+ > **Important**: Injection operators must be written **without spaces**:
1162
+ > - ✓ `func() <<==` / `func() +<<==` / `func() -<<==` (correct)
1163
+ > - ✗ `func() < <==` / `func() + <<==` / `func() - <<==` (wrong)
1164
+
1146
1165
  ### <<== (Replace)
1147
1166
 
1148
1167
  Replaces function content.
@@ -1776,11 +1776,31 @@ class CSSLParser:
1776
1776
  return node
1777
1777
 
1778
1778
  def _parse_return(self) -> ASTNode:
1779
- value = None
1779
+ """Parse return statement, supporting multiple values for shuffled functions.
1780
+
1781
+ Syntax:
1782
+ return; // Return None
1783
+ return value; // Return single value
1784
+ return a, b, c; // Return multiple values (for shuffled)
1785
+ """
1786
+ values = []
1780
1787
  if not self._check(TokenType.SEMICOLON) and not self._check(TokenType.BLOCK_END):
1781
- value = self._parse_expression()
1788
+ values.append(self._parse_expression())
1789
+
1790
+ # Check for comma-separated return values (shuffled return)
1791
+ while self._check(TokenType.COMMA):
1792
+ self._advance() # consume comma
1793
+ values.append(self._parse_expression())
1794
+
1782
1795
  self._match(TokenType.SEMICOLON)
1783
- return ASTNode('return', value=value)
1796
+
1797
+ if len(values) == 0:
1798
+ return ASTNode('return', value=None)
1799
+ elif len(values) == 1:
1800
+ return ASTNode('return', value=values[0])
1801
+ else:
1802
+ # Multiple return values - create tuple return
1803
+ return ASTNode('return', value={'multiple': True, 'values': values})
1784
1804
 
1785
1805
  def _parse_super_function(self) -> ASTNode:
1786
1806
  """Parse super-function for .cssl-pl payload files.
@@ -1892,6 +1912,25 @@ class CSSLParser:
1892
1912
  def _parse_expression_statement(self) -> Optional[ASTNode]:
1893
1913
  expr = self._parse_expression()
1894
1914
 
1915
+ # === TUPLE UNPACKING: a, b, c = shuffled_func() ===
1916
+ # Check if we have comma-separated identifiers before =
1917
+ if expr.type == 'identifier' and self._check(TokenType.COMMA):
1918
+ targets = [expr]
1919
+ while self._match(TokenType.COMMA):
1920
+ next_expr = self._parse_expression()
1921
+ if next_expr.type == 'identifier':
1922
+ targets.append(next_expr)
1923
+ else:
1924
+ # Not a simple identifier list, this is something else
1925
+ # Restore and fall through to normal parsing
1926
+ break
1927
+
1928
+ # Check if followed by =
1929
+ if self._match(TokenType.EQUALS):
1930
+ value = self._parse_expression()
1931
+ self._match(TokenType.SEMICOLON)
1932
+ return ASTNode('tuple_assignment', value={'targets': targets, 'value': value})
1933
+
1895
1934
  # === BASIC INJECTION: <== (replace target with source) ===
1896
1935
  if self._match(TokenType.INJECT_LEFT):
1897
1936
  # Check if this is a createcmd injection with a code block