1
1
mirror of https://github.com/KenanZhu/AutoLibrary.git synced 2026-06-18 07:23:03 +08:00

refactor(autoscript): 使用 ASTokenizer 和 NodeVisitor 重构解析与执行流程

This commit is contained in:
2026-05-17 01:33:22 +08:00
parent 500ddd41c5
commit 9bdc9a3de9
5 changed files with 771 additions and 225 deletions
+53 -50
View File
@@ -7,7 +7,12 @@ This software is provided "as is", without any warranty of any kind.
You may use, modify, and distribute this file under the terms of the MIT License.
See the LICENSE file for details.
"""
from datetime import datetime, timedelta, date, time
from datetime import (
datetime,
timedelta,
date,
time
)
from .ASObject import ASObject
@@ -51,8 +56,9 @@ class ASOperator:
}
_ARITH_TYPES = {"Date", "Time", "Int", "Float"}
@staticmethod
@classmethod
def apply(
cls,
target: ASObject,
operand: ASObject,
op: str,
@@ -73,7 +79,7 @@ class ASOperator:
tp = target.var_type
op_tp = operand.var_type
if tp not in ASOperator._ARITH_TYPES:
if tp not in cls._ARITH_TYPES:
raise ValueError(f"'{tp}' 类型字段不支持操作运算")
if op_tp not in ("Int", "Float"):
raise ValueError(f"操作数类型 '{op_tp}' 不能用于运算,需要数值类型 (Int / Float)")
@@ -83,73 +89,70 @@ class ASOperator:
if target_val is None:
raise ValueError(f"'{target.name}' 的值为空,无法进行运算")
if op == ".ADD.":
ASOperator._arithAdd(target, target_val, operand, target_data)
cls._arithAdd(target, target_val, operand, target_data)
elif op == ".SUB.":
ASOperator._arithSub(target, target_val, operand, target_data)
cls._arithSub(target, target_val, operand, target_data)
else:
raise ValueError(f"不支持的操作 '{op}'")
@staticmethod
@classmethod
def _arithBinary(
cls,
target: ASObject,
target_val,
operand: ASObject,
target_data: dict,
sign: int
):
"""Apply ADD (sign=1) or SUB (sign=-1) per type."""
tp = target.var_type
raw_op = operand._value
op_name = "ADD" if sign == 1 else "SUB"
if tp == "Date":
if not isinstance(target_val, date):
raise ValueError(f"'{target.name}' 的值 '{target_val}' 不是有效日期")
new_val = target_val + timedelta(days=int(raw_op)) * sign
elif tp == "Time":
if not isinstance(target_val, time):
raise ValueError(f"'{target.name}' 的值 '{target_val}' 不是有效时间")
delta = timedelta(hours=int(raw_op)) * sign
dt = datetime.combine(datetime.today(), target_val) + delta
new_val = dt.time()
elif tp == "Int":
new_val = int(target_val) + int(raw_op) * sign
elif tp == "Float":
new_val = float(target_val) + float(raw_op) * sign
else:
raise ValueError(f"'{tp}' 类型不支持 {op_name} 操作")
target.setValue(new_val, target_data)
@classmethod
def _arithAdd(
cls,
target: ASObject,
target_val,
operand: ASObject,
target_data: dict
):
"""Dispatch ADD per type."""
cls._arithBinary(target, target_val, operand, target_data, 1)
tp = target.var_type
raw_op = operand._value
if tp == "Date":
if not isinstance(target_val, date):
raise ValueError(f"'{target.name}' 的值 '{target_val}' 不是有效日期")
new_val = target_val + timedelta(days=int(raw_op))
elif tp == "Time":
if not isinstance(target_val, time):
raise ValueError(f"'{target.name}' 的值 '{target_val}' 不是有效时间")
dt = datetime.combine(datetime.today(), target_val) + timedelta(hours=int(raw_op))
new_val = dt.time()
elif tp == "Int":
new_val = int(target_val) + int(raw_op)
elif tp == "Float":
new_val = float(target_val) + float(raw_op)
else:
raise ValueError(f"'{tp}' 类型不支持 ADD 操作")
target.setValue(new_val, target_data)
@staticmethod
@classmethod
def _arithSub(
cls,
target: ASObject,
target_val,
operand: ASObject,
target_data: dict
):
"""Dispatch SUB per type."""
cls._arithBinary(target, target_val, operand, target_data, -1)
tp = target.var_type
raw_op = operand._value
if tp == "Date":
if not isinstance(target_val, date):
raise ValueError(f"'{target.name}' 的值 '{target_val}' 不是有效日期")
new_val = target_val - timedelta(days=int(raw_op))
elif tp == "Time":
if not isinstance(target_val, time):
raise ValueError(f"'{target.name}' 的值 '{target_val}' 不是有效时间")
dt = datetime.combine(datetime.today(), target_val) - timedelta(hours=int(raw_op))
new_val = dt.time()
elif tp == "Int":
new_val = int(target_val) - int(raw_op)
elif tp == "Float":
new_val = float(target_val) - float(raw_op)
else:
raise ValueError(f"'{tp}' 类型不支持 SUB 操作")
target.setValue(new_val, target_data)
@staticmethod
@classmethod
def compare(
cls,
left: ASObject,
right: ASObject,
op: str,
@@ -171,7 +174,7 @@ class ASOperator:
ValueError: If the types are incompatible for comparison.
"""
cmp_func = ASOperator._COMPARE.get(op)
cmp_func = cls._COMPARE.get(op)
if cmp_func is None:
raise ValueError(f"未知的比较操作 '{op}'")
left_val = left.getValue(target_data)