Files
2026-10-17 21:57:03 +08:00

1704 lines
61 KiB
Plaintext

from stdio import printf
import memhub
import stdlib
import string
from ast import (
AST, ASTKind, Module, FunctionDef, Assign, If, For, While, With,
Return, Expr, Name, Constant, BinOp, UnaryOp, Call, Compare,
Import, ImportFrom, Expression,
CONST_INT, CONST_STR, CONST_BOOL, CONST_NONE,
OpKind, ASTCtx,
FLAG_IS_ASYNC,
parse, parse_expression, dump,
)
ARENA_SIZE: int = 16777216
export def main() -> int:
printf("=== NewAstTest Start ===\n")
# Initialize allocator
arena: bytes = stdlib.malloc(ARENA_SIZE)
if arena is None:
printf("FAIL: arena alloc failed\n")
return 1
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, ARENA_SIZE)
if pool is None:
printf("FAIL: pool init failed\n")
return 1
passed: int = 0
failed: int = 0
# --- Allocate dump buffer for AST round-trip output tests ---
DUMP_BUF_SIZE: sizet = 8192
dump_buf: char* = stdlib.malloc(DUMP_BUF_SIZE)
if dump_buf is None:
printf("FAIL: dump_buf alloc failed\n")
stdlib.free(arena)
return 1
# --- Test 0: Match statement ---
match_src: str = """match x:
case 1:
pass
case _:
pass
"""
match_mod: Module* = parse(match_src, pool)
if match_mod is not None and match_mod.kind() == ASTKind.Module:
passed += 1
printf("PASS: parse('match x: case 1: ... case _: ...') -> Module\n")
else:
failed += 1
printf("FAIL: parse match with cases failed\n")
# --- Test 1: Name node creation ---
name_x: Name* = Name(pool, "x", ASTCtx.Load)
if name_x is None:
printf("FAIL: Name creation\n")
failed += 1
else:
passed += 1
printf("PASS: Name('x'), kind=%d\n", name_x.kind())
# --- Test 2: ConstantInt node ---
int_42: Constant* = Constant(pool, CONST_INT, 42, 0.0, None, 1, 0)
if int_42 is None:
printf("FAIL: ConstantInt creation\n")
failed += 1
else:
passed += 1
printf("PASS: ConstantInt(42), kind=%d, val=%lld\n",
int_42.kind(), int_42.int_val)
# --- Test 3: ConstantStr node ---
str_hello: Constant* = Constant(pool, CONST_STR, 0, 0.0, "hello", 2, 0)
if str_hello is None:
printf("FAIL: ConstantStr creation\n")
failed += 1
else:
passed += 1
printf("PASS: ConstantStr('hello'), kind=%d\n", str_hello.kind())
# --- Test 4: ConstantNone node ---
const_none: Constant* = Constant(pool, CONST_NONE, 0, 0.0, None, 3, 0)
if const_none is None:
printf("FAIL: ConstantNone creation\n")
failed += 1
else:
passed += 1
printf("PASS: ConstantNone, kind=%d\n", const_none.kind())
# --- Test 5: BinOp node (x + 42) ---
binop: BinOp* = BinOp(pool, name_x, OpKind.Add, int_42)
if binop is None:
printf("FAIL: BinOp creation\n")
failed += 1
else:
passed += 1
printf("PASS: BinOp(Add), kind=%d\n", binop.kind())
# --- Test 6: UnaryOp node (-x) ---
unary: UnaryOp* = UnaryOp(pool, OpKind.USub, name_x)
if unary is None:
printf("FAIL: UnaryOp creation\n")
failed += 1
else:
passed += 1
printf("PASS: UnaryOp(USub), kind=%d\n", unary.kind())
# --- Test 7: list[AST*] container ---
body: list[AST*]* = list[AST*](pool, 8)
if body is None:
printf("FAIL: list creation\n")
failed += 1
else:
body.append(binop)
body.append(unary)
cnt: sizet = body.__len__()
if cnt == 2:
passed += 1
printf("PASS: list append x2, count=%zu\n", cnt)
else:
failed += 1
printf("FAIL: list count=%zu (expected 2)\n", cnt)
# --- Test 8: list get + kind dispatch ---
if body is not None:
item0: AST* = body.get(0)
if item0 is not None:
k: int = item0.kind()
if k == ASTKind.BinOp:
passed += 1
printf("PASS: list get(0).kind()=%d (BinOp)\n", k)
else:
failed += 1
printf("FAIL: list get(0).kind()=%d (expected %d)\n", k, ASTKind.BinOp)
else:
failed += 1
printf("FAIL: list get(0) returned None\n")
# --- Test 9: Module node (Module(pool) + append) ---
mod: Module* = Module(pool)
if mod is None:
printf("FAIL: Module creation\n")
failed += 1
else:
mod.append(binop)
mod.append(unary)
passed += 1
printf("PASS: Module, kind=%d\n", mod.kind())
# --- Test 10: polymorphic dispatch via AST base pointer kind() ---
ast_ptr: AST* = mod
poly_kind: int = ast_ptr.kind()
if poly_kind == ASTKind.Module:
passed += 1
printf("PASS: polymorphic kind()=%d (Module via AST ptr)\n", poly_kind)
else:
failed += 1
printf("FAIL: polymorphic kind()=%d (expected %d)\n", poly_kind, ASTKind.Module)
# --- Test 11: polymorphic dispatch on list elements ---
if body is not None:
ast_item: AST* = body.get(1)
if ast_item is not None:
pk2: int = ast_item.kind()
if pk2 == ASTKind.UnaryOp:
passed += 1
printf("PASS: polymorphic kind()=%d (UnaryOp via AST ptr)\n", pk2)
else:
failed += 1
printf("FAIL: polymorphic kind()=%d (expected %d)\n", pk2, ASTKind.UnaryOp)
else:
failed += 1
printf("FAIL: list get(1) returned None\n")
# --- Test 12: Return node ---
ret: Return* = Return(pool, binop)
if ret is None:
printf("FAIL: Return creation\n")
failed += 1
else:
passed += 1
printf("PASS: Return, kind=%d\n", ret.kind())
# --- Test 13: Expr statement node ---
expr_stmt: Expr* = Expr(pool, binop)
if expr_stmt is None:
printf("FAIL: Expr creation\n")
failed += 1
else:
passed += 1
printf("PASS: Expr, kind=%d\n", expr_stmt.kind())
# --- Test 14: If node (If(pool, test, orelse), body = children) ---
empty_else: list[AST*]* = list[AST*](pool, 8)
if_stmt: If* = If(pool, binop, empty_else)
if if_stmt is None:
printf("FAIL: If creation\n")
failed += 1
else:
if_stmt.append(ret)
if_stmt.append(expr_stmt)
passed += 1
printf("PASS: If, kind=%d\n", if_stmt.kind())
# --- Test 15: Compare node ---
cmp_ops: list[int]* = list[int](pool)
cmp_ops.append(OpKind.Lt)
cmp_comparators: list[AST*]* = list[AST*](pool, 8)
cmp_comparators.append(int_42)
cmp_node: Compare* = Compare(pool, name_x, cmp_ops, cmp_comparators)
if cmp_node is None:
printf("FAIL: Compare creation\n")
failed += 1
else:
passed += 1
printf("PASS: Compare, kind=%d\n", cmp_node.kind())
# --- Test 16: Assign node ---
assign_targets: list[AST*]* = list[AST*](pool, 8)
assign_targets.append(name_x)
assign_node: Assign* = Assign(pool, assign_targets, int_42)
if assign_node is None:
printf("FAIL: Assign creation\n")
failed += 1
else:
passed += 1
printf("PASS: Assign, kind=%d\n", assign_node.kind())
# --- Test 17: Call node ---
call_args: list[AST*]* = list[AST*](pool, 8)
call_args.append(int_42)
call_kwargs: list[AST*]* = list[AST*](pool, 8)
call_node: Call* = Call(pool, name_x, call_args, call_kwargs)
if call_node is None:
printf("FAIL: Call creation\n")
failed += 1
else:
passed += 1
printf("PASS: Call, kind=%d\n", call_node.kind())
# --- Test 18: field access check ---
if name_x is not None:
nm: str = name_x.id
if nm is not None:
if string.strcmp(nm, "x") == 0:
passed += 1
printf("PASS: Name.id == 'x'\n")
else:
failed += 1
printf("FAIL: Name.id != 'x'\n")
else:
failed += 1
printf("FAIL: Name.id is None\n")
# --- Test 19: parent pointer check (binop appended to mod) ---
if binop is not None and binop.parent is mod:
passed += 1
printf("PASS: BinOp.parent == Module (via append)\n")
else:
failed += 1
printf("FAIL: BinOp.parent != Module\n")
# --- Test 20: Module.children traversal ---
if mod is not None and mod.children is not None:
mod_cnt: sizet = mod.children.__len__()
if mod_cnt == 2:
passed += 1
printf("PASS: Module.children count=%zu (expected 2)\n", mod_cnt)
else:
failed += 1
printf("FAIL: Module.children count=%zu (expected 2)\n", mod_cnt)
else:
failed += 1
printf("FAIL: Module.children is None\n")
# --- Test 21: Module.children polymorphic dispatch ---
if mod is not None and mod.children is not None:
c0: AST* = mod.children.get(0)
c1: AST* = mod.children.get(1)
if c0 is not None and c1 is not None:
k0: int = c0.kind()
k1: int = c1.kind()
if k0 == ASTKind.BinOp and k1 == ASTKind.UnaryOp:
passed += 1
printf("PASS: Module.children[0]=BinOp, [1]=UnaryOp\n")
else:
failed += 1
printf("FAIL: Module.children kinds=%d,%d\n", k0, k1)
else:
failed += 1
printf("FAIL: Module.children get returned None\n")
else:
failed += 1
printf("FAIL: Module.children unavailable\n")
# --- Test 22: If.children traversal (ret + expr_stmt) ---
if if_stmt is not None and if_stmt.children is not None:
if_cnt: sizet = if_stmt.children.__len__()
if if_cnt == 2:
passed += 1
printf("PASS: If.children count=%zu (expected 2)\n", if_cnt)
else:
failed += 1
printf("FAIL: If.children count=%zu (expected 2)\n", if_cnt)
else:
failed += 1
printf("FAIL: If.children is None\n")
# --- Test 23: parent upward traversal (child.parent == if_stmt) ---
if if_stmt is not None and if_stmt.children is not None:
first_child: AST* = if_stmt.children.get(0)
if first_child is not None and first_child.parent is if_stmt:
passed += 1
printf("PASS: If.children[0].parent == If\n")
else:
failed += 1
printf("FAIL: If.children[0].parent != If\n")
else:
failed += 1
printf("FAIL: If.children unavailable for parent test\n")
# --- Test 24: parse_expression on "x + 42" ---
expr_src: str = "x + 42"
expr_tree: AST* = parse_expression(expr_src, pool)
if expr_tree is not None:
passed += 1
printf("PASS: parse_expression('x + 42') -> kind=%d\n", expr_tree.kind())
else:
failed += 1
printf("FAIL: parse_expression returned None\n")
# --- Test 25: parse simple module "x = 42" ---
mod_src: str = "x = 42\n"
parsed_mod: Module* = parse(mod_src, pool)
if parsed_mod is not None and parsed_mod.kind() == ASTKind.Module:
passed += 1
printf("PASS: parse('x = 42') -> Module, kind=%d\n", parsed_mod.kind())
else:
failed += 1
printf("FAIL: parse('x = 42') failed\n")
# --- Test 26: parsed module children check ---
if parsed_mod is not None and parsed_mod.children is not None:
pmod_cnt: sizet = parsed_mod.children.__len__()
if pmod_cnt == 1:
passed += 1
printf("PASS: parsed Module.children count=%zu (expected 1)\n", pmod_cnt)
else:
failed += 1
printf("FAIL: parsed Module.children count=%zu (expected 1)\n", pmod_cnt)
else:
failed += 1
printf("FAIL: parsed Module.children is None\n")
# --- Test 27: parsed module child kind check (Assign) ---
if parsed_mod is not None and parsed_mod.children is not None:
pmod_child: AST* = parsed_mod.children.get(0)
if pmod_child is not None:
pmod_k: int = pmod_child.kind()
if pmod_k == ASTKind.Assign:
passed += 1
printf("PASS: parsed Module.children[0].kind()=%d (Assign)\n", pmod_k)
else:
failed += 1
printf("FAIL: parsed Module.children[0].kind()=%d (expected %d)\n",
pmod_k, ASTKind.Assign)
else:
failed += 1
printf("FAIL: parsed Module.children.get(0) returned None\n")
else:
failed += 1
printf("FAIL: parsed Module.children unavailable for kind test\n")
# --- Test 28: parse multi-statement module ---
multi_src: str = """a = 1
b = 2
c = a + b
"""
multi_mod: Module* = parse(multi_src, pool)
if multi_mod is not None and multi_mod.children is not None:
multi_cnt: sizet = multi_mod.children.__len__()
if multi_cnt == 3:
passed += 1
printf("PASS: parse multi-stmt, children=%zu (expected 3)\n", multi_cnt)
else:
failed += 1
printf("FAIL: parse multi-stmt, children=%zu (expected 3)\n", multi_cnt)
else:
failed += 1
printf("FAIL: parse multi-stmt failed\n")
# --- Test 29: parse if statement ---
if_src: str = """if x > 0:
y = 1
"""
if_mod: Module* = parse(if_src, pool)
if if_mod is not None and if_mod.children is not None:
if_cnt2: sizet = if_mod.children.__len__()
if_k: int = if_mod.children.get(0).kind()
if if_cnt2 == 1 and if_k == ASTKind.If:
passed += 1
printf("PASS: parse if, children=%zu kind=%d (If)\n", if_cnt2, if_k)
else:
failed += 1
printf("FAIL: parse if, children=%zu kind=%d\n", if_cnt2, if_k)
else:
failed += 1
printf("FAIL: parse if failed\n")
# --- Test 30: parse for loop ---
for_src: str = """for i in range(10):
pass
"""
for_mod: Module* = parse(for_src, pool)
if for_mod is not None and for_mod.children is not None:
for_cnt: sizet = for_mod.children.__len__()
for_k: int = for_mod.children.get(0).kind()
if for_cnt == 1 and for_k == ASTKind.For:
passed += 1
printf("PASS: parse for, children=%zu kind=%d (For)\n", for_cnt, for_k)
else:
failed += 1
printf("FAIL: parse for, children=%zu kind=%d\n", for_cnt, for_k)
else:
failed += 1
printf("FAIL: parse for failed\n")
# --- Test 31: parse while loop ---
while_src: str = """while x < 100:
x = x + 1
"""
while_mod: Module* = parse(while_src, pool)
if while_mod is not None and while_mod.children is not None:
while_cnt: sizet = while_mod.children.__len__()
while_k: int = while_mod.children.get(0).kind()
if while_cnt == 1 and while_k == ASTKind.While:
passed += 1
printf("PASS: parse while, children=%zu kind=%d (While)\n", while_cnt, while_k)
else:
failed += 1
printf("FAIL: parse while, children=%zu kind=%d\n", while_cnt, while_k)
else:
failed += 1
printf("FAIL: parse while failed\n")
# --- Test 32: parse function definition ---
def_src: str = """def foo(a, b):
return a + b
"""
def_mod: Module* = parse(def_src, pool)
if def_mod is not None and def_mod.children is not None:
def_cnt: sizet = def_mod.children.__len__()
def_k: int = def_mod.children.get(0).kind()
if def_cnt == 1 and def_k == ASTKind.FunctionDef:
passed += 1
printf("PASS: parse def, children=%zu kind=%d (FunctionDef)\n", def_cnt, def_k)
else:
failed += 1
printf("FAIL: parse def, children=%zu kind=%d\n", def_cnt, def_k)
else:
failed += 1
printf("FAIL: parse def failed\n")
# --- Test 33: parse complex expression (a + b * c - 1) ---
complex_expr_src: str = "a + b * c - 1"
complex_expr: AST* = parse_expression(complex_expr_src, pool)
if complex_expr is not None:
ce_k: int = complex_expr.kind()
if ce_k == ASTKind.Expression:
passed += 1
printf("PASS: parse complex expr, kind=%d (Expression)\n", ce_k)
else:
failed += 1
printf("FAIL: parse complex expr, kind=%d\n", ce_k)
else:
failed += 1
printf("FAIL: parse complex expr failed\n")
# --- Test 34: parse nested statement (if inside for) ---
nested_src: str = """for i in range(10):
if i > 5:
x = 1
"""
nested_mod: Module* = parse(nested_src, pool)
if nested_mod is not None and nested_mod.children is not None:
nested_cnt: sizet = nested_mod.children.__len__()
nested_k: int = nested_mod.children.get(0).kind()
if nested_cnt == 1 and nested_k == ASTKind.For:
passed += 1
printf("PASS: parse nested for-if, children=%zu kind=%d (For)\n", nested_cnt, nested_k)
else:
failed += 1
printf("FAIL: parse nested for-if, children=%zu kind=%d\n", nested_cnt, nested_k)
else:
failed += 1
printf("FAIL: parse nested for-if failed\n")
# --- Test 35: parse mixed multi-statement module ---
mixed_src: str = """x = 1
y = 2
if x < y:
z = x + y
else:
z = 0
w = z * 2
"""
mixed_mod: Module* = parse(mixed_src, pool)
if mixed_mod is not None and mixed_mod.children is not None:
mixed_cnt: sizet = mixed_mod.children.__len__()
if mixed_cnt == 4:
passed += 1
printf("PASS: parse mixed module, children=%zu (expected 4)\n", mixed_cnt)
else:
failed += 1
printf("FAIL: parse mixed module, children=%zu (expected 4)\n", mixed_cnt)
else:
failed += 1
printf("FAIL: parse mixed module failed\n")
# --- Test 36: dump round-trip - parse("x = 42") then strstr check ---
if parsed_mod is not None:
dump(parsed_mod, dump_buf, DUMP_BUF_SIZE)
has_assign: str = string.strstr(dump_buf, "Assign")
has_42: str = string.strstr(dump_buf, "42")
if has_assign is not None and has_42 is not None:
passed += 1
printf("PASS: dump parse('x = 42') contains 'Assign' and '42'\n")
else:
failed += 1
printf("FAIL: dump parse('x = 42') missing tokens\n")
else:
failed += 1
printf("FAIL: parsed_mod unavailable for dump test\n")
# --- Test 37: dump round-trip - complex expr then strstr BinOp ---
if complex_expr is not None:
dump(complex_expr, dump_buf, DUMP_BUF_SIZE)
has_binop: str = string.strstr(dump_buf, "BinOp")
if has_binop is not None:
passed += 1
printf("PASS: dump complex expr contains 'BinOp'\n")
else:
failed += 1
printf("FAIL: dump complex expr missing 'BinOp'\n")
else:
failed += 1
printf("FAIL: complex_expr unavailable for dump test\n")
# --- Test 38: dump round-trip - parse if then strstr If/Compare ---
if if_mod is not None:
dump(if_mod, dump_buf, DUMP_BUF_SIZE)
has_if: str = string.strstr(dump_buf, "If(")
has_cmp: str = string.strstr(dump_buf, "Compare")
if has_if is not None and has_cmp is not None:
passed += 1
printf("PASS: dump parse if contains 'If(' and 'Compare'\n")
else:
failed += 1
printf("FAIL: dump parse if missing tokens\n")
else:
failed += 1
printf("FAIL: if_mod unavailable for dump test\n")
# --- Test 39: dump round-trip - parse def then strstr FunctionDef ---
if def_mod is not None:
dump(def_mod, dump_buf, DUMP_BUF_SIZE)
has_fdef: str = string.strstr(dump_buf, "FunctionDef")
if has_fdef is not None:
passed += 1
printf("PASS: dump parse def contains 'FunctionDef'\n")
else:
failed += 1
printf("FAIL: dump parse def missing 'FunctionDef'\n")
else:
failed += 1
printf("FAIL: def_mod unavailable for dump test\n")
# --- Test 40: structured dump of multi-statement module ---
if mixed_mod is not None:
dump(mixed_mod, dump_buf, DUMP_BUF_SIZE)
printf("--- AST dump of mixed module ---\n%s\n--- end dump ---\n", dump_buf)
# Check multiple node kinds present
has_m_assign: str = string.strstr(dump_buf, "Assign")
has_m_if: str = string.strstr(dump_buf, "If(")
if has_m_assign is not None and has_m_if is not None:
passed += 1
printf("PASS: structured dump of mixed module contains Assign + If\n")
else:
failed += 1
printf("FAIL: structured dump of mixed module missing nodes\n")
else:
failed += 1
printf("FAIL: mixed_mod unavailable for structured dump\n")
# --- Test 41: structured dump of for loop ---
if for_mod is not None:
dump(for_mod, dump_buf, DUMP_BUF_SIZE)
printf("--- AST dump of for loop ---\n%s\n--- end dump ---\n", dump_buf)
has_for: str = string.strstr(dump_buf, "For(")
if has_for is not None:
passed += 1
printf("PASS: structured dump of for loop contains 'For('\n")
else:
failed += 1
printf("FAIL: structured dump of for loop missing 'For('\n")
else:
failed += 1
printf("FAIL: for_mod unavailable for structured dump\n")
# --- Test 42: type_name polymorphic dispatch check ---
if parsed_mod is not None and parsed_mod.children is not None:
tn_node: AST* = parsed_mod.children.get(0)
if tn_node is not None:
tn: str = tn_node.type_name()
if tn is not None and string.strcmp(tn, "Assign") == 0:
passed += 1
printf("PASS: type_name() = 'Assign' (polymorphic)\n")
else:
failed += 1
printf("FAIL: type_name() != 'Assign'\n")
else:
failed += 1
printf("FAIL: type_name test node None\n")
else:
failed += 1
printf("FAIL: parsed_mod unavailable for type_name test\n")
# --- Test 43: parse class definition ---
class_src: str = """class Foo(Base):
x = 1
def bar(self):
return self.x
"""
class_mod: Module* = parse(class_src, pool)
if class_mod is not None and class_mod.children is not None:
class_cnt: sizet = class_mod.children.__len__()
class_k: int = class_mod.children.get(0).kind()
if class_cnt == 1 and class_k == ASTKind.ClassDef:
passed += 1
printf("PASS: parse class, children=%zu kind=%d (ClassDef)\n", class_cnt, class_k)
else:
failed += 1
printf("FAIL: parse class, children=%zu kind=%d\n", class_cnt, class_k)
else:
failed += 1
printf("FAIL: parse class failed\n")
# --- Test 44: parse try/except ---
try_src: str = """try:
x = 1
except:
x = 0
"""
try_mod: Module* = parse(try_src, pool)
if try_mod is not None and try_mod.children is not None:
try_cnt: sizet = try_mod.children.__len__()
try_k: int = try_mod.children.get(0).kind()
if try_cnt == 1 and try_k == ASTKind.Try:
passed += 1
printf("PASS: parse try/except, children=%zu kind=%d (Try)\n", try_cnt, try_k)
else:
failed += 1
printf("FAIL: parse try/except, children=%zu kind=%d\n", try_cnt, try_k)
else:
failed += 1
printf("FAIL: parse try/except failed\n")
# --- Test 45: parse import statement ---
import_src: str = """import os
from sys import path
"""
import_mod: Module* = parse(import_src, pool)
if import_mod is not None and import_mod.children is not None:
import_cnt: sizet = import_mod.children.__len__()
k0: int = import_mod.children.get(0).kind()
k1: int = import_mod.children.get(1).kind()
if import_cnt == 2 and k0 == ASTKind.Import and k1 == ASTKind.ImportFrom:
passed += 1
printf("PASS: parse import, children=%zu k0=%d(Import) k1=%d(ImportFrom)\n",
import_cnt, k0, k1)
else:
failed += 1
printf("FAIL: parse import, children=%zu k0=%d k1=%d\n", import_cnt, k0, k1)
else:
failed += 1
printf("FAIL: parse import failed\n")
# --- Test 46: parse AugAssign (x += 1) ---
aug_src: str = """x = 0
x += 1
"""
aug_mod: Module* = parse(aug_src, pool)
if aug_mod is not None and aug_mod.children is not None:
aug_cnt: sizet = aug_mod.children.__len__()
aug_k: int = aug_mod.children.get(1).kind()
if aug_cnt == 2 and aug_k == ASTKind.AugAssign:
passed += 1
printf("PASS: parse AugAssign, children=%zu kind=%d (AugAssign)\n", aug_cnt, aug_k)
else:
failed += 1
printf("FAIL: parse AugAssign, children=%zu kind=%d\n", aug_cnt, aug_k)
else:
failed += 1
printf("FAIL: parse AugAssign failed\n")
# --- Test 47: parse conditional expression (x if y else z) ---
ifexp_src: str = "x if y else z"
ifexp_tree: AST* = parse_expression(ifexp_src, pool)
ifexp_expr: Expression* = (Expression*)(ifexp_tree)
if ifexp_expr is not None and ifexp_expr.body is not None:
ie_k: int = ifexp_expr.body.kind()
if ie_k == ASTKind.IfExp:
passed += 1
printf("PASS: parse IfExp, kind=%d (IfExp)\n", ie_k)
else:
failed += 1
printf("FAIL: parse IfExp, kind=%d\n", ie_k)
else:
failed += 1
printf("FAIL: parse IfExp failed\n")
# --- Test 48: parse nested function definition ---
nested_def_src: str = """def outer():
x = 1
def inner():
return x
return inner()
"""
nested_def_mod: Module* = parse(nested_def_src, pool)
if nested_def_mod is not None and nested_def_mod.children is not None:
nd_cnt: sizet = nested_def_mod.children.__len__()
nd_k: int = nested_def_mod.children.get(0).kind()
if nd_cnt == 1 and nd_k == ASTKind.FunctionDef:
passed += 1
printf("PASS: parse nested def, children=%zu kind=%d (FunctionDef)\n", nd_cnt, nd_k)
else:
failed += 1
printf("FAIL: parse nested def, children=%zu kind=%d\n", nd_cnt, nd_k)
else:
failed += 1
printf("FAIL: parse nested def failed\n")
# --- Test 49: dump complex code (class + try + nested def) ---
complex_src: str = """class Foo(Base):
x = 1
try:
y = Foo()
except:
y = None
def bar():
return y
"""
complex_mod: Module* = parse(complex_src, pool)
if complex_mod is not None:
dump(complex_mod, dump_buf, DUMP_BUF_SIZE)
printf("--- AST dump of complex module ---\n%s\n--- end dump ---\n", dump_buf)
has_cls: str = string.strstr(dump_buf, "ClassDef")
has_try: str = string.strstr(dump_buf, "Try")
has_fdef2: str = string.strstr(dump_buf, "FunctionDef")
if has_cls is not None and has_try is not None and has_fdef2 is not None:
passed += 1
printf("PASS: dump complex module contains ClassDef + Try + FunctionDef\n")
else:
failed += 1
printf("FAIL: dump complex module missing nodes\n")
else:
failed += 1
printf("FAIL: parse complex module failed\n")
# --- Test 50: complex mixed_src - combined syntax sample ---
complex_mixed_src: str = """def gcd(a, b):
while b:
t = b
b = a % b
a = t
return a
x = gcd(48, 36)
if x > 1 and x < 100:
y = x * 2 + 1
elif x == 1:
y = 1
else:
y = 0
"""
cmix_mod: Module* = parse(complex_mixed_src, pool)
if cmix_mod is not None and cmix_mod.children is not None:
cmix_cnt: sizet = cmix_mod.children.__len__()
dump(cmix_mod, dump_buf, DUMP_BUF_SIZE)
printf("--- AST dump of complex mixed ---\n%s\n--- end dump ---\n", dump_buf)
cm_def: str = string.strstr(dump_buf, "FunctionDef")
cm_while: str = string.strstr(dump_buf, "While(")
cm_call: str = string.strstr(dump_buf, "Call(")
cm_bool: str = string.strstr(dump_buf, "BoolOp(")
cm_cmp: str = string.strstr(dump_buf, "Compare(")
cm_ret: str = string.strstr(dump_buf, "Return(")
ok: int = 0
if cmix_cnt == 3:
if cm_def is not None and cm_while is not None:
if cm_call is not None and cm_bool is not None:
if cm_cmp is not None and cm_ret is not None:
ok = 1
if ok == 1:
passed += 1
printf("PASS: complex mixed_src, children=%zu contains Def+While+Call+BoolOp+Compare+Return\n", cmix_cnt)
else:
failed += 1
printf("FAIL: complex mixed_src, children=%zu def=%d while=%d call=%d bool=%d cmp=%d ret=%d\n",
cmix_cnt, cm_def is not None, cm_while is not None,
cm_call is not None, cm_bool is not None, cm_cmp is not None,
cm_ret is not None)
else:
failed += 1
printf("FAIL: complex mixed_src parse failed\n")
# --- Test 51: Lambda expression ---
lambda_src: str = "f = lambda x: x + 1"
lambda_mod: Module* = parse(lambda_src, pool)
if lambda_mod is not None:
dump(lambda_mod, dump_buf, DUMP_BUF_SIZE)
has_lambda: str = string.strstr(dump_buf, "Lambda(")
has_arg: str = string.strstr(dump_buf, "Arg(arg='x'")
if has_lambda is not None and has_arg is not None:
passed += 1
printf("PASS: Lambda with arg parsed\n")
else:
failed += 1
printf("FAIL: Lambda parse, lambda=%d arg=%d\n",
has_lambda is not None, has_arg is not None)
else:
failed += 1
printf("FAIL: Lambda parse returned None\n")
# --- Test 52: List comprehension ---
listcomp_src: str = "squares = [x*x for x in range(10)]"
lc_mod: Module* = parse(listcomp_src, pool)
if lc_mod is not None:
dump(lc_mod, dump_buf, DUMP_BUF_SIZE)
has_lc: str = string.strstr(dump_buf, "ListComp(")
has_comp: str = string.strstr(dump_buf, "Comprehension(")
if has_lc is not None and has_comp is not None:
passed += 1
printf("PASS: ListComp with Comprehension parsed\n")
else:
failed += 1
printf("FAIL: ListComp parse, lc=%d comp=%d\n",
has_lc is not None, has_comp is not None)
else:
failed += 1
printf("FAIL: ListComp parse returned None\n")
# --- Test 53: Dict comprehension ---
dictcomp_src: str = "d = {k: v for k, v in items}"
dc_mod: Module* = parse(dictcomp_src, pool)
if dc_mod is not None:
dump(dc_mod, dump_buf, DUMP_BUF_SIZE)
has_dc: str = string.strstr(dump_buf, "DictComp(")
if has_dc is not None:
passed += 1
printf("PASS: DictComp parsed\n")
else:
failed += 1
printf("FAIL: DictComp parse, dc=%d\n", has_dc is not None)
else:
failed += 1
printf("FAIL: DictComp parse returned None\n")
# --- Test 54: Set comprehension ---
setcomp_src: str = "s = {x for x in items}"
sc_mod: Module* = parse(setcomp_src, pool)
if sc_mod is not None:
dump(sc_mod, dump_buf, DUMP_BUF_SIZE)
has_sc: str = string.strstr(dump_buf, "SetComp(")
if has_sc is not None:
passed += 1
printf("PASS: SetComp parsed\n")
else:
failed += 1
printf("FAIL: SetComp parse, sc=%d\n", has_sc is not None)
else:
failed += 1
printf("FAIL: SetComp parse returned None\n")
# --- Test 55: With statement ---
with_src: str = """with open('f') as f:
data = f.read()
"""
with_mod: Module* = parse(with_src, pool)
if with_mod is not None and with_mod.children is not None:
dump(with_mod, dump_buf, DUMP_BUF_SIZE)
has_with: str = string.strstr(dump_buf, "With(")
has_witem: str = string.strstr(dump_buf, "WithItem(")
if has_with is not None and has_witem is not None:
passed += 1
printf("PASS: With + WithItem parsed\n")
else:
failed += 1
printf("FAIL: With parse, with=%d witem=%d\n",
has_with is not None, has_witem is not None)
else:
failed += 1
printf("FAIL: With parse returned None\n")
# --- Test 56: Raise statement ---
raise_src: str = "raise ValueError('bad')"
raise_mod: Module* = parse(raise_src, pool)
if raise_mod is not None:
dump(raise_mod, dump_buf, DUMP_BUF_SIZE)
has_raise: str = string.strstr(dump_buf, "Raise(")
if has_raise is not None:
passed += 1
printf("PASS: Raise parsed\n")
else:
failed += 1
printf("FAIL: Raise parse, raise=%d\n", has_raise is not None)
else:
failed += 1
printf("FAIL: Raise parse returned None\n")
# --- Test 57: Assert statement ---
assert_src: str = "assert x > 0, 'x must be positive'"
assert_mod: Module* = parse(assert_src, pool)
if assert_mod is not None:
dump(assert_mod, dump_buf, DUMP_BUF_SIZE)
has_assert: str = string.strstr(dump_buf, "Assert(")
if has_assert is not None:
passed += 1
printf("PASS: Assert parsed\n")
else:
failed += 1
printf("FAIL: Assert parse, assert=%d\n", has_assert is not None)
else:
failed += 1
printf("FAIL: Assert parse returned None\n")
# --- Test 58: Del statement ---
del_src: str = "del x"
del_mod: Module* = parse(del_src, pool)
if del_mod is not None:
dump(del_mod, dump_buf, DUMP_BUF_SIZE)
has_del: str = string.strstr(dump_buf, "Delete(")
if has_del is not None:
passed += 1
printf("PASS: Delete parsed\n")
else:
failed += 1
printf("FAIL: Delete parse, del=%d\n", has_del is not None)
else:
failed += 1
printf("FAIL: Delete parse returned None\n")
# --- Test 59: Subscript + Slice ---
slice_src: str = "y = a[1:3]"
slice_mod: Module* = parse(slice_src, pool)
if slice_mod is not None:
dump(slice_mod, dump_buf, DUMP_BUF_SIZE)
has_sub: str = string.strstr(dump_buf, "Subscript(")
has_slice: str = string.strstr(dump_buf, "Slice(")
if has_sub is not None and has_slice is not None:
passed += 1
printf("PASS: Subscript + Slice parsed\n")
else:
failed += 1
printf("FAIL: Slice parse, sub=%d slice=%d\n",
has_sub is not None, has_slice is not None)
else:
failed += 1
printf("FAIL: Slice parse returned None\n")
# --- Test 60: Tuple unpacking ---
tuple_src: str = "a, b = 1, 2"
tuple_mod: Module* = parse(tuple_src, pool)
if tuple_mod is not None:
dump(tuple_mod, dump_buf, DUMP_BUF_SIZE)
has_tuple: str = string.strstr(dump_buf, "Tuple(")
if has_tuple is not None:
passed += 1
printf("PASS: Tuple unpacking parsed\n")
else:
failed += 1
printf("FAIL: Tuple parse, tuple=%d\n", has_tuple is not None)
else:
failed += 1
printf("FAIL: Tuple parse returned None\n")
# --- Test 61: default args + keyword args signature ---
defdef_src: str = "def f(a, b=10): return a + b"
defdef_mod: Module* = parse(defdef_src, pool)
if defdef_mod is not None:
dump(defdef_mod, dump_buf, DUMP_BUF_SIZE)
has_fdef: str = string.strstr(dump_buf, "FunctionDef(name='f'")
has_def: str = string.strstr(dump_buf, "Constant(value=10)")
if has_fdef is not None and has_def is not None:
passed += 1
printf("PASS: FunctionDef with default arg parsed\n")
else:
failed += 1
printf("FAIL: defdef parse, fdef=%d def=%d\n",
has_fdef is not None, has_def is not None)
else:
failed += 1
printf("FAIL: defdef parse returned None\n")
# --- Test 62: decorator ---
deco_src: str = """@my_dec
def f():
pass
"""
deco_mod: Module* = parse(deco_src, pool)
if deco_mod is not None:
dump(deco_mod, dump_buf, DUMP_BUF_SIZE)
has_dec: str = string.strstr(dump_buf, "decorator_list=[Name(id='my_dec'")
if has_dec is not None:
passed += 1
printf("PASS: Decorator parsed\n")
else:
failed += 1
printf("FAIL: Decorator parse, dec=%d\n", has_dec is not None)
else:
failed += 1
printf("FAIL: Decorator parse returned None\n")
# --- Test 63: chained assignment ---
chain_src: str = "a = b = c = 42"
chain_mod: Module* = parse(chain_src, pool)
if chain_mod is not None:
dump(chain_mod, dump_buf, DUMP_BUF_SIZE)
has_chain: str = string.strstr(dump_buf, "Assign(targets=[Name(id='a'")
has_b: str = string.strstr(dump_buf, "Name(id='b'")
has_c: str = string.strstr(dump_buf, "Name(id='c'")
if has_chain is not None and has_b is not None and has_c is not None:
passed += 1
printf("PASS: Chain assignment a=b=c=42 parsed\n")
else:
failed += 1
printf("FAIL: Chain, a=%d b=%d c=%d\n",
has_chain is not None, has_b is not None, has_c is not None)
else:
failed += 1
printf("FAIL: Chain parse returned None\n")
# --- Test 64: bitwise ops ---
bit_src: str = "y = (a | b) & c ^ d << 2"
bit_mod: Module* = parse(bit_src, pool)
if bit_mod is not None:
dump(bit_mod, dump_buf, DUMP_BUF_SIZE)
has_bor: str = string.strstr(dump_buf, "op=BitOr")
has_band: str = string.strstr(dump_buf, "op=BitAnd")
has_bxor: str = string.strstr(dump_buf, "op=BitXor")
if has_bor is not None and has_band is not None and has_bxor is not None:
passed += 1
printf("PASS: Bit ops (| & ^) parsed\n")
else:
failed += 1
printf("FAIL: Bit ops, bor=%d band=%d bxor=%d\n",
has_bor is not None, has_band is not None, has_bxor is not None)
else:
failed += 1
printf("FAIL: Bit ops parse returned None\n")
# --- Test 65: multiple inheritance + decorators ---
multi_src: str = """@dec1
@dec2
class C(Base1, Base2):
pass
"""
multi_mod: Module* = parse(multi_src, pool)
if multi_mod is not None:
dump(multi_mod, dump_buf, DUMP_BUF_SIZE)
m_dec1: str = string.strstr(dump_buf, "Name(id='dec1'")
m_dec2: str = string.strstr(dump_buf, "Name(id='dec2'")
m_b1: str = string.strstr(dump_buf, "Name(id='Base1'")
m_b2: str = string.strstr(dump_buf, "Name(id='Base2'")
if m_dec1 is not None and m_dec2 is not None and m_b1 is not None and m_b2 is not None:
passed += 1
printf("PASS: Multi-decorator + multi-inheritance parsed\n")
else:
failed += 1
printf("FAIL: multi, dec1=%d dec2=%d b1=%d b2=%d\n",
m_dec1 is not None, m_dec2 is not None,
m_b1 is not None, m_b2 is not None)
else:
failed += 1
printf("FAIL: multi parse returned None\n")
# --- Test 66: Global / Nonlocal ---
glob_src: str = """def f():
global x
x = 1
"""
glob_mod: Module* = parse(glob_src, pool)
if glob_mod is not None:
dump(glob_mod, dump_buf, DUMP_BUF_SIZE)
has_glob: str = string.strstr(dump_buf, "Global(")
if has_glob is not None:
passed += 1
printf("PASS: Global statement parsed\n")
else:
failed += 1
printf("FAIL: Global parse, glob=%d\n", has_glob is not None)
else:
failed += 1
printf("FAIL: Global parse returned None\n")
# --- Test 67: f-string (FormattedValue) ---
fstr_src: str = "s = f'value={x}'"
fstr_mod: Module* = parse(fstr_src, pool)
if fstr_mod is not None:
dump(fstr_mod, dump_buf, DUMP_BUF_SIZE)
has_fv: str = string.strstr(dump_buf, "FormattedValue(")
has_js: str = string.strstr(dump_buf, "JoinedStr(")
if has_fv is not None and has_js is not None:
passed += 1
printf("PASS: f-string with FormattedValue + JoinedStr parsed\n")
else:
failed += 1
printf("FAIL: fstring, fv=%d js=%d\n",
has_fv is not None, has_js is not None)
else:
failed += 1
printf("FAIL: fstring parse returned None\n")
# --- Test 68: nested function + closure ---
nested_src: str = """def outer():
x = 10
def inner():
return x + 1
return inner()
"""
nested_mod: Module* = parse(nested_src, pool)
if nested_mod is not None and nested_mod.children is not None:
dump(nested_mod, dump_buf, DUMP_BUF_SIZE)
n_outer: str = string.strstr(dump_buf, "FunctionDef(name='outer'")
n_inner: str = string.strstr(dump_buf, "FunctionDef(name='inner'")
if n_outer is not None and n_inner is not None:
passed += 1
printf("PASS: Nested function definitions parsed\n")
else:
failed += 1
printf("FAIL: nested, outer=%d inner=%d\n",
n_outer is not None, n_inner is not None)
else:
failed += 1
printf("FAIL: nested parse returned None\n")
# --- Test 69: Match literal int pattern ---
m_lit_src: str = """match x:
case 1:
pass
"""
m_lit_mod: Module* = parse(m_lit_src, pool)
if m_lit_mod is not None:
dump(m_lit_mod, dump_buf, DUMP_BUF_SIZE)
has_mv: str = string.strstr(dump_buf, "MatchValue(")
if has_mv is not None:
passed += 1
printf("PASS: Match literal int -> MatchValue\n")
else:
failed += 1
printf("FAIL: Match literal int, mv=%d\n", has_mv is not None)
else:
failed += 1
printf("FAIL: Match literal int parse returned None\n")
# --- Test 70: Match literal string pattern ---
m_str_src: str = """match x:
case "hello":
pass
"""
m_str_mod: Module* = parse(m_str_src, pool)
if m_str_mod is not None:
dump(m_str_mod, dump_buf, DUMP_BUF_SIZE)
has_mv2: str = string.strstr(dump_buf, "MatchValue(")
if has_mv2 is not None:
passed += 1
printf("PASS: Match literal str -> MatchValue\n")
else:
failed += 1
printf("FAIL: Match literal str\n")
else:
failed += 1
printf("FAIL: Match literal str parse returned None\n")
# --- Test 71: Match negative literal pattern ---
m_neg_src: str = """match x:
case -1:
pass
"""
m_neg_mod: Module* = parse(m_neg_src, pool)
if m_neg_mod is not None:
dump(m_neg_mod, dump_buf, DUMP_BUF_SIZE)
has_mv3: str = string.strstr(dump_buf, "MatchValue(")
if has_mv3 is not None:
passed += 1
printf("PASS: Match negative literal -> MatchValue\n")
else:
failed += 1
printf("FAIL: Match negative literal\n")
else:
failed += 1
printf("FAIL: Match negative literal parse returned None\n")
# --- Test 72: Match None singleton pattern ---
m_none_src: str = """match x:
case None:
pass
"""
m_none_mod: Module* = parse(m_none_src, pool)
if m_none_mod is not None:
dump(m_none_mod, dump_buf, DUMP_BUF_SIZE)
has_ms: str = string.strstr(dump_buf, "MatchSingleton(")
if has_ms is not None:
passed += 1
printf("PASS: Match None -> MatchSingleton\n")
else:
failed += 1
printf("FAIL: Match None, ms=%d\n", has_ms is not None)
else:
failed += 1
printf("FAIL: Match None parse returned None\n")
# --- Test 73: Match True singleton pattern ---
m_true_src: str = """match x:
case True:
pass
"""
m_true_mod: Module* = parse(m_true_src, pool)
if m_true_mod is not None:
dump(m_true_mod, dump_buf, DUMP_BUF_SIZE)
has_ms2: str = string.strstr(dump_buf, "MatchSingleton(")
if has_ms2 is not None:
passed += 1
printf("PASS: Match True -> MatchSingleton\n")
else:
failed += 1
printf("FAIL: Match True\n")
else:
failed += 1
printf("FAIL: Match True parse returned None\n")
# --- Test 74: Match False singleton pattern ---
m_false_src: str = """match x:
case False:
pass
"""
m_false_mod: Module* = parse(m_false_src, pool)
if m_false_mod is not None:
dump(m_false_mod, dump_buf, DUMP_BUF_SIZE)
has_ms3: str = string.strstr(dump_buf, "MatchSingleton(")
if has_ms3 is not None:
passed += 1
printf("PASS: Match False -> MatchSingleton\n")
else:
failed += 1
printf("FAIL: Match False\n")
else:
failed += 1
printf("FAIL: Match False parse returned None\n")
# --- Test 75: Match wildcard _ pattern ---
m_wild_src: str = """match x:
case _:
pass
"""
m_wild_mod: Module* = parse(m_wild_src, pool)
if m_wild_mod is not None:
dump(m_wild_mod, dump_buf, DUMP_BUF_SIZE)
has_ma: str = string.strstr(dump_buf, "MatchAs(")
if has_ma is not None:
passed += 1
printf("PASS: Match wildcard _ -> MatchAs\n")
else:
failed += 1
printf("FAIL: Match wildcard, ma=%d\n", has_ma is not None)
else:
failed += 1
printf("FAIL: Match wildcard parse returned None\n")
# --- Test 76: Match capture variable pattern ---
m_cap_src: str = """match x:
case y:
pass
"""
m_cap_mod: Module* = parse(m_cap_src, pool)
if m_cap_mod is not None:
dump(m_cap_mod, dump_buf, DUMP_BUF_SIZE)
has_ma2: str = string.strstr(dump_buf, "name='y'")
if has_ma2 is not None:
passed += 1
printf("PASS: Match capture y -> MatchAs(name='y')\n")
else:
failed += 1
printf("FAIL: Match capture, ma=%d\n", has_ma2 is not None)
else:
failed += 1
printf("FAIL: Match capture parse returned None\n")
# --- Test 77: Match value pattern (dotted name Color.RED) ---
m_val_src: str = """match x:
case Color.RED:
pass
"""
m_val_mod: Module* = parse(m_val_src, pool)
if m_val_mod is not None:
dump(m_val_mod, dump_buf, DUMP_BUF_SIZE)
has_mv4: str = string.strstr(dump_buf, "MatchValue(")
has_attr: str = string.strstr(dump_buf, "Attribute(")
if has_mv4 is not None and has_attr is not None:
passed += 1
printf("PASS: Match Color.RED -> MatchValue + Attribute\n")
else:
failed += 1
printf("FAIL: Match value, mv=%d attr=%d\n",
has_mv4 is not None, has_attr is not None)
else:
failed += 1
printf("FAIL: Match value parse returned None\n")
# --- Test 78: Match sequence pattern [1, 2] ---
m_seq_src: str = """match x:
case [1, 2]:
pass
"""
m_seq_mod: Module* = parse(m_seq_src, pool)
if m_seq_mod is not None:
dump(m_seq_mod, dump_buf, DUMP_BUF_SIZE)
has_msq: str = string.strstr(dump_buf, "MatchSequence(")
if has_msq is not None:
passed += 1
printf("PASS: Match [1, 2] -> MatchSequence\n")
else:
failed += 1
printf("FAIL: Match sequence, msq=%d\n", has_msq is not None)
else:
failed += 1
printf("FAIL: Match sequence parse returned None\n")
# --- Test 79: Match starred sequence [a, *rest] ---
m_star_src: str = """match x:
case [a, *rest]:
pass
"""
m_star_mod: Module* = parse(m_star_src, pool)
if m_star_mod is not None:
dump(m_star_mod, dump_buf, DUMP_BUF_SIZE)
has_mstar: str = string.strstr(dump_buf, "MatchStar(name='rest')")
if has_mstar is not None:
passed += 1
printf("PASS: Match [a, *rest] -> MatchStar\n")
else:
failed += 1
printf("FAIL: Match star, mstar=%d\n", has_mstar is not None)
else:
failed += 1
printf("FAIL: Match star parse returned None\n")
# --- Test 80: Match class pattern Point(x, y) ---
m_cls_src: str = """match p:
case Point(x, y):
pass
"""
m_cls_mod: Module* = parse(m_cls_src, pool)
if m_cls_mod is not None:
dump(m_cls_mod, dump_buf, DUMP_BUF_SIZE)
has_mc: str = string.strstr(dump_buf, "MatchClass(")
if has_mc is not None:
passed += 1
printf("PASS: Match Point(x, y) -> MatchClass\n")
else:
failed += 1
printf("FAIL: Match class, mc=%d\n", has_mc is not None)
else:
failed += 1
printf("FAIL: Match class parse returned None\n")
# --- Test 81: Match keyword class pattern Point(x=0, y=0) ---
m_kwcls_src: str = """match p:
case Point(x=0, y=0):
pass
"""
m_kwcls_mod: Module* = parse(m_kwcls_src, pool)
if m_kwcls_mod is not None:
dump(m_kwcls_mod, dump_buf, DUMP_BUF_SIZE)
has_mc2: str = string.strstr(dump_buf, "MatchClass(")
if has_mc2 is not None:
passed += 1
printf("PASS: Match Point(x=0, y=0) -> MatchClass with kwd\n")
else:
failed += 1
printf("FAIL: Match class kwd, mc=%d\n", has_mc2 is not None)
else:
failed += 1
printf("FAIL: Match class kwd parse returned None\n")
# --- Test 82: Match OR pattern 1 | 2 ---
m_or_src: str = """match x:
case 1 | 2:
pass
"""
m_or_mod: Module* = parse(m_or_src, pool)
if m_or_mod is not None:
dump(m_or_mod, dump_buf, DUMP_BUF_SIZE)
has_mo: str = string.strstr(dump_buf, "MatchOr(")
if has_mo is not None:
passed += 1
printf("PASS: Match 1 | 2 -> MatchOr\n")
else:
failed += 1
printf("FAIL: Match OR, mo=%d\n", has_mo is not None)
else:
failed += 1
printf("FAIL: Match OR parse returned None\n")
# --- Test 83: Match AS pattern [x] as p ---
m_as_src: str = """match x:
case [x] as p:
pass
"""
m_as_mod: Module* = parse(m_as_src, pool)
if m_as_mod is not None:
dump(m_as_mod, dump_buf, DUMP_BUF_SIZE)
has_mas: str = string.strstr(dump_buf, "MatchAs(pattern=")
has_msq2: str = string.strstr(dump_buf, "MatchSequence(")
if has_mas is not None and has_msq2 is not None:
passed += 1
printf("PASS: Match [x] as p -> MatchAs(MatchSequence)\n")
else:
failed += 1
printf("FAIL: Match AS, mas=%d msq=%d\n",
has_mas is not None, has_msq2 is not None)
else:
failed += 1
printf("FAIL: Match AS parse returned None\n")
# --- Test 84: Match guard pattern case x if x > 0 ---
m_guard_src: str = """match x:
case x if x > 0:
pass
"""
m_guard_mod: Module* = parse(m_guard_src, pool)
if m_guard_mod is not None:
dump(m_guard_mod, dump_buf, DUMP_BUF_SIZE)
has_guard: str = string.strstr(dump_buf, "guard=Compare(")
if has_guard is not None:
passed += 1
printf("PASS: Match x if x > 0 -> guard=Compare\n")
else:
failed += 1
printf("FAIL: Match guard, guard=%d\n", has_guard is not None)
else:
failed += 1
printf("FAIL: Match guard parse returned None\n")
# --- Test 85: Match mapping pattern {"k": v} ---
m_map_src: str = """match x:
case {"k": v}:
pass
"""
m_map_mod: Module* = parse(m_map_src, pool)
if m_map_mod is not None:
dump(m_map_mod, dump_buf, DUMP_BUF_SIZE)
has_mm: str = string.strstr(dump_buf, "MatchMapping(")
if has_mm is not None:
passed += 1
printf("PASS: Match {'k': v} -> MatchMapping\n")
else:
failed += 1
printf("FAIL: Match mapping, mm=%d\n", has_mm is not None)
else:
failed += 1
printf("FAIL: Match mapping parse returned None\n")
# --- Test 86: Match mapping with rest {"k": v, **rest} ---
m_map2_src: str = """match x:
case {"k": v, **rest}:
pass
"""
m_map2_mod: Module* = parse(m_map2_src, pool)
if m_map2_mod is not None:
dump(m_map2_mod, dump_buf, DUMP_BUF_SIZE)
has_mm2: str = string.strstr(dump_buf, "MatchMapping(")
has_rest: str = string.strstr(dump_buf, "rest='rest'")
if has_mm2 is not None and has_rest is not None:
passed += 1
printf("PASS: Match {'k': v, **rest} -> MatchMapping with rest\n")
else:
failed += 1
printf("FAIL: Match mapping rest, mm=%d rest=%d\n",
has_mm2 is not None, has_rest is not None)
else:
failed += 1
printf("FAIL: Match mapping rest parse returned None\n")
# --- Test 87: Match combined pattern (1 | 2) as p ---
m_combo_src: str = """match x:
case (1 | 2) as p:
pass
"""
m_combo_mod: Module* = parse(m_combo_src, pool)
if m_combo_mod is not None:
dump(m_combo_mod, dump_buf, DUMP_BUF_SIZE)
has_combo_or: str = string.strstr(dump_buf, "MatchOr(")
has_combo_as: str = string.strstr(dump_buf, "MatchAs(")
if has_combo_or is not None and has_combo_as is not None:
passed += 1
printf("PASS: Match (1|2) as p -> MatchAs(MatchOr)\n")
else:
failed += 1
printf("FAIL: Match combo, or=%d as=%d\n",
has_combo_or is not None, has_combo_as is not None)
else:
failed += 1
printf("FAIL: Match combo parse returned None\n")
# --- Test 88: async def ---
adef_src: str = """async def f():
pass
"""
adef_mod: Module* = parse(adef_src, pool)
if adef_mod is not None and adef_mod.children is not None:
adef_cnt: sizet = adef_mod.children.__len__()
if adef_cnt == 1:
adef_child: AST* = adef_mod.children.get(0)
if adef_child is not None and adef_child.kind() == ASTKind.FunctionDef:
adef_fd: FunctionDef* = (FunctionDef*)(adef_child)
if (adef_fd.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async def f() -> FunctionDef with FLAG_IS_ASYNC\n")
else:
failed += 1
printf("FAIL: async def flags=%d (no FLAG_IS_ASYNC)\n", adef_fd.flags)
else:
failed += 1
printf("FAIL: async def child kind=%d\n",
adef_child.kind() if adef_child is not None else -1)
else:
failed += 1
printf("FAIL: async def children=%zu (expected 1)\n", adef_cnt)
else:
failed += 1
printf("FAIL: async def parse returned None\n")
# --- Test 89: async for (inside async def) ---
afor_src: str = """async def f():
async for x in y:
pass
"""
afor_mod: Module* = parse(afor_src, pool)
if afor_mod is not None and afor_mod.children is not None:
afor_cnt: sizet = afor_mod.children.__len__()
if afor_cnt == 1:
afor_child: AST* = afor_mod.children.get(0)
if afor_child is not None and afor_child.kind() == ASTKind.FunctionDef:
afor_fd2: FunctionDef* = (FunctionDef*)(afor_child)
if (afor_fd2.flags & FLAG_IS_ASYNC) != 0:
if afor_fd2.children is not None:
afor_inner: AST* = afor_fd2.children.get(0)
if afor_inner is not None and afor_inner.kind() == ASTKind.For:
afor_for: For* = (For*)(afor_inner)
if (afor_for.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async for -> For with FLAG_IS_ASYNC\n")
else:
failed += 1
printf("FAIL: async for flags=%d\n", afor_for.flags)
else:
failed += 1
printf("FAIL: async for inner kind=%d\n",
afor_inner.kind() if afor_inner is not None else -1)
else:
failed += 1
printf("FAIL: async for no children\n")
else:
failed += 1
printf("FAIL: async for outer def flags=%d\n", afor_fd2.flags)
else:
failed += 1
printf("FAIL: async for outer kind=%d\n",
afor_child.kind() if afor_child is not None else -1)
else:
failed += 1
printf("FAIL: async for children=%zu\n", afor_cnt)
else:
failed += 1
printf("FAIL: async for parse returned None\n")
# --- Test 90: async with (inside async def) ---
awith_src: str = """async def f():
async with ctx:
pass
"""
awith_mod: Module* = parse(awith_src, pool)
if awith_mod is not None and awith_mod.children is not None:
awith_cnt: sizet = awith_mod.children.__len__()
if awith_cnt == 1:
awith_child: AST* = awith_mod.children.get(0)
if awith_child is not None and awith_child.kind() == ASTKind.FunctionDef:
awith_fd: FunctionDef* = (FunctionDef*)(awith_child)
if (awith_fd.flags & FLAG_IS_ASYNC) != 0:
if awith_fd.children is not None:
awith_inner: AST* = awith_fd.children.get(0)
if awith_inner is not None and awith_inner.kind() == ASTKind.With:
awith_w: With* = (With*)(awith_inner)
if (awith_w.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async with -> With with FLAG_IS_ASYNC\n")
else:
failed += 1
printf("FAIL: async with flags=%d\n", awith_w.flags)
else:
failed += 1
printf("FAIL: async with inner kind=%d\n",
awith_inner.kind() if awith_inner is not None else -1)
else:
failed += 1
printf("FAIL: async with no children\n")
else:
failed += 1
printf("FAIL: async with outer def flags=%d\n", awith_fd.flags)
else:
failed += 1
printf("FAIL: async with outer kind=%d\n",
awith_child.kind() if awith_child is not None else -1)
else:
failed += 1
printf("FAIL: async with children=%zu\n", awith_cnt)
else:
failed += 1
printf("FAIL: async with parse returned None\n")
# --- Test 91: Match compound statement (multi-case, multi-pattern) ---
m_complex_src: str = """match cmd:
case "quit":
pass
case ["go", dir]:
pass
case Point(x=0, y=0):
pass
case _:
pass
"""
m_complex_mod: Module* = parse(m_complex_src, pool)
if m_complex_mod is not None:
dump(m_complex_mod, dump_buf, DUMP_BUF_SIZE)
has_c_mv: str = string.strstr(dump_buf, "MatchValue(")
has_c_msq: str = string.strstr(dump_buf, "MatchSequence(")
has_c_mc: str = string.strstr(dump_buf, "MatchClass(")
has_c_ma: str = string.strstr(dump_buf, "MatchAs(")
if has_c_mv is not None and has_c_msq is not None and \
has_c_mc is not None and has_c_ma is not None:
passed += 1
printf("PASS: Match complex (4 cases) -> all pattern types\n")
else:
failed += 1
printf("FAIL: Match complex, mv=%d msq=%d mc=%d ma=%d\n",
has_c_mv is not None, has_c_msq is not None,
has_c_mc is not None, has_c_ma is not None)
else:
failed += 1
printf("FAIL: Match complex parse returned None\n")
# --- Test 92: async def + async for + async with combo ---
acombo_src: str = """async def f():
async with ctx:
async for x in y:
pass
"""
acombo_mod: Module* = parse(acombo_src, pool)
if acombo_mod is not None and acombo_mod.children is not None:
acombo_cnt: sizet = acombo_mod.children.__len__()
if acombo_cnt == 1:
acombo_child: AST* = acombo_mod.children.get(0)
if acombo_child is not None and acombo_child.kind() == ASTKind.FunctionDef:
acombo_fd2: FunctionDef* = (FunctionDef*)(acombo_child)
if (acombo_fd2.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async def + async with + async for combo\n")
else:
failed += 1
printf("FAIL: async combo flags=%d\n", acombo_fd2.flags)
else:
failed += 1
printf("FAIL: async combo kind=%d\n",
acombo_child.kind() if acombo_child is not None else -1)
else:
failed += 1
printf("FAIL: async combo children=%zu\n", acombo_cnt)
else:
failed += 1
printf("FAIL: async combo parse returned None\n")
# --- Result summary ---
printf("\n=== Results: %d passed, %d failed ===\n", passed, failed)
stdlib.free(dump_buf)
stdlib.free(arena)
if failed > 0:
return 1
return 0