summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-22 12:33:12 +0300
committerPaul Buetow <paul@buetow.org>2026-05-22 12:33:12 +0300
commit9a68d3658e9d4f71121f90a1e0489898fea849f5 (patch)
treedfd9a946c6118a0831e8af4d3bcd2f7a7f748e68
parentcb1e4376afe9f887b9e3b3b2a9ddef116bedb0cc (diff)
rpn: eliminate duplicated prefixMode state between RPN and Operations
Remove the prefixMode field from the RPN struct; it was duplicated from Operations where it is actually used. Add GetPrefixMode to the Operator interface so RPN can delegate both GetPrefixMode and SetPrefixMode to the Operations instance behind the interface. In rpn_parse.go evaluate(), drop the direct r.prefixMode = IEC/SI writes and the now-unnecessary lock ordering comment; only r.ops.SetPrefixMode() remains.
-rw-r--r--internal/rpn/operations.go2
-rw-r--r--internal/rpn/rpn_parse.go5
-rw-r--r--internal/rpn/rpn_state.go8
3 files changed, 5 insertions, 10 deletions
diff --git a/internal/rpn/operations.go b/internal/rpn/operations.go
index 04c2014..d45ffd1 100644
--- a/internal/rpn/operations.go
+++ b/internal/rpn/operations.go
@@ -158,6 +158,8 @@ type Operator interface {
SetMode(CalculationMode)
// SetPrefixMode sets the prefix mode for data size calculations
SetPrefixMode(PrefixMode)
+ // GetPrefixMode returns the current prefix mode
+ GetPrefixMode() PrefixMode
// Metric command handlers
MetricShow(stack *Stack) (string, error)
MetricList(stack *Stack) (string, error)
diff --git a/internal/rpn/rpn_parse.go b/internal/rpn/rpn_parse.go
index 7abd41c..ab64ec7 100644
--- a/internal/rpn/rpn_parse.go
+++ b/internal/rpn/rpn_parse.go
@@ -367,17 +367,12 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) {
return result, nil
case "binary":
if i+2 < len(tokens) && tokens[i+2] == "set" {
- // Lock order: r.mu → o.mu (same as RPN.SetPrefixMode)
- // No deadlock risk: both paths acquire in the same direction.
- // r.mu is held by evaluate(); o.mu is a separate mutex on Operations.
- r.prefixMode = IEC
r.ops.SetPrefixMode(IEC)
return "prefix mode: IEC", nil
}
return "", fmt.Errorf("rpn: metric binary: use 'metric binary set'")
case "decimal":
if i+2 < len(tokens) && tokens[i+2] == "set" {
- r.prefixMode = SI
r.ops.SetPrefixMode(SI)
return "prefix mode: SI", nil
}
diff --git a/internal/rpn/rpn_state.go b/internal/rpn/rpn_state.go
index 3b63984..a146409 100644
--- a/internal/rpn/rpn_state.go
+++ b/internal/rpn/rpn_state.go
@@ -20,7 +20,6 @@ type RPN struct {
maxStack int
currentStack *Stack
mode CalculationMode
- prefixMode PrefixMode
}
// NewRPN creates a new RPN parser and evaluator with the given variable store.
@@ -37,7 +36,6 @@ func NewRPN(vars VariableStore) *RPN {
maxStack: 1000, // Reasonable limit for RPN expressions
currentStack: NewStack(),
mode: FloatMode, // Default mode
- prefixMode: SI, // Default prefix mode
}
}
@@ -96,19 +94,19 @@ func (r *RPN) Stack() []Number {
}
// SetPrefixMode sets the prefix mode (SI or IEC).
-// Propagates to the Operations instance so arithmetic uses the correct mode.
+// Delegates to the Operations instance.
// This method is thread-safe for writes.
func (r *RPN) SetPrefixMode(mode PrefixMode) {
r.mu.Lock()
defer r.mu.Unlock()
- r.prefixMode = mode
r.ops.SetPrefixMode(mode)
}
// GetPrefixMode returns the current prefix mode.
+// Delegates to the Operations instance.
// This method is thread-safe for concurrent reads.
func (r *RPN) GetPrefixMode() PrefixMode {
r.mu.RLock()
defer r.mu.RUnlock()
- return r.prefixMode
+ return r.ops.GetPrefixMode()
}