import t, c
from stdint import *
import memhub
import string
from .base import (
    AST, ASTKind, ASTCtx, OpKind,
    _init_ast, _copy_str, _set_parent_list,
    _emit, _emit_str, _emit_int, _dump_list,
    FLAG_IS_ASYNC,
)


# ============================================================
# Module 节点
# ============================================================

@t.CVTable
class Module(AST):
    """Module(children: list[AST | t.CPtr])"""

    def __new__(self, pool: memhub.MemManager | t.CPtr):
        ptr: Module | t.CPtr = pool.alloc(Module.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Module.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr):
        _init_ast(self, pool, 0, 0)

    def kind(self) -> t.CInt:
        return ASTKind.Module

    def type_name(self) -> str:
        return "Module"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Module(body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Assign 节点
# ============================================================

class Assign(AST):
    """Assign(targets: list[AST | t.CPtr], value: AST)"""
    targets: list[AST | t.CPtr] | t.CPtr
    value:   AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                targets: list[AST | t.CPtr] | t.CPtr, value: AST | t.CPtr):
        ptr: Assign | t.CPtr = pool.alloc(Assign.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Assign.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 targets: list[AST | t.CPtr] | t.CPtr, value: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.targets = targets
        self.value = value
        _set_parent_list(targets, self)

    def kind(self) -> t.CInt:
        return ASTKind.Assign

    def type_name(self) -> str:
        return "Assign"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Assign(targets=")
        pos = _dump_list(self.targets, buf, size, pos)
        pos = _emit(buf, size, pos, ", value=")
        if self.value is not None:
            pos = self.value.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# If 节点
# ============================================================

class If(AST):
    """If(test: AST, orelse: list[AST | t.CPtr])"""
    test:   AST | t.CPtr
    orelse: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                test: AST | t.CPtr,
                orelse: list[AST | t.CPtr] | t.CPtr):
        ptr: If | t.CPtr = pool.alloc(If.__sizeof__())
        if ptr:
            string.memset(ptr, 0, If.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 test: AST | t.CPtr,
                 orelse: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.test = test
        self.orelse = orelse
        _set_parent_list(orelse, self)

    def kind(self) -> t.CInt:
        return ASTKind.If

    def type_name(self) -> str:
        return "If"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "If(test=")
        if self.test is not None:
            pos = self.test.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ", orelse=")
        pos = _dump_list(self.orelse, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# For 节点
# ============================================================

class For(AST):
    """For(target: AST, iter: AST, orelse: list[AST | t.CPtr], is_async: CInt)"""
    target: AST | t.CPtr
    iter:   AST | t.CPtr
    orelse: list[AST | t.CPtr] | t.CPtr
    flags:  t.CInt

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                target: AST | t.CPtr, iter: AST | t.CPtr,
                orelse: list[AST | t.CPtr] | t.CPtr,
                is_async: t.CInt):
        ptr: For | t.CPtr = pool.alloc(For.__sizeof__())
        if ptr:
            string.memset(ptr, 0, For.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 target: AST | t.CPtr, iter: AST | t.CPtr,
                 orelse: list[AST | t.CPtr] | t.CPtr,
                 is_async: t.CInt):
        _init_ast(self, pool, 0, 0)
        self.target = target
        self.iter = iter
        self.orelse = orelse
        if is_async:
            self.flags = FLAG_IS_ASYNC
        else:
            self.flags = 0
        _set_parent_list(orelse, self)

    def kind(self) -> t.CInt:
        return ASTKind.For

    def type_name(self) -> str:
        return "For"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "For(target=")
        if self.target is not None:
            pos = self.target.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", iter=")
        if self.iter is not None:
            pos = self.iter.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# While 节点
# ============================================================

