IncludeCPP 3.6.0__py3-none-any.whl → 3.7.1__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.
@@ -14,7 +14,8 @@ from .cssl_builtins import CSSLBuiltins
14
14
  from .cssl_modules import get_module_registry, get_standard_module
15
15
  from .cssl_types import (
16
16
  Parameter, DataStruct, Shuffled, Iterator, Combo,
17
- Stack, Vector, Array, DataSpace, OpenQuote, List, Dictionary
17
+ Stack, Vector, Array, DataSpace, OpenQuote, List, Dictionary, Map,
18
+ CSSLClass, CSSLInstance
18
19
  )
19
20
 
20
21
 
@@ -145,6 +146,7 @@ class CSSLRuntime:
145
146
  self._injection_captures: Dict[str, Dict[str, Any]] = {} # Captured %vars per injection
146
147
  self._current_captured_values: Dict[str, Any] = {} # Current captured values during injection execution
147
148
  self._promoted_globals: Dict[str, Any] = {} # NEW: Variables promoted via global()
149
+ self._current_instance: Optional[CSSLInstance] = None # Current class instance for this-> access
148
150
  self._running = False
149
151
  self._exit_code = 0
150
152
  self._output_callback = output_callback # Callback for console output (text, level)
@@ -386,6 +388,8 @@ class CSSLRuntime:
386
388
 
387
389
  if child.type == 'struct':
388
390
  self._exec_struct(child)
391
+ elif child.type == 'class':
392
+ self._exec_class(child)
389
393
  elif child.type == 'function':
390
394
  self._exec_function(child)
391
395
  elif child.type == 'global_assignment':
@@ -394,6 +398,9 @@ class CSSLRuntime:
394
398
  elif child.type == 'typed_declaration':
395
399
  # Handle typed variable declaration: type<T> varName = value;
396
400
  result = self._exec_typed_declaration(child)
401
+ elif child.type == 'instance_declaration':
402
+ # Handle instance declaration: instance<"name"> varName;
403
+ result = self._exec_instance_declaration(child)
397
404
  elif child.type in ('assignment', 'expression', 'inject', 'receive', 'flow',
398
405
  'if', 'while', 'for', 'c_for', 'foreach', 'switch', 'try'):
399
406
  result = self._execute_node(child)
@@ -661,6 +668,57 @@ class CSSLRuntime:
661
668
 
662
669
  return struct_data
663
670
 
671
+ def _exec_class(self, node: ASTNode) -> CSSLClass:
672
+ """Execute class definition - registers class in scope.
673
+
674
+ Parses class members and methods, creating a CSSLClass object
675
+ that can be instantiated with 'new'.
676
+ """
677
+ class_info = node.value
678
+ class_name = class_info.get('name')
679
+
680
+ members = {} # Member variable defaults/types
681
+ methods = {} # Method AST nodes
682
+ constructor = None
683
+
684
+ for child in node.children:
685
+ if child.type == 'function':
686
+ # This is a method
687
+ func_info = child.value
688
+ method_name = func_info.get('name')
689
+
690
+ if func_info.get('is_constructor') or method_name == class_name or method_name == '__init__':
691
+ constructor = child
692
+ else:
693
+ methods[method_name] = child
694
+
695
+ elif child.type == 'typed_declaration':
696
+ # This is a member variable
697
+ decl = child.value
698
+ member_name = decl.get('name')
699
+ member_type = decl.get('type')
700
+ member_value = decl.get('value')
701
+
702
+ # Store member info with type and optional default
703
+ members[member_name] = {
704
+ 'type': member_type,
705
+ 'default': self._evaluate(member_value) if member_value else None
706
+ }
707
+
708
+ # Create class definition object
709
+ class_def = CSSLClass(
710
+ name=class_name,
711
+ members=members,
712
+ methods=methods,
713
+ constructor=constructor
714
+ )
715
+
716
+ # Register class in scope
717
+ self.scope.set(class_name, class_def)
718
+ self.global_scope.set(class_name, class_def)
719
+
720
+ return class_def
721
+
664
722
  def _exec_function(self, node: ASTNode) -> Any:
