From f3a0760739049a42be7b446eab1d4d085ebe2702 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 24 May 2026 14:07:06 +0300 Subject: =?UTF-8?q?fix(rpn):=20DIP=20violation=20=E2=80=94=20NewOperatorRe?= =?UTF-8?q?gistry=20accepts=20OperatorProvider=20interface=20(nj)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accept the OperatorProvider interface instead of concrete *Operations in NewOperatorRegistry() and all register* methods. OperatorProvider embeds ArithmeticOperator, PowerIntOperator, LogarithmicOperator, BooleanOperator, StackOperator, VariableOperator, ConstantOperator, MetricOperator, and HyperOperator, allowing mocking or alternative implementations. --- internal/rpn/operations.go | 1 + internal/rpn/operations_interfaces.go | 14 ++++++++++++++ internal/rpn/operator_registry.go | 14 +++++++------- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/internal/rpn/operations.go b/internal/rpn/operations.go index e5cc891..832ac77 100644 --- a/internal/rpn/operations.go +++ b/internal/rpn/operations.go @@ -32,6 +32,7 @@ var ( _ MetricCommander = (*Operations)(nil) _ CustomMetricManager = (*Operations)(nil) _ OperationsProvider = (*Operations)(nil) + _ OperatorProvider = (*Operations)(nil) ) // NewOperations creates a new Operations instance with the given variable store. diff --git a/internal/rpn/operations_interfaces.go b/internal/rpn/operations_interfaces.go index 7542993..cc60db2 100644 --- a/internal/rpn/operations_interfaces.go +++ b/internal/rpn/operations_interfaces.go @@ -101,6 +101,20 @@ type CustomMetricManager interface { CustomUndefine(name string) error } +// OperatorProvider combines all operator interfaces needed by the OperatorRegistry. +// This satisfies DIP by decoupling the registry from the concrete *Operations type. +type OperatorProvider interface { + ArithmeticOperator + PowerIntOperator + LogarithmicOperator + BooleanOperator + StackOperator + VariableOperator + ConstantOperator + MetricOperator + HyperOperator +} + // OperationsProvider combines all interfaces that RPN needs from Operations. // RPN depends on this interface (DIP) rather than the concrete *Operations type. type OperationsProvider interface { diff --git a/internal/rpn/operator_registry.go b/internal/rpn/operator_registry.go index 67898e5..605d1d7 100644 --- a/internal/rpn/operator_registry.go +++ b/internal/rpn/operator_registry.go @@ -17,7 +17,7 @@ type OperatorRegistry struct { } // NewOperatorRegistry creates a new operator registry and registers all operators. -func NewOperatorRegistry(op *Operations) *OperatorRegistry { +func NewOperatorRegistry(op OperatorProvider) *OperatorRegistry { registry := &OperatorRegistry{ standardOperators: make(map[string]OperatorHandler), hyperOperators: make(map[string]OperatorHandler), @@ -34,7 +34,7 @@ func NewOperatorRegistry(op *Operations) *OperatorRegistry { } // registerArithmeticOperators registers math and numeric operators. -func (r *OperatorRegistry) registerArithmeticOperators(op *Operations) { +func (r *OperatorRegistry) registerArithmeticOperators(op OperatorProvider) { r.registerStandardOperator("+", func(stack *Stack) error { return op.Add(stack) }) r.registerStandardOperator("-", func(stack *Stack) error { return op.Subtract(stack) }) r.registerStandardOperator("*", func(stack *Stack) error { return op.Multiply(stack) }) @@ -48,7 +48,7 @@ func (r *OperatorRegistry) registerArithmeticOperators(op *Operations) { } // registerComparisonOperators registers equality and ordering operators. -func (r *OperatorRegistry) registerComparisonOperators(op *Operations) { +func (r *OperatorRegistry) registerComparisonOperators(op OperatorProvider) { r.registerStandardOperator("gt", func(stack *Stack) error { return op.GT(stack) }) r.registerStandardOperator("lt", func(stack *Stack) error { return op.LT(stack) }) r.registerStandardOperator("<", func(stack *Stack) error { return op.LT(stack) }) @@ -64,7 +64,7 @@ func (r *OperatorRegistry) registerComparisonOperators(op *Operations) { } // registerStackOperators registers stack manipulation operators. -func (r *OperatorRegistry) registerStackOperators(op *Operations) { +func (r *OperatorRegistry) registerStackOperators(op OperatorProvider) { r.registerStandardOperator("dup", func(stack *Stack) error { return op.Dup(stack) }) r.registerStandardOperator("swap", func(stack *Stack) error { return op.Swap(stack) }) r.registerStandardOperator("pop", func(stack *Stack) error { return op.Pop(stack) }) @@ -87,14 +87,14 @@ func (r *OperatorRegistry) registerStackOperators(op *Operations) { } // registerVariableOperators registers assignment and conversion operators. -func (r *OperatorRegistry) registerVariableOperators(op *Operations) { +func (r *OperatorRegistry) registerVariableOperators(op OperatorProvider) { r.registerStandardOperator(":=", func(stack *Stack) error { return op.AssignRight(stack) }) r.registerStandardOperator("=:", func(stack *Stack) error { return op.AssignLeft(stack) }) r.registerStandardOperator("convert", func(stack *Stack) error { return op.Convert(stack) }) } // registerCommandOperators registers operators that return a result immediately. -func (r *OperatorRegistry) registerCommandOperators(op *Operations) { +func (r *OperatorRegistry) registerCommandOperators(op OperatorProvider) { r.registerCommandOperator("show", func(stack *Stack) (string, error) { return op.Show(stack) }) r.registerCommandOperator("showstack", func(stack *Stack) (string, error) { return op.Show(stack) }) r.registerCommandOperator("print", func(stack *Stack) (string, error) { return op.Show(stack) }) @@ -105,7 +105,7 @@ func (r *OperatorRegistry) registerCommandOperators(op *Operations) { } // registerHyperOperators registers hyper (vectorized) operators. -func (r *OperatorRegistry) registerHyperOperators(op *Operations) { +func (r *OperatorRegistry) registerHyperOperators(op OperatorProvider) { r.registerHyperOperator("[+]", func(stack *Stack) error { return op.HyperAdd(stack) }) r.registerHyperOperator("[-]", func(stack *Stack) error { return op.HyperSubtract(stack) }) r.registerHyperOperator("[*]", func(stack *Stack) error { return op.HyperMultiply(stack) }) -- cgit v1.2.3