from stdint import * import memhub import string from .base import ( AST, ExprNode, ASTKind, ASTCtx, OpKind, _init_ast, _copy_str, _set_parent_list, _emit, _emit_str, _emit_int, _dump_list, _dump_op_list, _op_name, CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR ) # ============================================================ # Name node # ============================================================ class Name(ExprNode): """Name(id: str, ctx: ASTCtx)""" id: str ctx: int def __new__(self, pool: memhub.MemManager*, id: str, ctx: int): ptr: Name* = pool.alloc(Name.__sizeof__()) if ptr: string.memset(ptr, 0, Name.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, id: str, ctx: int): _init_ast(self, pool, 0, 0) self.id = _copy_str(pool, id) self.ctx = ctx def kind(self) -> int: return ASTKind.Name def type_name(self) -> str: return "Name" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Name(id='") pos = _emit_str(buf, size, pos, self.id) pos = _emit(buf, size, pos, "', ctx=") if self.ctx == ASTCtx.Load: pos = _emit(buf, size, pos, "Load") elif self.ctx == ASTCtx.Store: pos = _emit(buf, size, pos, "Store") else: pos = _emit(buf, size, pos, "Del") pos = _emit(buf, size, pos, ")") return pos def name_get_id(node: Name*) -> str: """Get Name.id field (cross-module accessor; guards against stub field-access pitfalls)""" if node is None: return None return node.id def constant_get_str_val(node: Constant*) -> str: """Get Constant.str_val field (cross-module accessor)""" if node is None: return None return node.str_val def binop_get_left(node: BinOp*) -> AST*: """Get BinOp.left field (cross-module accessor)""" if node is None: return None return node.left def binop_get_right(node: BinOp*) -> AST*: """Get BinOp.right field (cross-module accessor)""" if node is None: return None return node.right # ============================================================ # Constant nodes (subtype marked by const_kind) # ============================================================ class Constant(ExprNode): """Constant(int_val/float_val/str_val, const_kind)""" int_val: int64 float_val: double str_val: str const_kind: int # 显式整型宽度后缀(_int/_uint):int_width>0 = 声明宽度,0 = 未指定; # int_unsigned=1 表示 uint 形式。追加在末尾,保持既有字段偏移不变(经 __sizeof__ 分配并 memset)。 int_width: int int_unsigned: int def __new__(self, pool: memhub.MemManager*, const_kind: int, int_val: int64, float_val: double, str_val: str, lineno: int, col: int, int_width: int = 0, int_unsigned: int = 0): ptr: Constant* = pool.alloc(Constant.__sizeof__()) if ptr: string.memset(ptr, 0, Constant.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, const_kind: int, int_val: int64, float_val: double, str_val: str, lineno: int, col: int, int_width: int = 0, int_unsigned: int = 0): _init_ast(self, pool, lineno, col) self.const_kind = const_kind self.int_val = int_val self.float_val = float_val self.int_width = int_width self.int_unsigned = int_unsigned if str_val is not None: self.str_val = _copy_str(pool, str_val) else: self.str_val = None def kind(self) -> int: return ASTKind.Constant def type_name(self) -> str: return "Constant" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Constant(value=") if self.const_kind == CONST_INT: pos = _emit_int(buf, size, pos, self.int_val) elif self.const_kind == CONST_FLOAT: pos = _emit(buf, size, pos, "") elif self.const_kind == CONST_STR: pos = _emit(buf, size, pos, "'") if self.str_val is not None: pos = _emit_str(buf, size, pos, self.str_val) else: pos = _emit(buf, size, pos, "(null)") pos = _emit(buf, size, pos, "'") elif self.const_kind == CONST_CHAR: # Single character → display as character ASCII value pos = _emit(buf, size, pos, "char(") pos = _emit_int(buf, size, pos, self.int_val) pos = _emit(buf, size, pos, ")") elif self.const_kind == CONST_BOOL: if self.int_val != 0: pos = _emit(buf, size, pos, "True") else: pos = _emit(buf, size, pos, "False") else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ")") return pos # ============================================================ # BinOp Node # ============================================================ class BinOp(ExprNode): """BinOp(left: AST, op: OpKind, right: AST)""" left: AST* op: int right: AST* def __new__(self, pool: memhub.MemManager*, left: AST*, op: int, right: AST*): ptr: BinOp* = pool.alloc(BinOp.__sizeof__()) if ptr: string.memset(ptr, 0, BinOp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, left: AST*, op: int, right: AST*): _init_ast(self, pool, 0, 0) self.left = left self.op = op self.right = right def kind(self) -> int: return ASTKind.BinOp def type_name(self) -> str: return "BinOp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "BinOp(left=") if self.left is not None: pos = self.left.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, ", right=") if self.right is not None: pos = self.right.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ")") return pos # ============================================================ # UnaryOp Node # ============================================================ class UnaryOp(ExprNode): """UnaryOp(op: OpKind, operand: AST)""" op: int operand: AST* def __new__(self, pool: memhub.MemManager*, op: int, operand: AST*): ptr: UnaryOp* = pool.alloc(UnaryOp.__sizeof__()) if ptr: string.memset(ptr, 0, UnaryOp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, op: int, operand: AST*): _init_ast(self, pool, 0, 0) self.op = op self.operand = operand def kind(self) -> int: return ASTKind.UnaryOp def type_name(self) -> str: return "UnaryOp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "UnaryOp(op=") pos = _emit(buf, size, pos, _op_name(self.op)) pos = _emit(buf, size, pos, ", operand=") if self.operand is not None: pos = self.operand.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Compare Node # ============================================================ class Compare(ExprNode): """Compare(left: AST, ops: list[CInt], comparators: list[AST | CPtr])""" left: AST* ops: t.CPtr comparators: list[AST*]* def __new__(self, pool: memhub.MemManager*, left: AST*, ops: t.CPtr, comparators: list[AST*]*): ptr: Compare* = pool.alloc(Compare.__sizeof__()) if ptr: string.memset(ptr, 0, Compare.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, left: AST*, ops: t.CPtr, comparators: list[AST*]*): _init_ast(self, pool, 0, 0) self.left = left self.ops = ops self.comparators = comparators _set_parent_list(comparators, self) def kind(self) -> int: return ASTKind.Compare def type_name(self) -> str: return "Compare" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Compare(left=") if self.left is not None: pos = self.left.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", ops=") pos = _dump_op_list(self.ops, buf, size, pos) pos = _emit(buf, size, pos, ", comparators=") pos = _dump_list(self.comparators, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Call Node # ============================================================ class Call(ExprNode): """Call(func: AST, args: list[AST | CPtr], keywords: list[AST | CPtr])""" func: AST* args: list[AST*]* keywords: list[AST*]* # Value-position `volatile f()` / `volatile S()` prefix marker (see _IsVolatileCallPrefix): # 1 = result/temp slot accessed volatile (struct writes too). Appended last: offsets unchanged. IsVolatile: int def __new__(self, pool: memhub.MemManager*, func: AST*, args: list[AST*]*, keywords: list[AST*]*): ptr: Call* = pool.alloc(Call.__sizeof__()) if ptr: string.memset(ptr, 0, Call.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, func: AST*, args: list[AST*]*, keywords: list[AST*]*): _init_ast(self, pool, 0, 0) self.func = func self.args = args self.keywords = keywords self.IsVolatile = 0 _set_parent_list(args, self) _set_parent_list(keywords, self) def kind(self) -> int: return ASTKind.Call def type_name(self) -> str: return "Call" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Call(func=") if self.func is not None: pos = self.func.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", args=") pos = _dump_list(self.args, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # New Node(M2.4:`new` 描述符分配) # ============================================================ # 两条正交轴,各取其一;顺序无关;重复/冲突在解析期即报错。 # 来源 SourceKind:缺省 = heap(D3) define NEW_SRC_DEFAULT = 0 define NEW_SRC_STACK = 1 define NEW_SRC_HEAP = 2 define NEW_SRC_MEMGR = 3 # 生命期 LifeKind:缺省由来源决定(stack→slife,heap/memgr→hlife) define NEW_LIFE_DEFAULT = 0 define NEW_LIFE_SLIFE = 1 define NEW_LIFE_HLIFE = 2 class New(ExprNode): """New(Source: CInt, Life: CInt, memgr: AST | CPtr, func: AST, args: list[AST | CPtr])""" Source: int # SourceKind(NEW_SRC_*) Life: int # LifeKind(NEW_LIFE_*) memgr: AST* # `memgr(x)` 的 x;无 memgr 描述符时为 None func: AST* # 被构造的类型/可调用(`new ... T(args)` 里的 T) args: list[AST*]* def __new__(self, pool: memhub.MemManager*, Source: int, Life: int, memgr: AST*, func: AST*, args: list[AST*]*): ptr: New* = pool.alloc(New.__sizeof__()) if ptr: string.memset(ptr, 0, New.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, Source: int, Life: int, memgr: AST*, func: AST*, args: list[AST*]*): _init_ast(self, pool, 0, 0) self.Source = Source self.Life = Life self.memgr = memgr self.func = func self.args = args _set_parent_list(args, self) def kind(self) -> int: return ASTKind.New def type_name(self) -> str: return "New" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "New(") if self.memgr is not None: pos = _emit(buf, size, pos, ", memgr=") pos = self.memgr.dump(buf, size, pos) pos = _emit(buf, size, pos, ", func=") if self.func is not None: pos = self.func.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", args=") pos = _dump_list(self.args, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # BoolOp Node # ============================================================ class BoolOp(ExprNode): """BoolOp(op: CInt, values: list[AST | CPtr])""" op: int values: list[AST*]* def __new__(self, pool: memhub.MemManager*, op: int, values: list[AST*]*): ptr: BoolOp* = pool.alloc(BoolOp.__sizeof__()) if ptr: string.memset(ptr, 0, BoolOp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, op: int, values: list[AST*]*): _init_ast(self, pool, 0, 0) self.op = op self.values = values _set_parent_list(values, self) def kind(self) -> int: return ASTKind.BoolOp def type_name(self) -> str: return "BoolOp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "BoolOp(op=") pos = _emit(buf, size, pos, _op_name(self.op)) pos = _emit(buf, size, pos, ", values=") pos = _dump_list(self.values, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Lambda Node # ============================================================ class Lambda(ExprNode): """Lambda(args: AST, body: AST)""" args: AST* body: AST* def __new__(self, pool: memhub.MemManager*, args: AST*, body: AST*): ptr: Lambda* = pool.alloc(Lambda.__sizeof__()) if ptr: string.memset(ptr, 0, Lambda.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, args: AST*, body: AST*): _init_ast(self, pool, 0, 0) self.args = args self.body = body def kind(self) -> int: return ASTKind.Lambda def type_name(self) -> str: return "Lambda" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Lambda(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=") 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 # ============================================================ # IfExp Node # ============================================================ class IfExp(ExprNode): """IfExp(test: AST, body: AST, orelse: AST)""" test: AST* body: AST* orelse: AST* def __new__(self, pool: memhub.MemManager*, test: AST*, body: AST*, orelse: AST*): ptr: IfExp* = pool.alloc(IfExp.__sizeof__()) if ptr: string.memset(ptr, 0, IfExp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, test: AST*, body: AST*, orelse: AST*): _init_ast(self, pool, 0, 0) self.test = test self.body = body self.orelse = orelse def kind(self) -> int: return ASTKind.IfExp def type_name(self) -> str: return "IfExp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "IfExp(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=") 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, ", orelse=") if self.orelse is not None: pos = self.orelse.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Dict Node # ============================================================ class Dict(ExprNode): """Dict(keys: list[AST | CPtr], values: list[AST | CPtr])""" keys: list[AST*]* values: list[AST*]* def __new__(self, pool: memhub.MemManager*, keys: list[AST*]*, values: list[AST*]*): ptr: Dict* = pool.alloc(Dict.__sizeof__()) if ptr: string.memset(ptr, 0, Dict.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, keys: list[AST*]*, values: list[AST*]*): _init_ast(self, pool, 0, 0) self.keys = keys self.values = values _set_parent_list(keys, self) _set_parent_list(values, self) def kind(self) -> int: return ASTKind.Dict def type_name(self) -> str: return "Dict" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Dict(keys=") pos = _dump_list(self.keys, buf, size, pos) pos = _emit(buf, size, pos, ", values=") pos = _dump_list(self.values, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Set Node # ============================================================ class Set(ExprNode): """Set(elts: list[AST | CPtr])""" elts: list[AST*]* def __new__(self, pool: memhub.MemManager*, elts: list[AST*]*): ptr: Set* = pool.alloc(Set.__sizeof__()) if ptr: string.memset(ptr, 0, Set.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, elts: list[AST*]*): _init_ast(self, pool, 0, 0) self.elts = elts _set_parent_list(elts, self) def kind(self) -> int: return ASTKind.Set def type_name(self) -> str: return "Set" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Set(elts=") pos = _dump_list(self.elts, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # ListComp Node # ============================================================ class ListComp(ExprNode): """ListComp(elt: AST, generators: list[AST | CPtr])""" elt: AST* generators: list[AST*]* def __new__(self, pool: memhub.MemManager*, elt: AST*, generators: list[AST*]*): ptr: ListComp* = pool.alloc(ListComp.__sizeof__()) if ptr: string.memset(ptr, 0, ListComp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, elt: AST*, generators: list[AST*]*): _init_ast(self, pool, 0, 0) self.elt = elt self.generators = generators _set_parent_list(generators, self) def kind(self) -> int: return ASTKind.ListComp def type_name(self) -> str: return "ListComp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "ListComp(elt=") if self.elt is not None: pos = self.elt.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", generators=") pos = _dump_list(self.generators, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # SetComp Node # ============================================================ class SetComp(ExprNode): """SetComp(elt: AST, generators: list[AST | CPtr])""" elt: AST* generators: list[AST*]* def __new__(self, pool: memhub.MemManager*, elt: AST*, generators: list[AST*]*): ptr: SetComp* = pool.alloc(SetComp.__sizeof__()) if ptr: string.memset(ptr, 0, SetComp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, elt: AST*, generators: list[AST*]*): _init_ast(self, pool, 0, 0) self.elt = elt self.generators = generators _set_parent_list(generators, self) def kind(self) -> int: return ASTKind.SetComp def type_name(self) -> str: return "SetComp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "SetComp(elt=") if self.elt is not None: pos = self.elt.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", generators=") pos = _dump_list(self.generators, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # DictComp Node # ============================================================ class DictComp(ExprNode): """DictComp(key: AST, value: AST, generators: list[AST | CPtr])""" key: AST* value: AST* generators: list[AST*]* def __new__(self, pool: memhub.MemManager*, key: AST*, value: AST*, generators: list[AST*]*): ptr: DictComp* = pool.alloc(DictComp.__sizeof__()) if ptr: string.memset(ptr, 0, DictComp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, key: AST*, value: AST*, generators: list[AST*]*): _init_ast(self, pool, 0, 0) self.key = key self.value = value self.generators = generators _set_parent_list(generators, self) def kind(self) -> int: return ASTKind.DictComp def type_name(self) -> str: return "DictComp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "DictComp(key=") if self.key is not None: pos = self.key.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, ", generators=") pos = _dump_list(self.generators, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # GeneratorExp Node # ============================================================ class GeneratorExp(ExprNode): """GeneratorExp(elt: AST, generators: list[AST | CPtr])""" elt: AST* generators: list[AST*]* def __new__(self, pool: memhub.MemManager*, elt: AST*, generators: list[AST*]*): ptr: GeneratorExp* = pool.alloc(GeneratorExp.__sizeof__()) if ptr: string.memset(ptr, 0, GeneratorExp.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, elt: AST*, generators: list[AST*]*): _init_ast(self, pool, 0, 0) self.elt = elt self.generators = generators _set_parent_list(generators, self) def kind(self) -> int: return ASTKind.GeneratorExp def type_name(self) -> str: return "GeneratorExp" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "GeneratorExp(elt=") if self.elt is not None: pos = self.elt.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", generators=") pos = _dump_list(self.generators, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Await Node # ============================================================ class Await(ExprNode): """Await(value: AST)""" value: AST* def __new__(self, pool: memhub.MemManager*, value: AST*): ptr: Await* = pool.alloc(Await.__sizeof__()) if ptr: string.memset(ptr, 0, Await.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*): _init_ast(self, pool, 0, 0) self.value = value def kind(self) -> int: return ASTKind.Await def type_name(self) -> str: return "Await" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Await(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 # ============================================================ # Yield Node # ============================================================ class Yield(ExprNode): """Yield(value: AST)""" value: AST* def __new__(self, pool: memhub.MemManager*, value: AST*): ptr: Yield* = pool.alloc(Yield.__sizeof__()) if ptr: string.memset(ptr, 0, Yield.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*): _init_ast(self, pool, 0, 0) self.value = value def kind(self) -> int: return ASTKind.Yield def type_name(self) -> str: return "Yield" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Yield(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 # ============================================================ # YieldFrom Node # ============================================================ class YieldFrom(ExprNode): """YieldFrom(value: AST)""" value: AST* def __new__(self, pool: memhub.MemManager*, value: AST*): ptr: YieldFrom* = pool.alloc(YieldFrom.__sizeof__()) if ptr: string.memset(ptr, 0, YieldFrom.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*): _init_ast(self, pool, 0, 0) self.value = value def kind(self) -> int: return ASTKind.YieldFrom def type_name(self) -> str: return "YieldFrom" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "YieldFrom(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 # ============================================================ # FormattedValue Node # ============================================================ class FormattedValue(ExprNode): """FormattedValue(value: AST, conversion: CInt, format_spec: AST)""" value: AST* conversion: int format_spec: AST* def __new__(self, pool: memhub.MemManager*, value: AST*, conversion: int, format_spec: AST*): ptr: FormattedValue* = pool.alloc(FormattedValue.__sizeof__()) if ptr: string.memset(ptr, 0, FormattedValue.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*, conversion: int, format_spec: AST*): _init_ast(self, pool, 0, 0) self.value = value self.conversion = conversion self.format_spec = format_spec def kind(self) -> int: return ASTKind.FormattedValue def type_name(self) -> str: return "FormattedValue" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "FormattedValue(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, ", conversion=") pos = _emit_int(buf, size, pos, int64(self.conversion)) pos = _emit(buf, size, pos, ", format_spec=") if self.format_spec is not None: pos = self.format_spec.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ")") return pos # ============================================================ # JoinedStr Node # ============================================================ class JoinedStr(ExprNode): """JoinedStr(values: list[AST | CPtr])""" values: list[AST*]* def __new__(self, pool: memhub.MemManager*, values: list[AST*]*): ptr: JoinedStr* = pool.alloc(JoinedStr.__sizeof__()) if ptr: string.memset(ptr, 0, JoinedStr.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, values: list[AST*]*): _init_ast(self, pool, 0, 0) self.values = values _set_parent_list(values, self) def kind(self) -> int: return ASTKind.JoinedStr def type_name(self) -> str: return "JoinedStr" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "JoinedStr(values=") pos = _dump_list(self.values, buf, size, pos) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Attribute Node # ============================================================ class Attribute(ExprNode): """Attribute(value: AST, attr: str, ctx: CInt)""" value: AST* attr: str ctx: int def __new__(self, pool: memhub.MemManager*, value: AST*, attr: str, ctx: int): ptr: Attribute* = pool.alloc(Attribute.__sizeof__()) if ptr: string.memset(ptr, 0, Attribute.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*, attr: str, ctx: int): _init_ast(self, pool, 0, 0) self.value = value self.attr = _copy_str(pool, attr) self.ctx = ctx def kind(self) -> int: return ASTKind.Attribute def type_name(self) -> str: return "Attribute" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Attribute(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, ", attr='") pos = _emit_str(buf, size, pos, self.attr) pos = _emit(buf, size, pos, "', ctx=") pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Field accessors (guard against cross-module stub field-access pitfalls): other modules reading # ast.Attribute fields directly may get a wrong stub GEP and crash, so they use these accessors. # ============================================================ def attribute_get_value(node: Attribute*) -> AST*: """Get Attribute.value field (cross-module accessor)""" if node is None: return None return node.value def attribute_get_attr(node: Attribute*) -> str: """Get Attribute.attr field (cross-module accessor)""" if node is None: return None return node.attr # ============================================================ # Subscript Node # ============================================================ class Subscript(ExprNode): """Subscript(value: AST, slice: AST, ctx: CInt)""" value: AST* slice: AST* ctx: int def __new__(self, pool: memhub.MemManager*, value: AST*, slice: AST*, ctx: int): ptr: Subscript* = pool.alloc(Subscript.__sizeof__()) if ptr: string.memset(ptr, 0, Subscript.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*, slice: AST*, ctx: int): _init_ast(self, pool, 0, 0) self.value = value self.slice = slice self.ctx = ctx def kind(self) -> int: return ASTKind.Subscript def type_name(self) -> str: return "Subscript" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Subscript(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, ", slice=") if self.slice is not None: pos = self.slice.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", ctx=") pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Starred Node # ============================================================ class Starred(ExprNode): """Starred(value: AST, ctx: CInt)""" value: AST* ctx: int def __new__(self, pool: memhub.MemManager*, value: AST*, ctx: int): ptr: Starred* = pool.alloc(Starred.__sizeof__()) if ptr: string.memset(ptr, 0, Starred.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, value: AST*, ctx: int): _init_ast(self, pool, 0, 0) self.value = value self.ctx = ctx def kind(self) -> int: return ASTKind.Starred def type_name(self) -> str: return "Starred" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Starred(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, ", ctx=") pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # List Node # ============================================================ class List(ExprNode): """List(elts: list[AST | CPtr], ctx: CInt)""" elts: list[AST*]* ctx: int def __new__(self, pool: memhub.MemManager*, elts: list[AST*]*, ctx: int): ptr: List* = pool.alloc(List.__sizeof__()) if ptr: string.memset(ptr, 0, List.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, elts: list[AST*]*, ctx: int): _init_ast(self, pool, 0, 0) self.elts = elts self.ctx = ctx _set_parent_list(elts, self) def kind(self) -> int: return ASTKind.List def type_name(self) -> str: return "List" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "List(elts=") pos = _dump_list(self.elts, buf, size, pos) pos = _emit(buf, size, pos, ", ctx=") pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Tuple Node # ============================================================ class Tuple(ExprNode): """Tuple(elts: list[AST | CPtr], ctx: CInt)""" elts: list[AST*]* ctx: int def __new__(self, pool: memhub.MemManager*, elts: list[AST*]*, ctx: int): ptr: Tuple* = pool.alloc(Tuple.__sizeof__()) if ptr: string.memset(ptr, 0, Tuple.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, elts: list[AST*]*, ctx: int): _init_ast(self, pool, 0, 0) self.elts = elts self.ctx = ctx _set_parent_list(elts, self) def kind(self) -> int: return ASTKind.Tuple def type_name(self) -> str: return "Tuple" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Tuple(elts=") pos = _dump_list(self.elts, buf, size, pos) pos = _emit(buf, size, pos, ", ctx=") pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos # ============================================================ # Slice Node # ============================================================ class Slice(ExprNode): """Slice(lower: AST, upper: AST, step: AST)""" lower: AST* upper: AST* step: AST* def __new__(self, pool: memhub.MemManager*, lower: AST*, upper: AST*, step: AST*): ptr: Slice* = pool.alloc(Slice.__sizeof__()) if ptr: string.memset(ptr, 0, Slice.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, lower: AST*, upper: AST*, step: AST*): _init_ast(self, pool, 0, 0) self.lower = lower self.upper = upper self.step = step def kind(self) -> int: return ASTKind.Slice def type_name(self) -> str: return "Slice" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "Slice(lower=") if self.lower is not None: pos = self.lower.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", upper=") if self.upper is not None: pos = self.upper.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", step=") if self.step is not None: pos = self.step.dump(buf, size, pos) else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ")") return pos # ============================================================ # NamedExpr Node # ============================================================ class NamedExpr(ExprNode): """NamedExpr(target: AST, value: AST)""" target: AST* value: AST* def __new__(self, pool: memhub.MemManager*, target: AST*, value: AST*): ptr: NamedExpr* = pool.alloc(NamedExpr.__sizeof__()) if ptr: string.memset(ptr, 0, NamedExpr.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, target: AST*, value: AST*): _init_ast(self, pool, 0, 0) self.target = target self.value = value def kind(self) -> int: return ASTKind.NamedExpr def type_name(self) -> str: return "NamedExpr" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "NamedExpr(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, ", 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 # ============================================================ # OpNode Node # ============================================================ class OpNode(AST): """OpNode(op: CInt)""" op: int def __new__(self, pool: memhub.MemManager*, op: int): ptr: OpNode* = pool.alloc(OpNode.__sizeof__()) if ptr: string.memset(ptr, 0, OpNode.__sizeof__()) return ptr def __init__(self, pool: memhub.MemManager*, op: int): _init_ast(self, pool, 0, 0) self.op = op def kind(self) -> int: return ASTKind.OpNode def type_name(self) -> str: return "OpNode" def dump(self, buf: str, size: sizet, pos: sizet) -> sizet: pos = _emit(buf, size, pos, "OpNode(op=") pos = _emit(buf, size, pos, _op_name(self.op)) pos = _emit(buf, size, pos, ")") return pos