665
723
  """Execute function definition - just registers it"""
666
724
  func_info = node.value
@@ -714,6 +772,8 @@ class CSSLRuntime:
714
772
  instance = List(element_type)
715
773
  elif type_name in ('dictionary', 'dict'):
716
774
  instance = Dictionary(element_type)
775
+ elif type_name == 'map':
776
+ instance = Map(element_type)
717
777
  else:
718
778
  # Default: evaluate the value or set to None
719
779
  instance = self._evaluate(value_node) if value_node else None
@@ -732,6 +792,34 @@ class CSSLRuntime:
732
792
  self.scope.set(var_name, instance)
733
793
  return instance
734
794
 
795
+ def _exec_instance_declaration(self, node: ASTNode) -> Any:
796
+ """Execute instance declaration: instance<"name"> varName;
797
+
798
+ Gets or creates a shared instance by name.
799
+ """
800
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
801
+ decl = node.value
802
+ instance_name = decl.get('instance_name')
803
+ var_name = decl.get('name')
804
+ value_node = decl.get('value')
805
+
806
+ # Get existing shared instance
807
+ instance = None
808
+ if instance_name in _live_objects:
809
+ instance = SharedObjectProxy(instance_name, _live_objects[instance_name])
810
+ elif self.global_scope.has(f'${instance_name}'):
811
+ instance = self.global_scope.get(f'${instance_name}')
812
+
813
+ # If value is provided, use that and register as shared
814
+ if value_node:
815
+ instance = self._evaluate(value_node)
816
+ # Register in global scope for future access
817
+ self.global_scope.set(f'${instance_name}', instance)
818
+
819
+ # Store in scope
820
+ self.scope.set(var_name, instance)
821
+ return instance
822
+
735
823
  def _exec_global_assignment(self, node: ASTNode) -> Any:
