summaryrefslogtreecommitdiff
path: root/internal/rpn/operations_hyper.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-24 11:22:59 +0300
committerPaul Buetow <paul@buetow.org>2026-05-24 11:22:59 +0300
commit871f7fa2b9a0fd5653adadfc9efb90fcbd2da203 (patch)
tree1f9c21649bf437e9ef6678d7037d24617e71d736 /internal/rpn/operations_hyper.go
parentd35efdcdde0b6985473684f0b5668950a8477703 (diff)
rpn: replace panic with error returns in metric registry lookups
resolveMetric, coolMetric, and baseMetric all panicked when the metric registry was missing expected entries. panic() violates Go best practice (no panic except truly unrecoverable) and can crash the REPL. resolveMetric is called for every arithmetic operation, making this a high-impact surface. Change all three functions to return (*Metric, error) instead of panicking. Propagate errors through all callers: - operations_metric.go: resolveMetric, coolMetric, baseMetric, convertToBase, convertFromBase, resultMetricForMul, resultMetricForDiv, Convert - operations_arithmetic.go: binaryMetricOp, Divide, Modulo - operations_compare.go: compareValues - operations_hyper.go: HyperAdd, HyperMultiply, HyperSubtract, HyperDivide, HyperPower, HyperModulo, hyperLog - operations_metric_cmd.go: MetricCompatible
Diffstat (limited to 'internal/rpn/operations_hyper.go')
-rw-r--r--internal/rpn/operations_hyper.go53
1 files changed, 43 insertions, 10 deletions
diff --git a/internal/rpn/operations_hyper.go b/internal/rpn/operations_hyper.go
index 19c9398..34b520b 100644
--- a/internal/rpn/operations_hyper.go
+++ b/internal/rpn/operations_hyper.go
@@ -23,7 +23,11 @@ func (o *Operations) HyperAdd(stack *Stack) error {
// Resolve metrics for all values
metrics := make([]*Metric, len(values))
for i, v := range values {
- metrics[i] = resolveMetric(o.metricRegistry, v)
+ m, err := resolveMetric(o.metricRegistry, v)
+ if err != nil {
+ return buildError("[+]", err)
+ }
+ metrics[i] = m
}
// Validate all are compatible (all same category, or Cool absorbs)
@@ -45,7 +49,10 @@ func (o *Operations) HyperAdd(stack *Stack) error {
sum += base
}
- resultVal := convertFromBase(o.metricRegistry, sum, resultMetric, pm)
+ resultVal, err := convertFromBase(o.metricRegistry, sum, resultMetric, pm)
+ if err != nil {
+ return buildError("[+]", err)
+ }
stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric))
return nil
@@ -72,7 +79,10 @@ func (o *Operations) HyperMultiply(stack *Stack) error {
}
}
- cool := coolMetric(o.metricRegistry)
+ cool, err := coolMetric(o.metricRegistry)
+ if err != nil {
+ return buildError("[*]", err)
+ }
stack.Push(NewNumberWithMetric(product, o.GetMode(), cool))
return nil
}
@@ -89,7 +99,11 @@ func (o *Operations) HyperSubtract(stack *Stack) error {
// Resolve metrics for all values
metrics := make([]*Metric, len(values))
for i, v := range values {
- metrics[i] = resolveMetric(o.metricRegistry, v)
+ m, err := resolveMetric(o.metricRegistry, v)
+ if err != nil {
+ return buildError("[-]", err)
+ }
+ metrics[i] = m
}
// Validate all are compatible (all same category, or Cool absorbs)
@@ -115,7 +129,10 @@ func (o *Operations) HyperSubtract(stack *Stack) error {
result -= base
}
- resultVal := convertFromBase(o.metricRegistry, result, resultMetric, pm)
+ resultVal, err := convertFromBase(o.metricRegistry, result, resultMetric, pm)
+ if err != nil {
+ return buildError("[-]", err)
+ }
stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric))
return nil
@@ -145,7 +162,10 @@ func (o *Operations) HyperDivide(stack *Stack) error {
result /= val
}
- cool := coolMetric(o.metricRegistry)
+ cool, err := coolMetric(o.metricRegistry)
+ if err != nil {
+ return buildError("[/]", err)
+ }
stack.Push(NewNumberWithMetric(result, o.GetMode(), cool))
return nil
}
@@ -171,7 +191,10 @@ func (o *Operations) HyperPower(stack *Stack) error {
result = math.Pow(result, val)
}
- cool := coolMetric(o.metricRegistry)
+ cool, err := coolMetric(o.metricRegistry)
+ if err != nil {
+ return buildError("[^]", err)
+ }
stack.Push(NewNumberWithMetric(result, o.GetMode(), cool))
return nil
}
@@ -188,7 +211,11 @@ func (o *Operations) HyperModulo(stack *Stack) error {
// Resolve metrics for all values
metrics := make([]*Metric, len(values))
for i, v := range values {
- metrics[i] = resolveMetric(o.metricRegistry, v)
+ m, err := resolveMetric(o.metricRegistry, v)
+ if err != nil {
+ return buildError("[%]", err)
+ }
+ metrics[i] = m
}
// Validate all are compatible (all same category, or Cool absorbs)
@@ -217,7 +244,10 @@ func (o *Operations) HyperModulo(stack *Stack) error {
result = math.Mod(result, base)
}
- resultVal := convertFromBase(o.metricRegistry, result, resultMetric, pm)
+ resultVal, err := convertFromBase(o.metricRegistry, result, resultMetric, pm)
+ if err != nil {
+ return buildError("[%]", err)
+ }
stack.Push(NewNumberWithMetric(resultVal, o.GetMode(), resultMetric))
return nil
@@ -243,7 +273,10 @@ func (o *Operations) hyperLog(stack *Stack, opName string, logFn func(float64) f
result += logFn(val)
}
- cool := coolMetric(o.metricRegistry)
+ cool, err := coolMetric(o.metricRegistry)
+ if err != nil {
+ return buildError(opName, err)
+ }
stack.Push(NewNumberWithMetric(result, o.GetMode(), cool))
return nil
}