初始提交,未完全测试

This commit is contained in:
2026-02-27 14:37:10 +08:00
parent 76c0f469be
commit e270f02073
68 changed files with 5886 additions and 0 deletions

172
template/expr/ast/Arith.py Normal file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env python3.9
# -*- coding: utf-8 -*-
"""
JFinal Arith - Arithmetic Expression
"""
from .Expr import Expr
from decimal import Decimal, ROUND_HALF_UP
class Arith(Expr):
"""Arithmetic expression"""
ADD = "+"
SUB = "-"
MUL = "*"
DIV = "/"
MOD = "%"
_rounding_mode = ROUND_HALF_UP
def __init__(self, left: Expr, operator: str, right: Expr):
"""
Initialize arithmetic expression
Args:
left: Left expression
operator: Arithmetic operator
right: Right expression
"""
self._left = left
self._operator = operator
self._right = right
def eval(self, scope):
"""Evaluate arithmetic expression"""
left_val = self._left.eval(scope)
right_val = self._right.eval(scope)
# Handle None values
if left_val is None or right_val is None:
return None
# Convert to appropriate numeric types
left_num = self._to_number(left_val)
right_num = self._to_number(right_val)
if left_num is None or right_num is None:
return None
# Perform operation
if self._operator == Arith.ADD:
return left_num + right_num
elif self._operator == Arith.SUB:
return left_num - right_num
elif self._operator == Arith.MUL:
return left_num * right_num
elif self._operator == Arith.DIV:
if right_num == 0:
raise ZeroDivisionError("Division by zero")
return self._divide(left_num, right_num)
elif self._operator == Arith.MOD:
return left_num % right_num
else:
raise ValueError(f"Unknown operator: {self._operator}")
def _to_number(self, value):
"""Convert value to number"""
if isinstance(value, (int, float)):
return value
if isinstance(value, Decimal):
return value
if isinstance(value, str):
try:
if '.' in value:
return float(value)
else:
return int(value)
except ValueError:
return None
return None
def _divide(self, left, right):
"""Handle division with proper rounding"""
if isinstance(left, Decimal) or isinstance(right, Decimal):
result = Decimal(str(left)) / Decimal(str(right))
return result.quantize(Decimal('0.00000001'), rounding=self._rounding_mode)
else:
return left / right
@classmethod
def set_big_decimal_divide_rounding_mode(cls, rounding_mode):
"""Set rounding mode for decimal division"""
cls._rounding_mode = rounding_mode
def __repr__(self) -> str:
return f"Arith({self._left} {self._operator} {self._right})"
class Unary(Expr):
"""Unary expression (positive, negative, increment, decrement)"""
POSITIVE = "+"
NEGATIVE = "-"
NOT = "!"
def __init__(self, operator: str, expr: Expr):
"""
Initialize unary expression
Args:
operator: Unary operator
expr: Expression to operate on
"""
self._operator = operator
self._expr = expr
def eval(self, scope):
"""Evaluate unary expression"""
val = self._expr.eval(scope)
if self._operator == Unary.POSITIVE:
return +val if isinstance(val, (int, float)) else val
elif self._operator == Unary.NEGATIVE:
return -val if isinstance(val, (int, float)) else val
elif self._operator == Unary.NOT:
return not val
else:
raise ValueError(f"Unknown operator: {self._operator}")
def __repr__(self) -> str:
return f"Unary({self._operator}{self._expr})"
class IncDec(Expr):
"""Increment/Decrement expression"""
INC = "++"
DEC = "--"
def __init__(self, expr: Expr, operator: str, is_prefix: bool = True):
"""
Initialize increment/decrement
Args:
expr: Expression to increment/decrement
operator: INC or DEC
is_prefix: Whether this is prefix (++x) or postfix (x++)
"""
self._expr = expr
self._operator = operator
self._is_prefix = is_prefix
def eval(self, scope):
"""Evaluate increment/decrement"""
# This is a simplified implementation
# In a real implementation, this would modify the variable
current_val = self._expr.eval(scope)
if isinstance(current_val, int):
if self._operator == IncDec.INC:
return current_val + 1
else:
return current_val - 1
return current_val
def __repr__(self) -> str:
op_str = self._operator
if self._is_prefix:
return f"IncDec({op_str}{self._expr})"
else:
return f"IncDec({self._expr}{op_str})"