class While(AST):
    """While(test: AST, orelse: list[AST | t.CPtr])"""
    test:   AST | t.CPtr
    orelse: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                test: AST | t.CPtr,
                orelse: list[AST | t.CPtr] | t.CPtr):
        ptr: While | t.CPtr = pool.alloc(While.__sizeof__())
        if ptr:
            string.memset(ptr, 0, While.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 test: AST | t.CPtr,
                 orelse: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.test = test
        self.orelse = orelse
        _set_parent_list(orelse, self)

    def kind(self) -> t.CInt:
        return ASTKind.While

    def type_name(self) -> str:
        return "While"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "While(test=")
        if self.test is not None:
            pos = self.test.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Return 节点
# ============================================================

class Return(AST):
    """Return(value: AST | None)"""
    value: AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr):
        ptr: Return | t.CPtr = pool.alloc(Return.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Return.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.value = value

    def kind(self) -> t.CInt:
        return ASTKind.Return

    def type_name(self) -> str:
        return "Return"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Return(value=")
        if self.value is not None:
            pos = self.value.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Expr 节点（表达式语句）
# ============================================================

class Expr(AST):
    """Expr(value: AST)"""
    value: AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr):
        ptr: Expr | t.CPtr = pool.alloc(Expr.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Expr.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.value = value

    def kind(self) -> t.CInt:
        return ASTKind.Expr

    def type_name(self) -> str:
        return "Expr"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Expr(value=")
        if self.value is not None:
            pos = self.value.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# FunctionDef 节点
# ============================================================

class FunctionDef(AST):
    """FunctionDef(name: str, args: AST,
                   decorator_list: list[AST | t.CPtr], returns: AST, flags: CInt)"""
    name:            str
    args:            AST | t.CPtr
    decorator_list:  list[AST | t.CPtr] | t.CPtr
    returns:         AST | t.CPtr
    flags:           t.CInt

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                name: str, args: AST | t.CPtr,
                decorator_list: list[AST | t.CPtr] | t.CPtr,
                returns: AST | t.CPtr, is_async: t.CInt):
        ptr: FunctionDef | t.CPtr = pool.alloc(FunctionDef.__sizeof__())
        if ptr:
            string.memset(ptr, 0, FunctionDef.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 name: str, args: AST | t.CPtr,
                 decorator_list: list[AST | t.CPtr] | t.CPtr,
                 returns: AST | t.CPtr, is_async: t.CInt):
        _init_ast(self, pool, 0, 0)
        self.name = _copy_str(pool, name)
        self.args = args
        self.decorator_list = decorator_list
        self.returns = returns
        if is_async:
            self.flags = FLAG_IS_ASYNC
        else:
            self.flags = 0
        _set_parent_list(decorator_list, self)

    def kind(self) -> t.CInt:
        return ASTKind.FunctionDef

    def type_name(self) -> str:
        return "FunctionDef"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "FunctionDef(name='")
        pos = _emit_str(buf, size, pos, self.name)
        pos = _emit(buf, size, pos, "', args=")
        if self.args is not None:
            pos = self.args.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ", decorator_list=")
        pos = _dump_list(self.decorator_list, buf, size, pos)
        pos = _emit(buf, size, pos, ", returns=")
        if self.returns is not None:
            pos = self.returns.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Expression 节点
# ============================================================

