IncludeCPP 3.8.0__py3-none-any.whl → 3.8.9__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.
@@ -110,11 +110,14 @@ class TokenType(Enum):
110
110
  EOF = auto()
111
111
  # Super-functions for .cssl-pl payload files (v3.8.0)
112
112
  SUPER_FUNC = auto() # #$run(), #$exec(), #$printl() - pre-execution hooks
113
+ # Append operator for constructor/function extension
114
+ PLUS_PLUS = auto() # ++ for constructor/function append (keeps old + adds new)
115
+ MINUS_MINUS = auto() # -- for potential future use
113
116
 
114
117
 
115
118
  KEYWORDS = {
116
119
  # Service structure
117
- 'service-init', 'service-run', 'service-include', 'struct', 'define', 'main', 'class', 'new', 'this',
120
+ 'service-init', 'service-run', 'service-include', 'struct', 'define', 'main', 'class', 'constr', 'extends', 'overwrites', 'new', 'this', 'super',
118
121
  # Control flow
119
122
  'if', 'else', 'elif', 'while', 'for', 'foreach', 'in', 'range',
120
123
  'switch', 'case', 'default', 'break', 'continue', 'return',
@@ -307,8 +310,13 @@ class CSSLLexer:
307
310
  self._add_token(TokenType.DOT, '.')
308
311
  self._advance()
309
312
  elif char == '+':
313
+ # Check for ++ (append operator for constructor/function extension)
314
+ if self._peek(1) == '+':
315
+ self._add_token(TokenType.PLUS_PLUS, '++')
316
+ self._advance()
317
+ self._advance()
310
318
  # Check for BruteForce Injection: +<== or +<<==
311
- if self._peek(1) == '<' and self._peek(2) == '<' and self._peek(3) == '=' and self._peek(4) == '=':
319
+ elif self._peek(1) == '<' and self._peek(2) == '<' and self._peek(3) == '=' and self._peek(4) == '=':
312
320
  self._add_token(TokenType.INFUSE_PLUS_LEFT, '+<<==')
313
321
  for _ in range(5): self._advance()
314
322
  elif self._peek(1) == '<' and self._peek(2) == '=' and self._peek(3) == '=':
@@ -1025,7 +1033,11 @@ class CSSLParser:
1025
1033
  return result
1026
1034
 
1027
1035
  def _parse_typed_variable(self) -> Optional[ASTNode]:
1028
- """Parse a typed variable declaration: type varName; or type<T> varName = value;"""
1036
+ """Parse a typed variable declaration: type varName; or type<T> *varName = value;
1037
+
1038
+ The * prefix indicates a non-nullable variable (can never be None/null).
1039
+ Example: vector<dynamic> *MyVector - can never contain None values.
1040
+ """
1029
1041
  # Get type name
1030
1042
  type_name = self._advance().value # Consume type keyword
1031
1043
 
@@ -1039,6 +1051,11 @@ class CSSLParser:
1039
1051
  element_type = self._advance().value
1040
1052
  self._expect(TokenType.COMPARE_GT)
1041
1053
 
1054
+ # Check for * prefix (non-nullable indicator)
1055
+ non_null = False
1056
+ if self._match(TokenType.MULTIPLY):
1057
+ non_null = True
1058
+
1042
1059
  # Get variable name
1043
1060
  if not self._check(TokenType.IDENTIFIER):
1044
1061
  return None
@@ -1056,14 +1073,16 @@ class CSSLParser:
1056
1073
  return ASTNode('instance_declaration', value={
1057
1074
  'instance_name': element_type,
1058
1075
  'name': var_name,
1059
- 'value': value
1076
+ 'value': value,
1077
+ 'non_null': non_null
1060
1078
  })
1061
1079
 
1062
1080
  return ASTNode('typed_declaration', value={
1063
1081
  'type': type_name,
1064
1082
  'element_type': element_type,
1065
1083
  'name': var_name,
1066
- 'value': value
1084
+ 'value': value,
1085
+ 'non_null': non_null
1067
1086
  })
1068
1087
 
1069
1088
  def parse_program(self) -> ASTNode:
@@ -1361,10 +1380,79 @@ class CSSLParser:
1361
1380
  printl("Hello " + this->name);
1362
1381
  }
