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.
@@ -0,0 +1,488 @@
1
+ """
2
+ CSSL Syntax Highlighting
3
+
4
+ Provides syntax highlighting for CSSL (CSO Service Script Language) code.
5
+ Can be used with:
6
+ - PyQt5/6 QSyntaxHighlighter
7
+ - VSCode/TextMate grammar export
8
+ - Terminal ANSI colors
9
+ """
10
+
11
+ from typing import Dict, List, Tuple, Optional
12
+ from dataclasses import dataclass
13
+ from enum import Enum, auto
14
+ import re
15
+
16
+
17
+ class TokenCategory(Enum):
18
+ """Categories for syntax highlighting"""
19
+ KEYWORD = auto() # service-init, struct, define, if, while, etc.
20
+ BUILTIN = auto() # print, len, typeof, etc.
21
+ OPERATOR = auto() # <==, ==>, ->, <-, +, -, etc.
22
+ STRING = auto() # "string" or 'string'
23
+ STRING_INTERP = auto() # <variable> in strings - NEW
24
+ NUMBER = auto() # 123, 45.67
25
+ COMMENT = auto() # # comment or // comment
26
+ MODULE_REF = auto() # @Module, @VSRAM, @Desktop
27
+ SELF_REF = auto() # s@StructName, s@Backend.Loop
28
+ IDENTIFIER = auto() # variable names
29
+ PROPERTY = auto() # service-name:, service-version:
30
+ BOOLEAN = auto() # True, False, true, false
31
+ NULL = auto() # null, None
32
+ PACKAGE_KW = auto() # package, package-includes - NEW
33
+ TYPE_LITERAL = auto() # list, dict - NEW
34
+
35
+
36
+ @dataclass
37
+ class HighlightRule:
38
+ """Rule for syntax highlighting"""
39
+ pattern: str
40
+ category: TokenCategory
41
+ group: int = 0 # Regex group to highlight
42
+
43
+
44
+ # CSSL Keywords
45
+ KEYWORDS = {
46
+ 'service-init', 'service-run', 'service-include',
47
+ 'struct', 'define', 'main',
48
+ 'if', 'else', 'elif', 'while', 'for', 'foreach', 'in', 'range',
49
+ 'switch', 'case', 'default', 'break', 'continue', 'return',
50
+ 'try', 'catch', 'finally', 'throw',
51
+ 'and', 'or', 'not',
52
+ 'start', 'stop', 'wait_for', 'on_event', 'emit_event',
53
+ 'await',
54
+ # NEW: Extended keywords
55
+ 'package', 'package-includes', 'exec', 'as', 'global'
56
+ }
57
+
58
+ # NEW: Package-related keywords for special highlighting
59
+ PACKAGE_KEYWORDS = {'package', 'package-includes'}
60
+
61
+ # NEW: Type literals
62
+ TYPE_LITERALS = {'list', 'dict'}
63
+
64
+ # CSSL Built-in Functions
65
+ BUILTINS = {
66
+ # Output
67
+ 'print', 'println', 'debug', 'error', 'warn', 'log',
68
+ # Type conversion
69
+ 'int', 'float', 'str', 'bool', 'list', 'dict',
70
+ # Type checking
71
+ 'typeof', 'isinstance', 'isint', 'isfloat', 'isstr', 'isbool', 'islist', 'isdict', 'isnull',
72
+ # String
73
+ 'len', 'upper', 'lower', 'trim', 'split', 'join', 'replace', 'contains', 'startswith', 'endswith',
74
+ 'substr', 'format', 'reverse', 'repeat',
75
+ # List
76
+ 'append', 'extend', 'insert', 'remove', 'pop', 'index', 'count', 'sort', 'sorted', 'filter', 'map',
77
+ # Dict
78
+ 'keys', 'values', 'items', 'get', 'set', 'has', 'merge', 'delete',
79
+ # Math
80
+ 'abs', 'round', 'floor', 'ceil', 'min', 'max', 'sum', 'pow', 'sqrt', 'sin', 'cos', 'tan', 'log10',
81
+ 'random', 'randint', 'randrange', 'choice', 'shuffle', 'sample',
82
+ # Time
83
+ 'now', 'timestamp', 'sleep', 'date', 'time', 'datetime', 'strftime', 'strptime',
84
+ # File I/O
85
+ 'read_file', 'write_file', 'append_file', 'file_exists', 'delete_file',
86
+ 'mkdir', 'rmdir', 'listdir', 'getcwd', 'chdir',
87
+ # System
88
+ 'exit', 'getenv', 'setenv', 'exec', 'system', 'platform', 'argv',
89
+ # JSON
90
+ 'json_encode', 'json_decode', 'json_load', 'json_dump',
91
+ # Regex
92
+ 'regex_match', 'regex_search', 'regex_replace', 'regex_split', 'regex_findall',
93
+ # Hash
94
+ 'md5', 'sha1', 'sha256', 'sha512', 'hash',
95
+ # Other
96
+ 'copy', 'deepcopy', 'assert', 'range', 'enumerate', 'zip', 'any', 'all',
97
+ 'include', 'cso_root', 'createcmd', 'wait_for_booted', 'emit', 'on_event'
98
+ }
99
+
100
+
101
+ class CSSLSyntaxRules:
102
+ """Collection of syntax highlighting rules for CSSL"""
103
+
104
+ @staticmethod
105
+ def get_rules() -> List[HighlightRule]:
106
+ """Get all highlighting rules in priority order"""
107
+ rules = []
108
+
109
+ # Comments (highest priority - should match first)
110
+ # NEW: Both # and // style comments
111
+ rules.append(HighlightRule(
112
+ pattern=r'#[^\n]*',
113
+ category=TokenCategory.COMMENT
114
+ ))
115
+ rules.append(HighlightRule(
116
+ pattern=r'//[^\n]*',
117
+ category=TokenCategory.COMMENT
118
+ ))
119
+
120
+ # Strings
121
+ rules.append(HighlightRule(
122
+ pattern=r'"(?:[^"\\]|\\.)*"',
123
+ category=TokenCategory.STRING
124
+ ))
125
+ rules.append(HighlightRule(
126
+ pattern=r"'(?:[^'\\]|\\.)*'",
127
+ category=TokenCategory.STRING
128
+ ))
129
+
130
+ # NEW: String interpolation <variable> in strings
131
+ rules.append(HighlightRule(
132
+ pattern=r'<[A-Za-z_][A-Za-z0-9_]*>',
133
+ category=TokenCategory.STRING_INTERP
134
+ ))
135
+
136
+ # NEW: Package keywords (special highlighting)
137
+ rules.append(HighlightRule(
138
+ pattern=r'\b(package|package-includes)\b',
139
+ category=TokenCategory.PACKAGE_KW
140
+ ))
141
+
142
+ # NEW: Type literals (list, dict)
143
+ rules.append(HighlightRule(
144
+ pattern=r'\b(list|dict)\b(?!\s*\()',
145
+ category=TokenCategory.TYPE_LITERAL
146
+ ))
147
+
148
+ # Self-references (s@Name, s@Backend.Loop)
149
+ rules.append(HighlightRule(
150
+ pattern=r's@[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*',
151
+ category=TokenCategory.SELF_REF
152
+ ))
153
+
154
+ # Module references (@Module, @VSRAM.Read)
155
+ rules.append(HighlightRule(
156
+ pattern=r'@[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*',
157
+ category=TokenCategory.MODULE_REF
158
+ ))
159
+
160
+ # Properties (key: value in service-init)
161
+ rules.append(HighlightRule(
162
+ pattern=r'\b(service-name|service-version|service-author|service-description|execution|executation)\s*:',
163
+ category=TokenCategory.PROPERTY,
164
+ group=1
165
+ ))
166
+
167
+ # Keywords
168
+ keyword_pattern = r'\b(' + '|'.join(re.escape(k) for k in KEYWORDS) + r')\b'
169
+ rules.append(HighlightRule(
170
+ pattern=keyword_pattern,
171
+ category=TokenCategory.KEYWORD
172
+ ))
173
+
174
+ # Builtins
175
+ builtin_pattern = r'\b(' + '|'.join(re.escape(b) for b in BUILTINS) + r')\s*\('
176
+ rules.append(HighlightRule(
177
+ pattern=builtin_pattern,
178
+ category=TokenCategory.BUILTIN,
179
+ group=1
180
+ ))
181
+
182
+ # Boolean literals
183
+ rules.append(HighlightRule(
184
+ pattern=r'\b(True|False|true|false)\b',
185
+ category=TokenCategory.BOOLEAN
186
+ ))
187
+
188
+ # Null literals
189
+ rules.append(HighlightRule(
190
+ pattern=r'\b(null|None|none)\b',
191
+ category=TokenCategory.NULL
192
+ ))
193
+
194
+ # Numbers
195
+ rules.append(HighlightRule(
196
+ pattern=r'\b\d+\.?\d*\b',
197
+ category=TokenCategory.NUMBER
198
+ ))
199
+
200
+ # Special operators
201
+ rules.append(HighlightRule(
202
+ pattern=r'<==|==>|->|<-',
203
+ category=TokenCategory.OPERATOR
204
+ ))
205
+
206
+ # Comparison operators
207
+ rules.append(HighlightRule(
208
+ pattern=r'==|!=|<=|>=|<|>',
209
+ category=TokenCategory.OPERATOR
210
+ ))
211
+
212
+ return rules
213
+
214
+
215
+ # Default color schemes
216
+ class ColorScheme:
217
+ """Color scheme for syntax highlighting"""
218
+
219
+ # CSO Theme (Orange accent, dark background)
220
+ CSO_THEME = {
221
+ TokenCategory.KEYWORD: '#508cff', # Blue
222
+ TokenCategory.BUILTIN: '#ff8c00', # Orange
223
+ TokenCategory.OPERATOR: '#c8c8d2', # Light gray
224
+ TokenCategory.STRING: '#50c878', # Green
225
+ TokenCategory.STRING_INTERP: '#f1fa8c',# Yellow for interpolation - NEW
226
+ TokenCategory.NUMBER: '#f0c040', # Yellow
227
+ TokenCategory.COMMENT: '#707080', # Gray
228
+ TokenCategory.MODULE_REF: '#ff8c00', # Orange
229
+ TokenCategory.SELF_REF: '#60c8dc', # Cyan
230
+ TokenCategory.IDENTIFIER: '#f0f0f5', # White
231
+ TokenCategory.PROPERTY: '#c8a8ff', # Purple
232
+ TokenCategory.BOOLEAN: '#ff8c00', # Orange
233
+ TokenCategory.NULL: '#ff6464', # Red
234
+ TokenCategory.PACKAGE_KW: '#bd93f9', # Purple for package - NEW
235
+ TokenCategory.TYPE_LITERAL: '#8be9fd', # Cyan for type literals - NEW
236
+ }
237
+
238
+ # Light theme variant
239
+ LIGHT_THEME = {
240
+ TokenCategory.KEYWORD: '#0000ff', # Blue
241
+ TokenCategory.BUILTIN: '#c65d00', # Dark orange
242
+ TokenCategory.OPERATOR: '#444444', # Dark gray
243
+ TokenCategory.STRING: '#008000', # Green
244
+ TokenCategory.STRING_INTERP: '#b8860b',# DarkGoldenrod for interpolation - NEW
245
+ TokenCategory.NUMBER: '#a06000', # Brown
246
+ TokenCategory.COMMENT: '#808080', # Gray
247
+ TokenCategory.MODULE_REF: '#c65d00', # Dark orange
248
+ TokenCategory.SELF_REF: '#008b8b', # Dark cyan
249
+ TokenCategory.IDENTIFIER: '#000000', # Black
250
+ TokenCategory.PROPERTY: '#800080', # Purple
251
+ TokenCategory.BOOLEAN: '#c65d00', # Dark orange
252
+ TokenCategory.NULL: '#ff0000', # Red
253
+ TokenCategory.PACKAGE_KW: '#8b008b', # DarkMagenta for package - NEW
254
+ TokenCategory.TYPE_LITERAL: '#008b8b', # Dark cyan for type literals - NEW
255
+ }
256
+
257
+
258
+ def highlight_cssl(source: str, scheme: Dict[TokenCategory, str] = None) -> List[Tuple[int, int, str, TokenCategory]]:
259
+ """
260
+ Highlight CSSL source code.
261
+
262
+ Args:
263
+ source: CSSL source code
264
+ scheme: Color scheme dict (defaults to CSO_THEME)
265
+
266
+ Returns:
267
+ List of (start, end, color, category) tuples
268
+ """
269
+ if scheme is None:
270
+ scheme = ColorScheme.CSO_THEME
271
+
272
+ highlights = []
273
+ rules = CSSLSyntaxRules.get_rules()
274
+
275
+ # Track which positions are already highlighted (for priority)
276
+ highlighted_positions = set()
277
+
278
+ for rule in rules:
279
+ try:
280
+ pattern = re.compile(rule.pattern)
281
+ for match in pattern.finditer(source):
282
+ if rule.group > 0 and rule.group <= len(match.groups()):
283
+ start = match.start(rule.group)
284
+ end = match.end(rule.group)
285
+ else:
286
+ start = match.start()
287
+ end = match.end()
288
+
289
+ # Check if position already highlighted
290
+ pos_range = range(start, end)
291
+ if any(p in highlighted_positions for p in pos_range):
292
+ continue
293
+
294
+ # Add highlight
295
+ color = scheme.get(rule.category, '#ffffff')
296
+ highlights.append((start, end, color, rule.category))
297
+
298
+ # Mark positions as highlighted
299
+ highlighted_positions.update(pos_range)
300
+
301
+ except re.error:
302
+ continue
303
+
304
+ # Sort by start position
305
+ highlights.sort(key=lambda h: h[0])
306
+
307
+ return highlights
308
+
309
+
310
+ def highlight_cssl_ansi(source: str) -> str:
311
+ """
312
+ Highlight CSSL source with ANSI terminal colors.
313
+
314
+ Args:
315
+ source: CSSL source code
316
+
317
+ Returns:
318
+ Source with ANSI color codes
319
+ """
320
+ # ANSI color codes
321
+ ANSI_COLORS = {
322
+ TokenCategory.KEYWORD: '\033[94m', # Blue
323
+ TokenCategory.BUILTIN: '\033[33m', # Yellow/Orange
324
+ TokenCategory.OPERATOR: '\033[37m', # White
325
+ TokenCategory.STRING: '\033[92m', # Green
326
+ TokenCategory.STRING_INTERP: '\033[93m',# Yellow for interpolation - NEW
327
+ TokenCategory.NUMBER: '\033[93m', # Yellow
328
+ TokenCategory.COMMENT: '\033[90m', # Gray
329
+ TokenCategory.MODULE_REF: '\033[33m', # Yellow/Orange
330
+ TokenCategory.SELF_REF: '\033[96m', # Cyan
331
+ TokenCategory.IDENTIFIER: '\033[0m', # Default
332
+ TokenCategory.PROPERTY: '\033[95m', # Magenta
333
+ TokenCategory.BOOLEAN: '\033[33m', # Yellow/Orange
334
+ TokenCategory.NULL: '\033[91m', # Red
335
+ TokenCategory.PACKAGE_KW: '\033[95m', # Magenta for package - NEW
336
+ TokenCategory.TYPE_LITERAL: '\033[96m', # Cyan for type literals - NEW
337
+ }
338
+ RESET = '\033[0m'
339
+
340
+ highlights = highlight_cssl(source, ColorScheme.CSO_THEME)
341
+
342
+ # Build highlighted string
343
+ result = []
344
+ last_end = 0
345
+
346
+ for start, end, color, category in highlights:
347
+ # Add unhighlighted text before this highlight
348
+ if start > last_end:
349
+ result.append(source[last_end:start])
350
+
351
+ # Add highlighted text
352
+ ansi_color = ANSI_COLORS.get(category, '')
353
+ result.append(f"{ansi_color}{source[start:end]}{RESET}")
354
+ last_end = end
355
+
356
+ # Add remaining text
357
+ if last_end < len(source):
358
+ result.append(source[last_end:])
359
+
360
+ return ''.join(result)
361
+
362
+
363
+ # PyQt5/6 Syntax Highlighter
364
+ def get_pyqt_highlighter():
365
+ """
366
+ Get a QSyntaxHighlighter class for CSSL.
367
+
368
+ Returns:
369
+ CSSLHighlighter class (requires PyQt5 or PyQt6)
370
+ """
371
+ try:
372
+ from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor, QFont
373
+ from PyQt5.QtCore import QRegularExpression
374
+ except ImportError:
375
+ try:
376
+ from PyQt6.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor, QFont
377
+ from PyQt6.QtCore import QRegularExpression
378
+ except ImportError:
379
+ return None
380
+
381
+ class CSSLHighlighter(QSyntaxHighlighter):
382
+ """Syntax highlighter for CSSL code in Qt editors"""
383
+
384
+ def __init__(self, parent=None):
385
+ super().__init__(parent)
386
+ self._rules = []
387
+ self._setup_rules()
388
+
389
+ def _setup_rules(self):
390
+ """Setup highlighting rules"""
391
+ scheme = ColorScheme.CSO_THEME
392
+
393
+ for rule in CSSLSyntaxRules.get_rules():
394
+ fmt = QTextCharFormat()
395
+ color = QColor(scheme.get(rule.category, '#ffffff'))
396
+ fmt.setForeground(color)
397
+
398
+ # Bold for keywords and builtins
399
+ if rule.category in (TokenCategory.KEYWORD, TokenCategory.BUILTIN):
400
+ fmt.setFontWeight(QFont.Bold)
401
+
402
+ # Italic for comments
403
+ if rule.category == TokenCategory.COMMENT:
404
+ fmt.setFontItalic(True)
405
+
406
+ self._rules.append((QRegularExpression(rule.pattern), fmt, rule.group))
407
+
408
+ def highlightBlock(self, text):
409
+ """Apply highlighting to a block of text"""
410
+ for pattern, fmt, group in self._rules:
411
+ match_iterator = pattern.globalMatch(text)
412
+ while match_iterator.hasNext():
413
+ match = match_iterator.next()
414
+ if group > 0 and group <= match.lastCapturedIndex():
415
+ start = match.capturedStart(group)
416
+ length = match.capturedLength(group)
417
+ else:
418
+ start = match.capturedStart()
419
+ length = match.capturedLength()
420
+ self.setFormat(start, length, fmt)
421
+
422
+ return CSSLHighlighter
423
+
424
+
425
+ # Export for external editors (TextMate/VSCode grammar format)
426
+ def export_textmate_grammar() -> dict:
427
+ """
428
+ Export CSSL syntax as TextMate grammar for VSCode.
429
+
430
+ Returns:
431
+ Dictionary suitable for JSON export as .tmLanguage.json
432
+ """
433
+ return {
434
+ "scopeName": "source.cssl",
435
+ "name": "CSSL",
436
+ "fileTypes": ["cssl", "service"],
437
+ "patterns": [
438
+ {
439
+ "name": "comment.line.cssl",
440
+ "match": "#.*$"
441
+ },
442
+ {
443
+ "name": "string.quoted.double.cssl",
444
+ "match": '"(?:[^"\\\\]|\\\\.)*"'
445
+ },
446
+ {
447
+ "name": "string.quoted.single.cssl",
448
+ "match": "'(?:[^'\\\\]|\\\\.)*'"
449
+ },
450
+ {
451
+ "name": "variable.other.self-reference.cssl",
452
+ "match": "s@[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*"
453
+ },
454
+ {
455
+ "name": "variable.other.module-reference.cssl",
456
+ "match": "@[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*"
457
+ },
458
+ {
459
+ "name": "keyword.control.cssl",
460
+ "match": "\\b(service-init|service-run|service-include|struct|define|if|else|elif|while|for|foreach|in|switch|case|default|break|continue|return|try|catch|await)\\b"
461
+ },
462
+ {
463
+ "name": "keyword.operator.cssl",
464
+ "match": "\\b(and|or|not)\\b"
465
+ },
466
+ {
467
+ "name": "constant.language.cssl",
468
+ "match": "\\b(True|False|true|false|null|None)\\b"
469
+ },
470
+ {
471
+ "name": "constant.numeric.cssl",
472
+ "match": "\\b\\d+\\.?\\d*\\b"
473
+ },
474
+ {
475
+ "name": "keyword.operator.assignment.cssl",
476
+ "match": "<==|==>|->|<-"
477
+ }
478
+ ]
479
+ }
480
+
481
+
482
+ # Export public API
483
+ __all__ = [
484
+ 'TokenCategory', 'HighlightRule', 'CSSLSyntaxRules', 'ColorScheme',
485
+ 'highlight_cssl', 'highlight_cssl_ansi', 'get_pyqt_highlighter',
486
+ 'export_textmate_grammar', 'KEYWORDS', 'BUILTINS',
487
+ 'PACKAGE_KEYWORDS', 'TYPE_LITERALS' # NEW
488
+ ]