736
824
  """Execute global variable assignment: global Name = value
737
825
 
@@ -1471,6 +1559,12 @@ class CSSLRuntime:
1471
1559
  name = target.value
1472
1560
  _live_objects[name] = final_value
1473
1561
  self.global_scope.set(f'${name}', SharedObjectProxy(name, final_value))
1562
+ elif target.type == 'instance_ref':
1563
+ # value ==> instance<"name"> - create/update shared object
1564
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
1565
+ name = target.value
1566
+ _live_objects[name] = final_value
1567
+ self.global_scope.set(f'${name}', SharedObjectProxy(name, final_value))
1474
1568
  elif target.type == 'member_access':
1475
1569
  self._set_member(target, final_value)
1476
1570
 
@@ -1620,6 +1714,12 @@ class CSSLRuntime:
1620
1714
  self._set_member(target, value)
1621
1715
  elif target.type == 'index_access':
1622
1716
  self._set_index(target, value)
1717
+ elif target.type == 'this_access':
1718
+ # this->member = value
1719
+ if self._current_instance is None:
1720
+ raise CSSLRuntimeError("'this' used outside of class method context")
1721
+ member = target.value.get('member')
1722
+ self._current_instance.set_member(member, value)
1623
1723
  elif isinstance(target, str):
1624
1724
  self.scope.set(target, value)
1625
1725
 
@@ -1767,6 +1867,28 @@ class CSSLRuntime:
1767
1867
  return value
1768
1868
  raise CSSLRuntimeError(f"Captured reference '%{name}' not found.")
1769
1869
 
1870
+ if node.type == 'instance_ref':
1871
+ # instance<"name"> - get shared instance by name
1872
+ # Works like $name but with explicit syntax
1873
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
1874
+ name = node.value
1875
+ if name in _live_objects:
1876
+ return SharedObjectProxy(name, _live_objects[name])
1877
+ # Check if stored in runtime's scope
1878
+ scoped_val = self.global_scope.get(f'${name}')
1879
+ if scoped_val is not None:
1880
+ return scoped_val
1881
+ # Return None if instance doesn't exist (can be created via ==>)
1882
+ return None
1883
+
1884
+ if node.type == 'new':
1885
+ # Create new instance of a class: new ClassName(args)
1886
+ return self._eval_new(node)
1887
+
1888
+ if node.type == 'this_access':
1889
+ # this->member access
1890
+ return self._eval_this_access(node)
1891
+
1770
1892
  if node.type == 'type_instantiation':
1771
1893
  # Create new instance of a type: stack<string>, vector<int>, etc.
1772
1894
  type_name = node.value.get('type')
@@ -2136,6 +2258,140 @@ class CSSLRuntime:
2136
2258
  hint="Typed functions use format: FunctionName<Type>(args)"
2137
2259
  )
2138
2260
 
2261
+ def _eval_new(self, node: ASTNode) -> CSSLInstance:
2262
+ """Evaluate 'new ClassName(args)' expression.
2263
+
2264
+ Creates a new instance of a CSSL class and calls its constructor.
2265
+ """
2266
+ class_name = node.value.get('class')
2267
+ args = [self._evaluate(arg) for arg in node.value.get('args', [])]
2268
+ kwargs = {k: self._evaluate(v) for k, v in node.value.get('kwargs', {}).items()}
2269
+
2270
+ # Get class definition from scope
2271
+ class_def = self.scope.get(class_name)
2272
+ if class_def is None:
2273
+ class_def = self.global_scope.get(class_name)
2274
+
2275
+ if class_def is None:
2276
+ raise CSSLRuntimeError(
2277
+ f"Class '{class_name}' not found",
2278
+ node.line,
2279
+ hint="Make sure the class is defined before instantiation"
2280
+ )
2281
+
2282
+ if not isinstance(class_def, CSSLClass):
2283
+ raise CSSLRuntimeError(
2284
+ f"'{class_name}' is not a class",
2285
+ node.line,
2286
+ hint=f"'{class_name}' is of type {type(class_def).__name__}"
2287
+ )
2288
+
2289
+ # Create new instance
2290
+ instance = CSSLInstance(class_def)
2291
+
2292
+ # Call constructor if defined
2293
+ if class_def.constructor:
2294
+ self._call_method(instance, class_def.constructor, args, kwargs)
2295
+
2296
+ return instance
2297
+
2298
+ def _eval_this_access(self, node: ASTNode) -> Any:
2299
+ """Evaluate 'this->member' access.
2300
+
2301
+ Returns the value of a member from the current class instance.
2302
+ """
2303
+ if self._current_instance is None:
2304
+ raise CSSLRuntimeError(
2305
+ "'this' used outside of class method context",
2306
+ node.line if hasattr(node, 'line') else 0,
2307
+ hint="'this->' can only be used inside class methods"
2308
+ )
2309
+
2310
+ member = node.value.get('member')
2311
+
2312
+ # Check if it's a chained access (this->a->b)
2313
+ if 'object' in node.value:
2314
+ # First evaluate the object part
2315
+ obj = self._evaluate(node.value.get('object'))
2316
+ if obj is None:
2317
+ return None
2318
+ if hasattr(obj, member):
2319
+ return getattr(obj, member)
2320
+ if isinstance(obj, dict):
2321
+ return obj.get(member)
2322
+ return None
2323
+
2324
+ # Direct this->member access
2325
+ instance = self._current_instance
2326
+
2327
+ # Check if it's a member variable
2328
+ if instance.has_member(member):
2329
+ return instance.get_member(member)
2330
+
2331
+ # Check if it's a method
2332
+ if instance.has_method(member):
2333
+ # Return a callable that will invoke the method with instance context
2334
+ method_node = instance.get_method(member)
2335
+ return lambda *args, **kwargs: self._call_method(instance, method_node, list(args), kwargs)
2336
+
2337
+ raise CSSLRuntimeError(
2338
+ f"'{instance._class.name}' has no member or method '{member}'",
2339
+ node.line if hasattr(node, 'line') else 0
2340
+ )
2341
+
2342
+ def _call_method(self, instance: CSSLInstance, method_node: ASTNode, args: list, kwargs: dict = None) -> Any:
2343
+ """Call a method on an instance with 'this' context.
2344
+
2345
+ Sets up the instance as the current 'this' context and executes the method.
2346
+ """
2347
+ kwargs = kwargs or {}
2348
+ func_info = method_node.value
2349
+ params = func_info.get('params', [])
2350
+ modifiers = func_info.get('modifiers', [])
2351
+
2352
+ # Check for undefined modifier
2353
+ is_undefined = 'undefined' in modifiers
2354
+
2355
+ # Create new scope for method
2356
+ new_scope = Scope(parent=self.scope)
2357
+
2358
+ # Bind parameters
2359
+ for i, param in enumerate(params):
2360
+ param_name = param['name'] if isinstance(param, dict) else param
2361
+
2362
+ if param_name in kwargs:
2363
+ new_scope.set(param_name, kwargs[param_name])
2364
+ elif i < len(args):
2365
+ new_scope.set(param_name, args[i])
2366
+ else:
2367
+ new_scope.set(param_name, None)
2368
+
2369
+ # Save current state
2370
+ old_scope = self.scope
2371
+ old_instance = self._current_instance
2372
+
2373
+ # Set up method context
2374
+ self.scope = new_scope
2375
+ self._current_instance = instance
2376
+
2377
+ try:
2378
+ for child in method_node.children:
2379
+ if not self._running:
2380
+ break
2381
+ self._execute_node(child)
2382
+ except CSSLReturn as ret:
2383
+ return ret.value
2384
+ except Exception as e:
2385
+ if is_undefined:
2386
+ return None
2387
+ raise
2388
+ finally:
2389
+ # Restore previous state
2390
+ self.scope = old_scope
2391
+ self._current_instance = old_instance
2392
+
2393
+ return None
2394
+
2139
2395
  def _eval_member_access(self, node: ASTNode) -> Any:
2140
2396
  """Evaluate member access"""
2141
2397
  obj = self._evaluate(node.value.get('object'))
@@ -2149,6 +2405,17 @@ class CSSLRuntime:
2149
2405
  if isinstance(obj, Parameter) and member == 'return':
2150
2406
  member = 'return_'
2151
2407
 
2408
+ # === CSSL CLASS INSTANCE METHODS ===
2409
+ if isinstance(obj, CSSLInstance):
2410
+ # Check for member variable
2411
+ if obj.has_member(member):
2412
+ return obj.get_member(member)
2413
+ # Check for method
2414
+ if obj.has_method(member):
2415
+ method_node = obj.get_method(member)
2416
+ return lambda *args, **kwargs: self._call_method(obj, method_node, list(args), kwargs)
2417
+ raise CSSLRuntimeError(f"'{obj._class.name}' has no member or method '{member}'")
2418
+
2152
2419
  # === STRING METHODS ===
2153
2420
  if isinstance(obj, str):
2154
2421
  string_methods = self._get_string_method(obj, member)
@@ -2382,6 +2649,11 @@ class CSSLRuntime:
2382
2649
  if obj is None:
2383
2650
  return
2384
2651
 
2652
+ # Check for CSSLInstance - use set_member method
2653
+ if isinstance(obj, CSSLInstance):
2654
+ obj.set_member(member, value)
2655
+ return
2656
+
2385
2657
  # Check for SharedObjectProxy - directly access underlying object
2386
2658
  # This is more robust than relying on the proxy's __setattr__
2387
2659
  if hasattr(obj, '_direct_object') and hasattr(obj, '_name'):
@@ -1281,10 +1281,232 @@ def create_dictionary(key_type: str = 'dynamic', value_type: str = 'dynamic') ->
1281
1281
  return Dictionary(key_type, value_type)
1282
1282
 
1283
1283
 
1284
+ class Map(dict):
1285
+ """C++ style map container with ordered key-value pairs.
1286
+
1287
+ Similar to Dictionary but with C++ map semantics.
1288
+ Keys are maintained in sorted order.
1289
+
1290
+ Usage:
1291
+ map<string, int> ages;
1292
+ ages.insert("Alice", 30);
1293
+ ages.find("Alice");
1294
+ ages.erase("Alice");
1295
+ """
1296
+
1297
+ def __init__(self, key_type: str = 'dynamic', value_type: str = 'dynamic'):
1298
+ super().__init__()
1299
+ self._key_type = key_type
1300
+ self._value_type = value_type
1301
+
1302
+ def insert(self, key: Any, value: Any) -> 'Map':
1303
+ """Insert key-value pair (C++ style)"""
1304
+ self[key] = value
1305
+ return self
1306
+
1307
+ def find(self, key: Any) -> Optional[Any]:
1308
+ """Find value by key, returns None if not found (C++ style)"""
1309
+ return self.get(key, None)
1310
+
1311
+ def erase(self, key: Any) -> bool:
1312
+ """Erase key-value pair, returns True if existed"""
1313
+ if key in self:
1314
+ del self[key]
1315
+ return True
1316
+ return False
1317
+
1318
+ def contains(self, key: Any) -> bool:
1319
+ """Check if key exists (C++20 style)"""
1320
+ return key in self
1321
+
1322
+ def count(self, key: Any) -> int:
1323
+ """Return 1 if key exists, 0 otherwise (C++ style)"""
1324
+ return 1 if key in self else 0
1325
+
1326
+ def size(self) -> int:
1327
+ """Return map size"""
1328
+ return len(self)
1329
+
1330
+ def empty(self) -> bool:
1331
+ """Check if map is empty"""
1332
+ return len(self) == 0
1333
+
1334
+ def at(self, key: Any) -> Any:
1335
+ """Get value at key, raises error if not found (C++ style)"""
1336
+ if key not in self:
1337
+ raise KeyError(f"Key '{key}' not found in map")
1338
+ return self[key]
1339
+
1340
+ def begin(self) -> Optional[tuple]:
1341
+ """Return first key-value pair"""
1342
+ if len(self) == 0:
1343
+ return None
1344
+ first_key = next(iter(self))
1345
+ return (first_key, self[first_key])
1346
+
1347
+ def end(self) -> Optional[tuple]:
1348
+ """Return last key-value pair"""
1349
+ if len(self) == 0:
1350
+ return None
1351
+ last_key = list(self.keys())[-1]
1352
+ return (last_key, self[last_key])
1353
+
1354
+ def lower_bound(self, key: Any) -> Optional[Any]:
1355
+ """Find first key >= given key (for sorted keys)"""
1356
+ sorted_keys = sorted(self.keys())
1357
+ for k in sorted_keys:
1358
+ if k >= key:
1359
+ return k
1360
+ return None
1361
+
1362
+ def upper_bound(self, key: Any) -> Optional[Any]:
1363
+ """Find first key > given key (for sorted keys)"""
1364
+ sorted_keys = sorted(self.keys())
1365
+ for k in sorted_keys:
1366
+ if k > key:
1367
+ return k
1368
+ return None
1369
+
1370
+
1371
+ def create_map(key_type: str = 'dynamic', value_type: str = 'dynamic') -> Map:
1372
+ """Create a Map object"""
1373
+ return Map(key_type, value_type)
1374
+
1375
+
1376
+ class CSSLClass:
1377
+ """Represents a CSSL class definition.
1378
+
1379
+ Stores class name, member variables, methods, and constructor.
1380
+ Used by the runtime to instantiate CSSLInstance objects.
1381
+ """
1382
+
1383
+ def __init__(self, name: str, members: Dict[str, Any] = None,
1384
+ methods: Dict[str, Any] = None, constructor: Any = None):
1385
+ self.name = name
1386
+ self.members = members or {} # Default member values/types
1387
+ self.methods = methods or {} # Method AST nodes
1388
+ self.constructor = constructor # Constructor AST node
1389
+
1390
+ def __repr__(self):
1391
+ return f"<CSSLClass '{self.name}' with {len(self.methods)} methods>"
1392
+
1393
+
1394
+ class CSSLInstance:
1395
+ """Represents an instance of a CSSL class.
1396
+
1397
+ Holds instance member values and provides access to class methods.
1398
+ Supports this-> member access pattern.
1399
+ """
1400
+
1401
+ def __init__(self, class_def: CSSLClass):
1402
+ self._class = class_def
1403
+ self._members: Dict[str, Any] = {}
1404
+ # Initialize members with defaults from class definition
1405
+ for name, default in class_def.members.items():
1406
+ if isinstance(default, dict):
1407
+ # Type declaration with optional default
1408
+ member_type = default.get('type')
1409
+ member_default = default.get('default')
1410
+
1411
+ if member_default is not None:
1412
+ self._members[name] = member_default
1413
+ elif member_type:
1414
+ # Create instance of container types
1415
+ self._members[name] = self._create_default_for_type(member_type)
1416
+ else:
1417
+ self._members[name] = None
1418
+ else:
1419
+ self._members[name] = default
1420
+
1421
+ def _create_default_for_type(self, type_name: str) -> Any:
1422
+ """Create a default value for a given type name."""
1423
+ # Container types
1424
+ if type_name == 'map':
1425
+ return Map()
1426
+ elif type_name in ('stack',):
1427
+ return Stack()
1428
+ elif type_name in ('vector',):
1429
+ return Vector()
1430
+ elif type_name in ('array',):
1431
+ return Array()
1432
+ elif type_name in ('list',):
1433
+ return List()
1434
+ elif type_name in ('dictionary', 'dict'):
1435
+ return Dictionary()
1436
+ elif type_name == 'datastruct':
1437
+ return DataStruct()
1438
+ elif type_name == 'dataspace':
1439
+ return DataSpace()
1440
+ elif type_name == 'shuffled':
1441
+ return Shuffled()
1442
+ elif type_name == 'iterator':
1443
+ return Iterator()
1444
+ elif type_name == 'combo':
1445
+ return Combo()
1446
+ # Primitive types
1447
+ elif type_name == 'int':
1448
+ return 0
1449
+ elif type_name == 'float':
1450
+ return 0.0
1451
+ elif type_name == 'string':
1452
+ return ""
1453
+ elif type_name == 'bool':
1454
+ return False
1455
+ elif type_name == 'json':
1456
+ return {}
1457
+ return None
1458
+
1459
+ def get_member(self, name: str) -> Any:
1460
+ """Get member value by name"""
1461
+ if name in self._members:
1462
+ return self._members[name]
1463
+ raise AttributeError(f"'{self._class.name}' has no member '{name}'")
1464
+
1465
+ def set_member(self, name: str, value: Any) -> None:
1466
+ """Set member value by name"""
1467
+ self._members[name] = value
1468
+
1469
+ def has_member(self, name: str) -> bool:
1470
+ """Check if member exists"""
1471
+ return name in self._members
1472
+
1473
+ def get_method(self, name: str) -> Any:
1474
+ """Get method AST node by name"""
1475
+ if name in self._class.methods:
1476
+ return self._class.methods[name]
1477
+ raise AttributeError(f"'{self._class.name}' has no method '{name}'")
1478
+
1479
+ def has_method(self, name: str) -> bool:
1480
+ """Check if method exists"""
1481
+ return name in self._class.methods
1482
+
1483
+ def __getattr__(self, name: str) -> Any:
1484
+ """Allow direct attribute access for members"""
1485
+ if name.startswith('_'):
1486
+ raise AttributeError(name)
1487
+ if name in self._members:
1488
+ return self._members[name]
1489
+ raise AttributeError(f"'{self._class.name}' has no member '{name}'")
1490
+
1491
+ def __setattr__(self, name: str, value: Any) -> None:
1492
+ """Allow direct attribute setting for members"""
1493
+ if name.startswith('_'):
1494
+ object.__setattr__(self, name, value)
1495
+ else:
1496
+ if hasattr(self, '_members'):
1497
+ self._members[name] = value
1498
+ else:
1499
+ object.__setattr__(self, name, value)
1500
+
1501
+ def __repr__(self):
1502
+ return f"<CSSLInstance of '{self._class.name}'>"
1503
+
1504
+
1284
1505
  __all__ = [
1285
1506
  'DataStruct', 'Shuffled', 'Iterator', 'Combo', 'DataSpace', 'OpenQuote',
1286
- 'OpenFind', 'Parameter', 'Stack', 'Vector', 'Array', 'List', 'Dictionary',
1507
+ 'OpenFind', 'Parameter', 'Stack', 'Vector', 'Array', 'List', 'Dictionary', 'Map',
1508
+ 'CSSLClass', 'CSSLInstance',
1287
1509
  'create_datastruct', 'create_shuffled', 'create_iterator',
1288
1510
  'create_combo', 'create_dataspace', 'create_openquote', 'create_parameter',
1289
- 'create_stack', 'create_vector', 'create_array', 'create_list', 'create_dictionary'
1511
+ 'create_stack', 'create_vector', 'create_array', 'create_list', 'create_dictionary', 'create_map'
1290
1512
  ]
@@ -1,14 +1,24 @@
1
1
  {
2
2
  "name": "cssl",
3
3
  "displayName": "CSSL - CSO Service Script Language",
4
- "description": "Syntax highlighting and language support for CSSL scripts",
5
- "version": "1.0.0",
4
+ "description": "Professional syntax highlighting, snippets, and language support for CSSL scripts (.cssl, .cssl-pl, .cssl-mod)",
5
+ "version": "1.1.0",
6
6
  "publisher": "IncludeCPP",
7
+ "icon": "images/cssl-icon.png",
7
8
  "engines": {
8
9
  "vscode": "^1.60.0"
9
10
  },
10
11
  "categories": [
11
- "Programming Languages"
12
+ "Programming Languages",
13
+ "Snippets"
14
+ ],
15
+ "keywords": [
16
+ "cssl",
17
+ "cso",
18
+ "script",
19
+ "includecpp",
20
+ "c++",
21
+ "python"
12
22
  ],
13
23
  "contributes": {
14
24
  "languages": [
@@ -16,7 +26,11 @@
16
26
  "id": "cssl",
17
27
  "aliases": ["CSSL", "cssl", "CSO Service Script"],
18
28
  "extensions": [".cssl", ".cssl-pl", ".cssl-mod"],
19
- "configuration": "./language-configuration.json"
29
+ "configuration": "./language-configuration.json",
30
+ "icon": {
31
+ "light": "./images/cssl-icon.png",
32
+ "dark": "./images/cssl-icon.png"
33
+ }
20
34
  }
21
35
  ],
22
36
  "grammars": [
@@ -25,6 +39,12 @@
25
39
  "scopeName": "source.cssl",
26
40
  "path": "./syntaxes/cssl.tmLanguage.json"
27
41
  }
42
+ ],
43
+ "snippets": [
44
+ {
45
+ "language": "cssl",
46
+ "path": "./snippets/cssl.snippets.json"
47
+ }
28
48
  ]
29
49
  }
30
50
  }