summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-24 14:07:06 +0300
committerPaul Buetow <paul@buetow.org>2026-05-24 14:07:06 +0300
commitf3a0760739049a42be7b446eab1d4d085ebe2702 (patch)
treee5b0a1a42862a4dceefa0e9c7f048dff74f6cf0d
parent7c9f67ff1e149dc28afe59d14bbc59d7695422ad (diff)
fix(rpn): DIP violation — NewOperatorRegistry accepts OperatorProvider interface (nj)
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.
-rw-r--r--internal/rpn/operations.go1
-rw-r--r--internal/rpn/operations_interfaces.go14
-rw-r--r--internal/rpn/operator_registry.go14
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) })