snapshot before regression test
This commit is contained in:
1
lib/includes/__init__.py
Normal file
1
lib/includes/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""类型系统与 C 语法定义 (t.py / c.py)"""
|
||||
721
lib/includes/c.py
Normal file
721
lib/includes/c.py
Normal file
@@ -0,0 +1,721 @@
|
||||
# C语法定义模块
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import logging
|
||||
from typing import Any, Optional
|
||||
|
||||
from . import t
|
||||
from lib.constants.config import mode as _config_mode
|
||||
|
||||
def _to_str(node: Any) -> str:
|
||||
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: str = type(node).__name__
|
||||
if NodeType == 'Constant':
|
||||
return node.value
|
||||
elif NodeType == 'ID':
|
||||
return node.name
|
||||
elif NodeType == 'BinaryOp':
|
||||
left: str = _to_str(node.left)
|
||||
right: str = _to_str(node.right)
|
||||
return f'{left} {node.op} {right}'
|
||||
elif NodeType == 'UnaryOp':
|
||||
expr: str = _to_str(node.expr)
|
||||
return f'{node.op}{expr}'
|
||||
else:
|
||||
return repr(node)
|
||||
|
||||
class Asm:
|
||||
@staticmethod
|
||||
def _parse_asm_descr(expr: ast.AST) -> str:
|
||||
"""递归解析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: str = Asm._parse_asm_descr(expr.left)
|
||||
right_val: str = Asm._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: str = 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: str = 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 ""
|
||||
|
||||
@staticmethod
|
||||
def _extract_val_expr(translator: Any, expr_node: ast.AST) -> str:
|
||||
"""从AST表达式节点提取值表达式的字符串形式"""
|
||||
val_ExprNode: Any = translator.HandleExpr(expr_node)[0]
|
||||
if isinstance(val_ExprNode, str):
|
||||
return val_ExprNode
|
||||
try:
|
||||
return str(val_ExprNode)
|
||||
except Exception as _e:
|
||||
if _config_mode == "strict":
|
||||
logging.warning(f"异常被忽略: {_e}")
|
||||
return ''
|
||||
|
||||
@staticmethod
|
||||
def _parse_asm_template(translator: Any, args: list[ast.AST]) -> tuple[str, list[tuple[str, str]], list[tuple[str, str]], int]:
|
||||
"""解析f-string或常量模板字符串,返回(asm_code, output_ops, input_ops, operand_seq)"""
|
||||
output_ops: list[tuple[str, str]] = []
|
||||
input_ops: list[tuple[str, str]] = []
|
||||
operand_seq: int = 0
|
||||
asm_code: str = ""
|
||||
first_arg: ast.AST = args[0]
|
||||
|
||||
if isinstance(first_arg, ast.JoinedStr):
|
||||
asm_parts: list[str] = []
|
||||
for part in first_arg.values:
|
||||
if isinstance(part, ast.Constant):
|
||||
asm_parts.append(part.value)
|
||||
elif isinstance(part, ast.FormattedValue):
|
||||
expr: ast.AST = part.value
|
||||
if isinstance(expr, ast.Call) and isinstance(expr.func, ast.Attribute) and expr.func.value.id == 'c':
|
||||
# 解析内联的AsmInp/AsmOut
|
||||
call_node: ast.Call = expr
|
||||
val_expr: str = Asm._extract_val_expr(translator, call_node.args[0]) if len(call_node.args)>=1 else ""
|
||||
constraint: str = Asm._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
|
||||
|
||||
return asm_code, output_ops, input_ops, operand_seq
|
||||
|
||||
@staticmethod
|
||||
def _parse_asm_operands(translator: Any, args: list[ast.AST], keywords: list[ast.keyword], output_ops: list[tuple[str, str]], input_ops: list[tuple[str, str]], operand_seq: int) -> tuple[list[tuple[str, str]], list[tuple[str, str]], int]:
|
||||
"""解析位置参数和关键字参数中的输出/输入操作数"""
|
||||
|
||||
def parse_operand(arg: ast.AST) -> Optional[tuple[str, str, str]]:
|
||||
"""解析 AsmInp/AsmOut 参数"""
|
||||
if isinstance(arg, ast.Call) and isinstance(arg.func, ast.Attribute) and arg.func.value.id == 'c':
|
||||
call_node: ast.Call = arg
|
||||
val_expr: str = Asm._extract_val_expr(translator, call_node.args[0]) if len(call_node.args)>=1 else ""
|
||||
constraint: str = Asm._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: Optional[tuple[str, str, str]] = 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
|
||||
|
||||
# 处理关键字参数中的操作数
|
||||
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 == '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_expr: str = Asm._extract_val_expr(translator, elt.elts[0]) if len(elt.elts) >= 1 else ""
|
||||
constraint: str = Asm._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_expr: str = Asm._extract_val_expr(translator, kw.value.elts[0]) if len(kw.value.elts) >= 1 else ""
|
||||
constraint: str = Asm._parse_asm_descr(kw.value.elts[1])
|
||||
input_ops.append((val_expr, constraint))
|
||||
operand_seq += 1
|
||||
|
||||
return output_ops, input_ops, operand_seq
|
||||
|
||||
@staticmethod
|
||||
def _parse_asm_clobbers(args: list[ast.AST], keywords: list[ast.keyword]) -> list[str]:
|
||||
"""解析位置参数和关键字参数中的破坏列表"""
|
||||
clobbers: list[str] = []
|
||||
|
||||
# 处理位置参数中的破坏列表
|
||||
for arg in args[1:]:
|
||||
if isinstance(arg, ast.List):
|
||||
# 解析破坏列表(支持|组合)
|
||||
for elt in arg.elts:
|
||||
clobber_val: str = Asm._parse_asm_descr(elt)
|
||||
if clobber_val:
|
||||
clobbers.append(clobber_val)
|
||||
|
||||
# 处理关键字参数中的破坏列表
|
||||
for kw in keywords:
|
||||
if kw.arg == 'op':
|
||||
# 处理 op 关键字参数 (clobber,破坏列表)
|
||||
if isinstance(kw.value, ast.List):
|
||||
for elt in kw.value.elts:
|
||||
clobber_val: str = Asm._parse_asm_descr(elt)
|
||||
if clobber_val:
|
||||
clobbers.append(clobber_val)
|
||||
elif kw.arg == 'clobber':
|
||||
# 处理 clobber 关键字参数
|
||||
if isinstance(kw.value, ast.List):
|
||||
for elt in kw.value.elts:
|
||||
clobber_val: str = Asm._parse_asm_descr(elt)
|
||||
if clobber_val:
|
||||
clobbers.append(clobber_val)
|
||||
|
||||
return clobbers
|
||||
|
||||
@staticmethod
|
||||
def _generate_asm_code(asm_code: str, output_ops: list[tuple[str, str]], input_ops: list[tuple[str, str]], clobbers: list[str], asm_format: str) -> list[str]:
|
||||
"""格式化汇编代码并生成最终的__asm__代码字符串"""
|
||||
# 格式化汇编代码
|
||||
asm_lines: list[str] = [line.strip() for line in asm_code.split('\n') if line.strip()]
|
||||
formatted_asm: str = '\n '.join([f'"{line}\\n"' for line in asm_lines])
|
||||
|
||||
# 拼接约束字符串
|
||||
# 输出约束:如果约束已包含 = 或 +,直接使用;否则添加 =
|
||||
def format_constraint(constraint: str, is_output: bool = True) -> str:
|
||||
if not constraint:
|
||||
return ""
|
||||
# 如果约束已包含修饰符,直接返回
|
||||
if '=' in constraint or '+' in constraint:
|
||||
return constraint
|
||||
# 否则添加适当的修饰符
|
||||
return ('=' if is_output else '') + constraint
|
||||
|
||||
out_const: str = ', '.join([f'"{format_constraint(c, True)}"({v})' for v, c in output_ops]) if output_ops else ""
|
||||
in_const: str = ', '.join([f'"{format_constraint(c, False)}"({v})' for v, c in input_ops]) if input_ops else ""
|
||||
clobber_const: str = ', '.join([f'"{x}"' for x in clobbers]) if clobbers else ""
|
||||
|
||||
# 构建约束部分:确保冒号格式正确
|
||||
constraint_parts: list[str] = []
|
||||
# 输出约束
|
||||
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: str = ' '.join(constraint_parts)
|
||||
|
||||
# 生成最终代码
|
||||
if asm_format == 'ARM':
|
||||
# ARM 使用 .arch 指令和不同的内联汇编语法
|
||||
final_asm: str = f'__asm__ __volatile__ (\n {formatted_asm} {constraint_str});'
|
||||
elif asm_format == 'AT&T':
|
||||
# AT&T 语法不需要额外标记,GCC 默认就是 AT&T
|
||||
final_asm = f'__asm__ __volatile__ (\n {formatted_asm} {constraint_str});'
|
||||
else:
|
||||
# Intel 语法需要 .intel_syntax 指令
|
||||
final_asm = f'__asm__ __volatile__ (".intel_syntax noprefix\\n\\t"\n {formatted_asm} ".att_syntax prefix" {constraint_str});'
|
||||
return [final_asm]
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: list[ast.AST], keywords: list[ast.keyword]) -> list[str]:
|
||||
if not args:
|
||||
return ['__asm__ volatile ("nop");']
|
||||
|
||||
# 解析模板
|
||||
asm_code: str
|
||||
output_ops: list[tuple[str, str]]
|
||||
input_ops: list[tuple[str, str]]
|
||||
operand_seq: int
|
||||
asm_code, output_ops, input_ops, operand_seq = Asm._parse_asm_template(translator, args)
|
||||
|
||||
# 解析操作数
|
||||
output_ops, input_ops, operand_seq = Asm._parse_asm_operands(
|
||||
translator, args, keywords, output_ops, input_ops, operand_seq)
|
||||
|
||||
# 解析破坏列表
|
||||
clobbers: list[str] = Asm._parse_asm_clobbers(args, keywords)
|
||||
|
||||
# 解析汇编格式
|
||||
asm_format: str = 'Intel'
|
||||
for kw in keywords:
|
||||
if kw.arg == 'format':
|
||||
if isinstance(kw.value, ast.Constant) and isinstance(kw.value.value, str):
|
||||
asm_format = kw.value.value
|
||||
|
||||
# 生成最终代码
|
||||
return Asm._generate_asm_code(asm_code, output_ops, input_ops, clobbers, asm_format)
|
||||
|
||||
class AsmInp:
|
||||
def __init__(self, value: Any, constraint: Any) -> None:
|
||||
self.value: Any = value
|
||||
self.constraint: Any = constraint
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]:
|
||||
return []
|
||||
|
||||
class AsmOut:
|
||||
def __init__(self, value: Any, constraint: Any) -> None:
|
||||
self.value: Any = value
|
||||
self.constraint: Any = constraint
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]:
|
||||
return []
|
||||
|
||||
class NoBreak:
|
||||
""" switch 分支无break """
|
||||
pass
|
||||
|
||||
class Break:
|
||||
""" switch 分支提前break """
|
||||
pass
|
||||
|
||||
class Load:
|
||||
"""解引用a写入b,等价于 *b = *a,无拷贝副作用"""
|
||||
def __init__(self, src: Any, dst: Any) -> None:
|
||||
self.src: Any = src
|
||||
self.dst: Any = dst
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
if len(args) >= 2:
|
||||
src: Any = translator.HandleExpr(args[0])[0]
|
||||
dst: Any = translator.HandleExpr(args[1])[0]
|
||||
return [f'*({dst}) = *({src})']
|
||||
return []
|
||||
|
||||
|
||||
class Addr:
|
||||
"""取地址"""
|
||||
def __init__(self, addr: Any) -> None:
|
||||
self.addr: Any = addr
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.Addr() 调用"""
|
||||
if args:
|
||||
expr: Any = 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: Any) -> None:
|
||||
self.ptr: Any = ptr
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.Deref() 调用"""
|
||||
if args:
|
||||
expr: Any = 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: Any, value: Any) -> None:
|
||||
self.ptr: Any = ptr
|
||||
self.value: Any = value
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.DerefAs() 调用"""
|
||||
if len(args) >= 2:
|
||||
ptr: Any = translator.HandleExpr(args[0])[0]
|
||||
val: Any = translator.HandleExpr(args[1])[0]
|
||||
return [f'*({_to_str(ptr)}) = {_to_str(val)}']
|
||||
return []
|
||||
|
||||
|
||||
class Set:
|
||||
"""设置值"""
|
||||
def __init__(self, key: Any, value: Any) -> None:
|
||||
self.key: Any = key
|
||||
self.value: Any = value
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.Set() 调用"""
|
||||
if len(args) >= 2:
|
||||
target: Any = translator.HandleExpr(args[0])[0]
|
||||
value: Any = 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: Any) -> None:
|
||||
self.ReturnTypes: tuple[Any, ...] = ReturnTypes
|
||||
|
||||
def __call__(self, func: Any) -> Any:
|
||||
"""装饰器调用"""
|
||||
# 将返回类型信息附加到函数上
|
||||
func._CreturnTypes = self.ReturnTypes
|
||||
return func
|
||||
|
||||
|
||||
class CDefine:
|
||||
"""#define 宏定义"""
|
||||
def __init__(self, name: Any, value: Any) -> None:
|
||||
self.name: Any = name
|
||||
self.value: Any = value
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CDefine() 调用"""
|
||||
if len(args) >= 1:
|
||||
if isinstance(args[0], ast.Constant):
|
||||
name: Any = args[0].value
|
||||
else:
|
||||
name = 'MACRO'
|
||||
if len(args) >= 2:
|
||||
value: Any = translator.HandleExpr(args[1])[0]
|
||||
return ['#define ' + str(name) + ' ' + _to_str(value)]
|
||||
return ['#define ' + str(name)]
|
||||
return []
|
||||
|
||||
|
||||
class CIfndef:
|
||||
"""#ifndef 条件编译"""
|
||||
def __init__(self, condition: Any) -> None:
|
||||
self.condition: Any = condition
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CIfndef() 调用"""
|
||||
if args:
|
||||
condition: Any = translator.HandleExpr(args[0])[0]
|
||||
return ['#ifndef ' + _to_str(condition)]
|
||||
return ['#if 0']
|
||||
|
||||
class CIfdef:
|
||||
"""#ifdef 条件编译"""
|
||||
def __init__(self, condition: Any) -> None:
|
||||
self.condition: Any = condition
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CIfdef() 调用"""
|
||||
if args:
|
||||
condition: Any = translator.HandleExpr(args[0])[0]
|
||||
return ['#ifdef ' + _to_str(condition)]
|
||||
return ['#if 0']
|
||||
|
||||
class CError:
|
||||
"""#error 错误信息"""
|
||||
def __init__(self, condition: Any) -> None:
|
||||
self.condition: Any = condition
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CError() 调用"""
|
||||
if args:
|
||||
# 如果是字符串常量,保留引号
|
||||
if isinstance(args[0], ast.Constant) and isinstance(args[0].value, str):
|
||||
return ['#error "' + args[0].value + '"']
|
||||
else:
|
||||
condition: Any = translator.HandleExpr(args[0])[0]
|
||||
return ['#error ' + _to_str(condition)]
|
||||
return ['#error "Error: Condition is not met."']
|
||||
|
||||
|
||||
class TokenPast:
|
||||
"""## 连接符"""
|
||||
def __init__(self, left: Any, right: Any) -> None:
|
||||
self.left: Any = left
|
||||
self.right: Any = right
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]:
|
||||
"""处理 c.TokenPast() 调用"""
|
||||
if len(args) >= 2:
|
||||
# 处理左操作数 - 去掉引号
|
||||
if isinstance(args[0], ast.Constant):
|
||||
left: str = str(args[0].value)
|
||||
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 = str(args[1].value)
|
||||
elif isinstance(args[1], ast.Name):
|
||||
right = args[1].id
|
||||
else:
|
||||
right = _to_str(translator.HandleExpr(args[1])[0])
|
||||
|
||||
# 返回字符串,但用特殊标记包装,让 _AstNodeToStr 能正确处理
|
||||
result: str = left + ' ## ' + right
|
||||
# 使用一个特殊的类来包装结果,让 _AstNodeToStr 直接返回其值
|
||||
class TokenPastResult:
|
||||
def __init__(self, value: str) -> None:
|
||||
self.value: str = value
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
return [TokenPastResult(result)]
|
||||
return ['']
|
||||
|
||||
|
||||
class CIf:
|
||||
"""#if 条件编译"""
|
||||
def __init__(self, condition: Any) -> None:
|
||||
self.condition: Any = condition
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CIf() 调用"""
|
||||
if args:
|
||||
condition: Any = translator.HandleExpr(args[0])[0]
|
||||
return ['#if ' + _to_str(condition)]
|
||||
return ['#if 0']
|
||||
|
||||
|
||||
class CElif:
|
||||
"""#elif 条件编译"""
|
||||
def __init__(self, condition: Any) -> None:
|
||||
self.condition: Any = condition
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CElif() 调用"""
|
||||
if args:
|
||||
condition: Any = translator.HandleExpr(args[0])[0]
|
||||
return ['#elif ' + _to_str(condition)]
|
||||
return ['#else']
|
||||
|
||||
|
||||
class CElse:
|
||||
"""#else 条件编译"""
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CElse() 调用"""
|
||||
return ['#else']
|
||||
|
||||
|
||||
class CEndif:
|
||||
"""#endif 条件编译"""
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CEndif() 调用"""
|
||||
return ['#endif']
|
||||
|
||||
|
||||
class CUndef:
|
||||
"""#undef 取消宏定义"""
|
||||
def __init__(self, name: Any) -> None:
|
||||
self.name: Any = name
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CUndef(name) 调用"""
|
||||
if args:
|
||||
arg: Any = args[0]
|
||||
if isinstance(arg, str):
|
||||
name: str = 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: Any, ret_type: Any = None) -> None:
|
||||
self.ir_template: Any = ir_template
|
||||
self.ret_type: Any = ret_type
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
return ['/* LLVMIR */']
|
||||
|
||||
|
||||
class LInp:
|
||||
"""LLVM IR 输入操作数标记
|
||||
|
||||
用法: c.LInp(expr) - 标记 expr 为输入操作数
|
||||
在 c.LLVMIR 的 f-string 中使用,翻译后替换为 %N 形式的操作数引用
|
||||
"""
|
||||
def __init__(self, value: Any) -> None:
|
||||
self.value: Any = value
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]:
|
||||
return []
|
||||
|
||||
|
||||
class LOut:
|
||||
"""LLVM IR 输出操作数标记
|
||||
|
||||
用法: c.LOut(expr) - 标记 expr 为输出操作数
|
||||
在 c.LLVMIR 的 f-string 中使用,翻译后替换为 %N 形式的操作数引用
|
||||
"""
|
||||
def __init__(self, value: Any) -> None:
|
||||
self.value: Any = value
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[Any]:
|
||||
return []
|
||||
|
||||
|
||||
class CPragma:
|
||||
"""#pragma 指令
|
||||
|
||||
用于生成 C 语言的 #pragma 指令。
|
||||
例如:c.CPragma("GCC diagnostic push") 生成 #pragma GCC diagnostic push
|
||||
"""
|
||||
def __init__(self, directive: Any) -> None:
|
||||
self.directive: Any = directive
|
||||
|
||||
@staticmethod
|
||||
def HandleCall(translator: Any, args: Any, keywords: Any) -> list[str]:
|
||||
"""处理 c.CPragma() 调用"""
|
||||
if args:
|
||||
arg: Any = args[0]
|
||||
if isinstance(arg, ast.Constant):
|
||||
directive: Any = arg.value
|
||||
else:
|
||||
expr: Any = 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: Any) -> None:
|
||||
self.attrs: tuple[Any, ...] = attrs
|
||||
|
||||
def __call__(self, func: Any) -> Any:
|
||||
# 将属性附加到函数上
|
||||
func._c_attributes = self.attrs
|
||||
return func
|
||||
1163
lib/includes/t.py
Normal file
1163
lib/includes/t.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user