diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-20 21:39:32 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-20 21:39:32 +0200 |
| commit | 92c9b9c1cf5f6b1d71d9f0178ad262068b6d5684 (patch) | |
| tree | 6cd199e1b696dfc2b40a5fed0fbcdb277d5ef018 | |
| parent | 8701f048229e0bbb2d97ba23a9ba38397eb70286 (diff) | |
internal/repl: add RPN support to REPL
- Import rpn package in repl.go
- Add 'rpn' and 'calc' as built-in commands
- Update executor to handle 'rpn <expr>' and 'calc <expr>' commands
- Add rpn/calc descriptions to help text
- All tests pass, go vet passes
| -rw-r--r-- | internal/repl/commands.go | 19 | ||||
| -rw-r--r-- | internal/repl/repl.go | 23 |
2 files changed, 39 insertions, 3 deletions
diff --git a/internal/repl/commands.go b/internal/repl/commands.go index 7800653..ad8a34d 100644 --- a/internal/repl/commands.go +++ b/internal/repl/commands.go @@ -6,7 +6,7 @@ import ( ) // builtinCommands defines the built-in REPL commands -var builtinCommands = []string{"help", "clear", "quit", "exit"} +var builtinCommands = []string{"help", "clear", "quit", "exit", "rpn", "calc"} // Commands returns the list of built-in command names func Commands() []string { @@ -27,8 +27,11 @@ func ExecuteCommand(cmd string) (string, error) { return "", cmdClear() case "quit", "exit": return "", cmdQuit() + case "rpn", "calc": + // rpn/calc commands are handled in executor(), not here + return "", nil default: - return "", fmt.Errorf("unknown command: %s. Available commands: help, clear, quit, exit", args[0]) + return "", fmt.Errorf("unknown command: %s. Available commands: help, clear, quit, exit, rpn, calc", args[0]) } } @@ -40,6 +43,7 @@ Built-in Commands: help <command> Show help for a specific topic clear Clear the screen quit / exit Exit the REPL + rpn / calc Evaluate an RPN (postfix notation) expression Usage Examples: 20% of 150 Calculate 20% of 150 @@ -47,6 +51,15 @@ Usage Examples: 30 is what % of 150 Calculate what percentage 30 is of 150 30 is 20% of what Calculate what number 30 is 20% of +RPN (Reverse Polish Notation) Examples: + rpn 3 4 + 3 + 4 = 7 + rpn 3 4 + 4 4 - * (3 + 4) * (4 - 4) = 0 + rpn x 5 = x x + Assign x=5, then x + x = 10 + rpn 2 3 ^ 2^3 = 8 + rpn 1 2 swap Swap top two stack values + rpn 1 2 3 dup Duplicate top value + rpn show Show current stack state + Keyboard Shortcuts (Vi Mode): Normal Mode: i Enter Insert mode @@ -79,7 +92,7 @@ Press Ctrl+D or type 'quit'/'exit' to exit. case "quit", "exit": return "quit / exit - Exit the REPL\nUsage: quit or exit" default: - return fmt.Sprintf("No help available for: %s\nAvailable commands: help, clear, quit, exit", subCmd) + return fmt.Sprintf("No help available for: %s\nAvailable commands: help, clear, quit, exit, rpn, calc", subCmd) } } diff --git a/internal/repl/repl.go b/internal/repl/repl.go index 0f690e9..79a94f4 100644 --- a/internal/repl/repl.go +++ b/internal/repl/repl.go @@ -10,6 +10,7 @@ import ( "syscall" "codeberg.org/snonux/perc/internal/calculator" + "codeberg.org/snonux/perc/internal/rpn" "github.com/mattn/go-isatty" "github.com/c-bata/go-prompt" @@ -37,6 +38,19 @@ func executor(input string) { return } + // Check for rpn command prefix + if strings.HasPrefix(strings.ToLower(input), "rpn ") || strings.HasPrefix(strings.ToLower(input), "calc ") { + // Extract the expression after rpn/calc + rest := strings.TrimSpace(strings.TrimPrefix(input, strings.SplitN(input, " ", 2)[0])) + result, err := runRPN(rest) + if err != nil { + fmt.Printf("Error: %v\n", err) + return + } + fmt.Println(result) + return + } + // Run the calculation result, err := calculator.Parse(input) if err != nil { @@ -46,6 +60,13 @@ func executor(input string) { fmt.Println(result) } +// runRPN parses and evaluates an RPN expression +func runRPN(input string) (string, error) { + vars := rpn.NewVariables().(*rpn.Variables) + rpnCalc := rpn.NewRPN(vars) + return rpnCalc.ParseAndEvaluate(input) +} + // isBuiltinCommand checks if input starts with a built-in command func isBuiltinCommand(input string) (string, bool) { args := strings.Fields(input) @@ -180,6 +201,8 @@ func getCommandDescription(cmd string) string { "clear": "Clear the screen", "quit": "Exit the REPL", "exit": "Exit the REPL", + "rpn": "Evaluate an RPN (postfix notation) expression", + "calc": "Same as rpn - evaluate an RPN expression", } return descriptions[cmd] } |
