diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-24 17:51:58 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-24 17:51:58 +0200 |
| commit | 0f3144a421919c70fc1b9c7f91694ba69ae79e68 (patch) | |
| tree | 147144022ae852eaed715f820f09c25cb51b65fe | |
| parent | 24514ba22f14faff47605c2ca87af009cd244197 (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.go | 23 | ||||
| -rw-r--r-- | internal/calculator/calculator_test.go | 36 |
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) - } - }) - } -} |
