IncludeCPP 3.3.20__py3-none-any.whl → 3.4.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 +59 -58
- includecpp/cli/commands.py +400 -21
- includecpp/core/cppy_converter.py +143 -18
- includecpp/core/cssl/__init__.py +40 -0
- includecpp/core/cssl/cssl_builtins.py +1693 -0
- includecpp/core/cssl/cssl_events.py +621 -0
- includecpp/core/cssl/cssl_modules.py +2803 -0
- includecpp/core/cssl/cssl_parser.py +1791 -0
- includecpp/core/cssl/cssl_runtime.py +1587 -0
- includecpp/core/cssl/cssl_syntax.py +488 -0
- includecpp/core/cssl/cssl_types.py +438 -0
- includecpp/core/cssl_bridge.py +409 -0
- includecpp/core/cssl_bridge.pyi +311 -0
- includecpp/core/project_ui.py +684 -34
- includecpp/generator/parser.cpp +81 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/METADATA +48 -4
- includecpp-3.4.8.dist-info/RECORD +41 -0
- includecpp-3.3.20.dist-info/RECORD +0 -31
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/WHEEL +0 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/entry_points.txt +0 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.3.20.dist-info → includecpp-3.4.8.dist-info}/top_level.txt +0 -0
|
@@ -25,6 +25,65 @@ def _safe_get(lst: List[Any], index: int, default: Any = None) -> Any:
|
|
|
25
25
|
return default
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
# v3.3.22: Python reserved keywords - names that need escaping when used as identifiers
|
|
29
|
+
PYTHON_KEYWORDS = {
|
|
30
|
+
'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await',
|
|
31
|
+
'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except',
|
|
32
|
+
'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is',
|
|
33
|
+
'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try',
|
|
34
|
+
'while', 'with', 'yield'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# v3.4.1: C++ reserved words that need escaping when used as Python identifiers
|
|
38
|
+
# These are C++ types/keywords that are valid Python identifiers but confusing
|
|
39
|
+
CPP_RESERVED_WORDS = {
|
|
40
|
+
# Primitive types
|
|
41
|
+
'int', 'float', 'double', 'char', 'bool', 'void', 'auto',
|
|
42
|
+
'short', 'long', 'signed', 'unsigned', 'wchar_t',
|
|
43
|
+
# Type modifiers
|
|
44
|
+
'const', 'static', 'virtual', 'volatile', 'mutable', 'extern',
|
|
45
|
+
'register', 'inline', 'explicit', 'constexpr', 'consteval',
|
|
46
|
+
# Access modifiers
|
|
47
|
+
'public', 'private', 'protected',
|
|
48
|
+
# Other keywords
|
|
49
|
+
'template', 'typename', 'namespace', 'using', 'typedef',
|
|
50
|
+
'struct', 'union', 'enum', 'sizeof', 'alignof', 'decltype',
|
|
51
|
+
'new', 'delete', 'operator', 'friend', 'this',
|
|
52
|
+
'throw', 'catch', 'noexcept', 'final', 'override',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _escape_python_keyword(name: str) -> str:
|
|
57
|
+
"""Escape Python reserved keywords by adding underscore suffix.
|
|
58
|
+
|
|
59
|
+
Example: 'class' -> 'class_', 'def' -> 'def_', 'import' -> 'import_'
|
|
60
|
+
"""
|
|
61
|
+
if name in PYTHON_KEYWORDS:
|
|
62
|
+
return name + '_'
|
|
63
|
+
return name
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _escape_cpp_reserved(name: str) -> str:
|
|
67
|
+
"""Escape C++ reserved words when used as Python identifiers.
|
|
68
|
+
|
|
69
|
+
Example: 'double' -> 'double_', 'int' -> 'int_', 'void' -> 'void_'
|
|
70
|
+
v3.4.1: Prevents C++ type names from being used as Python function/variable names.
|
|
71
|
+
"""
|
|
72
|
+
if name in CPP_RESERVED_WORDS:
|
|
73
|
+
return name + '_'
|
|
74
|
+
return name
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _escape_identifier(name: str) -> str:
|
|
78
|
+
"""Escape both Python keywords and C++ reserved words.
|
|
79
|
+
|
|
80
|
+
Combines both escaping functions for comprehensive identifier safety.
|
|
81
|
+
"""
|
|
82
|
+
name = _escape_python_keyword(name)
|
|
83
|
+
name = _escape_cpp_reserved(name)
|
|
84
|
+
return name
|
|
85
|
+
|
|
86
|
+
|
|
28
87
|
# Python type to C++ type mapping
|
|
29
88
|
PY_TO_CPP_TYPES = {
|
|
30
89
|
'int': 'int',
|
|
@@ -2205,11 +2264,31 @@ class CppToPythonConverter:
|
|
|
2205
2264
|
|
|
2206
2265
|
def _parse_class_fields(self, body: str) -> List[Tuple[str, str, Optional[str]]]:
|
|
2207
2266
|
fields = []
|
|
2267
|
+
all_field_names = set() # v3.4.1: Track ALL fields for self. prefix
|
|
2208
2268
|
|
|
2269
|
+
# v3.4.1: Parse fields from ALL sections (public, private, protected)
|
|
2270
|
+
# for self. prefix detection, but only return public fields for dataclass
|
|
2209
2271
|
sections = re.split(r'(?:public|private|protected)\s*:', body)
|
|
2210
|
-
public_section = sections[1] if len(sections) > 1 else body
|
|
2211
2272
|
|
|
2212
2273
|
field_pattern = r'(\w+(?:<[^>]+>)?)\s+(\w+)\s*(?:=\s*([^;]+))?\s*;'
|
|
2274
|
+
|
|
2275
|
+
# First pass: collect ALL field names from all sections
|
|
2276
|
+
for section in sections:
|
|
2277
|
+
for match in re.finditer(field_pattern, section):
|
|
2278
|
+
field_type = match.group(1)
|
|
2279
|
+
field_name = match.group(2)
|
|
2280
|
+
|
|
2281
|
+
if '(' in field_type or field_type in ('return', 'if', 'for', 'while'):
|
|
2282
|
+
continue
|
|
2283
|
+
|
|
2284
|
+
all_field_names.add(field_name)
|
|
2285
|
+
|
|
2286
|
+
# Store all field names for self. prefix detection
|
|
2287
|
+
self._current_class_fields = all_field_names
|
|
2288
|
+
|
|
2289
|
+
# Second pass: return only public fields for the Python class definition
|
|
2290
|
+
public_section = sections[1] if len(sections) > 1 else body
|
|
2291
|
+
|
|
2213
2292
|
for match in re.finditer(field_pattern, public_section):
|
|
2214
2293
|
field_type = match.group(1)
|
|
2215
2294
|
field_name = match.group(2)
|
|
@@ -2500,18 +2579,20 @@ class CppToPythonConverter:
|
|
|
2500
2579
|
if var_name not in ('if', 'for', 'while', 'return'):
|
|
2501
2580
|
return f'{var_name} = {self._get_default_value(var_type)}'
|
|
2502
2581
|
|
|
2503
|
-
# Assignment
|
|
2504
|
-
assign_match = re.match(r'(\w
|
|
2582
|
+
# Assignment - v3.3.22: Expanded pattern to capture -> and ::
|
|
2583
|
+
assign_match = re.match(r'([a-zA-Z_][\w:>-]*(?:->|\.)?[a-zA-Z_][\w]*(?:\[[^\]]+\])?)\s*=\s*(.+)$', stmt)
|
|
2505
2584
|
if assign_match:
|
|
2506
2585
|
target = assign_match.group(1)
|
|
2507
|
-
|
|
2586
|
+
# v3.3.22: Apply full expression conversion to target as well
|
|
2587
|
+
target = self._convert_cpp_expr(target)
|
|
2508
2588
|
value = self._convert_cpp_expr(assign_match.group(2))
|
|
2509
2589
|
return f'{target} = {value}'
|
|
2510
2590
|
|
|
2511
2591
|
# Augmented assignment
|
|
2512
2592
|
aug_match = re.match(r'(\w+(?:\.\w+)*)\s*(\+\+|--|\+=|-=|\*=|/=)', stmt)
|
|
2513
2593
|
if aug_match:
|
|
2514
|
-
|
|
2594
|
+
# v3.3.22: Apply full expression conversion to target
|
|
2595
|
+
target = self._convert_cpp_expr(aug_match.group(1))
|
|
2515
2596
|
op = aug_match.group(2)
|
|
2516
2597
|
if op == '++':
|
|
2517
2598
|
return f'{target} += 1'
|
|
@@ -2572,13 +2653,30 @@ class CppToPythonConverter:
|
|
|
2572
2653
|
expr = re.sub(r'std::max\(([^,]+),\s*([^)]+)\)', r'max(\1, \2)', expr)
|
|
2573
2654
|
|
|
2574
2655
|
# Handle std::accumulate(container.begin(), container.end(), init) -> sum(container) [+ init]
|
|
2656
|
+
# v3.4.1: Also handle accumulate without std:: prefix
|
|
2575
2657
|
def _accumulate_to_sum(m):
|
|
2576
2658
|
container = m.group(1)
|
|
2577
2659
|
init_val = m.group(2).strip()
|
|
2578
2660
|
if init_val == '0' or init_val == '0.0':
|
|
2579
2661
|
return f'sum({container})'
|
|
2580
2662
|
return f'sum({container}) + {init_val}'
|
|
2581
|
-
expr = re.sub(r'std::accumulate\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)', _accumulate_to_sum, expr)
|
|
2663
|
+
expr = re.sub(r'(?:std::)?accumulate\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)', _accumulate_to_sum, expr)
|
|
2664
|
+
|
|
2665
|
+
# v3.4.1: Handle std::find, std::count, std::sort with .begin()/.end()
|
|
2666
|
+
# std::find(vec.begin(), vec.end(), val) -> val in vec
|
|
2667
|
+
expr = re.sub(r'(?:std::)?find\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)\s*!=\s*\1\.end\(\)', r'\2 in \1', expr)
|
|
2668
|
+
# std::count(vec.begin(), vec.end(), val) -> vec.count(val)
|
|
2669
|
+
expr = re.sub(r'(?:std::)?count\((\w+)\.begin\(\),\s*\1\.end\(\),\s*([^)]+)\)', r'\1.count(\2)', expr)
|
|
2670
|
+
# std::sort(vec.begin(), vec.end()) -> vec.sort()
|
|
2671
|
+
expr = re.sub(r'(?:std::)?sort\((\w+)\.begin\(\),\s*\1\.end\(\)\)', r'\1.sort()', expr)
|
|
2672
|
+
# std::reverse(vec.begin(), vec.end()) -> vec.reverse()
|
|
2673
|
+
expr = re.sub(r'(?:std::)?reverse\((\w+)\.begin\(\),\s*\1\.end\(\)\)', r'\1.reverse()', expr)
|
|
2674
|
+
|
|
2675
|
+
# v3.4.1: Clean up any remaining .begin()/.end() that couldn't be converted
|
|
2676
|
+
# container.begin() -> iter(container) for iteration context
|
|
2677
|
+
# But typically these are errors - flag as comment if they remain
|
|
2678
|
+
expr = re.sub(r'(\w+)\.begin\(\)', r'\1[0]', expr) # Approximate as first element
|
|
2679
|
+
expr = re.sub(r'(\w+)\.end\(\)', r'len(\1)', expr) # Approximate as length
|
|
2582
2680
|
|
|
2583
2681
|
# Handle .size() -> len()
|
|
2584
2682
|
expr = re.sub(r'(\w+)\.size\(\)', r'len(\1)', expr)
|
|
@@ -2617,33 +2715,53 @@ class CppToPythonConverter:
|
|
|
2617
2715
|
# Handle negation !
|
|
2618
2716
|
expr = re.sub(r'!(\w)', r'not \1', expr)
|
|
2619
2717
|
|
|
2620
|
-
# Add self. prefix for class member access (when not already prefixed)
|
|
2718
|
+
# v3.3.22: Add self. prefix for class member access (when not already prefixed)
|
|
2621
2719
|
if self._current_class_fields:
|
|
2622
2720
|
for field in self._current_class_fields:
|
|
2623
2721
|
# Match field name that's not already prefixed with self. or another identifier
|
|
2624
|
-
|
|
2722
|
+
# Fixed lookahead to be more permissive - match non-word chars or end
|
|
2723
|
+
expr = re.sub(rf'(?<![.\w])(?<!self\.){re.escape(field)}(?=\W|$)', f'self.{field}', expr)
|
|
2724
|
+
|
|
2725
|
+
# v3.4.1: Handle common C++ member naming conventions
|
|
2726
|
+
# Convert m_name to self.name when in class context
|
|
2727
|
+
if self._current_class_fields:
|
|
2728
|
+
# Convert m_xxx to self.xxx
|
|
2729
|
+
expr = re.sub(r'(?<![.\w])m_(\w+)(?=\W|$)', r'self.\1', expr)
|
|
2730
|
+
# Convert _xxx to self.xxx (leading underscore)
|
|
2731
|
+
expr = re.sub(r'(?<![.\w])_(\w+)(?=\W|$)', r'self.\1', expr)
|
|
2732
|
+
# v3.4.1: Convert xxx_ to self.xxx_ (trailing underscore - Google style)
|
|
2733
|
+
# Only if it's a known field or matches the pattern
|
|
2734
|
+
for field in self._current_class_fields:
|
|
2735
|
+
if field.endswith('_') and field not in ('self_',):
|
|
2736
|
+
expr = re.sub(rf'(?<![.\w]){re.escape(field)}(?=\W|$)', f'self.{field}', expr)
|
|
2625
2737
|
|
|
2626
2738
|
return expr
|
|
2627
2739
|
|
|
2628
2740
|
def _generate_struct(self, struct: StructInfo) -> List[str]:
|
|
2629
2741
|
lines = ['@dataclass']
|
|
2630
|
-
|
|
2742
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in struct/class names
|
|
2743
|
+
struct_name = _escape_identifier(struct.name)
|
|
2744
|
+
lines.append(f'class {struct_name}:')
|
|
2631
2745
|
|
|
2632
2746
|
if not struct.fields:
|
|
2633
2747
|
lines.append(f'{self.indent}pass')
|
|
2634
2748
|
else:
|
|
2635
2749
|
for fname, ftype in struct.fields:
|
|
2636
|
-
|
|
2750
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in field names
|
|
2751
|
+
escaped_fname = _escape_identifier(fname)
|
|
2752
|
+
lines.append(f'{self.indent}{escaped_fname}: {ftype}')
|
|
2637
2753
|
|
|
2638
2754
|
return lines
|
|
2639
2755
|
|
|
2640
2756
|
def _generate_class(self, cls: ClassInfo) -> List[str]:
|
|
2641
2757
|
lines = []
|
|
2642
2758
|
|
|
2759
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in class names
|
|
2760
|
+
class_name = _escape_identifier(cls.name)
|
|
2643
2761
|
if cls.bases:
|
|
2644
|
-
lines.append(f'class {
|
|
2762
|
+
lines.append(f'class {class_name}({", ".join(cls.bases)}):')
|
|
2645
2763
|
else:
|
|
2646
|
-
lines.append(f'class {
|
|
2764
|
+
lines.append(f'class {class_name}:')
|
|
2647
2765
|
|
|
2648
2766
|
if not cls.fields and not cls.methods and not cls.constructors:
|
|
2649
2767
|
lines.append(f'{self.indent}pass')
|
|
@@ -2665,16 +2783,19 @@ class CppToPythonConverter:
|
|
|
2665
2783
|
|
|
2666
2784
|
params = ['self'] if not method.is_static else []
|
|
2667
2785
|
for pname, ptype in method.params:
|
|
2786
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in parameter names
|
|
2787
|
+
escaped_pname = _escape_identifier(pname)
|
|
2668
2788
|
if ptype and ptype != 'Any':
|
|
2669
|
-
params.append(f'{
|
|
2789
|
+
params.append(f'{escaped_pname}: {ptype}')
|
|
2670
2790
|
else:
|
|
2671
|
-
params.append(
|
|
2791
|
+
params.append(escaped_pname)
|
|
2672
2792
|
|
|
2673
2793
|
ret_type = ''
|
|
2674
2794
|
if not is_init and method.return_type and method.return_type != 'None':
|
|
2675
2795
|
ret_type = f' -> {method.return_type}'
|
|
2676
2796
|
|
|
2677
|
-
|
|
2797
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in method names
|
|
2798
|
+
method_name = '__init__' if is_init else _escape_identifier(method.name)
|
|
2678
2799
|
lines.append(f'{self.indent}def {method_name}({", ".join(params)}){ret_type}:')
|
|
2679
2800
|
|
|
2680
2801
|
body_lines = method.body.split('\n')
|
|
@@ -2691,16 +2812,20 @@ class CppToPythonConverter:
|
|
|
2691
2812
|
|
|
2692
2813
|
params = []
|
|
2693
2814
|
for pname, ptype in func.params:
|
|
2815
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in parameter names
|
|
2816
|
+
escaped_pname = _escape_identifier(pname)
|
|
2694
2817
|
if ptype and ptype != 'Any':
|
|
2695
|
-
params.append(f'{
|
|
2818
|
+
params.append(f'{escaped_pname}: {ptype}')
|
|
2696
2819
|
else:
|
|
2697
|
-
params.append(
|
|
2820
|
+
params.append(escaped_pname)
|
|
2698
2821
|
|
|
2699
2822
|
ret_type = ''
|
|
2700
2823
|
if func.return_type and func.return_type != 'None':
|
|
2701
2824
|
ret_type = f' -> {func.return_type}'
|
|
2702
2825
|
|
|
2703
|
-
|
|
2826
|
+
# v3.4.1: Escape Python keywords and C++ reserved words in function names
|
|
2827
|
+
func_name = _escape_identifier(func.name)
|
|
2828
|
+
lines.append(f'def {func_name}({", ".join(params)}){ret_type}:')
|
|
2704
2829
|
|
|
2705
2830
|
body_lines = func.body.split('\n')
|
|
2706
2831
|
if body_lines and body_lines[0].strip():
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CSSL - CSO Service Script Language
|
|
3
|
+
Bundled with IncludeCPP for integrated scripting support.
|
|
4
|
+
|
|
5
|
+
Features:
|
|
6
|
+
- BruteForce Injection System: <==, ==>, +<==, -<==, <<==, ==>>
|
|
7
|
+
- Dynamic typing with 'dynamic' keyword
|
|
8
|
+
- Function modifiers: undefined, open, meta, super, closed, private, virtual
|
|
9
|
+
- Advanced data types: datastruct, shuffled, iterator, combo, dataspace
|
|
10
|
+
- Injection helpers: string::where, json::key, array::index, etc.
|
|
11
|
+
- Global references: @Name, r@Name, s@Name
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from .cssl_parser import (
|
|
15
|
+
parse_cssl, parse_cssl_program, tokenize_cssl,
|
|
16
|
+
CSSLSyntaxError, CSSLLexer, CSSLParser, ASTNode,
|
|
17
|
+
KEYWORDS, TYPE_GENERICS, INJECTION_HELPERS
|
|
18
|
+
)
|
|
19
|
+
from .cssl_runtime import CSSLRuntime, CSSLRuntimeError, CSSLServiceRunner, run_cssl, run_cssl_file
|
|
20
|
+
from .cssl_types import (
|
|
21
|
+
DataStruct, Shuffled, Iterator, Combo, DataSpace, OpenQuote,
|
|
22
|
+
OpenFind, Parameter,
|
|
23
|
+
create_datastruct, create_shuffled, create_iterator,
|
|
24
|
+
create_combo, create_dataspace, create_openquote, create_parameter
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
# Parser
|
|
29
|
+
'parse_cssl', 'parse_cssl_program', 'tokenize_cssl',
|
|
30
|
+
'CSSLSyntaxError', 'CSSLLexer', 'CSSLParser', 'ASTNode',
|
|
31
|
+
'KEYWORDS', 'TYPE_GENERICS', 'INJECTION_HELPERS',
|
|
32
|
+
# Runtime
|
|
33
|
+
'CSSLRuntime', 'CSSLRuntimeError', 'CSSLServiceRunner',
|
|
34
|
+
'run_cssl', 'run_cssl_file',
|
|
35
|
+
# Data Types
|
|
36
|
+
'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
|
|
37
|
+
'OpenFind', 'Parameter',
|
|
38
|
+
'create_datastruct', 'create_shuffled', 'create_iterator',
|
|
39
|
+
'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter'
|
|
40
|
+
]
|