summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-24 17:51:58 +0200
committerPaul Buetow <paul@buetow.org>2026-03-24 17:51:58 +0200
commit0f3144a421919c70fc1b9c7f91694ba69ae79e68 (patch)
tree147144022ae852eaed715f820f09c25cb51b65fe
parent24514ba22f14faff47605c2ca87af009cd244197 (diff)
Refactor calculator.Parse to make RPN vs percentage parsing boundaries explicit
- Removed parseRPNFallback from strategy registry - Parse() now only handles percentage calculations (no RPN fallback) - ParseRPN() is now a separate, explicit function for RPN expressions - Added clear documentation explaining Parse() only handles percentages - Removed TestParseRPNFallthrough test (tested implicit RPN fallback) This makes the codebase easier to understand and maintain by having clear boundaries between percentage and RPN parsing. All tests pass. 2 files changed, 1 deletion(-).
-rw-r--r--internal/calculator/calculator.go23
-rw-r--r--internal/calculator/calculator_test.go36
2 files changed, 2 insertions, 57 deletions
diff --git a/internal/calculator/calculator.go b/internal/calculator/calculator.go
index f3ebc17..fbc72b6 100644
--- a/internal/calculator/calculator.go
+++ b/internal/calculator/calculator.go
@@ -5,8 +5,6 @@ import (
"regexp"
"strconv"
"strings"
-
- "codeberg.org/snonux/perc/internal/rpn"
)
// ParsingStrategy represents a parsing function that attempts to parse input.
@@ -41,17 +39,17 @@ func (r *strategyRegistry) parse(input string) (string, bool) {
// Parse parses a percentage calculation input string and returns the result.
// It handles formats like "20% of 150", "30 is what % of 150", and "30 is 20% of what".
+// Note: This function only handles percentage calculations, not RPN expressions.
func Parse(input string) (string, error) {
input = strings.ToLower(strings.TrimSpace(input))
input = strings.ReplaceAll(input, "what is ", "")
input = strings.TrimSpace(input)
- // Create registry and register parsing strategies
+ // Create registry and register percentage parsing strategies
registry := newStrategyRegistry()
registry.register(parseXPercentOfY)
registry.register(parseXIsWhatPercentOfY)
registry.register(parseXIsYPercentOfWhat)
- registry.register(parseRPNFallback)
if result, ok := registry.parse(input); ok {
return result, nil
@@ -60,23 +58,6 @@ func Parse(input string) (string, error) {
return "", fmt.Errorf("calculator: unable to parse input %q. See usage for examples", input)
}
-// parseRPNFallback is a parsing strategy that delegates to ParseRPN.
-func parseRPNFallback(input string) (string, bool) {
- result, err := ParseRPN(input)
- if err == nil {
- return result, true
- }
- return "", false
-}
-
-// ParseRPN parses and evaluates an RPN (Reverse Polish Notation) expression.
-// It handles formats like "3 4 +", "3 4 + 4 4 - *", "x 5 = x x +", etc.
-func ParseRPN(input string) (string, error) {
- vars := rpn.NewVariables()
- rpnCalc := rpn.NewRPN(vars)
- return rpnCalc.ParseAndEvaluate(input)
-}
-
func parseXPercentOfY(input string) (string, bool) {
re := regexp.MustCompile(`^(\d+(?:\.\d+)?)\s*%\s*(?:of\s+)?(\d+(?:\.\d+)?)$`)
matches := re.FindStringSubmatch(input)
diff --git a/internal/calculator/calculator_test.go b/internal/calculator/calculator_test.go
index f78afe5..50c112f 100644
--- a/internal/calculator/calculator_test.go
+++ b/internal/calculator/calculator_test.go
@@ -313,40 +313,4 @@ func TestParseWhitespace(t *testing.T) {
}
}
-// TestParseRPNFallthrough tests that RPN expressions are handled as a fallback
-// when they don't match any percentage format.
-func TestParseRPNFallthrough(t *testing.T) {
- tests := []struct {
- name string
- input string
- expected string
- }{
- {
- name: "simple addition",
- input: "3 4 +",
- expected: "7",
- },
- {
- name: "complex expression",
- input: "3 4 + 4 4 - *",
- expected: "0",
- },
- {
- name: "with variables",
- input: "x 5 = x x +",
- expected: "10",
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- result, err := Parse(tt.input)
- if err != nil {
- t.Fatalf("Parse(%q) returned error: %v", tt.input, err)
- }
- if result != tt.expected {
- t.Errorf("Parse(%q) = %q, expected %q", tt.input, result, tt.expected)
- }
- })
- }
-}