diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-11 22:50:50 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-11 22:50:50 +0300 |
| commit | 5c22c011c9118f53929cd2e84f8a7b49e828a6d3 (patch) | |
| tree | c3aeaf72ed6b3c4f521b8088ee0f12e08d67c91e /internal | |
| parent | fe31559af818bcc1771b1a2eafc7f3aa1cac3f75 (diff) | |
refactor: extract repeated stack-popping logic into popAll helper
- Added popAll helper function to reduce boilerplate in hyper-operators
- Refactored HyperAdd to use popAll
- Refactored HyperSubtract to use popAll
- Updated error handling to use buildError helper consistently
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/rpn/operations.go | 70 |
1 files changed, 33 insertions, 37 deletions
diff --git a/internal/rpn/operations.go b/internal/rpn/operations.go index 1d693d1..d47557f 100644 --- a/internal/rpn/operations.go +++ b/internal/rpn/operations.go @@ -58,6 +58,30 @@ func buildError(op string, err error) error { return fmt.Errorf("%s: %w", op, err) } +// popAll pops all values from stack into a slice and reverses them for left-to-right processing. +// Returns values in order from bottom to top of stack (first pushed to last pushed). +func popAll(stack *Stack, op string) ([]Number, error) { + if stack.Len() < 2 { + return nil, fmt.Errorf("insufficient operands for %s: need at least 2 values", op) + } + + var values []Number + for stack.Len() > 0 { + val, err := stack.Pop() + if err != nil { + return nil, fmt.Errorf("%s: failed to pop: %w", op, err) + } + values = append(values, val) + } + + // Reverse to get left-to-right order (first pushed = first in) + for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 { + values[i], values[j] = values[j], values[i] + } + + return values, nil +} + // ArithmeticOperator defines the interface for basic arithmetic operators. type ArithmeticOperator interface { Add(stack *Stack) error @@ -527,23 +551,9 @@ func (o *Operations) Ln(stack *Stack) error { // HyperAdd pops all values from stack, adds them left-associative (with boolean-to-number coercion), and pushes result. func (o *Operations) HyperAdd(stack *Stack) error { - if stack.Len() < 2 { - return fmt.Errorf("insufficient operands for hyperadd: need at least 2 values") - } - - // Pop all values into a slice (in reverse order - top first) - var values []Number - for stack.Len() > 0 { - val, err := stack.Pop() - if err != nil { - return fmt.Errorf("hyperadd: %w", err) - } - values = append(values, val) - } - - // Reverse to get left-to-right order (first pushed = first in) - for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 { - values[i], values[j] = values[j], values[i] + values, err := popAll(stack, "hyperadd") + if err != nil { + return err } // Process left-associative with Number interface @@ -551,7 +561,7 @@ func (o *Operations) HyperAdd(stack *Stack) error { for i := 0; i < len(values); i++ { val, err := values[i].Float64() if err != nil { - return fmt.Errorf("hyperadd: failed to get float64 value: %w", err) + return buildError("hyperadd", fmt.Errorf("failed to get float64 value: %w", err)) } sum += val } @@ -585,35 +595,21 @@ func (o *Operations) HyperMultiply(stack *Stack) error { // HyperSubtract pops all values from stack, subtracts them left-associative, and pushes result. func (o *Operations) HyperSubtract(stack *Stack) error { - if stack.Len() < 2 { - return fmt.Errorf("insufficient operands for hypersubtract: need at least 2 values") - } - - // Pop all values into a slice (in reverse order - top first) - var values []Number - for stack.Len() > 0 { - val, err := stack.Pop() - if err != nil { - return fmt.Errorf("hypersubtract: %w", err) - } - values = append(values, val) - } - - // Reverse to get left-to-right order (first pushed = first in) - for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 { - values[i], values[j] = values[j], values[i] + values, err := popAll(stack, "hypersubtract") + if err != nil { + return err } // Process left-associative with Number interface firstVal, err := values[0].Float64() if err != nil { - return fmt.Errorf("hypersubtract: failed to get float64 value: %w", err) + return buildError("hypersubtract", fmt.Errorf("failed to get float64 value: %w", err)) } result := firstVal for i := 1; i < len(values); i++ { val, err := values[i].Float64() if err != nil { - return fmt.Errorf("hypersubtract: failed to get float64 value: %w", err) + return buildError("hypersubtract", fmt.Errorf("failed to get float64 value: %w", err)) } result -= val } |