class Expression(AST):
    """Expression(body: AST)"""
    body: AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                body: AST | t.CPtr):
        ptr: Expression | t.CPtr = pool.alloc(Expression.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Expression.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 body: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.body = body

    def kind(self) -> t.CInt:
        return ASTKind.Expression

    def type_name(self) -> str:
        return "Expression"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Expression(body=")
        if self.body is not None:
            pos = self.body.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Interactive 节点
# ============================================================

class Interactive(AST):
    """Interactive(body: AST)"""
    body: AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                body: AST | t.CPtr):
        ptr: Interactive | t.CPtr = pool.alloc(Interactive.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Interactive.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 body: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.body = body

    def kind(self) -> t.CInt:
        return ASTKind.Interactive

    def type_name(self) -> str:
        return "Interactive"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Interactive(body=")
        if self.body is not None:
            pos = self.body.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# FunctionType 节点
# ============================================================

class FunctionType(AST):
    """FunctionType(argtypes: list[AST | t.CPtr], returns: AST)"""
    argtypes: list[AST | t.CPtr] | t.CPtr
    returns:  AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                argtypes: list[AST | t.CPtr] | t.CPtr,
                returns: AST | t.CPtr):
        ptr: FunctionType | t.CPtr = pool.alloc(FunctionType.__sizeof__())
        if ptr:
            string.memset(ptr, 0, FunctionType.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 argtypes: list[AST | t.CPtr] | t.CPtr,
                 returns: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.argtypes = argtypes
        self.returns = returns

    def kind(self) -> t.CInt:
        return ASTKind.FunctionType

    def type_name(self) -> str:
        return "FunctionType"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "FunctionType(argtypes=")
        pos = _dump_list(self.argtypes, buf, size, pos)
        pos = _emit(buf, size, pos, ", returns=")
        if self.returns is not None:
            pos = self.returns.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# ClassDef 节点
# ============================================================

class ClassDef(AST):
    """ClassDef(name: str, bases: list[AST | t.CPtr], keywords: list[AST | t.CPtr],
                decorator_list: list[AST | t.CPtr], type_params: list[str] | t.CPtr)

    type_params: 泛型类型参数名列表（PEP 695 class list[T]: 中的 [T]），
                 None 表示非泛型类。"""
    name:            str
    bases:           list[AST | t.CPtr] | t.CPtr
    keywords:        list[AST | t.CPtr] | t.CPtr
    decorator_list:  list[AST | t.CPtr] | t.CPtr
    type_params:     list[str] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                name: str,
                bases: list[AST | t.CPtr] | t.CPtr,
                keywords: list[AST | t.CPtr] | t.CPtr,
                decorator_list: list[AST | t.CPtr] | t.CPtr,
                type_params: list[str] | t.CPtr = None):
        ptr: ClassDef | t.CPtr = pool.alloc(ClassDef.__sizeof__())
        if ptr:
            string.memset(ptr, 0, ClassDef.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 name: str,
                 bases: list[AST | t.CPtr] | t.CPtr,
                 keywords: list[AST | t.CPtr] | t.CPtr,
                 decorator_list: list[AST | t.CPtr] | t.CPtr,
                 type_params: list[str] | t.CPtr = None):
        _init_ast(self, pool, 0, 0)
        self.name = _copy_str(pool, name)
        self.bases = bases
        self.keywords = keywords
        self.decorator_list = decorator_list
        self.type_params = type_params
        _set_parent_list(decorator_list, self)

    def kind(self) -> t.CInt:
        return ASTKind.ClassDef

    def type_name(self) -> str:
        return "ClassDef"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "ClassDef(name='")
        pos = _emit_str(buf, size, pos, self.name)
        pos = _emit(buf, size, pos, "', bases=")
        pos = _dump_list(self.bases, buf, size, pos)
        pos = _emit(buf, size, pos, ", keywords=")
        pos = _dump_list(self.keywords, buf, size, pos)
        pos = _emit(buf, size, pos, ", body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ", decorator_list=")
        pos = _dump_list(self.decorator_list, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Delete 节点
# ============================================================

class Delete(AST):
    """Delete(targets: list[AST | t.CPtr])"""
    targets: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                targets: list[AST | t.CPtr] | t.CPtr):
        ptr: Delete | t.CPtr = pool.alloc(Delete.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Delete.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 targets: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.targets = targets
        _set_parent_list(targets, self)

    def kind(self) -> t.CInt:
        return ASTKind.Delete

    def type_name(self) -> str:
        return "Delete"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Delete(targets=")
        pos = _dump_list(self.targets, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# AugAssign 节点
# ============================================================

class AugAssign(AST):
    """AugAssign(target: AST, op: CInt, value: AST)"""
    target: AST | t.CPtr
    op:     t.CInt
    value:  AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                target: AST | t.CPtr, op: t.CInt, value: AST | t.CPtr):
        ptr: AugAssign | t.CPtr = pool.alloc(AugAssign.__sizeof__())
        if ptr:
            string.memset(ptr, 0, AugAssign.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 target: AST | t.CPtr, op: t.CInt, value: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.target = target
        self.op = op
        self.value = value

    def kind(self) -> t.CInt:
        return ASTKind.AugAssign

    def type_name(self) -> str:
        return "AugAssign"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "AugAssign(target=")
        if self.target is not None:
            pos = self.target.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", op=")
        pos = _emit(buf, size, pos, _op_name(self.op))
        pos = _emit(buf, size, pos, ", value=")
        if self.value is not None:
            pos = self.value.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# AnnAssign 节点
# ============================================================

class AnnAssign(AST):
    """AnnAssign(target: AST, annotation: AST, value: AST, simple: CInt)"""
    target:     AST | t.CPtr
    annotation: AST | t.CPtr
    value:      AST | t.CPtr
    simple:     t.CInt

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                target: AST | t.CPtr, annotation: AST | t.CPtr,
                value: AST | t.CPtr, simple: t.CInt):
        ptr: AnnAssign | t.CPtr = pool.alloc(AnnAssign.__sizeof__())
        if ptr:
            string.memset(ptr, 0, AnnAssign.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 target: AST | t.CPtr, annotation: AST | t.CPtr,
                 value: AST | t.CPtr, simple: t.CInt):
        _init_ast(self, pool, 0, 0)
        self.target = target
        self.annotation = annotation
        self.value = value
        self.simple = simple

    def kind(self) -> t.CInt:
        return ASTKind.AnnAssign

    def type_name(self) -> str:
        return "AnnAssign"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "AnnAssign(target=")
        if self.target is not None:
            pos = self.target.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", annotation=")
        if self.annotation is not None:
            pos = self.annotation.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", value=")
        if self.value is not None:
            pos = self.value.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", simple=")
        pos = _emit_int(buf, size, pos, t.CInt64T(self.simple))
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# With 节点
# ============================================================

