IncludeCPP 3.7.9__py3-none-any.whl → 3.7.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- includecpp/__init__.py +1 -1
- includecpp/__init__.pyi +2 -2
- includecpp/cli/commands.py +107 -65
- includecpp/core/cssl/__init__.py +7 -2
- includecpp/core/cssl/cssl_builtins.py +201 -9
- includecpp/core/cssl/cssl_builtins.pyi +3682 -401
- includecpp/core/cssl/cssl_parser.py +117 -29
- includecpp/core/cssl/cssl_runtime.py +446 -25
- includecpp/core/cssl/cssl_syntax.py +7 -7
- includecpp/core/cssl/cssl_types.py +75 -2
- includecpp/core/cssl_bridge.py +64 -6
- includecpp/vscode/cssl/extension.js +133 -0
- includecpp/vscode/cssl/images/cssl.png +0 -0
- includecpp/vscode/cssl/images/cssl_pl.png +0 -0
- includecpp/vscode/cssl/package.json +117 -11
- includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +38 -15
- {includecpp-3.7.9.dist-info → includecpp-3.7.25.dist-info}/METADATA +2 -2
- {includecpp-3.7.9.dist-info → includecpp-3.7.25.dist-info}/RECORD +22 -19
- {includecpp-3.7.9.dist-info → includecpp-3.7.25.dist-info}/WHEEL +0 -0
- {includecpp-3.7.9.dist-info → includecpp-3.7.25.dist-info}/entry_points.txt +0 -0
- {includecpp-3.7.9.dist-info → includecpp-3.7.25.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.7.9.dist-info → includecpp-3.7.25.dist-info}/top_level.txt +0 -0
includecpp/__init__.py
CHANGED
includecpp/__init__.pyi
CHANGED
|
@@ -13,7 +13,7 @@ except ImportError:
|
|
|
13
13
|
pass # Generated during rebuild
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
# ========== CSSL Module
|
|
16
|
+
# ========== CSSL Module ==========
|
|
17
17
|
class _CSSLModule:
|
|
18
18
|
"""CSSL callable module created via CSSL.module()"""
|
|
19
19
|
def __call__(self, *args: Any) -> Any:
|
|
@@ -139,7 +139,7 @@ class _CSSLBridge:
|
|
|
139
139
|
...
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
# CSSL module instance
|
|
142
|
+
# CSSL module instance
|
|
143
143
|
CSSL: _CSSLBridge
|
|
144
144
|
|
|
145
145
|
__version__: str
|
includecpp/cli/commands.py
CHANGED
|
@@ -7720,7 +7720,13 @@ def cssl_doc(search, list_sections):
|
|
|
7720
7720
|
click.echo("Or use: includecpp cssl doc --list")
|
|
7721
7721
|
else:
|
|
7722
7722
|
# Full documentation mode
|
|
7723
|
-
|
|
7723
|
+
# Replace Unicode characters that may not be supported on all terminals
|
|
7724
|
+
safe_content = content.replace('✓', '[OK]').replace('✗', '[X]').replace('→', '->').replace('←', '<-').replace('•', '*').replace('─', '-').replace('│', '|').replace('└', '+').replace('├', '+').replace('▸', '>').replace('▾', 'v')
|
|
7725
|
+
try:
|
|
7726
|
+
click.echo_via_pager(safe_content)
|
|
7727
|
+
except UnicodeEncodeError:
|
|
7728
|
+
# Fallback: encode with errors='replace'
|
|
7729
|
+
click.echo(safe_content.encode('ascii', errors='replace').decode('ascii'))
|
|
7724
7730
|
else:
|
|
7725
7731
|
click.secho("Documentation file not found.", fg='yellow')
|
|
7726
7732
|
click.echo("Looking for: CSSL_DOCUMENTATION.md")
|
|
@@ -7858,26 +7864,46 @@ def cssl_vscode():
|
|
|
7858
7864
|
click.secho("CSSL extension files not found in package.", fg='red')
|
|
7859
7865
|
return
|
|
7860
7866
|
|
|
7861
|
-
#
|
|
7862
|
-
|
|
7867
|
+
# Get version from package.json
|
|
7868
|
+
pkg_json = source_ext_dir / 'package.json'
|
|
7869
|
+
current_version = "1.1.0"
|
|
7870
|
+
if pkg_json.exists():
|
|
7871
|
+
try:
|
|
7872
|
+
pkg_data = json.loads(pkg_json.read_text(encoding='utf-8'))
|
|
7873
|
+
current_version = pkg_data.get('version', '1.1.0')
|
|
7874
|
+
except:
|
|
7875
|
+
pass
|
|
7876
|
+
|
|
7877
|
+
target_dir = vscode_ext_dir / f'includecpp.cssl-{current_version}'
|
|
7863
7878
|
|
|
7864
7879
|
try:
|
|
7880
|
+
# Check for existing installations
|
|
7881
|
+
existing_version = None
|
|
7882
|
+
for existing in vscode_ext_dir.glob('includecpp.cssl-*'):
|
|
7883
|
+
existing_version = existing.name.split('-')[-1]
|
|
7884
|
+
if existing_version != current_version:
|
|
7885
|
+
click.echo(f"Removing old version: {existing_version}")
|
|
7886
|
+
shutil.rmtree(existing)
|
|
7887
|
+
|
|
7865
7888
|
if target_dir.exists():
|
|
7866
7889
|
shutil.rmtree(target_dir)
|
|
7867
7890
|
|
|
7868
7891
|
shutil.copytree(source_ext_dir, target_dir)
|
|
7869
7892
|
|
|
7870
|
-
|
|
7893
|
+
if existing_version and existing_version != current_version:
|
|
7894
|
+
click.secho(f"CSSL extension updated: v{existing_version} -> v{current_version}", fg='green', bold=True)
|
|
7895
|
+
else:
|
|
7896
|
+
click.secho(f"CSSL VSCode extension installed! (v{current_version})", fg='green', bold=True)
|
|
7871
7897
|
click.echo()
|
|
7872
7898
|
click.echo(f"Installed to: {target_dir}")
|
|
7873
7899
|
click.echo()
|
|
7874
7900
|
click.echo("Features:")
|
|
7875
7901
|
click.echo(" - Syntax highlighting for .cssl, .cssl-pl, .cssl-mod files")
|
|
7876
|
-
click.echo(" -
|
|
7877
|
-
click.echo(" -
|
|
7902
|
+
click.echo(" - OOP support: class, constructor, this->member")
|
|
7903
|
+
click.echo(" - Injection operators: <== (brute), <<== (infuse)")
|
|
7904
|
+
click.echo(" - Type highlighting: int, string, stack<T>, instance<>")
|
|
7878
7905
|
click.echo(" - Global references: @Name, r@Name, s@Name")
|
|
7879
7906
|
click.echo(" - Shared objects: $Name")
|
|
7880
|
-
click.echo(" - Filter helpers: string::contains, json::key, etc.")
|
|
7881
7907
|
click.echo()
|
|
7882
7908
|
click.secho("Restart VSCode to activate the extension.", fg='yellow')
|
|
7883
7909
|
|
|
@@ -7901,35 +7927,28 @@ cli.add_command(cssl)
|
|
|
7901
7927
|
def vscode(force, stubs_only):
|
|
7902
7928
|
"""Initialize or update VSCode configuration for IncludeCPP/CSSL.
|
|
7903
7929
|
|
|
7904
|
-
|
|
7905
|
-
- CSSL language support (syntax highlighting, snippets)
|
|
7906
|
-
- Type stubs for builtins (.pyi files)
|
|
7907
|
-
- Auto-generated stubs for your plugins and modules
|
|
7930
|
+
Installs CSSL extension globally and sets up project stubs.
|
|
7908
7931
|
|
|
7909
7932
|
\b
|
|
7910
7933
|
Usage:
|
|
7911
|
-
includecpp vscode #
|
|
7912
|
-
includecpp vscode --force # Force
|
|
7934
|
+
includecpp vscode # Install/update extension + stubs
|
|
7935
|
+
includecpp vscode --force # Force reinstall extension
|
|
7913
7936
|
includecpp vscode --stubs-only # Only update stubs
|
|
7914
7937
|
|
|
7915
7938
|
\b
|
|
7916
|
-
What it
|
|
7917
|
-
.vscode/
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
stubs/ - Type stubs for IDE support
|
|
7921
|
-
cssl_builtins.pyi - CSSL builtin functions
|
|
7922
|
-
plugins/ - Stubs for your .cp plugins
|
|
7923
|
-
modules/ - Stubs for your modules
|
|
7939
|
+
What it does:
|
|
7940
|
+
1. Installs CSSL extension globally (~/.vscode/extensions/)
|
|
7941
|
+
2. Creates .vscode/settings.json with file associations
|
|
7942
|
+
3. Creates .vscode/stubs/ with type hints for IDE support
|
|
7924
7943
|
"""
|
|
7925
7944
|
from pathlib import Path as PathLib
|
|
7945
|
+
import os
|
|
7926
7946
|
|
|
7927
7947
|
cwd = PathLib.cwd()
|
|
7928
7948
|
vscode_dir = cwd / '.vscode'
|
|
7929
7949
|
stubs_dir = vscode_dir / 'stubs'
|
|
7930
7950
|
plugins_stubs_dir = stubs_dir / 'plugins'
|
|
7931
7951
|
modules_stubs_dir = stubs_dir / 'modules'
|
|
7932
|
-
cssl_ext_dir = vscode_dir / 'cssl'
|
|
7933
7952
|
|
|
7934
7953
|
# Create directories
|
|
7935
7954
|
vscode_dir.mkdir(exist_ok=True)
|
|
@@ -7945,56 +7964,79 @@ def vscode(force, stubs_only):
|
|
|
7945
7964
|
updated_count = 0
|
|
7946
7965
|
created_count = 0
|
|
7947
7966
|
|
|
7948
|
-
# 1.
|
|
7967
|
+
# 1. Install CSSL extension GLOBALLY (unless stubs-only)
|
|
7949
7968
|
if not stubs_only:
|
|
7950
|
-
click.secho("
|
|
7969
|
+
click.secho("Installing CSSL extension globally...", fg='yellow')
|
|
7951
7970
|
|
|
7952
7971
|
# Find source extension directory
|
|
7953
7972
|
source_ext_dir = PathLib(__file__).parent.parent / 'vscode' / 'cssl'
|
|
7954
7973
|
|
|
7955
7974
|
if source_ext_dir.exists():
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
click.echo(f"
|
|
7975
|
+
# Get version from package.json
|
|
7976
|
+
pkg_json = source_ext_dir / 'package.json'
|
|
7977
|
+
current_version = "1.1.0"
|
|
7978
|
+
if pkg_json.exists():
|
|
7979
|
+
try:
|
|
7980
|
+
pkg_data = json.loads(pkg_json.read_text(encoding='utf-8'))
|
|
7981
|
+
current_version = pkg_data.get('version', '1.1.0')
|
|
7982
|
+
except:
|
|
7983
|
+
pass
|
|
7984
|
+
|
|
7985
|
+
# Find global VSCode extensions directory
|
|
7986
|
+
if os.name == 'nt': # Windows
|
|
7987
|
+
global_ext_dir = PathLib(os.environ.get('USERPROFILE', '')) / '.vscode' / 'extensions'
|
|
7988
|
+
else: # Linux/Mac
|
|
7989
|
+
global_ext_dir = PathLib.home() / '.vscode' / 'extensions'
|
|
7990
|
+
|
|
7991
|
+
if not global_ext_dir.exists():
|
|
7992
|
+
# Try VSCode Insiders
|
|
7993
|
+
if os.name == 'nt':
|
|
7994
|
+
global_ext_dir = PathLib(os.environ.get('USERPROFILE', '')) / '.vscode-insiders' / 'extensions'
|
|
7995
|
+
else:
|
|
7996
|
+
global_ext_dir = PathLib.home() / '.vscode-insiders' / 'extensions'
|
|
7997
|
+
|
|
7998
|
+
if global_ext_dir.exists():
|
|
7999
|
+
target_dir = global_ext_dir / f'includecpp.cssl-{current_version}'
|
|
8000
|
+
|
|
8001
|
+
# Check if already installed with same or older version
|
|
8002
|
+
needs_install = force
|
|
8003
|
+
existing_version = None
|
|
8004
|
+
|
|
8005
|
+
# Find existing installations
|
|
8006
|
+
for existing in global_ext_dir.glob('includecpp.cssl-*'):
|
|
8007
|
+
existing_version = existing.name.split('-')[-1]
|
|
8008
|
+
if existing_version != current_version:
|
|
8009
|
+
# Remove old version
|
|
8010
|
+
click.echo(f" Removing old version: {existing_version}")
|
|
8011
|
+
shutil.rmtree(existing)
|
|
8012
|
+
needs_install = True
|
|
8013
|
+
elif not force:
|
|
8014
|
+
click.echo(f" Already installed: v{current_version}")
|
|
8015
|
+
needs_install = False
|
|
8016
|
+
|
|
8017
|
+
if not target_dir.exists():
|
|
8018
|
+
needs_install = True
|
|
8019
|
+
|
|
8020
|
+
if needs_install:
|
|
8021
|
+
# Remove target if exists (force reinstall)
|
|
8022
|
+
if target_dir.exists():
|
|
8023
|
+
shutil.rmtree(target_dir)
|
|
8024
|
+
|
|
8025
|
+
# Copy extension to global directory
|
|
8026
|
+
shutil.copytree(source_ext_dir, target_dir)
|
|
8027
|
+
created_count += 1
|
|
8028
|
+
|
|
8029
|
+
if existing_version and existing_version != current_version:
|
|
8030
|
+
click.secho(f" Updated: v{existing_version} -> v{current_version}", fg='green')
|
|
8031
|
+
else:
|
|
8032
|
+
click.secho(f" Installed: v{current_version}", fg='green')
|
|
7996
8033
|
|
|
7997
|
-
|
|
8034
|
+
click.echo(f" Location: {target_dir}")
|
|
8035
|
+
click.echo()
|
|
8036
|
+
click.secho(" Restart VSCode to activate the extension!", fg='yellow', bold=True)
|
|
8037
|
+
else:
|
|
8038
|
+
click.secho(" VSCode extensions directory not found.", fg='red')
|
|
8039
|
+
click.echo(" Make sure VSCode is installed.")
|
|
7998
8040
|
else:
|
|
7999
8041
|
click.secho(" Warning: CSSL extension source not found", fg='yellow')
|
|
8000
8042
|
|
includecpp/core/cssl/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
CSSL -
|
|
2
|
+
CSSL - C-Style Scripting Language
|
|
3
3
|
Bundled with IncludeCPP for integrated scripting support.
|
|
4
4
|
|
|
5
5
|
Features:
|
|
@@ -16,7 +16,10 @@ from .cssl_parser import (
|
|
|
16
16
|
CSSLSyntaxError, CSSLLexer, CSSLParser, ASTNode,
|
|
17
17
|
KEYWORDS, TYPE_GENERICS, TYPE_PARAM_FUNCTIONS, INJECTION_HELPERS
|
|
18
18
|
)
|
|
19
|
-
from .cssl_runtime import
|
|
19
|
+
from .cssl_runtime import (
|
|
20
|
+
CSSLRuntime, CSSLRuntimeError, CSSLServiceRunner, run_cssl, run_cssl_file,
|
|
21
|
+
register_filter, unregister_filter, get_custom_filters
|
|
22
|
+
)
|
|
20
23
|
from .cssl_types import (
|
|
21
24
|
DataStruct, Shuffled, Iterator, Combo, DataSpace, OpenQuote,
|
|
22
25
|
OpenFind, Parameter, Stack, Vector, Array,
|
|
@@ -33,6 +36,8 @@ __all__ = [
|
|
|
33
36
|
# Runtime
|
|
34
37
|
'CSSLRuntime', 'CSSLRuntimeError', 'CSSLServiceRunner',
|
|
35
38
|
'run_cssl', 'run_cssl_file',
|
|
39
|
+
# Filter Registration
|
|
40
|
+
'register_filter', 'unregister_filter', 'get_custom_filters',
|
|
36
41
|
# Data Types
|
|
37
42
|
'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
|
|
38
43
|
'OpenFind', 'Parameter', 'Stack', 'Vector', 'Array',
|
|
@@ -307,6 +307,10 @@ class CSSLBuiltins:
|
|
|
307
307
|
self._functions['dataspace'] = self.builtin_dataspace
|
|
308
308
|
self._functions['openquote'] = self.builtin_openquote
|
|
309
309
|
self._functions['OpenFind'] = self.builtin_openfind
|
|
310
|
+
self._functions['vector'] = self.builtin_vector
|
|
311
|
+
self._functions['array'] = self.builtin_array
|
|
312
|
+
self._functions['stack'] = self.builtin_stack
|
|
313
|
+
self._functions['map'] = self.builtin_map
|
|
310
314
|
|
|
311
315
|
# Print aliases for CSSL
|
|
312
316
|
self._functions['printl'] = self.builtin_println # CSSL uses printl for println
|
|
@@ -433,13 +437,50 @@ class CSSLBuiltins:
|
|
|
433
437
|
# ============= Type Checking =============
|
|
434
438
|
|
|
435
439
|
def builtin_typeof(self, value: Any) -> str:
|
|
436
|
-
"""Get type name"""
|
|
440
|
+
"""Get type name - returns CSSL-specific type names for CSSL types"""
|
|
437
441
|
if value is None:
|
|
438
442
|
return 'null'
|
|
443
|
+
|
|
444
|
+
# Check CSSL-specific types first
|
|
445
|
+
from .cssl_types import (Vector, Array, Stack, DataStruct,
|
|
446
|
+
List as CSSLList, Dictionary, Map,
|
|
447
|
+
Shuffled, Iterator, Combo, DataSpace,
|
|
448
|
+
OpenQuote, Parameter, CSSLInstance)
|
|
449
|
+
|
|
450
|
+
if isinstance(value, Vector):
|
|
451
|
+
return 'vector'
|
|
452
|
+
elif isinstance(value, Array):
|
|
453
|
+
return 'array'
|
|
454
|
+
elif isinstance(value, Stack):
|
|
455
|
+
return 'stack'
|
|
456
|
+
elif isinstance(value, DataStruct):
|
|
457
|
+
return 'datastruct'
|
|
458
|
+
elif isinstance(value, CSSLList):
|
|
459
|
+
return 'list'
|
|
460
|
+
elif isinstance(value, Dictionary):
|
|
461
|
+
return 'dictionary'
|
|
462
|
+
elif isinstance(value, Map):
|
|
463
|
+
return 'map'
|
|
464
|
+
elif isinstance(value, Shuffled):
|
|
465
|
+
return 'shuffled'
|
|
466
|
+
elif isinstance(value, Iterator):
|
|
467
|
+
return 'iterator'
|
|
468
|
+
elif isinstance(value, Combo):
|
|
469
|
+
return 'combo'
|
|
470
|
+
elif isinstance(value, DataSpace):
|
|
471
|
+
return 'dataspace'
|
|
472
|
+
elif isinstance(value, OpenQuote):
|
|
473
|
+
return 'openquote'
|
|
474
|
+
elif isinstance(value, Parameter):
|
|
475
|
+
return 'parameter'
|
|
476
|
+
elif isinstance(value, CSSLInstance):
|
|
477
|
+
return value._class.name
|
|
478
|
+
|
|
479
|
+
# Python types as fallback
|
|
439
480
|
type_map = {
|
|
440
481
|
int: 'int',
|
|
441
482
|
float: 'float',
|
|
442
|
-
str: '
|
|
483
|
+
str: 'string',
|
|
443
484
|
bool: 'bool',
|
|
444
485
|
list: 'list',
|
|
445
486
|
dict: 'dict',
|
|
@@ -1044,6 +1085,13 @@ class CSSLBuiltins:
|
|
|
1044
1085
|
Usage: instance::getMethods(@module) or instance::getMethods($obj)
|
|
1045
1086
|
Returns list of method names.
|
|
1046
1087
|
"""
|
|
1088
|
+
from .cssl_types import CSSLInstance
|
|
1089
|
+
|
|
1090
|
+
# Handle CSSL class instances
|
|
1091
|
+
if isinstance(obj, CSSLInstance):
|
|
1092
|
+
return list(obj._class.methods.keys())
|
|
1093
|
+
|
|
1094
|
+
# Handle Python objects
|
|
1047
1095
|
import inspect
|
|
1048
1096
|
methods = []
|
|
1049
1097
|
for name in dir(obj):
|
|
@@ -1056,8 +1104,20 @@ class CSSLBuiltins:
|
|
|
1056
1104
|
def builtin_instance_getClasses(self, obj: Any) -> list:
|
|
1057
1105
|
"""Get all classes from an object/module.
|
|
1058
1106
|
Usage: instance::getClasses(@module)
|
|
1059
|
-
Returns list of class names.
|
|
1107
|
+
Returns list of class names (including merged classes).
|
|
1060
1108
|
"""
|
|
1109
|
+
from .cssl_types import CSSLInstance
|
|
1110
|
+
|
|
1111
|
+
# Handle CSSL class instances
|
|
1112
|
+
if isinstance(obj, CSSLInstance):
|
|
1113
|
+
classes = [obj._class.name] # Primary class
|
|
1114
|
+
# Check for merged class instances in members
|
|
1115
|
+
for name, member in obj._members.items():
|
|
1116
|
+
if isinstance(member, CSSLInstance):
|
|
1117
|
+
classes.append(member._class.name)
|
|
1118
|
+
return classes
|
|
1119
|
+
|
|
1120
|
+
# Handle Python objects
|
|
1061
1121
|
import inspect
|
|
1062
1122
|
classes = []
|
|
1063
1123
|
for name in dir(obj):
|
|
@@ -1070,8 +1130,20 @@ class CSSLBuiltins:
|
|
|
1070
1130
|
def builtin_instance_getVars(self, obj: Any) -> list:
|
|
1071
1131
|
"""Get all variables/attributes (non-callable) from an object.
|
|
1072
1132
|
Usage: instance::getVars(@module)
|
|
1073
|
-
Returns list of variable names.
|
|
1133
|
+
Returns list of variable names (excludes merged class instances).
|
|
1074
1134
|
"""
|
|
1135
|
+
from .cssl_types import CSSLInstance
|
|
1136
|
+
|
|
1137
|
+
# Handle CSSL class instances
|
|
1138
|
+
if isinstance(obj, CSSLInstance):
|
|
1139
|
+
vars_list = []
|
|
1140
|
+
for name, member in obj._members.items():
|
|
1141
|
+
# Exclude merged class instances
|
|
1142
|
+
if not isinstance(member, CSSLInstance):
|
|
1143
|
+
vars_list.append(name)
|
|
1144
|
+
return vars_list
|
|
1145
|
+
|
|
1146
|
+
# Handle Python objects
|
|
1075
1147
|
vars_list = []
|
|
1076
1148
|
for name in dir(obj):
|
|
1077
1149
|
if not name.startswith('_'):
|
|
@@ -1085,12 +1157,31 @@ class CSSLBuiltins:
|
|
|
1085
1157
|
Usage: instance::getAll(@module)
|
|
1086
1158
|
Returns dict with 'methods', 'classes', 'vars' keys.
|
|
1087
1159
|
"""
|
|
1088
|
-
import
|
|
1160
|
+
from .cssl_types import CSSLInstance
|
|
1161
|
+
|
|
1089
1162
|
result = {
|
|
1090
1163
|
'methods': [],
|
|
1091
1164
|
'classes': [],
|
|
1092
1165
|
'vars': []
|
|
1093
1166
|
}
|
|
1167
|
+
|
|
1168
|
+
# Handle CSSL class instances
|
|
1169
|
+
if isinstance(obj, CSSLInstance):
|
|
1170
|
+
result['methods'] = list(obj._class.methods.keys())
|
|
1171
|
+
result['classes'] = [obj._class.name]
|
|
1172
|
+
|
|
1173
|
+
# Separate regular vars from merged class instances
|
|
1174
|
+
for name, member in obj._members.items():
|
|
1175
|
+
if isinstance(member, CSSLInstance):
|
|
1176
|
+
# Merged class - add to classes list
|
|
1177
|
+
result['classes'].append(member._class.name)
|
|
1178
|
+
else:
|
|
1179
|
+
# Regular variable
|
|
1180
|
+
result['vars'].append(name)
|
|
1181
|
+
return result
|
|
1182
|
+
|
|
1183
|
+
# Handle Python objects
|
|
1184
|
+
import inspect
|
|
1094
1185
|
for name in dir(obj):
|
|
1095
1186
|
if not name.startswith('_'):
|
|
1096
1187
|
attr = getattr(obj, name, None)
|
|
@@ -1106,21 +1197,46 @@ class CSSLBuiltins:
|
|
|
1106
1197
|
"""Dynamically call a method on an object.
|
|
1107
1198
|
Usage: instance::call(@module, 'methodName', arg1, arg2)
|
|
1108
1199
|
"""
|
|
1200
|
+
from .cssl_types import CSSLInstance
|
|
1201
|
+
|
|
1202
|
+
# Handle CSSL class instances
|
|
1203
|
+
if isinstance(obj, CSSLInstance):
|
|
1204
|
+
if obj.has_method(method_name):
|
|
1205
|
+
# Need runtime to call the method
|
|
1206
|
+
if self.runtime:
|
|
1207
|
+
return self.runtime._call_method(obj, obj.get_method(method_name), list(args), kwargs or {})
|
|
1208
|
+
raise RuntimeError(f"Method '{method_name}' not found on CSSL instance")
|
|
1209
|
+
|
|
1210
|
+
# Handle Python objects
|
|
1109
1211
|
method = getattr(obj, method_name, None)
|
|
1110
1212
|
if method and callable(method):
|
|
1111
1213
|
return method(*args, **kwargs)
|
|
1112
1214
|
raise RuntimeError(f"Method '{method_name}' not found on object")
|
|
1113
1215
|
|
|
1114
1216
|
def builtin_instance_has(self, obj: Any, name: str) -> bool:
|
|
1115
|
-
"""Check if object has an attribute.
|
|
1217
|
+
"""Check if object has an attribute or method.
|
|
1116
1218
|
Usage: instance::has(@module, 'methodName')
|
|
1117
1219
|
"""
|
|
1220
|
+
from .cssl_types import CSSLInstance
|
|
1221
|
+
|
|
1222
|
+
# Handle CSSL class instances
|
|
1223
|
+
if isinstance(obj, CSSLInstance):
|
|
1224
|
+
return obj.has_member(name) or obj.has_method(name)
|
|
1225
|
+
|
|
1226
|
+
# Handle Python objects
|
|
1118
1227
|
return hasattr(obj, name)
|
|
1119
1228
|
|
|
1120
1229
|
def builtin_instance_type(self, obj: Any) -> str:
|
|
1121
1230
|
"""Get the type name of an object.
|
|
1122
1231
|
Usage: instance::type(@module)
|
|
1123
1232
|
"""
|
|
1233
|
+
from .cssl_types import CSSLInstance
|
|
1234
|
+
|
|
1235
|
+
# Handle CSSL class instances
|
|
1236
|
+
if isinstance(obj, CSSLInstance):
|
|
1237
|
+
return obj._class.name
|
|
1238
|
+
|
|
1239
|
+
# Handle Python objects
|
|
1124
1240
|
return type(obj).__name__
|
|
1125
1241
|
|
|
1126
1242
|
def builtin_isavailable(self, name_or_obj: Any) -> bool:
|
|
@@ -1140,6 +1256,50 @@ class CSSLBuiltins:
|
|
|
1140
1256
|
# Otherwise, check if the object is not None (for $name or instance<"name">)
|
|
1141
1257
|
return name_or_obj is not None
|
|
1142
1258
|
|
|
1259
|
+
# ============= Filter Registration Functions =============
|
|
1260
|
+
|
|
1261
|
+
def builtin_filter_register(self, filter_type: str, helper: str, callback: Any) -> bool:
|
|
1262
|
+
"""Register a custom filter.
|
|
1263
|
+
Usage: filter::register("mytype", "where", myCallback)
|
|
1264
|
+
|
|
1265
|
+
The callback receives (source, filter_value, runtime) and returns filtered result.
|
|
1266
|
+
Use "*" as helper for catch-all.
|
|
1267
|
+
|
|
1268
|
+
Example:
|
|
1269
|
+
define myFilter(source, value, runtime) {
|
|
1270
|
+
return source + value;
|
|
1271
|
+
}
|
|
1272
|
+
filter::register("custom", "add", myFilter);
|
|
1273
|
+
|
|
1274
|
+
result <==[custom::add=10] 5; // result = 15
|
|
1275
|
+
"""
|
|
1276
|
+
from .cssl_runtime import register_filter
|
|
1277
|
+
register_filter(filter_type, helper, callback)
|
|
1278
|
+
return True
|
|
1279
|
+
|
|
1280
|
+
def builtin_filter_unregister(self, filter_type: str, helper: str) -> bool:
|
|
1281
|
+
"""Unregister a custom filter.
|
|
1282
|
+
Usage: filter::unregister("mytype", "where")
|
|
1283
|
+
"""
|
|
1284
|
+
from .cssl_runtime import unregister_filter
|
|
1285
|
+
return unregister_filter(filter_type, helper)
|
|
1286
|
+
|
|
1287
|
+
def builtin_filter_list(self) -> list:
|
|
1288
|
+
"""List all registered custom filters.
|
|
1289
|
+
Usage: filter::list()
|
|
1290
|
+
Returns list of filter keys like ["mytype::where", "custom::*"]
|
|
1291
|
+
"""
|
|
1292
|
+
from .cssl_runtime import get_custom_filters
|
|
1293
|
+
return list(get_custom_filters().keys())
|
|
1294
|
+
|
|
1295
|
+
def builtin_filter_exists(self, filter_type: str, helper: str) -> bool:
|
|
1296
|
+
"""Check if a custom filter exists.
|
|
1297
|
+
Usage: filter::exists("mytype", "where")
|
|
1298
|
+
"""
|
|
1299
|
+
from .cssl_runtime import get_custom_filters
|
|
1300
|
+
key = f"{filter_type}::{helper}"
|
|
1301
|
+
return key in get_custom_filters()
|
|
1302
|
+
|
|
1143
1303
|
# ============= Regex Functions =============
|
|
1144
1304
|
|
|
1145
1305
|
def builtin_match(self, pattern: str, string: str) -> Optional[dict]:
|
|
@@ -1680,7 +1840,7 @@ class CSSLBuiltins:
|
|
|
1680
1840
|
|
|
1681
1841
|
def builtin_cso_root(self, path: str = "") -> str:
|
|
1682
1842
|
"""
|
|
1683
|
-
Get absolute path relative to
|
|
1843
|
+
Get absolute path relative to project root directory
|
|
1684
1844
|
Usage: cso_root('/services/myservice.cssl')
|
|
1685
1845
|
Returns: Full absolute path to the file
|
|
1686
1846
|
"""
|
|
@@ -1729,7 +1889,7 @@ class CSSLBuiltins:
|
|
|
1729
1889
|
if os.path.exists(cwd_path):
|
|
1730
1890
|
filepath = cwd_path
|
|
1731
1891
|
else:
|
|
1732
|
-
# Fall back to cso_root for
|
|
1892
|
+
# Fall back to cso_root for service context
|
|
1733
1893
|
filepath = self.builtin_cso_root(filepath)
|
|
1734
1894
|
|
|
1735
1895
|
# Check file exists
|
|
@@ -1923,7 +2083,7 @@ class CSSLBuiltins:
|
|
|
1923
2083
|
if os.path.exists(cwd_path):
|
|
1924
2084
|
filepath = cwd_path
|
|
1925
2085
|
else:
|
|
1926
|
-
# Fall back to cso_root for
|
|
2086
|
+
# Fall back to cso_root for service context
|
|
1927
2087
|
filepath = self.builtin_cso_root(filepath)
|
|
1928
2088
|
|
|
1929
2089
|
# Check file exists
|
|
@@ -2203,6 +2363,38 @@ class CSSLBuiltins:
|
|
|
2203
2363
|
from .cssl_types import OpenQuote
|
|
2204
2364
|
return OpenQuote(db_ref)
|
|
2205
2365
|
|
|
2366
|
+
def builtin_vector(self, element_type: str = 'dynamic') -> Any:
|
|
2367
|
+
"""Create a vector container.
|
|
2368
|
+
|
|
2369
|
+
Usage: vector<int> myVector; or vector('int')
|
|
2370
|
+
"""
|
|
2371
|
+
from .cssl_types import Vector
|
|
2372
|
+
return Vector(element_type)
|
|
2373
|
+
|
|
2374
|
+
def builtin_array(self, element_type: str = 'dynamic') -> Any:
|
|
2375
|
+
"""Create an array container.
|
|
2376
|
+
|
|
2377
|
+
Usage: array<string> myArray; or array('string')
|
|
2378
|
+
"""
|
|
2379
|
+
from .cssl_types import Array
|
|
2380
|
+
return Array(element_type)
|
|
2381
|
+
|
|
2382
|
+
def builtin_stack(self, element_type: str = 'dynamic') -> Any:
|
|
2383
|
+
"""Create a stack container.
|
|
2384
|
+
|
|
2385
|
+
Usage: stack<int> myStack; or stack('int')
|
|
2386
|
+
"""
|
|
2387
|
+
from .cssl_types import Stack
|
|
2388
|
+
return Stack(element_type)
|
|
2389
|
+
|
|
2390
|
+
def builtin_map(self, key_type: str = 'dynamic', value_type: str = 'dynamic') -> Any:
|
|
2391
|
+
"""Create a map container.
|
|
2392
|
+
|
|
2393
|
+
Usage: map<string, int> myMap; or map('string', 'int')
|
|
2394
|
+
"""
|
|
2395
|
+
from .cssl_types import Map
|
|
2396
|
+
return Map(key_type, value_type)
|
|
2397
|
+
|
|
2206
2398
|
def builtin_openfind(self, combo_or_type: Any, index: int = 0, params: list = None) -> Any:
|
|
2207
2399
|
"""Find open parameter by type or combo space.
|
|
2208
2400
|
|