IncludeCPP 3.4.10__py3-none-any.whl → 3.4.21__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 +131 -3
- includecpp/cli/commands.py +124 -0
- includecpp/core/cssl/CSSL_DOCUMENTATION.md +1482 -0
- includecpp/core/cssl/__init__.py +6 -6
- includecpp/core/cssl/cssl_builtins.py +243 -5
- includecpp/core/cssl/cssl_parser.py +298 -10
- includecpp/core/cssl/cssl_runtime.py +704 -53
- includecpp/core/cssl/cssl_types.py +403 -2
- includecpp/core/cssl_bridge.py +363 -0
- includecpp/generator/parser.cpp +1 -1
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/METADATA +270 -3
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/RECORD +17 -16
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/WHEEL +0 -0
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/entry_points.txt +0 -0
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.4.10.dist-info → includecpp-3.4.21.dist-info}/top_level.txt +0 -0
includecpp/core/cssl_bridge.py
CHANGED
|
@@ -3,11 +3,125 @@ CSSL Bridge - Python API for CSSL Language
|
|
|
3
3
|
Provides CsslLang class for executing CSSL code from Python.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
import os
|
|
7
|
+
import pickle
|
|
8
|
+
import random
|
|
6
9
|
import threading
|
|
7
10
|
from pathlib import Path
|
|
8
11
|
from typing import Any, List, Optional, Callable, Dict
|
|
9
12
|
|
|
10
13
|
|
|
14
|
+
def _get_share_directory() -> Path:
|
|
15
|
+
"""Get the directory for shared objects."""
|
|
16
|
+
# Use APPDATA on Windows, ~/.config on Unix
|
|
17
|
+
if os.name == 'nt':
|
|
18
|
+
base = Path(os.environ.get('APPDATA', Path.home() / 'AppData' / 'Roaming'))
|
|
19
|
+
else:
|
|
20
|
+
base = Path(os.environ.get('XDG_CONFIG_HOME', Path.home() / '.config'))
|
|
21
|
+
|
|
22
|
+
share_dir = base / 'IncludeCPP' / 'shared_objects'
|
|
23
|
+
share_dir.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
return share_dir
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Global live object registry - holds actual object references for live sharing
|
|
28
|
+
_live_objects: Dict[str, Any] = {}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SharedObjectProxy:
|
|
32
|
+
"""
|
|
33
|
+
Live proxy for accessing a shared Python object from CSSL.
|
|
34
|
+
Changes made through this proxy are reflected in the original object.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, name: str, obj: Any = None):
|
|
38
|
+
object.__setattr__(self, '_name', name)
|
|
39
|
+
object.__setattr__(self, '_direct_object', obj)
|
|
40
|
+
|
|
41
|
+
def _get_object(self):
|
|
42
|
+
"""Get the live object reference."""
|
|
43
|
+
# First check direct object (same-instance sharing)
|
|
44
|
+
direct = object.__getattribute__(self, '_direct_object')
|
|
45
|
+
if direct is not None:
|
|
46
|
+
return direct
|
|
47
|
+
|
|
48
|
+
# Fall back to global registry
|
|
49
|
+
name = object.__getattribute__(self, '_name')
|
|
50
|
+
if name in _live_objects:
|
|
51
|
+
return _live_objects[name]
|
|
52
|
+
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
def __getattr__(self, name: str):
|
|
56
|
+
"""Access attributes/methods on the shared object."""
|
|
57
|
+
obj = self._get_object()
|
|
58
|
+
if obj is None:
|
|
59
|
+
obj_name = object.__getattribute__(self, '_name')
|
|
60
|
+
raise AttributeError(f"Shared object '${obj_name}' not available")
|
|
61
|
+
|
|
62
|
+
return getattr(obj, name)
|
|
63
|
+
|
|
64
|
+
def __setattr__(self, name: str, value: Any):
|
|
65
|
+
"""Set attributes on the shared object (live update)."""
|
|
66
|
+
if name.startswith('_'):
|
|
67
|
+
object.__setattr__(self, name, value)
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
obj = self._get_object()
|
|
71
|
+
if obj is None:
|
|
72
|
+
obj_name = object.__getattribute__(self, '_name')
|
|
73
|
+
raise AttributeError(f"Shared object '${obj_name}' not available")
|
|
74
|
+
|
|
75
|
+
setattr(obj, name, value)
|
|
76
|
+
|
|
77
|
+
def __repr__(self):
|
|
78
|
+
obj = self._get_object()
|
|
79
|
+
name = object.__getattribute__(self, '_name')
|
|
80
|
+
return f"<SharedObject ${name} type={type(obj).__name__ if obj else 'None'}>"
|
|
81
|
+
|
|
82
|
+
def __call__(self, *args, **kwargs):
|
|
83
|
+
"""Allow calling the object if it's callable."""
|
|
84
|
+
obj = self._get_object()
|
|
85
|
+
if obj is None:
|
|
86
|
+
name = object.__getattribute__(self, '_name')
|
|
87
|
+
raise TypeError(f"Shared object '${name}' not available")
|
|
88
|
+
if callable(obj):
|
|
89
|
+
return obj(*args, **kwargs)
|
|
90
|
+
name = object.__getattribute__(self, '_name')
|
|
91
|
+
raise TypeError(f"Shared object '${name}' is not callable")
|
|
92
|
+
|
|
93
|
+
def __getitem__(self, key):
|
|
94
|
+
"""Allow indexing on the shared object."""
|
|
95
|
+
obj = self._get_object()
|
|
96
|
+
if obj is None:
|
|
97
|
+
name = object.__getattribute__(self, '_name')
|
|
98
|
+
raise KeyError(f"Shared object '${name}' not available")
|
|
99
|
+
return obj[key]
|
|
100
|
+
|
|
101
|
+
def __setitem__(self, key, value):
|
|
102
|
+
"""Allow setting items on the shared object (live update)."""
|
|
103
|
+
obj = self._get_object()
|
|
104
|
+
if obj is None:
|
|
105
|
+
name = object.__getattribute__(self, '_name')
|
|
106
|
+
raise KeyError(f"Shared object '${name}' not available")
|
|
107
|
+
obj[key] = value
|
|
108
|
+
|
|
109
|
+
def __iter__(self):
|
|
110
|
+
"""Allow iterating over the shared object."""
|
|
111
|
+
obj = self._get_object()
|
|
112
|
+
if obj is None:
|
|
113
|
+
name = object.__getattribute__(self, '_name')
|
|
114
|
+
raise TypeError(f"Shared object '${name}' not available")
|
|
115
|
+
return iter(obj)
|
|
116
|
+
|
|
117
|
+
def __len__(self):
|
|
118
|
+
"""Get length of the shared object."""
|
|
119
|
+
obj = self._get_object()
|
|
120
|
+
if obj is None:
|
|
121
|
+
return 0
|
|
122
|
+
return len(obj)
|
|
123
|
+
|
|
124
|
+
|
|
11
125
|
class CSSLModule:
|
|
12
126
|
"""
|
|
13
127
|
A callable CSSL module that executes code with arguments.
|
|
@@ -276,6 +390,255 @@ class CsslLang:
|
|
|
276
390
|
"""
|
|
277
391
|
return CSSLFunctionModule(self, code)
|
|
278
392
|
|
|
393
|
+
def code(self, name: str, code: str) -> None:
|
|
394
|
+
"""
|
|
395
|
+
Register inline CSSL code as a payload that can be loaded via payload().
|
|
396
|
+
|
|
397
|
+
This allows creating payloads from Python code without external files.
|
|
398
|
+
|
|
399
|
+
Usage:
|
|
400
|
+
from includecpp import CSSL
|
|
401
|
+
cssl = CSSL.CsslLang()
|
|
402
|
+
|
|
403
|
+
# Register a helper payload
|
|
404
|
+
cssl.code("helpers", '''
|
|
405
|
+
global version = "1.0.0";
|
|
406
|
+
void log(string msg) {
|
|
407
|
+
printl("[LOG] " + msg);
|
|
408
|
+
}
|
|
409
|
+
''')
|
|
410
|
+
|
|
411
|
+
# Use it in CSSL code
|
|
412
|
+
cssl.exec('''
|
|
413
|
+
payload("helpers"); // Load the inline payload
|
|
414
|
+
@log("Hello!"); // Call the helper function
|
|
415
|
+
printl(@version); // Access the global
|
|
416
|
+
''')
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
name: Name to register the payload under (used in payload("name"))
|
|
420
|
+
code: CSSL code string
|
|
421
|
+
"""
|
|
422
|
+
runtime = self._get_runtime()
|
|
423
|
+
if not hasattr(runtime, '_inline_payloads'):
|
|
424
|
+
runtime._inline_payloads = {}
|
|
425
|
+
runtime._inline_payloads[name] = code
|
|
426
|
+
|
|
427
|
+
def share(self, instance: Any, name: str) -> str:
|
|
428
|
+
"""
|
|
429
|
+
Share a Python object instance with CSSL scripts (LIVE sharing).
|
|
430
|
+
|
|
431
|
+
The object is stored as a LIVE reference - changes made in CSSL
|
|
432
|
+
will be reflected in the original Python object immediately.
|
|
433
|
+
Call share() again with the same name to update the shared object.
|
|
434
|
+
|
|
435
|
+
Usage in Python:
|
|
436
|
+
from includecpp import CSSL
|
|
437
|
+
cssl = CSSL.CsslLang()
|
|
438
|
+
|
|
439
|
+
# Share a Python object
|
|
440
|
+
class MyAPI:
|
|
441
|
+
def __init__(self):
|
|
442
|
+
self.counter = 0
|
|
443
|
+
def greet(self, name):
|
|
444
|
+
return f"Hello, {name}!"
|
|
445
|
+
def increment(self):
|
|
446
|
+
self.counter += 1
|
|
447
|
+
|
|
448
|
+
api = MyAPI()
|
|
449
|
+
cssl.share(api, "myapi")
|
|
450
|
+
|
|
451
|
+
# Use in CSSL - changes are LIVE!
|
|
452
|
+
cssl.exec('''
|
|
453
|
+
ob <== $myapi;
|
|
454
|
+
printl(ob.greet("World"));
|
|
455
|
+
ob.increment();
|
|
456
|
+
printl(ob.counter); // 1
|
|
457
|
+
''')
|
|
458
|
+
|
|
459
|
+
# Changes reflect back to Python!
|
|
460
|
+
print(api.counter) # 1
|
|
461
|
+
|
|
462
|
+
Args:
|
|
463
|
+
instance: Python object to share
|
|
464
|
+
name: Name for the shared object (accessed as $name in CSSL)
|
|
465
|
+
|
|
466
|
+
Returns:
|
|
467
|
+
Path to the shared object marker file
|
|
468
|
+
"""
|
|
469
|
+
global _live_objects
|
|
470
|
+
runtime = self._get_runtime()
|
|
471
|
+
|
|
472
|
+
# Initialize shared objects registry
|
|
473
|
+
if not hasattr(runtime, '_shared_objects'):
|
|
474
|
+
runtime._shared_objects = {}
|
|
475
|
+
|
|
476
|
+
# Generate unique filename: <name>.shareobj<7digits>
|
|
477
|
+
random_suffix = ''.join([str(random.randint(0, 9)) for _ in range(7)])
|
|
478
|
+
share_dir = _get_share_directory()
|
|
479
|
+
filepath = share_dir / f"{name}.shareobj{random_suffix}"
|
|
480
|
+
|
|
481
|
+
# Remove old file if updating
|
|
482
|
+
if name in runtime._shared_objects:
|
|
483
|
+
old_path = runtime._shared_objects[name]['path']
|
|
484
|
+
try:
|
|
485
|
+
Path(old_path).unlink(missing_ok=True)
|
|
486
|
+
except Exception:
|
|
487
|
+
pass
|
|
488
|
+
|
|
489
|
+
# Store LIVE object reference in global registry
|
|
490
|
+
_live_objects[name] = instance
|
|
491
|
+
|
|
492
|
+
# Write marker file with metadata (not the actual object)
|
|
493
|
+
import json
|
|
494
|
+
metadata = {
|
|
495
|
+
'name': name,
|
|
496
|
+
'type': type(instance).__name__,
|
|
497
|
+
'live': True,
|
|
498
|
+
'id': id(instance)
|
|
499
|
+
}
|
|
500
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
501
|
+
json.dump(metadata, f)
|
|
502
|
+
|
|
503
|
+
# Register in runtime
|
|
504
|
+
runtime._shared_objects[name] = {
|
|
505
|
+
'path': str(filepath),
|
|
506
|
+
'type': type(instance).__name__,
|
|
507
|
+
'live': True
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
# Also register the live proxy in the runtime's scope for $name access
|
|
511
|
+
proxy = SharedObjectProxy(name, instance)
|
|
512
|
+
runtime.global_scope.set(f'${name}', proxy)
|
|
513
|
+
|
|
514
|
+
return str(filepath)
|
|
515
|
+
|
|
516
|
+
def unshare(self, name: str) -> bool:
|
|
517
|
+
"""
|
|
518
|
+
Remove a shared object.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
name: Name of the shared object to remove
|
|
522
|
+
|
|
523
|
+
Returns:
|
|
524
|
+
True if removed, False if not found
|
|
525
|
+
"""
|
|
526
|
+
global _live_objects
|
|
527
|
+
runtime = self._get_runtime()
|
|
528
|
+
|
|
529
|
+
if not hasattr(runtime, '_shared_objects'):
|
|
530
|
+
return False
|
|
531
|
+
|
|
532
|
+
if name not in runtime._shared_objects:
|
|
533
|
+
return False
|
|
534
|
+
|
|
535
|
+
# Remove from live objects registry
|
|
536
|
+
if name in _live_objects:
|
|
537
|
+
del _live_objects[name]
|
|
538
|
+
|
|
539
|
+
# Remove from runtime scope
|
|
540
|
+
try:
|
|
541
|
+
runtime.global_scope.delete(f'${name}')
|
|
542
|
+
except Exception:
|
|
543
|
+
pass
|
|
544
|
+
|
|
545
|
+
# Remove marker file
|
|
546
|
+
filepath = runtime._shared_objects[name]['path']
|
|
547
|
+
try:
|
|
548
|
+
Path(filepath).unlink(missing_ok=True)
|
|
549
|
+
except Exception:
|
|
550
|
+
pass
|
|
551
|
+
|
|
552
|
+
del runtime._shared_objects[name]
|
|
553
|
+
return True
|
|
554
|
+
|
|
555
|
+
def get_shared(self, name: str) -> Optional[Any]:
|
|
556
|
+
"""
|
|
557
|
+
Get a shared object by name (for Python-side access).
|
|
558
|
+
|
|
559
|
+
Returns the actual live object reference, not a copy.
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
name: Name of the shared object
|
|
563
|
+
|
|
564
|
+
Returns:
|
|
565
|
+
The live shared object or None if not found
|
|
566
|
+
"""
|
|
567
|
+
global _live_objects
|
|
568
|
+
|
|
569
|
+
# Return live object if available
|
|
570
|
+
if name in _live_objects:
|
|
571
|
+
return _live_objects[name]
|
|
572
|
+
|
|
573
|
+
return None
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
# Global shared objects registry (for cross-instance sharing)
|
|
577
|
+
_global_shared_objects: Dict[str, str] = {}
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
def share(instance: Any, name: str) -> str:
|
|
581
|
+
"""
|
|
582
|
+
Share a Python object globally for all CSSL instances (LIVE sharing).
|
|
583
|
+
|
|
584
|
+
Changes made through CSSL will reflect back to the original object.
|
|
585
|
+
"""
|
|
586
|
+
global _live_objects
|
|
587
|
+
|
|
588
|
+
random_suffix = ''.join([str(random.randint(0, 9)) for _ in range(7)])
|
|
589
|
+
share_dir = _get_share_directory()
|
|
590
|
+
filepath = share_dir / f"{name}.shareobj{random_suffix}"
|
|
591
|
+
|
|
592
|
+
# Remove old file if updating
|
|
593
|
+
if name in _global_shared_objects:
|
|
594
|
+
try:
|
|
595
|
+
Path(_global_shared_objects[name]).unlink(missing_ok=True)
|
|
596
|
+
except Exception:
|
|
597
|
+
pass
|
|
598
|
+
|
|
599
|
+
# Store LIVE object reference
|
|
600
|
+
_live_objects[name] = instance
|
|
601
|
+
|
|
602
|
+
# Write marker file with metadata
|
|
603
|
+
import json
|
|
604
|
+
metadata = {
|
|
605
|
+
'name': name,
|
|
606
|
+
'type': type(instance).__name__,
|
|
607
|
+
'live': True,
|
|
608
|
+
'id': id(instance)
|
|
609
|
+
}
|
|
610
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
611
|
+
json.dump(metadata, f)
|
|
612
|
+
|
|
613
|
+
_global_shared_objects[name] = str(filepath)
|
|
614
|
+
return str(filepath)
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
def unshare(name: str) -> bool:
|
|
618
|
+
"""Remove a globally shared object."""
|
|
619
|
+
global _live_objects
|
|
620
|
+
|
|
621
|
+
if name not in _global_shared_objects:
|
|
622
|
+
return False
|
|
623
|
+
|
|
624
|
+
# Remove from live objects
|
|
625
|
+
if name in _live_objects:
|
|
626
|
+
del _live_objects[name]
|
|
627
|
+
|
|
628
|
+
try:
|
|
629
|
+
Path(_global_shared_objects[name]).unlink(missing_ok=True)
|
|
630
|
+
except Exception:
|
|
631
|
+
pass
|
|
632
|
+
|
|
633
|
+
del _global_shared_objects[name]
|
|
634
|
+
return True
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
def get_shared(name: str) -> Optional[Any]:
|
|
638
|
+
"""Get a globally shared object by name."""
|
|
639
|
+
global _live_objects
|
|
640
|
+
return _live_objects.get(name)
|
|
641
|
+
|
|
279
642
|
|
|
280
643
|
# Singleton for convenience
|
|
281
644
|
_default_instance: Optional[CsslLang] = None
|
includecpp/generator/parser.cpp
CHANGED
|
@@ -705,7 +705,7 @@ ModuleDescriptor API::parse_cp_file(const std::string& filepath) {
|
|
|
705
705
|
std::ifstream source_file(desc.source_path);
|
|
706
706
|
if (source_file.is_open()) {
|
|
707
707
|
std::string line;
|
|
708
|
-
std::regex include_regex(R"(^\s*#include\s*"([^"]+\.h(?:pp)?)")");
|
|
708
|
+
std::regex include_regex(R"re(^\s*#include\s*"([^"]+\.h(?:pp)?)")re");
|
|
709
709
|
std::smatch match;
|
|
710
710
|
|
|
711
711
|
while (std::getline(source_file, line)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: IncludeCPP
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.21
|
|
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
|
|
@@ -621,10 +621,277 @@ Then check **"Enable Experimental Features"** and save.
|
|
|
621
621
|
- Have breaking changes between versions
|
|
622
622
|
- Be removed or significantly changed
|
|
623
623
|
|
|
624
|
-
Use at your own discretion. Report issues at: https://github.com/
|
|
624
|
+
Use at your own discretion. Report issues at: https://github.com/liliassg/IncludeCPP/issues
|
|
625
|
+
|
|
626
|
+
# CSSL - CSO Service Script Language
|
|
627
|
+
|
|
628
|
+
IncludeCPP includes CSSL, a scripting language with advanced data manipulation features.
|
|
629
|
+
|
|
630
|
+
## Basic Usage
|
|
631
|
+
|
|
632
|
+
```python
|
|
633
|
+
from includecpp import CSSL
|
|
634
|
+
|
|
635
|
+
# Execute CSSL code
|
|
636
|
+
CSSL.exec('''
|
|
637
|
+
printl("Hello from CSSL!");
|
|
638
|
+
|
|
639
|
+
int x = 10;
|
|
640
|
+
for (i in range(0, 5)) {
|
|
641
|
+
x = x + i;
|
|
642
|
+
}
|
|
643
|
+
printl(x);
|
|
644
|
+
''')
|
|
645
|
+
|
|
646
|
+
# Execute with arguments
|
|
647
|
+
result = CSSL.exec('''
|
|
648
|
+
int a = parameter.get(0);
|
|
649
|
+
int b = parameter.get(1);
|
|
650
|
+
parameter.return(a + b);
|
|
651
|
+
''', 5, 3)
|
|
652
|
+
print(result) # 8
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
## Live Object Sharing
|
|
656
|
+
|
|
657
|
+
Share Python objects with CSSL scripts. Changes in CSSL reflect back to Python:
|
|
658
|
+
|
|
659
|
+
```python
|
|
660
|
+
from includecpp import CSSL
|
|
661
|
+
|
|
662
|
+
class Counter:
|
|
663
|
+
def __init__(self):
|
|
664
|
+
self.value = 100
|
|
665
|
+
|
|
666
|
+
counter = Counter()
|
|
667
|
+
cssl = CSSL.CsslLang()
|
|
668
|
+
cssl.share(counter, "cnt")
|
|
669
|
+
|
|
670
|
+
# Modify in CSSL - changes reflect in Python!
|
|
671
|
+
cssl.exec('''
|
|
672
|
+
$cnt.value = $cnt.value - 10;
|
|
673
|
+
printl($cnt.value); // 90
|
|
674
|
+
''')
|
|
675
|
+
|
|
676
|
+
print(counter.value) # 90 - Changed!
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### Shared Object Syntax
|
|
680
|
+
|
|
681
|
+
- `$name` - Access shared object
|
|
682
|
+
- `$name.property` - Access/modify properties
|
|
683
|
+
- `$name.method()` - Call methods
|
|
684
|
+
- `delete("name")` - Remove shared object
|
|
685
|
+
|
|
686
|
+
## Data Types
|
|
687
|
+
|
|
688
|
+
```cssl
|
|
689
|
+
// Basic types
|
|
690
|
+
int x = 42;
|
|
691
|
+
float pi = 3.14;
|
|
692
|
+
string name = "CSSL";
|
|
693
|
+
bool active = true;
|
|
694
|
+
|
|
695
|
+
// Collections
|
|
696
|
+
array<int> arr;
|
|
697
|
+
arr.push(1);
|
|
698
|
+
arr.push(2);
|
|
699
|
+
printl(arr.length()); // 2
|
|
700
|
+
|
|
701
|
+
vector<string> vec;
|
|
702
|
+
vec.push("A");
|
|
703
|
+
vec.push("B");
|
|
704
|
+
|
|
705
|
+
stack<int> s;
|
|
706
|
+
s.push(10);
|
|
707
|
+
s.pop();
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
## Control Flow
|
|
711
|
+
|
|
712
|
+
```cssl
|
|
713
|
+
// If/elif/else
|
|
714
|
+
if (x > 10) {
|
|
715
|
+
printl("big");
|
|
716
|
+
} elif (x > 5) {
|
|
717
|
+
printl("medium");
|
|
718
|
+
} else {
|
|
719
|
+
printl("small");
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// For loops
|
|
723
|
+
for (i in range(0, 10)) {
|
|
724
|
+
printl(i);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
for (i in range(0, 10, 2)) { // with step
|
|
728
|
+
printl(i); // 0, 2, 4, 6, 8
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Foreach
|
|
732
|
+
array<string> items;
|
|
733
|
+
items.push("A");
|
|
734
|
+
items.push("B");
|
|
735
|
+
foreach (item in items) {
|
|
736
|
+
printl(item);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// While
|
|
740
|
+
int count = 0;
|
|
741
|
+
while (count < 5) {
|
|
742
|
+
printl(count);
|
|
743
|
+
count = count + 1;
|
|
744
|
+
}
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
## Functions
|
|
748
|
+
|
|
749
|
+
```cssl
|
|
750
|
+
// Basic function
|
|
751
|
+
void greet(string name) {
|
|
752
|
+
printl("Hello, " + name + "!");
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Return value
|
|
756
|
+
int add(int a, int b) {
|
|
757
|
+
return a + b;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// Global variables
|
|
761
|
+
global version = "1.0.0";
|
|
762
|
+
printl(@version);
|
|
763
|
+
|
|
764
|
+
// r@ syntax for global declaration
|
|
765
|
+
r@myGlobal = "value";
|
|
766
|
+
printl(@myGlobal);
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
## BruteForce Injection System
|
|
770
|
+
|
|
771
|
+
CSSL's unique injection operators for data manipulation:
|
|
772
|
+
|
|
773
|
+
```cssl
|
|
774
|
+
// <== Move data (replaces target)
|
|
775
|
+
target <== source;
|
|
776
|
+
|
|
777
|
+
// +<== Copy & add to target
|
|
778
|
+
target +<== source;
|
|
779
|
+
|
|
780
|
+
// -<== Move & remove from source
|
|
781
|
+
target -<== source;
|
|
782
|
+
|
|
783
|
+
// <<== Code infusion into functions
|
|
784
|
+
myFunc() <<== {
|
|
785
|
+
printl("Injected code!");
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
// +<<== Add code without replacing
|
|
789
|
+
myFunc() +<<== {
|
|
790
|
+
printl("Additional code!");
|
|
791
|
+
};
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
## String Methods
|
|
795
|
+
|
|
796
|
+
```cssl
|
|
797
|
+
string s = "Hello World";
|
|
798
|
+
|
|
799
|
+
// Methods
|
|
800
|
+
s.length(); // 11
|
|
801
|
+
s.toUpper(); // "HELLO WORLD"
|
|
802
|
+
s.toLower(); // "hello world"
|
|
803
|
+
s.contains("World"); // true
|
|
804
|
+
s.startsWith("Hello"); // true
|
|
805
|
+
s.endsWith("World"); // true
|
|
806
|
+
s.replace("World", "CSSL");
|
|
807
|
+
s.split(" "); // ["Hello", "World"]
|
|
808
|
+
s.trim(); // Remove whitespace
|
|
809
|
+
s.substring(0, 5); // "Hello"
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
## CSSL Modules
|
|
813
|
+
|
|
814
|
+
```python
|
|
815
|
+
# Create callable module
|
|
816
|
+
module = CSSL.module('''
|
|
817
|
+
string name = parameter.get(0);
|
|
818
|
+
printl("Hello, " + name + "!");
|
|
819
|
+
''')
|
|
820
|
+
module("World") # Prints: Hello, World!
|
|
821
|
+
|
|
822
|
+
# Create module with functions
|
|
823
|
+
math_mod = CSSL.makemodule('''
|
|
824
|
+
int add(int a, int b) {
|
|
825
|
+
return a + b;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
int multiply(int a, int b) {
|
|
829
|
+
return a * b;
|
|
830
|
+
}
|
|
831
|
+
''')
|
|
832
|
+
print(math_mod.add(2, 3)) # 5
|
|
833
|
+
print(math_mod.multiply(4, 5)) # 20
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
## Inline Payloads
|
|
837
|
+
|
|
838
|
+
```python
|
|
839
|
+
cssl = CSSL.CsslLang()
|
|
840
|
+
|
|
841
|
+
# Register code as payload
|
|
842
|
+
cssl.code("helpers", '''
|
|
843
|
+
global version = "1.0.0";
|
|
844
|
+
void log(string msg) {
|
|
845
|
+
printl("[LOG] " + msg);
|
|
846
|
+
}
|
|
847
|
+
''')
|
|
848
|
+
|
|
849
|
+
# Use in CSSL
|
|
850
|
+
cssl.exec('''
|
|
851
|
+
payload("helpers");
|
|
852
|
+
@log("Application started");
|
|
853
|
+
printl(@version);
|
|
854
|
+
''')
|
|
855
|
+
```
|
|
625
856
|
|
|
626
857
|
# Changelog
|
|
627
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
|
+
|
|
628
895
|
## v3.4.2
|
|
629
896
|
- **New Feature: `exec` Command**
|
|
630
897
|
- Interactive REPL for quick code testing without creating files
|
|
@@ -806,4 +1073,4 @@ Use at your own discretion. Report issues at: https://github.com/hatte/IncludeCP
|
|
|
806
1073
|
|
|
807
1074
|
---
|
|
808
1075
|
|
|
809
|
-
MIT License | v3.4.
|
|
1076
|
+
MIT License | v3.4.20 | [GitHub](https://github.com/liliassg/IncludeCPP)
|