From 56996691d842b6568160ccbffa5ff282ca7b20fe Mon Sep 17 00:00:00 2001 From: ignis Date: Thu, 4 Jun 2026 01:08:18 +0000 Subject: [PATCH] refactor: introduce registries for OCP compliance (Phase 1) --- code/code_gen/post.py | 103 ++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 30 deletions(-) diff --git a/code/code_gen/post.py b/code/code_gen/post.py index 4eb791b..8a9a267 100644 --- a/code/code_gen/post.py +++ b/code/code_gen/post.py @@ -29,6 +29,73 @@ from jinja2 import Template import sympy from sympy.printing.fortran import FCodePrinter +# --- Registries for SOLID (OCP) Compliance --- + +class FunctionRegistry: + def __init__(self): + self._sympy_registry = {} + self._latex_registry = {} + + def register_sympy(self, name, sympy_builder): + self._sympy_registry[name] = sympy_builder + + def register_latex(self, name, latex_builder): + self._latex_registry[name] = latex_builder + + def to_sympy(self, name, *args): + if name in self._sympy_registry: + return self._sympy_registry[name](*args) + return sympy.Function(name)(*args) + + def to_latex(self, name, *args): + if name in self._latex_registry: + return self._latex_registry[name](*args) + b = ", ".join(args) + if name.startswith("\\"): + return r"{}{{({})}}".format(name, b) + return r"\mathrm{{{}}}({})".format(name, b) + +function_registry = FunctionRegistry() + +# Register standard mathematical functions +function_registry.register_sympy("sqrt", lambda *args: sympy.sqrt(args[0])) +function_registry.register_sympy("abs", lambda *args: sympy.Abs(args[0])) +function_registry.register_sympy("log", lambda *args: sympy.log(args[0])) +function_registry.register_sympy("exp", lambda *args: sympy.exp(args[0])) +function_registry.register_sympy("rxn_rate", lambda *args: sympy.Function("rxn_rate")(args[0])) + +function_registry.register_latex("sqrt", lambda *args: r"\sqrt{{{}}}".format(", ".join(args))) +function_registry.register_latex("abs", lambda *args: r"\left| {} \right|".format(", ".join(args))) +function_registry.register_latex(r"\log", lambda *args: r"\log{{({})}}".format(", ".join(args))) +function_registry.register_latex(r"\exp", lambda *args: r"\exp{{({})}}".format(", ".join(args))) +function_registry.register_latex(r"\omega", lambda *args: r"\omega{{({})}}".format(", ".join(args))) + + +class DifferentialOperatorRegistry: + def __init__(self): + self._operators = {} + + def register(self, op_name, latex_symbol): + self._operators[op_name] = latex_symbol + + def get_latex_symbol(self, op_name): + if op_name in self._operators: + return self._operators[op_name] + # Fallback to dynamic parsing matching original code + fmt = r"\partial_{{{}}}" + coord = op_name[-1] if op_name else "" + return fmt.format(coord + coord if len(op_name) > 3 else coord) + +differential_operator_registry = DifferentialOperatorRegistry() + +# Register standard derivative operators +differential_operator_registry.register("ddx", r"\partial_{x}") +differential_operator_registry.register("d2dx", r"\partial_{xx}") +differential_operator_registry.register("ddy", r"\partial_{y}") +differential_operator_registry.register("d2dy", r"\partial_{yy}") +differential_operator_registry.register("ddz", r"\partial_{z}") +differential_operator_registry.register("d2dz", r"\partial_{zz}") + @v_args(inline=True) class LarkToSympy(Transformer): """Lark AST의 수학적 노드들을 SymPy 기호 수식 객체로 변환하는 Transformer 클래스입니다. @@ -81,19 +148,9 @@ class LarkToSympy(Transformer): # 내장 수학 함수(sqrt, exp, log, abs, rxn_rate) 또는 사용자 정의 UDF들을 SymPy 함수 노드로 매핑 a = args[0] func_name = a.value if hasattr(a, 'value') else str(a) - if func_name == "sqrt": - return sympy.sqrt(args[1]) - elif func_name == "exp": - return sympy.exp(args[1]) - elif func_name == "log": - return sympy.log(args[1]) - elif func_name == "abs": - return sympy.Abs(args[1]) - elif func_name == "rxn_rate": - return sympy.Function("rxn_rate")(args[1]) - elif func_name == "udf": - return sympy.Function(a.value)(*args[1:]) - return sympy.Function(func_name)(*args[1:]) + if func_name == "udf": + return sympy.Function(a.value if hasattr(a, 'value') else str(a))(*args[1:]) + return function_registry.to_sympy(func_name, *args[1:]) def neg(self, val): return -val @@ -574,19 +631,8 @@ class ExpToLatex(Transformer): def fcall (self, *args): a = args[0] - b = ", ".join(args[1:]) - if a == 'sqrt': - fcode = r"\sqrt{{{}}}".format(b) - return fcode - elif a == 'abs': - fcode = r"\left| {} \right|".format(b) - return fcode - elif a.startswith("\\"): - fcode = r"{}{{({})}}".format(a, b) - return fcode - else: - fcode = r"\mathrm{{{}}}({})".format(a, b) - return fcode + func_name = a.value if hasattr(a, 'value') else str(a) + return function_registry.to_latex(func_name, *args[1:]) def neg(self, b): fcode = "(-{})".format(b) @@ -1129,10 +1175,7 @@ class DerivedField (FieldBase): self.v = v self.dep = set([v]) - fmt = r"\partial_{{{}}}" - coord = op[-1] - partial = fmt.format(coord + coord if len(op) > 3 else coord) - + partial = differential_operator_registry.get_latex_symbol(op) self.latex = partial + "(" + fdict[v].latex + ")" def code (self, alloc=None):