1363
1382
  }
1383
+
1384
+ Non-null class (all methods return non-null):
1385
+ class *MyClass { ... }
1364
1386
  """
1387
+ # Check for * prefix (non-null class - all methods return non-null)
1388
+ non_null = False
1389
+ if self._match(TokenType.MULTIPLY):
1390
+ non_null = True
1391
+
1365
1392
  class_name = self._advance().value
1366
1393
 
1367
- node = ASTNode('class', value={'name': class_name}, children=[])
1394
+ # Check for class-level constructor parameters: class MyClass (int x, string y) { ... }
1395
+ class_params = []
1396
+ if self._match(TokenType.PAREN_START):
1397
+ class_params = self._parse_parameter_list()
1398
+ self._expect(TokenType.PAREN_END)
1399
+
1400
+ # Check for inheritance and overwrites:
1401
+ # class Child : extends Parent { ... }
1402
+ # class Child : extends $PythonObject { ... }
1403
+ # class Child : extends Parent : overwrites Parent { ... }
1404
+ # class Child : extends Parent (param1, param2) { ... } <- constructor args for parent
1405
+ extends_class = None
1406
+ extends_is_python = False
1407
+ extends_args = []
1408
+ overwrites_class = None
1409
+ overwrites_is_python = False
1410
+
1411
+ if self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON):
1412
+ # Parse extends and/or overwrites (can be chained with : or ::)
1413
+ while True:
1414
+ if self._match_keyword('extends'):
1415
+ if self._check(TokenType.IDENTIFIER):
1416
+ extends_class = self._advance().value
1417
+ elif self._check(TokenType.SHARED_REF):
1418
+ extends_class = self._advance().value
1419
+ extends_is_python = True
1420
+ else:
1421
+ raise CSSLSyntaxError("Expected parent class name after 'extends'")
1422
+ # Check for constructor arguments: extends Parent (arg1, arg2)
1423
+ if self._match(TokenType.PAREN_START):
1424
+ while not self._check(TokenType.PAREN_END):
1425
+ arg = self._parse_expression()
1426
+ extends_args.append(arg)
1427
+ self._match(TokenType.COMMA)
1428
+ self._expect(TokenType.PAREN_END)
1429
+ elif self._match_keyword('overwrites'):
1430
+ if self._check(TokenType.IDENTIFIER):
1431
+ overwrites_class = self._advance().value
1432
+ elif self._check(TokenType.SHARED_REF):
1433
+ overwrites_class = self._advance().value
1434
+ overwrites_is_python = True
1435
+ else:
1436
+ raise CSSLSyntaxError("Expected class name after 'overwrites'")
1437
+ # Skip optional () after class name
1438
+ if self._match(TokenType.PAREN_START):
1439
+ self._expect(TokenType.PAREN_END)
1440
+ else:
1441
+ raise CSSLSyntaxError("Expected 'extends' or 'overwrites' after ':' or '::' in class declaration")
1442
+ # Check for another : or :: for chaining
1443
+ if not (self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON)):
1444
+ break
1445
+
1446
+ node = ASTNode('class', value={
1447
+ 'name': class_name,
1448
+ 'non_null': non_null,
1449
+ 'class_params': class_params,
1450
+ 'extends': extends_class,
1451
+ 'extends_is_python': extends_is_python,
1452
+ 'extends_args': extends_args,
1453
+ 'overwrites': overwrites_class,
1454
+ 'overwrites_is_python': overwrites_is_python
1455
+ }, children=[])
1368
1456
  self._expect(TokenType.BLOCK_START)
1369
1457
 
1370
1458
  while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
@@ -1393,14 +1481,297 @@ class CSSLParser:
1393
1481
  method = self._parse_define()
1394
1482
  node.children.append(method)
1395
1483
 
1484
+ # Check for constr keyword (constructor declaration)
1485
+ # Syntax: constr ConstructorName() { ... }
1486
+ # or: constr ConstructorName() : extends Parent::ConstructorName { ... }
1487
+ elif self._match_keyword('constr'):
1488
+ constructor = self._parse_constructor(class_name)
1489
+ node.children.append(constructor)
1490
+
1396
1491
  else:
1397
1492
  self._advance()
1398
1493
 
1399
1494
  self._expect(TokenType.BLOCK_END)
1400
1495
  return node
1401
1496
 
1497
+ def _parse_constructor(self, class_name: str) -> ASTNode:
1498
+ """Parse constructor declaration inside a class.
1499
+
1500
+ Syntax:
1501
+ constr ConstructorName() { ... }
1502
+ constr ConstructorName() ++ { ... } // Append: keeps parent constructor + adds new code
1503
+ constr ConstructorName() &ParentClass::constructors ++ { ... } // Append specific parent constructor
1504
+ constr ConstructorName() : extends ParentClass::ConstructorName { ... }
1505
+ constr ConstructorName() : extends ParentClass::ConstructorName : overwrites ParentClass::ConstructorName { ... }
1506
+
1507
+ The ++ operator means: execute parent's version first, then execute this code (append mode).
1508
+ The &ClassName::member syntax references a specific member from the overwritten class.
1509
+ """
1510
+ # Get constructor name
1511
+ if not self._check(TokenType.IDENTIFIER):
1512
+ raise CSSLSyntaxError("Expected constructor name after 'constr'")
1513
+ constr_name = self._advance().value
1514
+
1515
+ # Parse method-level extends/overwrites with :: syntax
1516
+ extends_target = None
1517
+ extends_class_ref = None
1518
+ extends_method_ref = None
1519
+ overwrites_target = None
1520
+ overwrites_class_ref = None
1521
+ overwrites_method_ref = None
1522
+
1523
+ # New: Append mode and reference tracking
1524
+ append_mode = False # ++ operator: keep parent code + add new
1525
+ append_ref_class = None # &ClassName part
1526
+ append_ref_member = None # ::member part (constructors, functionName, etc.)
1527
+
1528
+ # Parse parameters
1529
+ params = []
1530
+ if self._match(TokenType.PAREN_START):
1531
+ params = self._parse_parameter_list()
1532
+ self._expect(TokenType.PAREN_END)
1533
+
1534
+ # Check for &ClassName::member reference (for targeting specific parent member)
1535
+ # Syntax: constr Name() &ParentClass::constructors ++ { ... }
1536
+ if self._match(TokenType.AMPERSAND):
1537
+ # Parse the class reference
1538
+ if self._check(TokenType.IDENTIFIER):
1539
+ append_ref_class = self._advance().value
1540
+ elif self._check(TokenType.SHARED_REF):
1541
+ append_ref_class = f'${self._advance().value}'
1542
+ else:
1543
+ raise CSSLSyntaxError("Expected class name after '&' in constructor reference")
1544
+
1545
+ # Check for ::member
1546
+ if self._match(TokenType.DOUBLE_COLON):
1547
+ if self._check(TokenType.IDENTIFIER) or self._check(TokenType.KEYWORD):
1548
+ append_ref_member = self._advance().value
1549
+ else:
1550
+ raise CSSLSyntaxError("Expected member name after '::' in constructor reference")
1551
+
1552
+ # Check for ++ append operator
1553
+ if self._match(TokenType.PLUS_PLUS):
1554
+ append_mode = True
1555
+
1556
+ # Check for method-level extends/overwrites with :: or :
1557
+ if self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON):
1558
+ while True:
1559
+ if self._match_keyword('extends'):
1560
+ # Parse Parent::method or just method
1561
+ extends_target = self._parse_qualified_method_ref()
1562
+ if '::' in extends_target:
1563
+ parts = extends_target.split('::')
1564
+ extends_class_ref = parts[0]
1565
+ extends_method_ref = parts[1]
1566
+ else:
1567
+ extends_method_ref = extends_target
1568
+ elif self._match_keyword('overwrites'):
1569
+ # Parse Parent::method or just method
1570
+ overwrites_target = self._parse_qualified_method_ref()
1571
+ if '::' in overwrites_target:
1572
+ parts = overwrites_target.split('::')
1573
+ overwrites_class_ref = parts[0]
1574
+ overwrites_method_ref = parts[1]
1575
+ else:
1576
+ overwrites_method_ref = overwrites_target
1577
+ else:
1578
+ break
1579
+ # Check for another :: or : for chaining
1580
+ if not (self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON)):
1581
+ break
1582
+
1583
+ # Parse constructor body
1584
+ self._expect(TokenType.BLOCK_START)
1585
+ body = []
1586
+ while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
1587
+ stmt = self._parse_statement()
1588
+ if stmt:
1589
+ body.append(stmt)
1590
+ self._expect(TokenType.BLOCK_END)
1591
+
1592
+ return ASTNode('constructor', value={
1593
+ 'name': constr_name,
1594
+ 'class_name': class_name,
1595
+ 'params': params,
1596
+ 'is_constructor': True,
1597
+ 'extends_target': extends_target,
1598
+ 'extends_class': extends_class_ref,
1599
+ 'extends_method': extends_method_ref,
1600
+ 'overwrites_target': overwrites_target,
1601
+ 'overwrites_class': overwrites_class_ref,
1602
+ 'overwrites_method': overwrites_method_ref,
1603
+ # New append mode fields
1604
+ 'append_mode': append_mode,
1605
+ 'append_ref_class': append_ref_class,
1606
+ 'append_ref_member': append_ref_member
1607
+ }, children=body)
1608
+
1609
+ def _parse_qualified_method_ref(self) -> str:
1610
+ """Parse a qualified method reference like 'ParentClass::methodName' or just 'methodName'.
1611
+
1612
+ Returns the qualified name as a string (e.g., 'Parent::init' or just 'init').
1613
+ """
1614
+ # Check for $PythonObject
1615
+ if self._check(TokenType.SHARED_REF):
1616
+ class_ref = self._advance().value # Gets the name without $
1617
+ class_ref = f'${class_ref}'
1618
+ elif self._check(TokenType.IDENTIFIER):
1619
+ class_ref = self._advance().value
1620
+ else:
1621
+ raise CSSLSyntaxError("Expected class or method name in extends/overwrites")
1622
+
1623
+ # Check for :: to get method part
1624
+ if self._match(TokenType.DOUBLE_COLON):
1625
+ if self._check(TokenType.IDENTIFIER):
1626
+ method_ref = self._advance().value
1627
+ return f'{class_ref}::{method_ref}'
1628
+ else:
1629
+ raise CSSLSyntaxError("Expected method name after '::'")
1630
+
1631
+ # Just method name, no class qualifier
1632
+ return class_ref
1633
+
1634
+ def _parse_parameter_list(self) -> list:
1635
+ """Parse a list of parameters (without the surrounding parentheses).
1636
+
1637
+ Returns a list of parameter definitions, each can be:
1638
+ - Simple string name: "paramName"
1639
+ - Dict with type info: {'name': 'paramName', 'type': 'string', 'ref': True, ...}
1640
+ """
1641
+ params = []
1642
+ while not self._check(TokenType.PAREN_END) and not self._is_at_end():
1643
+ param_info = {}
1644
+
1645
+ # Handle 'open' keyword for open parameters
1646
+ if self._match_keyword('open'):
1647
+ param_info['open'] = True
1648
+
1649
+ # Handle type annotations (e.g., string, int, dynamic, etc.)
1650
+ if self._check(TokenType.KEYWORD):
1651
+ param_info['type'] = self._advance().value
1652
+
1653
+ # Handle reference operator &
1654
+ if self._match(TokenType.AMPERSAND):
1655
+ param_info['ref'] = True
1656
+
1657
+ # Handle * prefix for non-null parameters
1658
+ if self._match(TokenType.MULTIPLY):
1659
+ param_info['non_null'] = True
1660
+
1661
+ # Get parameter name
1662
+ if self._check(TokenType.IDENTIFIER):
1663
+ param_name = self._advance().value
1664
+ if param_info:
1665
+ params.append({'name': param_name, **param_info})
1666
+ else:
1667
+ params.append(param_name)
1668
+ self._match(TokenType.COMMA)
1669
+ elif self._check(TokenType.KEYWORD):
1670
+ # Parameter name could be a keyword like 'Params'
1671
+ param_name = self._advance().value
1672
+ if param_info:
1673
+ params.append({'name': param_name, **param_info})
1674
+ else:
1675
+ params.append(param_name)
1676
+ self._match(TokenType.COMMA)
1677
+ else:
1678
+ break
1679
+
1680
+ return params
1681
+
1402
1682
  def _parse_define(self) -> ASTNode:
1683
+ """Parse define function declaration.
1684
+
1685
+ Syntax:
1686
+ define MyFunc(args) { }
1687
+ define *MyFunc(args) { } // Non-null: must never return None
1688
+ define MyFunc : extends OtherFunc() { } // Inherit local vars
1689
+ define MyFunc : overwrites OtherFunc() { } // Replace OtherFunc
1690
+ define MyFunc :: extends Parent::Method :: overwrites Parent::Method() { } // Method-level inheritance
1691
+ """
1692
+ # Check for * prefix (non-null function - must return non-null)
1693
+ non_null = False
1694
+ if self._match(TokenType.MULTIPLY):
1695
+ non_null = True
1696
+
1403
1697
  name = self._advance().value
1698
+
1699
+ # Check for extends/overwrites: define func : extends/overwrites target() { }
1700
+ # Also supports method-level :: syntax: define func :: extends Parent::method
1701
+ extends_func = None
1702
+ overwrites_func = None
1703
+ extends_is_python = False
1704
+ overwrites_is_python = False
1705
+ extends_class_ref = None
1706
+ extends_method_ref = None
1707
+ overwrites_class_ref = None
1708
+ overwrites_method_ref = None
1709
+
1710
+ if self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON):
1711
+ # Parse extends and/or overwrites (supports :: method-level syntax)
1712
+ while True:
1713
+ if self._match_keyword('extends'):
1714
+ # Check for qualified reference: Parent::method
1715
+ if self._check(TokenType.SHARED_REF):
1716
+ extends_is_python = True
1717
+ extends_func = self._advance().value
1718
+ # Check for ::method
1719
+ if self._match(TokenType.DOUBLE_COLON):
1720
+ extends_class_ref = f'${extends_func}'
1721
+ if self._check(TokenType.IDENTIFIER):
1722
+ extends_method_ref = self._advance().value
1723
+ else:
1724
+ raise CSSLSyntaxError("Expected method name after '::'")
1725
+ elif self._check(TokenType.IDENTIFIER):
1726
+ first_part = self._advance().value
1727
+ # Check for ::method (qualified reference)
1728
+ if self._match(TokenType.DOUBLE_COLON):
1729
+ extends_class_ref = first_part
1730
+ if self._check(TokenType.IDENTIFIER):
1731
+ extends_method_ref = self._advance().value
1732
+ else:
1733
+ raise CSSLSyntaxError("Expected method name after '::'")
1734
+ else:
1735
+ extends_func = first_part
1736
+ else:
1737
+ raise CSSLSyntaxError("Expected function name after 'extends'")
1738
+ # Skip optional () after function/method name
1739
+ if self._match(TokenType.PAREN_START):
1740
+ self._expect(TokenType.PAREN_END)
1741
+ elif self._match_keyword('overwrites'):
1742
+ # Check for qualified reference: Parent::method
1743
+ if self._check(TokenType.SHARED_REF):
1744
+ overwrites_is_python = True
1745
+ overwrites_func = self._advance().value
1746
+ # Check for ::method
1747
+ if self._match(TokenType.DOUBLE_COLON):
1748
+ overwrites_class_ref = f'${overwrites_func}'
1749
+ if self._check(TokenType.IDENTIFIER):
1750
+ overwrites_method_ref = self._advance().value
1751
+ else:
1752
+ raise CSSLSyntaxError("Expected method name after '::'")
1753
+ elif self._check(TokenType.IDENTIFIER):
1754
+ first_part = self._advance().value
1755
+ # Check for ::method (qualified reference)
1756
+ if self._match(TokenType.DOUBLE_COLON):
1757
+ overwrites_class_ref = first_part
1758
+ if self._check(TokenType.IDENTIFIER):
1759
+ overwrites_method_ref = self._advance().value
1760
+ else:
1761
+ raise CSSLSyntaxError("Expected method name after '::'")
1762
+ else:
1763
+ overwrites_func = first_part
1764
+ else:
1765
+ raise CSSLSyntaxError("Expected function name after 'overwrites'")
1766
+ # Skip optional () after function/method name
1767
+ if self._match(TokenType.PAREN_START):
1768
+ self._expect(TokenType.PAREN_END)
1769
+ else:
1770
+ break
1771
+ # Check for another :: or : for chaining extends/overwrites
1772
+ if not (self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON)):
1773
+ break
1774
+
1404
1775
  params = []
1405
1776
 
1406
1777
  if self._match(TokenType.PAREN_START):
@@ -1415,6 +1786,9 @@ class CSSLParser:
1415
1786
  # Handle reference operator &
1416
1787
  if self._match(TokenType.AMPERSAND):
1417
1788
  param_info['ref'] = True
1789
+ # Handle * prefix for non-null parameters
1790
+ if self._match(TokenType.MULTIPLY):
1791
+ param_info['non_null'] = True
1418
1792
  # Get parameter name
1419
1793
  if self._check(TokenType.IDENTIFIER):
1420
1794
  param_name = self._advance().value
@@ -1435,7 +1809,50 @@ class CSSLParser:
1435
1809
  break
1436
1810
  self._expect(TokenType.PAREN_END)
1437
1811
 
1438
- node = ASTNode('function', value={'name': name, 'params': params}, children=[])
1812
+ # New: Append mode and reference tracking for functions
1813
+ # Syntax: define XYZ(int zahl) &overwrittenclass::functionyouwanttokeep ++ { ... }
1814
+ append_mode = False
1815
+ append_ref_class = None
1816
+ append_ref_member = None
1817
+
1818
+ # Check for &ClassName::member reference
1819
+ if self._match(TokenType.AMPERSAND):
1820
+ if self._check(TokenType.IDENTIFIER):
1821
+ append_ref_class = self._advance().value
1822
+ elif self._check(TokenType.SHARED_REF):
1823
+ append_ref_class = f'${self._advance().value}'
1824
+ else:
1825
+ raise CSSLSyntaxError("Expected class name after '&' in function reference")
1826
+
1827
+ # Check for ::member
1828
+ if self._match(TokenType.DOUBLE_COLON):
1829
+ if self._check(TokenType.IDENTIFIER) or self._check(TokenType.KEYWORD):
1830
+ append_ref_member = self._advance().value
1831
+ else:
1832
+ raise CSSLSyntaxError("Expected member name after '::' in function reference")
1833
+
1834
+ # Check for ++ append operator
1835
+ if self._match(TokenType.PLUS_PLUS):
1836
+ append_mode = True
1837
+
1838
+ node = ASTNode('function', value={
1839
+ 'name': name,
1840
+ 'params': params,
1841
+ 'non_null': non_null,
1842
+ 'extends': extends_func,
1843
+ 'extends_is_python': extends_is_python,
1844
+ 'overwrites': overwrites_func,
1845
+ 'overwrites_is_python': overwrites_is_python,
1846
+ # Method-level inheritance (Parent::method syntax)
1847
+ 'extends_class': extends_class_ref,
1848
+ 'extends_method': extends_method_ref,
1849
+ 'overwrites_class': overwrites_class_ref,
1850
+ 'overwrites_method': overwrites_method_ref,
1851
+ # New append mode fields
1852
+ 'append_mode': append_mode,
1853
+ 'append_ref_class': append_ref_class,
1854
+ 'append_ref_member': append_ref_member
1855
+ }, children=[])
1439
1856
  self._expect(TokenType.BLOCK_START)
1440
1857
 
1441
1858
  while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
@@ -1481,6 +1898,11 @@ class CSSLParser:
1481
1898
  elif self._check(TokenType.SUPER_FUNC):
1482
1899
  # Super-function for .cssl-pl payload files
1483
1900
  return self._parse_super_function()
1901
+ elif (self._check(TokenType.KEYWORD) and self._current().value == 'super' and
1902
+ (self._peek(1).type == TokenType.PAREN_START or
1903
+ self._peek(1).type == TokenType.DOUBLE_COLON)):
1904
+ # super() or super::method() call - calls parent constructor/method
1905
+ return self._parse_super_call()
1484
1906
  elif (self._check(TokenType.IDENTIFIER) or self._check(TokenType.AT) or
1485
1907
  self._check(TokenType.CAPTURED_REF) or self._check(TokenType.SHARED_REF) or
1486
1908
  self._check(TokenType.GLOBAL_REF) or self._check(TokenType.SELF_REF) or
@@ -1491,6 +1913,43 @@ class CSSLParser:
1491
1913
  self._advance()
1492
1914
  return None
1493
1915
 
1916
+ def _parse_super_call(self) -> ASTNode:
1917
+ """Parse super() call to invoke parent constructor or method.
1918
+
1919
+ Syntax:
1920
+ super() - Call parent constructor with no args
1921
+ super(arg1, arg2) - Call parent constructor with args
1922
+ super::method() - Call specific parent method
1923
+ super::method(args) - Call specific parent method with args
1924
+
1925
+ Used inside constructors (constr) and methods to call parent implementations.
1926
+ """
1927
+ # Consume 'super' keyword
1928
+ self._advance()
1929
+
1930
+ # Check for ::method syntax
1931
+ target_method = None
1932
+ if self._match(TokenType.DOUBLE_COLON):
1933
+ if not self._check(TokenType.IDENTIFIER):
1934
+ raise CSSLSyntaxError("Expected method name after 'super::'")
1935
+ target_method = self._advance().value
1936
+
1937
+ # Parse arguments
1938
+ args = []
1939
+ self._expect(TokenType.PAREN_START)
1940
+ while not self._check(TokenType.PAREN_END):
1941
+ arg = self._parse_expression()
1942
+ args.append(arg)
1943
+ if not self._match(TokenType.COMMA):
1944
+ break
1945
+ self._expect(TokenType.PAREN_END)
1946
+ self._match(TokenType.SEMICOLON)
1947
+
1948
+ return ASTNode('super_call', value={
1949
+ 'method': target_method, # None for constructor, method name for specific method
1950
+ 'args': args
1951
+ })
1952
+
1494
1953
  def _parse_if(self) -> ASTNode:
1495
1954
  """Parse if statement with support for else if AND elif syntax."""
1496
1955
  self._expect(TokenType.PAREN_START)
@@ -2610,12 +3069,24 @@ class CSSLParser:
2610
3069
  'init_values': init_values
2611
3070
  })
2612
3071
 
2613
- # Check for type-parameterized function call: OpenFind<string>(0)
3072
+ # Check for type-parameterized function call: OpenFind<string>(0) or OpenFind<dynamic, "name">
2614
3073
  if name in TYPE_PARAM_FUNCTIONS and self._check(TokenType.COMPARE_LT):
2615
3074
  self._advance() # consume <
2616
3075
  type_param = 'dynamic'
3076
+ param_name = None # Optional: named parameter search
3077
+
2617
3078
  if self._check(TokenType.KEYWORD) or self._check(TokenType.IDENTIFIER):
2618
3079
  type_param = self._advance().value
3080
+
3081
+ # Check for second parameter: OpenFind<type, "name">
3082
+ if self._check(TokenType.COMMA):
3083
+ self._advance() # consume comma
3084
+ # Expect a string literal for the parameter name
3085
+ if self._check(TokenType.STRING):
3086
+ param_name = self._advance().value
3087
+ elif self._check(TokenType.IDENTIFIER):
3088
+ param_name = self._advance().value
3089
+
2619
3090
  self._expect(TokenType.COMPARE_GT) # consume >
2620
3091
 
2621
3092
  # Must be followed by ()
@@ -2632,6 +3103,7 @@ class CSSLParser:
2632
3103
  return ASTNode('typed_call', value={
2633
3104
  'name': name,
2634
3105
  'type_param': type_param,
3106
+ 'param_name': param_name, # Named parameter for OpenFind
2635
3107
  'args': args
2636
3108
  })
2637
3109