class With(AST):
    """With(items: list[AST | t.CPtr], is_async: CInt)"""
    items: list[AST | t.CPtr] | t.CPtr
    flags: t.CInt

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                items: list[AST | t.CPtr] | t.CPtr,
                is_async: t.CInt):
        ptr: With | t.CPtr = pool.alloc(With.__sizeof__())
        if ptr:
            string.memset(ptr, 0, With.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 items: list[AST | t.CPtr] | t.CPtr,
                 is_async: t.CInt):
        _init_ast(self, pool, 0, 0)
        self.items = items
        if is_async:
            self.flags = FLAG_IS_ASYNC
        else:
            self.flags = 0
        _set_parent_list(items, self)

    def kind(self) -> t.CInt:
        return ASTKind.With

    def type_name(self) -> str:
        return "With"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "With(items=")
        pos = _dump_list(self.items, buf, size, pos)
        pos = _emit(buf, size, pos, ", body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Raise 节点
# ============================================================

class Raise(AST):
    """Raise(exc: AST, cause: AST)"""
    exc:   AST | t.CPtr
    cause: AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                exc: AST | t.CPtr, cause: AST | t.CPtr):
        ptr: Raise | t.CPtr = pool.alloc(Raise.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Raise.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 exc: AST | t.CPtr, cause: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.exc = exc
        self.cause = cause

    def kind(self) -> t.CInt:
        return ASTKind.Raise

    def type_name(self) -> str:
        return "Raise"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Raise(exc=")
        if self.exc is not None:
            pos = self.exc.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", cause=")
        if self.cause is not None:
            pos = self.cause.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Try 节点
# ============================================================

class Try(AST):
    """Try(handlers: list[AST | t.CPtr],
          orelse: list[AST | t.CPtr], finalbody: list[AST | t.CPtr])"""
    handlers:  list[AST | t.CPtr] | t.CPtr
    orelse:    list[AST | t.CPtr] | t.CPtr
    finalbody: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                handlers: list[AST | t.CPtr] | t.CPtr,
                orelse: list[AST | t.CPtr] | t.CPtr,
                finalbody: list[AST | t.CPtr] | t.CPtr):
        ptr: Try | t.CPtr = pool.alloc(Try.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Try.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 handlers: list[AST | t.CPtr] | t.CPtr,
                 orelse: list[AST | t.CPtr] | t.CPtr,
                 finalbody: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.handlers = handlers
        self.orelse = orelse
        self.finalbody = finalbody
        _set_parent_list(handlers, self)
        _set_parent_list(orelse, self)
        _set_parent_list(finalbody, self)

    def kind(self) -> t.CInt:
        return ASTKind.Try

    def type_name(self) -> str:
        return "Try"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Try(body=")
        pos = _dump_list(self.children, buf, size, pos)
        pos = _emit(buf, size, pos, ", handlers=")
        pos = _dump_list(self.handlers, buf, size, pos)
        pos = _emit(buf, size, pos, ", orelse=")
        pos = _dump_list(self.orelse, buf, size, pos)
        pos = _emit(buf, size, pos, ", finalbody=")
        pos = _dump_list(self.finalbody, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Assert 节点
# ============================================================

class Assert(AST):
    """Assert(test: AST, msg: AST)"""
    test: AST | t.CPtr
    msg:  AST | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                test: AST | t.CPtr, msg: AST | t.CPtr):
        ptr: Assert | t.CPtr = pool.alloc(Assert.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Assert.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 test: AST | t.CPtr, msg: AST | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.test = test
        self.msg = msg

    def kind(self) -> t.CInt:
        return ASTKind.Assert

    def type_name(self) -> str:
        return "Assert"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Assert(test=")
        if self.test is not None:
            pos = self.test.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", msg=")
        if self.msg is not None:
            pos = self.msg.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Global 节点
# ============================================================

class Global(AST):
    """Global(names: list[AST | t.CPtr])"""
    names: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                names: list[AST | t.CPtr] | t.CPtr):
        ptr: Global | t.CPtr = pool.alloc(Global.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Global.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 names: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.names = names
        _set_parent_list(names, self)

    def kind(self) -> t.CInt:
        return ASTKind.Global

    def type_name(self) -> str:
        return "Global"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Global(names=")
        pos = _dump_list(self.names, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Nonlocal 节点
# ============================================================

class Nonlocal(AST):
    """Nonlocal(names: list[AST | t.CPtr])"""
    names: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                names: list[AST | t.CPtr] | t.CPtr):
        ptr: Nonlocal | t.CPtr = pool.alloc(Nonlocal.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Nonlocal.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 names: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.names = names
        _set_parent_list(names, self)

    def kind(self) -> t.CInt:
        return ASTKind.Nonlocal

    def type_name(self) -> str:
        return "Nonlocal"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Nonlocal(names=")
        pos = _dump_list(self.names, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Pass 节点
# ============================================================

class Pass(AST):
    """Pass()"""

    def __new__(self, pool: memhub.MemManager | t.CPtr):
        ptr: Pass | t.CPtr = pool.alloc(Pass.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Pass.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr):
        _init_ast(self, pool, 0, 0)

    def kind(self) -> t.CInt:
        return ASTKind.Pass

    def type_name(self) -> str:
        return "Pass"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Pass()")
        return pos


# ============================================================
# Break 节点
# ============================================================

class Break(AST):
    """Break()"""

    def __new__(self, pool: memhub.MemManager | t.CPtr):
        ptr: Break | t.CPtr = pool.alloc(Break.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Break.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr):
        _init_ast(self, pool, 0, 0)

    def kind(self) -> t.CInt:
        return ASTKind.Break

    def type_name(self) -> str:
        return "Break"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Break()")
        return pos


# ============================================================
# Continue 节点
# ============================================================

class Continue(AST):
    """Continue()"""

    def __new__(self, pool: memhub.MemManager | t.CPtr):
        ptr: Continue | t.CPtr = pool.alloc(Continue.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Continue.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr):
        _init_ast(self, pool, 0, 0)

    def kind(self) -> t.CInt:
        return ASTKind.Continue

    def type_name(self) -> str:
        return "Continue"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Continue()")
        return pos


# ============================================================
# Import 节点
# ============================================================

class Import(AST):
    """Import(names: list[AST | t.CPtr])"""
    names: list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                names: list[AST | t.CPtr] | t.CPtr):
        ptr: Import | t.CPtr = pool.alloc(Import.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Import.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 names: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.names = names
        _set_parent_list(names, self)

    def kind(self) -> t.CInt:
        return ASTKind.Import

    def type_name(self) -> str:
        return "Import"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Import(names=")
        pos = _dump_list(self.names, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# ImportFrom 节点
# ============================================================

class ImportFrom(AST):
    """ImportFrom(module: str, names: list[AST | t.CPtr], level: CInt)"""
    module: str
    names:  list[AST | t.CPtr] | t.CPtr
    level:  t.CInt

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                module: str,
                names: list[AST | t.CPtr] | t.CPtr,
                level: t.CInt):
        ptr: ImportFrom | t.CPtr = pool.alloc(ImportFrom.__sizeof__())
        if ptr:
            string.memset(ptr, 0, ImportFrom.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 module: str,
                 names: list[AST | t.CPtr] | t.CPtr,
                 level: t.CInt):
        _init_ast(self, pool, 0, 0)
        self.module = _copy_str(pool, module)
        self.names = names
        self.level = level
        _set_parent_list(names, self)

    def kind(self) -> t.CInt:
        return ASTKind.ImportFrom

    def type_name(self) -> str:
        return "ImportFrom"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "ImportFrom(module='")
        pos = _emit_str(buf, size, pos, self.module)
        pos = _emit(buf, size, pos, "', names=")
        pos = _dump_list(self.names, buf, size, pos)
        pos = _emit(buf, size, pos, ", level=")
        pos = _emit_int(buf, size, pos, t.CInt64T(self.level))
        pos = _emit(buf, size, pos, ")")
        return pos


# ============================================================
# Match 节点
# ============================================================

class Match(AST):
    """Match(subject: AST, cases: list[AST | t.CPtr])"""
    subject: AST | t.CPtr
    cases:   list[AST | t.CPtr] | t.CPtr

    def __new__(self, pool: memhub.MemManager | t.CPtr,
                subject: AST | t.CPtr,
                cases: list[AST | t.CPtr] | t.CPtr):
        ptr: Match | t.CPtr = pool.alloc(Match.__sizeof__())
        if ptr:
            string.memset(ptr, 0, Match.__sizeof__())
        return ptr

    def __init__(self, pool: memhub.MemManager | t.CPtr,
                 subject: AST | t.CPtr,
                 cases: list[AST | t.CPtr] | t.CPtr):
        _init_ast(self, pool, 0, 0)
        self.subject = subject
        self.cases = cases
        _set_parent_list(cases, self)

    def kind(self) -> t.CInt:
        return ASTKind.Match

    def type_name(self) -> str:
        return "Match"

    def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT,
             pos: t.CSizeT) -> t.CSizeT:
        pos = _emit(buf, size, pos, "Match(subject=")
        if self.subject is not None:
            pos = self.subject.dump(buf, size, pos)
        else:
            pos = _emit(buf, size, pos, "None")
        pos = _emit(buf, size, pos, ", cases=")
        pos = _dump_list(self.cases, buf, size, pos)
        pos = _emit(buf, size, pos, ")")
        return pos
