Files
Viper_VRTE/ast/exprs.vp
T
2026-09-16 16:07:35 +08:00

1290 lines
42 KiB
Plaintext

import t, c
from stdint import *
import memhub
import string
import stdio
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: rawptr[memhub.MemManager],
id: str, ctx: int):
ptr: rawptr[Name] = pool.alloc(Name.__sizeof__())
if ptr:
string.memset(ptr, 0, Name.__sizeof__())
return ptr
def __init__(self, pool: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[Name]) -> str:
"""获取 Name.id 字段(跨模块访问器,stub 字段访问陷阱防护)"""
if node is None:
return None
return node.id
def constant_get_str_val(node: rawptr[Constant]) -> str:
"""获取 Constant.str_val 字段(跨模块访问器)"""
if node is None:
return None
return node.str_val
def binop_get_left(node: rawptr[BinOp]) -> rawptr[AST]:
"""获取 BinOp.left 字段(跨模块访问器)"""
if node is None:
return None
return node.left
def binop_get_right(node: rawptr[BinOp]) -> rawptr[AST]:
"""获取 BinOp.right 字段(跨模块访问器)"""
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
def __new__(self, pool: rawptr[memhub.MemManager],
const_kind: int, int_val: int64,
float_val: double, str_val: str,
lineno: int, col: int):
ptr: rawptr[Constant] = pool.alloc(Constant.__sizeof__())
if ptr:
string.memset(ptr, 0, Constant.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
const_kind: int, int_val: int64,
float_val: double, str_val: str,
lineno: int, col: int):
_init_ast(self, pool, lineno, col)
self.const_kind = const_kind
self.int_val = int_val
self.float_val = float_val
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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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, "<float>")
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: rawptr[AST]
op: int
right: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
left: rawptr[AST], op: int, right: rawptr[AST]):
ptr: rawptr[BinOp] = pool.alloc(BinOp.__sizeof__())
if ptr:
string.memset(ptr, 0, BinOp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
left: rawptr[AST], op: int, right: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
op: int, operand: rawptr[AST]):
ptr: rawptr[UnaryOp] = pool.alloc(UnaryOp.__sizeof__())
if ptr:
string.memset(ptr, 0, UnaryOp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
op: int, operand: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
ops: t.CPtr
comparators: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
left: rawptr[AST],
ops: t.CPtr,
comparators: rawptr[list[rawptr[AST]]]):
ptr: rawptr[Compare] = pool.alloc(Compare.__sizeof__())
if ptr:
string.memset(ptr, 0, Compare.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
left: rawptr[AST],
ops: t.CPtr,
comparators: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
args: rawptr[list[rawptr[AST]]]
keywords: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
func: rawptr[AST],
args: rawptr[list[rawptr[AST]]],
keywords: rawptr[list[rawptr[AST]]]):
ptr: rawptr[Call] = pool.alloc(Call.__sizeof__())
if ptr:
string.memset(ptr, 0, Call.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
func: rawptr[AST],
args: rawptr[list[rawptr[AST]]],
keywords: rawptr[list[rawptr[AST]]]):
_init_ast(self, pool, 0, 0)
self.func = func
self.args = args
self.keywords = keywords
_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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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
# ============================================================
# BoolOp Node
# ============================================================
class BoolOp(ExprNode):
"""BoolOp(op: CInt, values: list[AST | CPtr])"""
op: int
values: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
op: int,
values: rawptr[list[rawptr[AST]]]):
ptr: rawptr[BoolOp] = pool.alloc(BoolOp.__sizeof__())
if ptr:
string.memset(ptr, 0, BoolOp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
op: int,
values: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
body: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
args: rawptr[AST], body: rawptr[AST]):
ptr: rawptr[Lambda] = pool.alloc(Lambda.__sizeof__())
if ptr:
string.memset(ptr, 0, Lambda.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
args: rawptr[AST], body: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
body: rawptr[AST]
orelse: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
test: rawptr[AST], body: rawptr[AST],
orelse: rawptr[AST]):
ptr: rawptr[IfExp] = pool.alloc(IfExp.__sizeof__())
if ptr:
string.memset(ptr, 0, IfExp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
test: rawptr[AST], body: rawptr[AST],
orelse: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[list[rawptr[AST]]]
values: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
keys: rawptr[list[rawptr[AST]]],
values: rawptr[list[rawptr[AST]]]):
ptr: rawptr[Dict] = pool.alloc(Dict.__sizeof__())
if ptr:
string.memset(ptr, 0, Dict.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
keys: rawptr[list[rawptr[AST]]],
values: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
elts: rawptr[list[rawptr[AST]]]):
ptr: rawptr[Set] = pool.alloc(Set.__sizeof__())
if ptr:
string.memset(ptr, 0, Set.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
elts: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
generators: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
elt: rawptr[AST],
generators: rawptr[list[rawptr[AST]]]):
ptr: rawptr[ListComp] = pool.alloc(ListComp.__sizeof__())
if ptr:
string.memset(ptr, 0, ListComp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
elt: rawptr[AST],
generators: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
generators: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
elt: rawptr[AST],
generators: rawptr[list[rawptr[AST]]]):
ptr: rawptr[SetComp] = pool.alloc(SetComp.__sizeof__())
if ptr:
string.memset(ptr, 0, SetComp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
elt: rawptr[AST],
generators: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
value: rawptr[AST]
generators: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
key: rawptr[AST], value: rawptr[AST],
generators: rawptr[list[rawptr[AST]]]):
ptr: rawptr[DictComp] = pool.alloc(DictComp.__sizeof__())
if ptr:
string.memset(ptr, 0, DictComp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
key: rawptr[AST], value: rawptr[AST],
generators: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
generators: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
elt: rawptr[AST],
generators: rawptr[list[rawptr[AST]]]):
ptr: rawptr[GeneratorExp] = pool.alloc(GeneratorExp.__sizeof__())
if ptr:
string.memset(ptr, 0, GeneratorExp.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
elt: rawptr[AST],
generators: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager], value: rawptr[AST]):
ptr: rawptr[Await] = pool.alloc(Await.__sizeof__())
if ptr:
string.memset(ptr, 0, Await.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager], value: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager], value: rawptr[AST]):
ptr: rawptr[Yield] = pool.alloc(Yield.__sizeof__())
if ptr:
string.memset(ptr, 0, Yield.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager], value: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager], value: rawptr[AST]):
ptr: rawptr[YieldFrom] = pool.alloc(YieldFrom.__sizeof__())
if ptr:
string.memset(ptr, 0, YieldFrom.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager], value: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
conversion: int
format_spec: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
value: rawptr[AST], conversion: int,
format_spec: rawptr[AST]):
ptr: rawptr[FormattedValue] = pool.alloc(FormattedValue.__sizeof__())
if ptr:
string.memset(ptr, 0, FormattedValue.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
value: rawptr[AST], conversion: int,
format_spec: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[list[rawptr[AST]]]
def __new__(self, pool: rawptr[memhub.MemManager],
values: rawptr[list[rawptr[AST]]]):
ptr: rawptr[JoinedStr] = pool.alloc(JoinedStr.__sizeof__())
if ptr:
string.memset(ptr, 0, JoinedStr.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
values: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
attr: str
ctx: int
def __new__(self, pool: rawptr[memhub.MemManager],
value: rawptr[AST], attr: str, ctx: int):
ptr: rawptr[Attribute] = pool.alloc(Attribute.__sizeof__())
if ptr:
string.memset(ptr, 0, Attribute.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
value: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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
# ============================================================
# 字段访问器(跨模块 stub 字段访问陷阱防护)
#
# 其他模块(如 TypeGenCType)直接访问 ast.Attribute 的字段时,
# TPC 可能按 stub 类型生成错误 GEP(读垃圾地址 → 0xC0000005 崩溃)。
# 本模块是完整类型,字段偏移正确;跨模块调用方用这些访问器。
# ============================================================
def attribute_get_value(node: rawptr[Attribute]) -> rawptr[AST]:
"""获取 Attribute.value 字段(跨模块访问器)"""
if node is None:
return None
return node.value
def attribute_get_attr(node: rawptr[Attribute]) -> str:
"""获取 Attribute.attr 字段(跨模块访问器)"""
if node is None:
return None
return node.attr
# ============================================================
# Subscript Node
# ============================================================
class Subscript(ExprNode):
"""Subscript(value: AST, slice: AST, ctx: CInt)"""
value: rawptr[AST]
slice: rawptr[AST]
ctx: int
def __new__(self, pool: rawptr[memhub.MemManager],
value: rawptr[AST], slice: rawptr[AST], ctx: int):
ptr: rawptr[Subscript] = pool.alloc(Subscript.__sizeof__())
if ptr:
string.memset(ptr, 0, Subscript.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
value: rawptr[AST], slice: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
ctx: int
def __new__(self, pool: rawptr[memhub.MemManager],
value: rawptr[AST], ctx: int):
ptr: rawptr[Starred] = pool.alloc(Starred.__sizeof__())
if ptr:
string.memset(ptr, 0, Starred.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
value: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[list[rawptr[AST]]]
ctx: int
def __new__(self, pool: rawptr[memhub.MemManager],
elts: rawptr[list[rawptr[AST]]], ctx: int):
ptr: rawptr[List] = pool.alloc(List.__sizeof__())
if ptr:
string.memset(ptr, 0, List.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
elts: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[list[rawptr[AST]]]
ctx: int
def __new__(self, pool: rawptr[memhub.MemManager],
elts: rawptr[list[rawptr[AST]]], ctx: int):
ptr: rawptr[Tuple] = pool.alloc(Tuple.__sizeof__())
if ptr:
string.memset(ptr, 0, Tuple.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
elts: rawptr[list[rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
upper: rawptr[AST]
step: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
lower: rawptr[AST], upper: rawptr[AST],
step: rawptr[AST]):
ptr: rawptr[Slice] = pool.alloc(Slice.__sizeof__())
if ptr:
string.memset(ptr, 0, Slice.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
lower: rawptr[AST], upper: rawptr[AST],
step: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[AST]
value: rawptr[AST]
def __new__(self, pool: rawptr[memhub.MemManager],
target: rawptr[AST], value: rawptr[AST]):
ptr: rawptr[NamedExpr] = pool.alloc(NamedExpr.__sizeof__())
if ptr:
string.memset(ptr, 0, NamedExpr.__sizeof__())
return ptr
def __init__(self, pool: rawptr[memhub.MemManager],
target: rawptr[AST], value: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
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: rawptr[memhub.MemManager], op: int):
ptr: rawptr[OpNode] = pool.alloc(OpNode.__sizeof__())
if ptr:
string.memset(ptr, 0, OpNode.__sizeof__())
return ptr
def __init__(self, pool: rawptr[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: t.CSizeT,
pos: t.CSizeT) -> t.CSizeT:
pos = _emit(buf, size, pos, "OpNode(op=")
pos = _emit(buf, size, pos, _op_name(self.op))
pos = _emit(buf, size, pos, ")")
return pos