IncludeCPP 3.7.25__py3-none-any.whl → 3.8.8__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/cli/commands.py +26 -6
- includecpp/core/cssl/CSSL_DOCUMENTATION.md +312 -1
- includecpp/core/cssl/cssl_builtins.py +343 -0
- includecpp/core/cssl/cssl_parser.py +422 -9
- includecpp/core/cssl/cssl_runtime.py +496 -17
- includecpp/core/cssl/cssl_types.py +58 -9
- includecpp/vscode/cssl/extension.js +5 -5
- includecpp/vscode/cssl/package.json +1 -1
- includecpp/vscode/cssl/snippets/cssl.snippets.json +126 -0
- includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +232 -2
- {includecpp-3.7.25.dist-info → includecpp-3.8.8.dist-info}/METADATA +55 -224
- {includecpp-3.7.25.dist-info → includecpp-3.8.8.dist-info}/RECORD +17 -17
- {includecpp-3.7.25.dist-info → includecpp-3.8.8.dist-info}/WHEEL +0 -0
- {includecpp-3.7.25.dist-info → includecpp-3.8.8.dist-info}/entry_points.txt +0 -0
- {includecpp-3.7.25.dist-info → includecpp-3.8.8.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.7.25.dist-info → includecpp-3.8.8.dist-info}/top_level.txt +0 -0
|
@@ -205,6 +205,13 @@ 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
|
+
self._functions['python::csslize'] = self.builtin_python_csslize
|
|
213
|
+
self._functions['python::import'] = self.builtin_python_csslize # Alias
|
|
214
|
+
|
|
208
215
|
# Regex functions
|
|
209
216
|
self._functions['match'] = self.builtin_match
|
|
210
217
|
self._functions['search'] = self.builtin_search
|
|
@@ -2445,6 +2452,342 @@ class CSSLBuiltins:
|
|
|
2445
2452
|
|
|
2446
2453
|
return None
|
|
2447
2454
|
|
|
2455
|
+
# ============= Python Interop Functions =============
|
|
2456
|
+
|
|
2457
|
+
def builtin_python_pythonize(self, cssl_instance: Any) -> Any:
|
|
2458
|
+
"""Convert a CSSL class instance to a Python-usable object.
|
|
2459
|
+
|
|
2460
|
+
This allows CSSL classes to be returned and used in Python code
|
|
2461
|
+
with proper attribute access and method calls.
|
|
2462
|
+
|
|
2463
|
+
Usage in CSSL:
|
|
2464
|
+
class Greeter {
|
|
2465
|
+
string name;
|
|
2466
|
+
|
|
2467
|
+
Greeter(string n) {
|
|
2468
|
+
this->name = n;
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
string sayHello() {
|
|
2472
|
+
return "Hello, " + this->name + "!";
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
void setName(string newName) {
|
|
2476
|
+
this->name = newName;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
string getName() {
|
|
2480
|
+
return this->name;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
greeter = new Greeter("World");
|
|
2485
|
+
pyclass = python::pythonize(greeter);
|
|
2486
|
+
parameter.return(pyclass);
|
|
2487
|
+
|
|
2488
|
+
Usage in Python:
|
|
2489
|
+
from includecpp import CSSL
|
|
2490
|
+
|
|
2491
|
+
cssl = CSSL.CsslLang()
|
|
2492
|
+
greeter = cssl.run('''
|
|
2493
|
+
class Greeter { ... }
|
|
2494
|
+
g = new Greeter("World");
|
|
2495
|
+
parameter.return(python::pythonize(g));
|
|
2496
|
+
''')
|
|
2497
|
+
|
|
2498
|
+
# Now use it like a normal Python object:
|
|
2499
|
+
print(greeter.name) # "World"
|
|
2500
|
+
print(greeter.sayHello()) # "Hello, World!"
|
|
2501
|
+
greeter.setName("Python")
|
|
2502
|
+
print(greeter.getName()) # "Python"
|
|
2503
|
+
|
|
2504
|
+
Args:
|
|
2505
|
+
cssl_instance: A CSSLInstance object (created via 'new ClassName()')
|
|
2506
|
+
|
|
2507
|
+
Returns:
|
|
2508
|
+
PythonizedCSSLInstance - A Python-friendly wrapper
|
|
2509
|
+
"""
|
|
2510
|
+
from .cssl_types import CSSLInstance, CSSLClass
|
|
2511
|
+
|
|
2512
|
+
if cssl_instance is None:
|
|
2513
|
+
return None
|
|
2514
|
+
|
|
2515
|
+
# Already pythonized
|
|
2516
|
+
if isinstance(cssl_instance, PythonizedCSSLInstance):
|
|
2517
|
+
return cssl_instance
|
|
2518
|
+
|
|
2519
|
+
# Must be a CSSLInstance
|
|
2520
|
+
if not isinstance(cssl_instance, CSSLInstance):
|
|
2521
|
+
# If it's a dict, wrap it as a simple object
|
|
2522
|
+
if isinstance(cssl_instance, dict):
|
|
2523
|
+
return PythonizedDict(cssl_instance)
|
|
2524
|
+
# Return as-is for primitives
|
|
2525
|
+
return cssl_instance
|
|
2526
|
+
|
|
2527
|
+
return PythonizedCSSLInstance(cssl_instance, self.runtime)
|
|
2528
|
+
|
|
2529
|
+
def builtin_python_csslize(self, python_obj: Any) -> Any:
|
|
2530
|
+
"""Convert a Python object (class instance or function) to a CSSL-compatible wrapper.
|
|
2531
|
+
|
|
2532
|
+
Syntax:
|
|
2533
|
+
cssl_obj <== python::csslize($python_instance);
|
|
2534
|
+
cssl_func <== python::csslize($python_function);
|
|
2535
|
+
|
|
2536
|
+
Example:
|
|
2537
|
+
# In Python:
|
|
2538
|
+
class MyPythonClass:
|
|
2539
|
+
def __init__(self, name):
|
|
2540
|
+
self.name = name
|
|
2541
|
+
def greet(self):
|
|
2542
|
+
return f"Hello, {self.name}!"
|
|
2543
|
+
|
|
2544
|
+
cssl = CSSL.CsslLang()
|
|
2545
|
+
cssl.set_variable('MyPython', MyPythonClass("World"))
|
|
2546
|
+
result = cssl.run('''
|
|
2547
|
+
py_obj <== python::csslize($MyPython);
|
|
2548
|
+
printl(py_obj.greet()); // "Hello, World!"
|
|
2549
|
+
''')
|
|
2550
|
+
|
|
2551
|
+
For class inheritance:
|
|
2552
|
+
py_class <== python::csslize($MyPythonClass);
|
|
2553
|
+
class MyExtended : extends py_class {
|
|
2554
|
+
void newMethod() { ... }
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
Args:
|
|
2558
|
+
python_obj: A Python object (class instance, function, or class)
|
|
2559
|
+
|
|
2560
|
+
Returns:
|
|
2561
|
+
CSSLizedPythonObject - A CSSL-compatible wrapper
|
|
2562
|
+
"""
|
|
2563
|
+
if python_obj is None:
|
|
2564
|
+
return None
|
|
2565
|
+
|
|
2566
|
+
# Already csslized
|
|
2567
|
+
if isinstance(python_obj, CSSLizedPythonObject):
|
|
2568
|
+
return python_obj
|
|
2569
|
+
|
|
2570
|
+
# Wrap the Python object
|
|
2571
|
+
return CSSLizedPythonObject(python_obj, self.runtime)
|
|
2572
|
+
|
|
2573
|
+
|
|
2574
|
+
class CSSLizedPythonObject:
|
|
2575
|
+
"""CSSL wrapper for Python objects (classes, instances, functions).
|
|
2576
|
+
|
|
2577
|
+
Allows Python objects to be used within CSSL code, including as base classes.
|
|
2578
|
+
"""
|
|
2579
|
+
|
|
2580
|
+
def __init__(self, python_obj: Any, runtime: Any = None):
|
|
2581
|
+
self._python_obj = python_obj
|
|
2582
|
+
self._runtime = runtime
|
|
2583
|
+
self._is_class = isinstance(python_obj, type)
|
|
2584
|
+
self._is_callable = callable(python_obj) and not self._is_class
|
|
2585
|
+
|
|
2586
|
+
def __repr__(self):
|
|
2587
|
+
if self._is_class:
|
|
2588
|
+
return f"<CSSLizedPythonClass: {self._python_obj.__name__}>"
|
|
2589
|
+
elif self._is_callable:
|
|
2590
|
+
return f"<CSSLizedPythonFunction: {getattr(self._python_obj, '__name__', 'anonymous')}>"
|
|
2591
|
+
else:
|
|
2592
|
+
return f"<CSSLizedPythonInstance: {type(self._python_obj).__name__}>"
|
|
2593
|
+
|
|
2594
|
+
def __call__(self, *args, **kwargs):
|
|
2595
|
+
"""Call the wrapped object (for functions or class instantiation)."""
|
|
2596
|
+
return self._python_obj(*args, **kwargs)
|
|
2597
|
+
|
|
2598
|
+
def __getattr__(self, name: str) -> Any:
|
|
2599
|
+
"""Get attribute from wrapped Python object."""
|
|
2600
|
+
if name.startswith('_'):
|
|
2601
|
+
raise AttributeError(f"Cannot access private attribute '{name}'")
|
|
2602
|
+
|
|
2603
|
+
obj = object.__getattribute__(self, '_python_obj')
|
|
2604
|
+
|
|
2605
|
+
if hasattr(obj, name):
|
|
2606
|
+
attr = getattr(obj, name)
|
|
2607
|
+
# If it's a method, wrap it for CSSL calling
|
|
2608
|
+
if callable(attr):
|
|
2609
|
+
return CSSLizedPythonMethod(attr, self._runtime)
|
|
2610
|
+
return attr
|
|
2611
|
+
|
|
2612
|
+
raise AttributeError(f"Python object has no attribute '{name}'")
|
|
2613
|
+
|
|
2614
|
+
def __setattr__(self, name: str, value: Any):
|
|
2615
|
+
"""Set attribute on wrapped Python object."""
|
|
2616
|
+
if name.startswith('_'):
|
|
2617
|
+
object.__setattr__(self, name, value)
|
|
2618
|
+
else:
|
|
2619
|
+
setattr(self._python_obj, name, value)
|
|
2620
|
+
|
|
2621
|
+
def has_member(self, name: str) -> bool:
|
|
2622
|
+
"""Check if the Python object has a member."""
|
|
2623
|
+
return hasattr(self._python_obj, name)
|
|
2624
|
+
|
|
2625
|
+
def get_member(self, name: str) -> Any:
|
|
2626
|
+
"""Get a member from the Python object."""
|
|
2627
|
+
return getattr(self._python_obj, name, None)
|
|
2628
|
+
|
|
2629
|
+
def set_member(self, name: str, value: Any):
|
|
2630
|
+
"""Set a member on the Python object."""
|
|
2631
|
+
setattr(self._python_obj, name, value)
|
|
2632
|
+
|
|
2633
|
+
def get_method(self, name: str):
|
|
2634
|
+
"""Get a method from the Python object."""
|
|
2635
|
+
if hasattr(self._python_obj, name):
|
|
2636
|
+
method = getattr(self._python_obj, name)
|
|
2637
|
+
if callable(method):
|
|
2638
|
+
return CSSLizedPythonMethod(method, self._runtime)
|
|
2639
|
+
return None
|
|
2640
|
+
|
|
2641
|
+
def get_python_obj(self):
|
|
2642
|
+
"""Get the underlying Python object (for inheritance)."""
|
|
2643
|
+
return self._python_obj
|
|
2644
|
+
|
|
2645
|
+
|
|
2646
|
+
class CSSLizedPythonMethod:
|
|
2647
|
+
"""Wrapper for Python methods to be called from CSSL."""
|
|
2648
|
+
|
|
2649
|
+
def __init__(self, method: Any, runtime: Any = None):
|
|
2650
|
+
self._method = method
|
|
2651
|
+
self._runtime = runtime
|
|
2652
|
+
|
|
2653
|
+
def __call__(self, *args, **kwargs):
|
|
2654
|
+
"""Call the Python method."""
|
|
2655
|
+
return self._method(*args, **kwargs)
|
|
2656
|
+
|
|
2657
|
+
def __repr__(self):
|
|
2658
|
+
return f"<CSSLizedPythonMethod: {getattr(self._method, '__name__', 'anonymous')}>"
|
|
2659
|
+
|
|
2660
|
+
|
|
2661
|
+
class PythonizedCSSLInstance:
|
|
2662
|
+
"""Python wrapper for CSSL class instances.
|
|
2663
|
+
|
|
2664
|
+
Provides Pythonic attribute access and method calling for CSSL objects.
|
|
2665
|
+
"""
|
|
2666
|
+
|
|
2667
|
+
def __init__(self, instance: Any, runtime: Any = None):
|
|
2668
|
+
# Use object.__setattr__ to avoid triggering our custom __setattr__
|
|
2669
|
+
object.__setattr__(self, '_cssl_instance', instance)
|
|
2670
|
+
object.__setattr__(self, '_cssl_runtime', runtime)
|
|
2671
|
+
object.__setattr__(self, '_cssl_class_name', instance._class.name if hasattr(instance, '_class') else 'Unknown')
|
|
2672
|
+
|
|
2673
|
+
def __getattr__(self, name: str) -> Any:
|
|
2674
|
+
"""Get member or method from CSSL instance."""
|
|
2675
|
+
if name.startswith('_'):
|
|
2676
|
+
raise AttributeError(f"'{self._cssl_class_name}' has no attribute '{name}'")
|
|
2677
|
+
|
|
2678
|
+
instance = object.__getattribute__(self, '_cssl_instance')
|
|
2679
|
+
runtime = object.__getattribute__(self, '_cssl_runtime')
|
|
2680
|
+
|
|
2681
|
+
# Check for member variable first
|
|
2682
|
+
if instance.has_member(name):
|
|
2683
|
+
value = instance.get_member(name)
|
|
2684
|
+
# Recursively pythonize nested CSSL instances
|
|
2685
|
+
from .cssl_types import CSSLInstance
|
|
2686
|
+
if isinstance(value, CSSLInstance):
|
|
2687
|
+
return PythonizedCSSLInstance(value, runtime)
|
|
2688
|
+
return value
|
|
2689
|
+
|
|
2690
|
+
# Check for method
|
|
2691
|
+
method = instance.get_method(name)
|
|
2692
|
+
if method is not None:
|
|
2693
|
+
# Return a callable wrapper for the method
|
|
2694
|
+
return PythonizedMethod(instance, name, method, runtime)
|
|
2695
|
+
|
|
2696
|
+
raise AttributeError(f"'{self._cssl_class_name}' has no attribute '{name}'")
|
|
2697
|
+
|
|
2698
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
2699
|
+
"""Set member value on CSSL instance."""
|
|
2700
|
+
if name.startswith('_'):
|
|
2701
|
+
object.__setattr__(self, name, value)
|
|
2702
|
+
return
|
|
2703
|
+
|
|
2704
|
+
instance = object.__getattribute__(self, '_cssl_instance')
|
|
2705
|
+
instance.set_member(name, value)
|
|
2706
|
+
|
|
2707
|
+
def __repr__(self) -> str:
|
|
2708
|
+
class_name = object.__getattribute__(self, '_cssl_class_name')
|
|
2709
|
+
instance = object.__getattribute__(self, '_cssl_instance')
|
|
2710
|
+
members = list(instance._members.keys()) if hasattr(instance, '_members') else []
|
|
2711
|
+
return f"<PythonizedCSSL '{class_name}' members={members}>"
|
|
2712
|
+
|
|
2713
|
+
def __dir__(self) -> list:
|
|
2714
|
+
"""List available attributes."""
|
|
2715
|
+
instance = object.__getattribute__(self, '_cssl_instance')
|
|
2716
|
+
members = list(instance._members.keys()) if hasattr(instance, '_members') else []
|
|
2717
|
+
methods = list(instance._class.methods.keys()) if hasattr(instance._class, 'methods') else []
|
|
2718
|
+
return members + methods
|
|
2719
|
+
|
|
2720
|
+
def _to_dict(self) -> dict:
|
|
2721
|
+
"""Convert to Python dictionary."""
|
|
2722
|
+
instance = object.__getattribute__(self, '_cssl_instance')
|
|
2723
|
+
result = {}
|
|
2724
|
+
for name, value in instance._members.items():
|
|
2725
|
+
from .cssl_types import CSSLInstance
|
|
2726
|
+
if isinstance(value, CSSLInstance):
|
|
2727
|
+
result[name] = PythonizedCSSLInstance(value, None)._to_dict()
|
|
2728
|
+
else:
|
|
2729
|
+
result[name] = value
|
|
2730
|
+
return result
|
|
2731
|
+
|
|
2732
|
+
|
|
2733
|
+
class PythonizedMethod:
|
|
2734
|
+
"""Wrapper that makes CSSL methods callable from Python."""
|
|
2735
|
+
|
|
2736
|
+
def __init__(self, instance: Any, method_name: str, method_ast: Any, runtime: Any):
|
|
2737
|
+
self._instance = instance
|
|
2738
|
+
self._method_name = method_name
|
|
2739
|
+
self._method_ast = method_ast
|
|
2740
|
+
self._runtime = runtime
|
|
2741
|
+
|
|
2742
|
+
def __call__(self, *args, **kwargs) -> Any:
|
|
2743
|
+
"""Call the CSSL method with arguments."""
|
|
2744
|
+
if self._runtime is None:
|
|
2745
|
+
raise RuntimeError(f"Cannot call method '{self._method_name}' - no runtime available")
|
|
2746
|
+
|
|
2747
|
+
# Execute the method through the runtime
|
|
2748
|
+
# Pass the method AST node, not the method name
|
|
2749
|
+
result = self._runtime._call_method(self._instance, self._method_ast, list(args), kwargs)
|
|
2750
|
+
|
|
2751
|
+
# Pythonize the result if it's a CSSL instance
|
|
2752
|
+
from .cssl_types import CSSLInstance
|
|
2753
|
+
if isinstance(result, CSSLInstance):
|
|
2754
|
+
return PythonizedCSSLInstance(result, self._runtime)
|
|
2755
|
+
|
|
2756
|
+
return result
|
|
2757
|
+
|
|
2758
|
+
def __repr__(self) -> str:
|
|
2759
|
+
return f"<method '{self._method_name}' of '{self._instance._class.name}'>"
|
|
2760
|
+
|
|
2761
|
+
|
|
2762
|
+
class PythonizedDict:
|
|
2763
|
+
"""Simple wrapper for dict objects with attribute access."""
|
|
2764
|
+
|
|
2765
|
+
def __init__(self, data: dict):
|
|
2766
|
+
object.__setattr__(self, '_data', data)
|
|
2767
|
+
|
|
2768
|
+
def __getattr__(self, name: str) -> Any:
|
|
2769
|
+
data = object.__getattribute__(self, '_data')
|
|
2770
|
+
if name in data:
|
|
2771
|
+
value = data[name]
|
|
2772
|
+
if isinstance(value, dict):
|
|
2773
|
+
return PythonizedDict(value)
|
|
2774
|
+
return value
|
|
2775
|
+
raise AttributeError(f"No attribute '{name}'")
|
|
2776
|
+
|
|
2777
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
2778
|
+
if name.startswith('_'):
|
|
2779
|
+
object.__setattr__(self, name, value)
|
|
2780
|
+
return
|
|
2781
|
+
data = object.__getattribute__(self, '_data')
|
|
2782
|
+
data[name] = value
|
|
2783
|
+
|
|
2784
|
+
def __repr__(self) -> str:
|
|
2785
|
+
data = object.__getattribute__(self, '_data')
|
|
2786
|
+
return f"<PythonizedDict {data}>"
|
|
2787
|
+
|
|
2788
|
+
def _to_dict(self) -> dict:
|
|
2789
|
+
return object.__getattribute__(self, '_data')
|
|
2790
|
+
|
|
2448
2791
|
|
|
2449
2792
|
# Module-level convenience functions
|
|
2450
2793
|
_default_builtins: Optional[CSSLBuiltins] = None
|