feat(tpc): 新增单目 * / & 运算符(Deref/AddrOf)AST 节点与 LLVM 翻译

This commit is contained in:
TermiNexus committed 2026-08-28 07:34:58 +08:00
1 parent d6150bd595
commit 0230385891
7 files changed
+67 -7

No files matched your search

+33
View File
@@ -248,6 +248,39 @@ class ExprOpsHandle(BaseHandle):
return Gen.builder.neg(OperandVal, name="neg_result")
elif isinstance(OperandVal.type, (ir.FloatType, ir.DoubleType)):
return Gen.builder.fneg(OperandVal, name="fneg_result")
elif OpSymbol == '*':
# 单目解引用:*p = load(p),要求操作数是指针
if not isinstance(OperandVal.type, ir.PointerType):
raise TypeError(
f"[fast-fail] 单目 '*' 解引用的操作数必须是指针类型,"
f"实际为 {OperandVal.type}"
)
return Gen._load(OperandVal, name="deref")
elif OpSymbol == '&':
# 单目取地址:&x 返回变量/字段/下标的地址(T*)
if isinstance(Node.operand, ast.Name):
VarName: str = Node.operand.id
if VarName in Gen.functions:
return Gen.functions[VarName]
if VarName in Gen.variables and Gen.variables[VarName] is not None:
var_ptr: ir.Value = Gen.variables[VarName]
if isinstance(var_ptr.type, ir.PointerType) and isinstance(var_ptr.type.pointee, ir.PointerType):
# T**:若 T 是 struct 类(变量语义即对象),返回对象指针
if isinstance(var_ptr.type.pointee.pointee, ir.IdentifiedStructType):
return self.HandleExprLlvm(Node.operand)
return var_ptr
elif isinstance(Node.operand, ast.Attribute):
AttrPtr: ir.Value | None = self.Trans.ExprAttrHandle._get_attr_ptr(Node.operand)
if AttrPtr and isinstance(AttrPtr.type, ir.PointerType):
return AttrPtr
elif isinstance(Node.operand, ast.Subscript):
SubPtr: ir.Value | None = self.Trans.ExprAttrHandle.HandleSubscriptPtrLlvm(Node.operand)
if SubPtr and isinstance(SubPtr.type, ir.PointerType):
return SubPtr
raise TypeError(
f"[fast-fail] 单目 '&' 取地址的操作数必须是左值"
f"(Name/Attribute/Subscript),实际为 {type(Node.operand).__name__}"
)
return None
def _HandleCompareLlvm(self, Node: ast.Compare) -> ir.Value | None:
+14 -2
View File
@@ -22,7 +22,10 @@ class ExprUtils:
return OpMap.get(type(Op), None)
def GetUnaryOpSymbol(self, Op: ast.unaryoperator) -> str | None:
OpMap: dict[type, str] = {ast.Invert: '~', ast.Not: 'not', ast.UAdd: '+', ast.USub: '-'}
OpMap: dict[type, str] = {
ast.Invert: '~', ast.Not: 'not', ast.UAdd: '+', ast.USub: '-',
ast.Deref: '*', ast.AddrOf: '&',
}
return OpMap.get(type(Op), None)
def GetComparatorSymbol(self, Op: ast.cmpop) -> str | None:
@@ -241,7 +244,16 @@ class ExprUtils:
return ir.PointerType(ir.IntType(8))
return ir.IntType(32)
elif isinstance(node, ast.UnaryOp):
return self._infer_expr_llvm_type_full(node.operand)
op_inner: ir.Type = self._infer_expr_llvm_type_full(node.operand)
if isinstance(node.op, ast.Deref):
# *p → pointee 类型
if isinstance(op_inner, ir.PointerType):
return op_inner.pointee
return op_inner
if isinstance(node.op, ast.AddrOf):
# &x → T*(取地址即指针)
return ir.PointerType(op_inner)
return op_inner
elif isinstance(node, ast.Subscript):
val_type: ir.Type = self._infer_expr_llvm_type_full(node.value)
if isinstance(val_type, ir.PointerType):