IncludeCPP 3.8.3__py3-none-any.whl → 3.8.5__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/core/cssl/CSSL_DOCUMENTATION.md +312 -1
- includecpp/core/cssl/cssl_builtins.py +133 -0
- includecpp/core/cssl/cssl_parser.py +314 -7
- includecpp/core/cssl/cssl_runtime.py +414 -6
- includecpp/core/cssl/cssl_types.py +58 -9
- includecpp/vscode/cssl/package.json +1 -1
- includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +173 -5
- {includecpp-3.8.3.dist-info → includecpp-3.8.5.dist-info}/METADATA +1 -1
- {includecpp-3.8.3.dist-info → includecpp-3.8.5.dist-info}/RECORD +14 -14
- {includecpp-3.8.3.dist-info → includecpp-3.8.5.dist-info}/WHEEL +0 -0
- {includecpp-3.8.3.dist-info → includecpp-3.8.5.dist-info}/entry_points.txt +0 -0
- {includecpp-3.8.3.dist-info → includecpp-3.8.5.dist-info}/licenses/LICENSE +0 -0
- {includecpp-3.8.3.dist-info → includecpp-3.8.5.dist-info}/top_level.txt +0 -0
|
@@ -114,7 +114,7 @@ class TokenType(Enum):
|
|
|
114
114
|
|
|
115
115
|
KEYWORDS = {
|
|
116
116
|
# Service structure
|
|
117
|
-
'service-init', 'service-run', 'service-include', 'struct', 'define', 'main', 'class', 'new', 'this',
|
|
117
|
+
'service-init', 'service-run', 'service-include', 'struct', 'define', 'main', 'class', 'constr', 'extends', 'overwrites', 'new', 'this', 'super',
|
|
118
118
|
# Control flow
|
|
119
119
|
'if', 'else', 'elif', 'while', 'for', 'foreach', 'in', 'range',
|
|
120
120
|
'switch', 'case', 'default', 'break', 'continue', 'return',
|
|
@@ -1045,7 +1045,7 @@ class CSSLParser:
|
|
|
1045
1045
|
|
|
1046
1046
|
# Check for * prefix (non-nullable indicator)
|
|
1047
1047
|
non_null = False
|
|
1048
|
-
if self._match(TokenType.
|
|
1048
|
+
if self._match(TokenType.MULTIPLY):
|
|
1049
1049
|
non_null = True
|
|
1050
1050
|
|
|
1051
1051
|
# Get variable name
|
|
@@ -1378,12 +1378,73 @@ class CSSLParser:
|
|
|
1378
1378
|
"""
|
|
1379
1379
|
# Check for * prefix (non-null class - all methods return non-null)
|
|
1380
1380
|
non_null = False
|
|
1381
|
-
if self._match(TokenType.
|
|
1381
|
+
if self._match(TokenType.MULTIPLY):
|
|
1382
1382
|
non_null = True
|
|
1383
1383
|
|
|
1384
1384
|
class_name = self._advance().value
|
|
1385
1385
|
|
|
1386
|
-
|
|
1386
|
+
# Check for class-level constructor parameters: class MyClass (int x, string y) { ... }
|
|
1387
|
+
class_params = []
|
|
1388
|
+
if self._match(TokenType.PAREN_START):
|
|
1389
|
+
class_params = self._parse_parameter_list()
|
|
1390
|
+
self._expect(TokenType.PAREN_END)
|
|
1391
|
+
|
|
1392
|
+
# Check for inheritance and overwrites:
|
|
1393
|
+
# class Child : extends Parent { ... }
|
|
1394
|
+
# class Child : extends $PythonObject { ... }
|
|
1395
|
+
# class Child : extends Parent : overwrites Parent { ... }
|
|
1396
|
+
# class Child : extends Parent (param1, param2) { ... } <- constructor args for parent
|
|
1397
|
+
extends_class = None
|
|
1398
|
+
extends_is_python = False
|
|
1399
|
+
extends_args = []
|
|
1400
|
+
overwrites_class = None
|
|
1401
|
+
overwrites_is_python = False
|
|
1402
|
+
|
|
1403
|
+
if self._match(TokenType.COLON):
|
|
1404
|
+
# Parse extends and/or overwrites (can be chained)
|
|
1405
|
+
while True:
|
|
1406
|
+
if self._match_keyword('extends'):
|
|
1407
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1408
|
+
extends_class = self._advance().value
|
|
1409
|
+
elif self._check(TokenType.SHARED_REF):
|
|
1410
|
+
extends_class = self._advance().value
|
|
1411
|
+
extends_is_python = True
|
|
1412
|
+
else:
|
|
1413
|
+
raise CSSLSyntaxError("Expected parent class name after 'extends'")
|
|
1414
|
+
# Check for constructor arguments: extends Parent (arg1, arg2)
|
|
1415
|
+
if self._match(TokenType.PAREN_START):
|
|
1416
|
+
while not self._check(TokenType.PAREN_END):
|
|
1417
|
+
arg = self._parse_expression()
|
|
1418
|
+
extends_args.append(arg)
|
|
1419
|
+
self._match(TokenType.COMMA)
|
|
1420
|
+
self._expect(TokenType.PAREN_END)
|
|
1421
|
+
elif self._match_keyword('overwrites'):
|
|
1422
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1423
|
+
overwrites_class = self._advance().value
|
|
1424
|
+
elif self._check(TokenType.SHARED_REF):
|
|
1425
|
+
overwrites_class = self._advance().value
|
|
1426
|
+
overwrites_is_python = True
|
|
1427
|
+
else:
|
|
1428
|
+
raise CSSLSyntaxError("Expected class name after 'overwrites'")
|
|
1429
|
+
# Skip optional () after class name
|
|
1430
|
+
if self._match(TokenType.PAREN_START):
|
|
1431
|
+
self._expect(TokenType.PAREN_END)
|
|
1432
|
+
else:
|
|
1433
|
+
raise CSSLSyntaxError("Expected 'extends' or 'overwrites' after ':' in class declaration")
|
|
1434
|
+
# Check for another : for chaining
|
|
1435
|
+
if not self._match(TokenType.COLON):
|
|
1436
|
+
break
|
|
1437
|
+
|
|
1438
|
+
node = ASTNode('class', value={
|
|
1439
|
+
'name': class_name,
|
|
1440
|
+
'non_null': non_null,
|
|
1441
|
+
'class_params': class_params,
|
|
1442
|
+
'extends': extends_class,
|
|
1443
|
+
'extends_is_python': extends_is_python,
|
|
1444
|
+
'extends_args': extends_args,
|
|
1445
|
+
'overwrites': overwrites_class,
|
|
1446
|
+
'overwrites_is_python': overwrites_is_python
|
|
1447
|
+
}, children=[])
|
|
1387
1448
|
self._expect(TokenType.BLOCK_START)
|
|
1388
1449
|
|
|
1389
1450
|
while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
|
|
@@ -1412,25 +1473,217 @@ class CSSLParser:
|
|
|
1412
1473
|
method = self._parse_define()
|
|
1413
1474
|
node.children.append(method)
|
|
1414
1475
|
|
|
1476
|
+
# Check for constr keyword (constructor declaration)
|
|
1477
|
+
# Syntax: constr ConstructorName() { ... }
|
|
1478
|
+
# or: constr ConstructorName() : extends Parent::ConstructorName { ... }
|
|
1479
|
+
elif self._match_keyword('constr'):
|
|
1480
|
+
constructor = self._parse_constructor(class_name)
|
|
1481
|
+
node.children.append(constructor)
|
|
1482
|
+
|
|
1415
1483
|
else:
|
|
1416
1484
|
self._advance()
|
|
1417
1485
|
|
|
1418
1486
|
self._expect(TokenType.BLOCK_END)
|
|
1419
1487
|
return node
|
|
1420
1488
|
|
|
1489
|
+
def _parse_constructor(self, class_name: str) -> ASTNode:
|
|
1490
|
+
"""Parse constructor declaration inside a class.
|
|
1491
|
+
|
|
1492
|
+
Syntax:
|
|
1493
|
+
constr ConstructorName() { ... }
|
|
1494
|
+
constr ConstructorName() : extends ParentClass::ConstructorName { ... }
|
|
1495
|
+
constr ConstructorName() : extends ParentClass::ConstructorName : overwrites ParentClass::ConstructorName { ... }
|
|
1496
|
+
|
|
1497
|
+
Multiple constructors are allowed and executed in order.
|
|
1498
|
+
Constructors can access parent constructor via super().
|
|
1499
|
+
"""
|
|
1500
|
+
# Get constructor name
|
|
1501
|
+
if not self._check(TokenType.IDENTIFIER):
|
|
1502
|
+
raise CSSLSyntaxError("Expected constructor name after 'constr'")
|
|
1503
|
+
constr_name = self._advance().value
|
|
1504
|
+
|
|
1505
|
+
# Parse method-level extends/overwrites with :: syntax
|
|
1506
|
+
# constr Name() :: extends Parent::Name :: overwrites Parent::Name { ... }
|
|
1507
|
+
extends_target = None
|
|
1508
|
+
extends_class_ref = None
|
|
1509
|
+
extends_method_ref = None
|
|
1510
|
+
overwrites_target = None
|
|
1511
|
+
overwrites_class_ref = None
|
|
1512
|
+
overwrites_method_ref = None
|
|
1513
|
+
|
|
1514
|
+
# Parse parameters
|
|
1515
|
+
params = []
|
|
1516
|
+
if self._match(TokenType.PAREN_START):
|
|
1517
|
+
params = self._parse_parameter_list()
|
|
1518
|
+
self._expect(TokenType.PAREN_END)
|
|
1519
|
+
|
|
1520
|
+
# Check for method-level extends/overwrites with :: or :
|
|
1521
|
+
if self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON):
|
|
1522
|
+
while True:
|
|
1523
|
+
if self._match_keyword('extends'):
|
|
1524
|
+
# Parse Parent::method or just method
|
|
1525
|
+
extends_target = self._parse_qualified_method_ref()
|
|
1526
|
+
if '::' in extends_target:
|
|
1527
|
+
parts = extends_target.split('::')
|
|
1528
|
+
extends_class_ref = parts[0]
|
|
1529
|
+
extends_method_ref = parts[1]
|
|
1530
|
+
else:
|
|
1531
|
+
extends_method_ref = extends_target
|
|
1532
|
+
elif self._match_keyword('overwrites'):
|
|
1533
|
+
# Parse Parent::method or just method
|
|
1534
|
+
overwrites_target = self._parse_qualified_method_ref()
|
|
1535
|
+
if '::' in overwrites_target:
|
|
1536
|
+
parts = overwrites_target.split('::')
|
|
1537
|
+
overwrites_class_ref = parts[0]
|
|
1538
|
+
overwrites_method_ref = parts[1]
|
|
1539
|
+
else:
|
|
1540
|
+
overwrites_method_ref = overwrites_target
|
|
1541
|
+
else:
|
|
1542
|
+
break
|
|
1543
|
+
# Check for another :: or : for chaining
|
|
1544
|
+
if not (self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON)):
|
|
1545
|
+
break
|
|
1546
|
+
|
|
1547
|
+
# Parse constructor body
|
|
1548
|
+
self._expect(TokenType.BLOCK_START)
|
|
1549
|
+
body = []
|
|
1550
|
+
while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
|
|
1551
|
+
stmt = self._parse_statement()
|
|
1552
|
+
if stmt:
|
|
1553
|
+
body.append(stmt)
|
|
1554
|
+
self._expect(TokenType.BLOCK_END)
|
|
1555
|
+
|
|
1556
|
+
return ASTNode('constructor', value={
|
|
1557
|
+
'name': constr_name,
|
|
1558
|
+
'class_name': class_name,
|
|
1559
|
+
'params': params,
|
|
1560
|
+
'is_constructor': True,
|
|
1561
|
+
'extends_target': extends_target,
|
|
1562
|
+
'extends_class': extends_class_ref,
|
|
1563
|
+
'extends_method': extends_method_ref,
|
|
1564
|
+
'overwrites_target': overwrites_target,
|
|
1565
|
+
'overwrites_class': overwrites_class_ref,
|
|
1566
|
+
'overwrites_method': overwrites_method_ref
|
|
1567
|
+
}, children=body)
|
|
1568
|
+
|
|
1569
|
+
def _parse_qualified_method_ref(self) -> str:
|
|
1570
|
+
"""Parse a qualified method reference like 'ParentClass::methodName' or just 'methodName'.
|
|
1571
|
+
|
|
1572
|
+
Returns the qualified name as a string (e.g., 'Parent::init' or just 'init').
|
|
1573
|
+
"""
|
|
1574
|
+
# Check for $PythonObject
|
|
1575
|
+
if self._check(TokenType.SHARED_REF):
|
|
1576
|
+
class_ref = self._advance().value # Gets the name without $
|
|
1577
|
+
class_ref = f'${class_ref}'
|
|
1578
|
+
elif self._check(TokenType.IDENTIFIER):
|
|
1579
|
+
class_ref = self._advance().value
|
|
1580
|
+
else:
|
|
1581
|
+
raise CSSLSyntaxError("Expected class or method name in extends/overwrites")
|
|
1582
|
+
|
|
1583
|
+
# Check for :: to get method part
|
|
1584
|
+
if self._match(TokenType.DOUBLE_COLON):
|
|
1585
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1586
|
+
method_ref = self._advance().value
|
|
1587
|
+
return f'{class_ref}::{method_ref}'
|
|
1588
|
+
else:
|
|
1589
|
+
raise CSSLSyntaxError("Expected method name after '::'")
|
|
1590
|
+
|
|
1591
|
+
# Just method name, no class qualifier
|
|
1592
|
+
return class_ref
|
|
1593
|
+
|
|
1421
1594
|
def _parse_define(self) -> ASTNode:
|
|
1422
1595
|
"""Parse define function declaration.
|
|
1423
1596
|
|
|
1424
1597
|
Syntax:
|
|
1425
1598
|
define MyFunc(args) { }
|
|
1426
1599
|
define *MyFunc(args) { } // Non-null: must never return None
|
|
1600
|
+
define MyFunc : extends OtherFunc() { } // Inherit local vars
|
|
1601
|
+
define MyFunc : overwrites OtherFunc() { } // Replace OtherFunc
|
|
1602
|
+
define MyFunc :: extends Parent::Method :: overwrites Parent::Method() { } // Method-level inheritance
|
|
1427
1603
|
"""
|
|
1428
1604
|
# Check for * prefix (non-null function - must return non-null)
|
|
1429
1605
|
non_null = False
|
|
1430
|
-
if self._match(TokenType.
|
|
1606
|
+
if self._match(TokenType.MULTIPLY):
|
|
1431
1607
|
non_null = True
|
|
1432
1608
|
|
|
1433
1609
|
name = self._advance().value
|
|
1610
|
+
|
|
1611
|
+
# Check for extends/overwrites: define func : extends/overwrites target() { }
|
|
1612
|
+
# Also supports method-level :: syntax: define func :: extends Parent::method
|
|
1613
|
+
extends_func = None
|
|
1614
|
+
overwrites_func = None
|
|
1615
|
+
extends_is_python = False
|
|
1616
|
+
overwrites_is_python = False
|
|
1617
|
+
extends_class_ref = None
|
|
1618
|
+
extends_method_ref = None
|
|
1619
|
+
overwrites_class_ref = None
|
|
1620
|
+
overwrites_method_ref = None
|
|
1621
|
+
|
|
1622
|
+
if self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON):
|
|
1623
|
+
# Parse extends and/or overwrites (supports :: method-level syntax)
|
|
1624
|
+
while True:
|
|
1625
|
+
if self._match_keyword('extends'):
|
|
1626
|
+
# Check for qualified reference: Parent::method
|
|
1627
|
+
if self._check(TokenType.SHARED_REF):
|
|
1628
|
+
extends_is_python = True
|
|
1629
|
+
extends_func = self._advance().value
|
|
1630
|
+
# Check for ::method
|
|
1631
|
+
if self._match(TokenType.DOUBLE_COLON):
|
|
1632
|
+
extends_class_ref = f'${extends_func}'
|
|
1633
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1634
|
+
extends_method_ref = self._advance().value
|
|
1635
|
+
else:
|
|
1636
|
+
raise CSSLSyntaxError("Expected method name after '::'")
|
|
1637
|
+
elif self._check(TokenType.IDENTIFIER):
|
|
1638
|
+
first_part = self._advance().value
|
|
1639
|
+
# Check for ::method (qualified reference)
|
|
1640
|
+
if self._match(TokenType.DOUBLE_COLON):
|
|
1641
|
+
extends_class_ref = first_part
|
|
1642
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1643
|
+
extends_method_ref = self._advance().value
|
|
1644
|
+
else:
|
|
1645
|
+
raise CSSLSyntaxError("Expected method name after '::'")
|
|
1646
|
+
else:
|
|
1647
|
+
extends_func = first_part
|
|
1648
|
+
else:
|
|
1649
|
+
raise CSSLSyntaxError("Expected function name after 'extends'")
|
|
1650
|
+
# Skip optional () after function/method name
|
|
1651
|
+
if self._match(TokenType.PAREN_START):
|
|
1652
|
+
self._expect(TokenType.PAREN_END)
|
|
1653
|
+
elif self._match_keyword('overwrites'):
|
|
1654
|
+
# Check for qualified reference: Parent::method
|
|
1655
|
+
if self._check(TokenType.SHARED_REF):
|
|
1656
|
+
overwrites_is_python = True
|
|
1657
|
+
overwrites_func = self._advance().value
|
|
1658
|
+
# Check for ::method
|
|
1659
|
+
if self._match(TokenType.DOUBLE_COLON):
|
|
1660
|
+
overwrites_class_ref = f'${overwrites_func}'
|
|
1661
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1662
|
+
overwrites_method_ref = self._advance().value
|
|
1663
|
+
else:
|
|
1664
|
+
raise CSSLSyntaxError("Expected method name after '::'")
|
|
1665
|
+
elif self._check(TokenType.IDENTIFIER):
|
|
1666
|
+
first_part = self._advance().value
|
|
1667
|
+
# Check for ::method (qualified reference)
|
|
1668
|
+
if self._match(TokenType.DOUBLE_COLON):
|
|
1669
|
+
overwrites_class_ref = first_part
|
|
1670
|
+
if self._check(TokenType.IDENTIFIER):
|
|
1671
|
+
overwrites_method_ref = self._advance().value
|
|
1672
|
+
else:
|
|
1673
|
+
raise CSSLSyntaxError("Expected method name after '::'")
|
|
1674
|
+
else:
|
|
1675
|
+
overwrites_func = first_part
|
|
1676
|
+
else:
|
|
1677
|
+
raise CSSLSyntaxError("Expected function name after 'overwrites'")
|
|
1678
|
+
# Skip optional () after function/method name
|
|
1679
|
+
if self._match(TokenType.PAREN_START):
|
|
1680
|
+
self._expect(TokenType.PAREN_END)
|
|
1681
|
+
else:
|
|
1682
|
+
break
|
|
1683
|
+
# Check for another :: or : for chaining extends/overwrites
|
|
1684
|
+
if not (self._match(TokenType.DOUBLE_COLON) or self._match(TokenType.COLON)):
|
|
1685
|
+
break
|
|
1686
|
+
|
|
1434
1687
|
params = []
|
|
1435
1688
|
|
|
1436
1689
|
if self._match(TokenType.PAREN_START):
|
|
@@ -1446,7 +1699,7 @@ class CSSLParser:
|
|
|
1446
1699
|
if self._match(TokenType.AMPERSAND):
|
|
1447
1700
|
param_info['ref'] = True
|
|
1448
1701
|
# Handle * prefix for non-null parameters
|
|
1449
|
-
if self._match(TokenType.
|
|
1702
|
+
if self._match(TokenType.MULTIPLY):
|
|
1450
1703
|
param_info['non_null'] = True
|
|
1451
1704
|
# Get parameter name
|
|
1452
1705
|
if self._check(TokenType.IDENTIFIER):
|
|
@@ -1468,7 +1721,20 @@ class CSSLParser:
|
|
|
1468
1721
|
break
|
|
1469
1722
|
self._expect(TokenType.PAREN_END)
|
|
1470
1723
|
|
|
1471
|
-
node = ASTNode('function', value={
|
|
1724
|
+
node = ASTNode('function', value={
|
|
1725
|
+
'name': name,
|
|
1726
|
+
'params': params,
|
|
1727
|
+
'non_null': non_null,
|
|
1728
|
+
'extends': extends_func,
|
|
1729
|
+
'extends_is_python': extends_is_python,
|
|
1730
|
+
'overwrites': overwrites_func,
|
|
1731
|
+
'overwrites_is_python': overwrites_is_python,
|
|
1732
|
+
# Method-level inheritance (Parent::method syntax)
|
|
1733
|
+
'extends_class': extends_class_ref,
|
|
1734
|
+
'extends_method': extends_method_ref,
|
|
1735
|
+
'overwrites_class': overwrites_class_ref,
|
|
1736
|
+
'overwrites_method': overwrites_method_ref
|
|
1737
|
+
}, children=[])
|
|
1472
1738
|
self._expect(TokenType.BLOCK_START)
|
|
1473
1739
|
|
|
1474
1740
|
while not self._check(TokenType.BLOCK_END) and not self._is_at_end():
|
|
@@ -1514,6 +1780,10 @@ class CSSLParser:
|
|
|
1514
1780
|
elif self._check(TokenType.SUPER_FUNC):
|
|
1515
1781
|
# Super-function for .cssl-pl payload files
|
|
1516
1782
|
return self._parse_super_function()
|
|
1783
|
+
elif (self._check(TokenType.KEYWORD) and self._current().value == 'super' and
|
|
1784
|
+
self._peek(1).type == TokenType.PAREN_START):
|
|
1785
|
+
# super() call - calls parent constructor/method
|
|
1786
|
+
return self._parse_super_call()
|
|
1517
1787
|
elif (self._check(TokenType.IDENTIFIER) or self._check(TokenType.AT) or
|
|
1518
1788
|
self._check(TokenType.CAPTURED_REF) or self._check(TokenType.SHARED_REF) or
|
|
1519
1789
|
self._check(TokenType.GLOBAL_REF) or self._check(TokenType.SELF_REF) or
|
|
@@ -1524,6 +1794,43 @@ class CSSLParser:
|
|
|
1524
1794
|
self._advance()
|
|
1525
1795
|
return None
|
|
1526
1796
|
|
|
1797
|
+
def _parse_super_call(self) -> ASTNode:
|
|
1798
|
+
"""Parse super() call to invoke parent constructor or method.
|
|
1799
|
+
|
|
1800
|
+
Syntax:
|
|
1801
|
+
super() - Call parent constructor with no args
|
|
1802
|
+
super(arg1, arg2) - Call parent constructor with args
|
|
1803
|
+
super::method() - Call specific parent method
|
|
1804
|
+
super::method(args) - Call specific parent method with args
|
|
1805
|
+
|
|
1806
|
+
Used inside constructors (constr) and methods to call parent implementations.
|
|
1807
|
+
"""
|
|
1808
|
+
# Consume 'super' keyword
|
|
1809
|
+
self._advance()
|
|
1810
|
+
|
|
1811
|
+
# Check for ::method syntax
|
|
1812
|
+
target_method = None
|
|
1813
|
+
if self._match(TokenType.DOUBLE_COLON):
|
|
1814
|
+
if not self._check(TokenType.IDENTIFIER):
|
|
1815
|
+
raise CSSLSyntaxError("Expected method name after 'super::'")
|
|
1816
|
+
target_method = self._advance().value
|
|
1817
|
+
|
|
1818
|
+
# Parse arguments
|
|
1819
|
+
args = []
|
|
1820
|
+
self._expect(TokenType.PAREN_START)
|
|
1821
|
+
while not self._check(TokenType.PAREN_END):
|
|
1822
|
+
arg = self._parse_expression()
|
|
1823
|
+
args.append(arg)
|
|
1824
|
+
if not self._match(TokenType.COMMA):
|
|
1825
|
+
break
|
|
1826
|
+
self._expect(TokenType.PAREN_END)
|
|
1827
|
+
self._match(TokenType.SEMICOLON)
|
|
1828
|
+
|
|
1829
|
+
return ASTNode('super_call', value={
|
|
1830
|
+
'method': target_method, # None for constructor, method name for specific method
|
|
1831
|
+
'args': args
|
|
1832
|
+
})
|
|
1833
|
+
|
|
1527
1834
|
def _parse_if(self) -> ASTNode:
|
|
1528
1835
|
"""Parse if statement with support for else if AND elif syntax."""
|
|
1529
1836
|
self._expect(TokenType.PAREN_START)
|