691 lines
24 KiB
Python
691 lines
24 KiB
Python
# C语法定义模块
|
||
|
||
import ast
|
||
import sys
|
||
import os
|
||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||
|
||
from . import t
|
||
|
||
def _to_str(node):
|
||
if node is None:
|
||
return ''
|
||
if isinstance(node, str):
|
||
return node
|
||
if isinstance(node, list):
|
||
return ' && '.join([_to_str(n) for n in node])
|
||
NodeType = type(node).__name__
|
||
if NodeType == 'Constant':
|
||
return node.value
|
||
elif NodeType == 'ID':
|
||
return node.name
|
||
elif NodeType == 'BinaryOp':
|
||
left = _to_str(node.left)
|
||
right = _to_str(node.right)
|
||
return f'{left} {node.op} {right}'
|
||
elif NodeType == 'UnaryOp':
|
||
expr = _to_str(node.expr)
|
||
return f'{node.op}{expr}'
|
||
else:
|
||
return repr(node)
|
||
|
||
class Asm:
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
if not args:
|
||
return ['__asm__ volatile ("nop");']
|
||
|
||
# ========== 核心变量 ==========
|
||
output_ops = [] # (值表达式, 约束符)
|
||
input_ops = [] # (值表达式, 约束符)
|
||
clobbers = [] # 破坏列表实际值
|
||
operand_seq = 0 # 占位符编号
|
||
|
||
# ========== 核心修复:递归提取ASM_DESCR值(支持|组合) ==========
|
||
def parse_asm_descr(expr):
|
||
"""
|
||
递归解析AST节点,确保获取t.ASM_DESCR的实际值,支持|组合
|
||
处理场景:
|
||
1. t.ASM_DESCR.XXX → 取属性值
|
||
2. t.ASM_DESCR.XXX | t.ASM_DESCR.YYY → 拼接两个值
|
||
3. 常量字符串 → 直接返回
|
||
"""
|
||
# 场景1:位或组合(XXX | YYY)
|
||
if isinstance(expr, ast.BinOp):
|
||
left_val = parse_asm_descr(expr.left)
|
||
right_val = parse_asm_descr(expr.right)
|
||
return left_val + right_val
|
||
|
||
# 场景2:t.ASM_DESCR.XXX 多层属性访问
|
||
elif isinstance(expr, ast.Attribute):
|
||
# 第一步:判断是否是 t.ASM_DESCR 的属性
|
||
if isinstance(expr.value, ast.Attribute):
|
||
# 内层是 t.ASM_DESCR
|
||
if (isinstance(expr.value.value, ast.Name) and
|
||
expr.value.value.id == 't' and
|
||
expr.value.attr == 'ASM_DESCR'):
|
||
# 取 t.ASM_DESCR.XXX 的实际值
|
||
AttrName = expr.attr
|
||
if hasattr(t.ASM_DESCR, AttrName):
|
||
return getattr(t.ASM_DESCR, AttrName, "")
|
||
|
||
# 兼容 t.XXX 简化写法(如果有的话)
|
||
elif isinstance(expr.value, ast.Name) and expr.value.id == 't':
|
||
AttrName = expr.attr
|
||
if hasattr(t.ASM_DESCR, AttrName):
|
||
return getattr(t.ASM_DESCR, AttrName, "")
|
||
|
||
# 场景3:直接传常量(如 "r"、"cc")
|
||
elif isinstance(expr, ast.Constant):
|
||
return expr.value
|
||
|
||
# 其他场景返回空
|
||
return ""
|
||
|
||
# ========== 步骤1:处理f-string中的内联AsmInp/AsmOut ==========
|
||
asm_code = ""
|
||
first_arg = args[0]
|
||
|
||
if isinstance(first_arg, ast.JoinedStr):
|
||
asm_parts = []
|
||
for part in first_arg.values:
|
||
if isinstance(part, ast.Constant):
|
||
asm_parts.append(part.value)
|
||
elif isinstance(part, ast.FormattedValue):
|
||
expr = part.value
|
||
if isinstance(expr, ast.Call) and isinstance(expr.func, ast.Attribute) and expr.func.value.id == 'c':
|
||
# 解析内联的AsmInp/AsmOut
|
||
call_node = expr
|
||
val_ExprNode = translator.HandleExpr(call_node.args[0])[0] if len(call_node.args)>=1 else ""
|
||
if isinstance(val_ExprNode, str):
|
||
val_expr = val_ExprNode
|
||
else:
|
||
try:
|
||
val_expr = str(val_ExprNode)
|
||
except:
|
||
val_expr = ''
|
||
constraint = parse_asm_descr(call_node.args[1]) if len(call_node.args)>=2 else ""
|
||
|
||
if call_node.func.attr == 'AsmOut':
|
||
output_ops.append((val_expr, constraint))
|
||
asm_parts.append(f"%{operand_seq}")
|
||
operand_seq += 1
|
||
elif call_node.func.attr == 'AsmInp':
|
||
input_ops.append((val_expr, constraint))
|
||
asm_parts.append(f"%{operand_seq}")
|
||
operand_seq += 1
|
||
else:
|
||
asm_parts.append(translator.HandleExpr(expr)[0])
|
||
asm_code = ''.join(asm_parts)
|
||
elif isinstance(first_arg, ast.Constant):
|
||
asm_code = first_arg.value
|
||
|
||
# ========== 步骤2:处理参数中的AsmInp/AsmOut和破坏列表 ==========
|
||
def parse_operand(arg):
|
||
"""解析 AsmInp/AsmOut 参数"""
|
||
if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Attribute) and arg.func.value.id == 'c':
|
||
call_node = arg
|
||
val_ExprNode = translator.HandleExpr(call_node.args[0])[0] if len(call_node.args)>=1 else ""
|
||
if isinstance(val_ExprNode, str):
|
||
val_expr = val_ExprNode
|
||
else:
|
||
try:
|
||
val_expr = str(val_ExprNode)
|
||
except:
|
||
val_expr = ''
|
||
constraint = parse_asm_descr(call_node.args[1]) if len(call_node.args)>=2 else ""
|
||
|
||
if call_node.func.attr == 'AsmOut':
|
||
return ('out', val_expr, constraint)
|
||
elif call_node.func.attr == 'AsmInp':
|
||
return ('in', val_expr, constraint)
|
||
return None
|
||
|
||
for arg in args[1:]:
|
||
result = parse_operand(arg)
|
||
if result:
|
||
direction, val_expr, constraint = result
|
||
if direction == 'out':
|
||
output_ops.append((val_expr, constraint))
|
||
operand_seq += 1
|
||
elif direction == 'in':
|
||
input_ops.append((val_expr, constraint))
|
||
operand_seq += 1
|
||
elif isinstance(arg, ast.List):
|
||
# 解析破坏列表(支持|组合)
|
||
for elt in arg.elts:
|
||
clobber_val = parse_asm_descr(elt)
|
||
if clobber_val:
|
||
clobbers.append(clobber_val)
|
||
|
||
# ========== 步骤2.5:处理关键字参数 out 和 op ==========
|
||
for kw in keywords:
|
||
if kw.arg == 'out':
|
||
# 处理 out 关键字参数 (输出操作数)
|
||
if isinstance(kw.value, ast.List):
|
||
for elt in kw.value.elts:
|
||
result = parse_operand(elt)
|
||
if result and result[0] == 'out':
|
||
output_ops.append((result[1], result[2]))
|
||
operand_seq += 1
|
||
elif isinstance(kw.value, ast.Call):
|
||
result = parse_operand(kw.value)
|
||
if result and result[0] == 'out':
|
||
output_ops.append((result[1], result[2]))
|
||
operand_seq += 1
|
||
elif kw.arg == 'op':
|
||
# 处理 op 关键字参数 (clobber,破坏列表)
|
||
if isinstance(kw.value, ast.List):
|
||
for elt in kw.value.elts:
|
||
clobber_val = parse_asm_descr(elt)
|
||
if clobber_val:
|
||
clobbers.append(clobber_val)
|
||
elif kw.arg == 'inp' or kw.arg == 'inputs':
|
||
# 处理 inp/inputs 关键字参数 (输入操作数,追加到f-string中已有输入之后)
|
||
if isinstance(kw.value, ast.List):
|
||
for elt in kw.value.elts:
|
||
if isinstance(elt, ast.Tuple):
|
||
# 处理列表中的 (value, constraint) 元组格式
|
||
if len(elt.elts) >= 2:
|
||
val_ExprNode = translator.HandleExpr(elt.elts[0])[0] if len(elt.elts) >= 1 else ""
|
||
if isinstance(val_ExprNode, str):
|
||
val_expr = val_ExprNode
|
||
else:
|
||
try:
|
||
val_expr = str(val_ExprNode)
|
||
except:
|
||
val_expr = ''
|
||
constraint = parse_asm_descr(elt.elts[1])
|
||
input_ops.append((val_expr, constraint))
|
||
operand_seq += 1
|
||
else:
|
||
result = parse_operand(elt)
|
||
if result and result[0] == 'in':
|
||
input_ops.append((result[1], result[2]))
|
||
operand_seq += 1
|
||
elif isinstance(kw.value, ast.Call):
|
||
result = parse_operand(kw.value)
|
||
if result and result[0] == 'in':
|
||
input_ops.append((result[1], result[2]))
|
||
operand_seq += 1
|
||
elif isinstance(kw.value, ast.Tuple):
|
||
# 处理 (value, constraint) 元组格式
|
||
if len(kw.value.elts) >= 2:
|
||
val_ExprNode = translator.HandleExpr(kw.value.elts[0])[0] if len(kw.value.elts) >= 1 else ""
|
||
if isinstance(val_ExprNode, str):
|
||
val_expr = val_ExprNode
|
||
else:
|
||
try:
|
||
val_expr = str(val_ExprNode)
|
||
except:
|
||
val_expr = ''
|
||
constraint = parse_asm_descr(kw.value.elts[1])
|
||
input_ops.append((val_expr, constraint))
|
||
operand_seq += 1
|
||
elif kw.arg == 'clobber':
|
||
# 处理 clobber 关键字参数
|
||
if isinstance(kw.value, ast.List):
|
||
for elt in kw.value.elts:
|
||
clobber_val = parse_asm_descr(elt)
|
||
if clobber_val:
|
||
clobbers.append(clobber_val)
|
||
|
||
# ========== 步骤3:格式化汇编代码 ==========
|
||
asm_lines = [line.strip() for line in asm_code.split('\n') if line.strip()]
|
||
formatted_asm = '\n '.join([f'"{line}\\n"' for line in asm_lines])
|
||
|
||
# ========== 步骤4:拼接约束字符串 ==========
|
||
# 输出约束:如果约束已包含 = 或 +,直接使用;否则添加 =
|
||
def format_constraint(constraint, is_output=True):
|
||
if not constraint:
|
||
return ""
|
||
# 如果约束已包含修饰符,直接返回
|
||
if '=' in constraint or '+' in constraint:
|
||
return constraint
|
||
# 否则添加适当的修饰符
|
||
return ('=' if is_output else '') + constraint
|
||
|
||
out_const = ', '.join([f'"{format_constraint(c, True)}"({v})' for v, c in output_ops]) if output_ops else ""
|
||
in_const = ', '.join([f'"{format_constraint(c, False)}"({v})' for v, c in input_ops]) if input_ops else ""
|
||
clobber_const = ', '.join([f'"{x}"' for x in clobbers]) if clobbers else ""
|
||
|
||
# 构建约束部分:确保冒号格式正确
|
||
constraint_parts = []
|
||
# 输出约束
|
||
if output_ops:
|
||
constraint_parts.append(f': {out_const}')
|
||
elif input_ops or clobbers:
|
||
constraint_parts.append(':')
|
||
|
||
# 输入约束
|
||
if input_ops:
|
||
constraint_parts.append(f': {in_const}')
|
||
elif clobbers:
|
||
constraint_parts.append(':')
|
||
|
||
# 破坏列表
|
||
if clobbers:
|
||
constraint_parts.append(f': {clobber_const}')
|
||
|
||
constraint_str = ' '.join(constraint_parts)
|
||
|
||
# ========== 生成最终代码 ==========
|
||
final_asm = f'__asm__ __volatile__ (\n {formatted_asm} {constraint_str});'
|
||
return [final_asm]
|
||
|
||
class AsmInp:
|
||
def __init__(self, value, constraint):
|
||
self.value = value
|
||
self.constraint = constraint
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
return []
|
||
|
||
class AsmOut:
|
||
def __init__(self, value, constraint):
|
||
self.value = value
|
||
self.constraint = constraint
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
return []
|
||
|
||
class NoBreak:
|
||
""" switch 分支无break """
|
||
pass
|
||
|
||
class Break:
|
||
""" switch 分支提前break """
|
||
pass
|
||
|
||
class Load:
|
||
"""解引用a写入b,等价于 *b = *a,无拷贝副作用"""
|
||
def __init__(self, src, dst):
|
||
self.src = src
|
||
self.dst = dst
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
if len(args) >= 2:
|
||
src = translator.HandleExpr(args[0])[0]
|
||
dst = translator.HandleExpr(args[1])[0]
|
||
return [f'*({dst}) = *({src})']
|
||
return []
|
||
|
||
|
||
class Addr:
|
||
"""取地址"""
|
||
def __init__(self, addr):
|
||
self.addr = addr
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.Addr() 调用"""
|
||
if args:
|
||
expr = translator.HandleExpr(args[0])[0]
|
||
if isinstance(expr, str):
|
||
return [f'&{expr}']
|
||
return [f'&{_to_str(expr)}']
|
||
return ['0']
|
||
|
||
|
||
class Deref:
|
||
"""解引用"""
|
||
def __init__(self, ptr):
|
||
self.ptr = ptr
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.Deref() 调用"""
|
||
if args:
|
||
expr = translator.HandleExpr(args[0])[0]
|
||
if hasattr(expr, 'op') and expr.op == '*':
|
||
return [expr]
|
||
return [f'*({_to_str(expr)})']
|
||
return ['0']
|
||
|
||
|
||
class DerefAs:
|
||
"""解引用写入,等价于 *ptr = value"""
|
||
def __init__(self, ptr, value):
|
||
self.ptr = ptr
|
||
self.value = value
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.DerefAs() 调用"""
|
||
if len(args) >= 2:
|
||
ptr = translator.HandleExpr(args[0])[0]
|
||
val = translator.HandleExpr(args[1])[0]
|
||
return [f'*({_to_str(ptr)}) = {_to_str(val)}']
|
||
return []
|
||
|
||
|
||
class Set:
|
||
"""设置值"""
|
||
def __init__(self, key, value):
|
||
self.key = key
|
||
self.value = value
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.Set() 调用"""
|
||
if len(args) >= 2:
|
||
target = translator.HandleExpr(args[0])[0]
|
||
value = translator.HandleExpr(args[1])[0]
|
||
return [f'{_to_str(target)} = {_to_str(value)}']
|
||
return []
|
||
|
||
|
||
class CReturn:
|
||
"""多返回值装饰器
|
||
|
||
用于实现函数多返回值,通过匿名结构体返回实现。
|
||
例如:@c.CReturn(t.CInt, t.CInt) 表示函数返回两个 int 值。
|
||
等价于 -> tuple[t.CInt, t.CInt] 返回类型注解。
|
||
|
||
规则:
|
||
1. CReturn 中有几个类型就说明要返回几个值
|
||
2. 函数返回类型为匿名结构体 { type1, type2, ... }
|
||
3. return 语句使用 insert_value 构建结构体
|
||
4. 调用处使用 extract_value 提取各字段
|
||
"""
|
||
def __init__(self, *ReturnTypes):
|
||
self.ReturnTypes = ReturnTypes
|
||
|
||
def __call__(self, func):
|
||
"""装饰器调用"""
|
||
# 将返回类型信息附加到函数上
|
||
func._CreturnTypes = self.ReturnTypes
|
||
return func
|
||
|
||
|
||
class CDefine:
|
||
"""#define 宏定义"""
|
||
def __init__(self, name, value):
|
||
self.name = name
|
||
self.value = value
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CDefine() 调用"""
|
||
if len(args) >= 1:
|
||
if isinstance(args[0], ast.Constant):
|
||
name = args[0].value
|
||
else:
|
||
name = 'MACRO'
|
||
if len(args) >= 2:
|
||
value = translator.HandleExpr(args[1])[0]
|
||
return ['#define ' + str(name) + ' ' + _to_str(value)]
|
||
return ['#define ' + str(name)]
|
||
return []
|
||
|
||
|
||
class CIfndef:
|
||
"""#ifndef 条件编译"""
|
||
def __init__(self, condition):
|
||
self.condition = condition
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CIfndef() 调用"""
|
||
if args:
|
||
condition = translator.HandleExpr(args[0])[0]
|
||
return ['#ifndef ' + _to_str(condition)]
|
||
return ['#if 0']
|
||
|
||
class CIfdef:
|
||
"""#ifdef 条件编译"""
|
||
def __init__(self, condition):
|
||
self.condition = condition
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CIfdef() 调用"""
|
||
if args:
|
||
condition = translator.HandleExpr(args[0])[0]
|
||
return ['#ifdef ' + _to_str(condition)]
|
||
return ['#if 0']
|
||
|
||
class CError:
|
||
"""#error 错误信息"""
|
||
def __init__(self, condition):
|
||
self.condition = condition
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CError() 调用"""
|
||
if args:
|
||
# 如果是字符串常量,保留引号
|
||
if isinstance(args[0], ast.Constant) and isinstance(args[0].value, str):
|
||
return ['#error "' + args[0].value + '"']
|
||
elif isinstance(args[0], ast.Str):
|
||
return ['#error "' + args[0].s + '"']
|
||
else:
|
||
condition = translator.HandleExpr(args[0])[0]
|
||
return ['#error ' + _to_str(condition)]
|
||
return ['#error "Error: Condition is not met."']
|
||
|
||
|
||
class TokenPast:
|
||
"""## 连接符"""
|
||
def __init__(self, left, right):
|
||
self.left = left
|
||
self.right = right
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.TokenPast() 调用"""
|
||
if len(args) >= 2:
|
||
# 处理左操作数 - 去掉引号
|
||
if isinstance(args[0], ast.Constant):
|
||
left = str(args[0].value)
|
||
elif isinstance(args[0], ast.Str):
|
||
left = str(args[0].s)
|
||
elif isinstance(args[0], ast.Name):
|
||
left = args[0].id
|
||
else:
|
||
left = _to_str(translator.HandleExpr(args[0])[0])
|
||
|
||
# 处理右操作数 - 去掉引号
|
||
if isinstance(args[1], ast.Constant):
|
||
right = str(args[1].value)
|
||
elif isinstance(args[1], ast.Str):
|
||
right = str(args[1].s)
|
||
elif isinstance(args[1], ast.Name):
|
||
right = args[1].id
|
||
else:
|
||
right = _to_str(translator.HandleExpr(args[1])[0])
|
||
|
||
# 返回字符串,但用特殊标记包装,让 _AstNodeToStr 能正确处理
|
||
result = left + ' ## ' + right
|
||
# 使用一个特殊的类来包装结果,让 _AstNodeToStr 直接返回其值
|
||
class TokenPastResult:
|
||
def __init__(self, value):
|
||
self.value = value
|
||
def __str__(self):
|
||
return self.value
|
||
return [TokenPastResult(result)]
|
||
return ['']
|
||
|
||
|
||
class CIf:
|
||
"""#if 条件编译"""
|
||
def __init__(self, condition):
|
||
self.condition = condition
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CIf() 调用"""
|
||
if args:
|
||
condition = translator.HandleExpr(args[0])[0]
|
||
return ['#if ' + _to_str(condition)]
|
||
return ['#if 0']
|
||
|
||
|
||
class CElif:
|
||
"""#elif 条件编译"""
|
||
def __init__(self, condition):
|
||
self.condition = condition
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CElif() 调用"""
|
||
if args:
|
||
condition = translator.HandleExpr(args[0])[0]
|
||
return ['#elif ' + _to_str(condition)]
|
||
return ['#else']
|
||
|
||
|
||
class CElse:
|
||
"""#else 条件编译"""
|
||
def __init__(self):
|
||
pass
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CElse() 调用"""
|
||
return ['#else']
|
||
|
||
|
||
class CEndif:
|
||
"""#endif 条件编译"""
|
||
def __init__(self):
|
||
pass
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CEndif() 调用"""
|
||
return ['#endif']
|
||
|
||
|
||
class CUndef:
|
||
"""#undef 取消宏定义"""
|
||
def __init__(self, name):
|
||
self.name = name
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CUndef(name) 调用"""
|
||
import ast
|
||
if args:
|
||
arg = args[0]
|
||
if isinstance(arg, str):
|
||
name = arg
|
||
elif isinstance(arg, ast.Name):
|
||
name = arg.id
|
||
elif isinstance(arg, ast.Constant):
|
||
name = str(arg.value)
|
||
else:
|
||
name = str(arg)
|
||
return [f'#undef {name}']
|
||
return ['#undef']
|
||
|
||
|
||
class LLVMIR:
|
||
"""内联 LLVM IR
|
||
|
||
用法: c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||
或: c.LLVMIR(f"%{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||
|
||
c.LInp(expr) - 输入操作数,翻译后替换为对应的 LLVM 临时变量名
|
||
c.LOut(expr) - 输出操作数,翻译后替换为对应的 LLVM 临时变量名
|
||
"""
|
||
def __init__(self, ir_template, ret_type=None):
|
||
self.ir_template = ir_template
|
||
self.ret_type = ret_type
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
return ['/* LLVMIR */']
|
||
|
||
|
||
class LInp:
|
||
"""LLVM IR 输入操作数标记
|
||
|
||
用法: c.LInp(expr) - 标记 expr 为输入操作数
|
||
在 c.LLVMIR 的 f-string 中使用,翻译后替换为 %N 形式的操作数引用
|
||
"""
|
||
def __init__(self, value):
|
||
self.value = value
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
return []
|
||
|
||
|
||
class LOut:
|
||
"""LLVM IR 输出操作数标记
|
||
|
||
用法: c.LOut(expr) - 标记 expr 为输出操作数
|
||
在 c.LLVMIR 的 f-string 中使用,翻译后替换为 %N 形式的操作数引用
|
||
"""
|
||
def __init__(self, value):
|
||
self.value = value
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
return []
|
||
|
||
|
||
class CPragma:
|
||
"""#pragma 指令
|
||
|
||
用于生成 C 语言的 #pragma 指令。
|
||
例如:c.CPragma("GCC diagnostic push") 生成 #pragma GCC diagnostic push
|
||
"""
|
||
def __init__(self, directive):
|
||
self.directive = directive
|
||
|
||
@staticmethod
|
||
def HandleCall(translator, args, keywords):
|
||
"""处理 c.CPragma() 调用"""
|
||
if args:
|
||
arg = args[0]
|
||
if isinstance(arg, ast.Constant):
|
||
directive = arg.value
|
||
elif isinstance(arg, ast.Str):
|
||
directive = arg.s
|
||
else:
|
||
expr = translator.HandleExpr(arg)[0]
|
||
directive = _to_str(expr)
|
||
return [f'#pragma {directive}']
|
||
return ['#pragma']
|
||
|
||
|
||
# C 库类字典,用于 HandleCSpecialCall
|
||
Library_C = {
|
||
'Asm': Asm,
|
||
'Load': Load,
|
||
'Addr': Addr,
|
||
'Deref': Deref,
|
||
'Set': Set,
|
||
'AsmInp': AsmInp,
|
||
'AsmOut': AsmOut,
|
||
'CDefine': CDefine,
|
||
'CIfndef': CIfndef,
|
||
'CIfdef': CIfdef,
|
||
'CIf': CIf,
|
||
'CElif': CElif,
|
||
'CElse': CElse,
|
||
'CEndif': CEndif,
|
||
'CUndef': CUndef,
|
||
'CError': CError,
|
||
'TokenPast': TokenPast,
|
||
'CReturn': CReturn,
|
||
'CPragma': CPragma,
|
||
'LLVMIR': LLVMIR,
|
||
'LInp': LInp,
|
||
'LOut': LOut,
|
||
}
|
||
|
||
|
||
class Attribute:
|
||
"""函数/变量属性装饰器"""
|
||
def __init__(self, *attrs):
|
||
self.attrs = attrs
|
||
|
||
def __call__(self, func):
|
||
# 将属性附加到函数上
|
||
func._c_attributes = self.attrs
|
||
return func
|