summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-23 23:04:11 +0300
committerPaul Buetow <paul@buetow.org>2026-05-23 23:04:11 +0300
commitd56e16dc85ff3efe7b5865bd27e4804423a6e463 (patch)
tree4d2d94459dd3ea74d71dc26ce2d952419c7d9f02
parente3978519df6e7ec34627100401805a6bda619f92 (diff)
feat: wire DeleteVariable to OperatorRegistry as 'd' operator
The 'd' token was previously a no-op error. Now it pops a value from the stack and deletes the variable with that name. Accepts Symbol (:x) or StringNum as the variable name. Added DeleteVariable to VariableOperator interface so the operator can call it through the Operator interface. Example: x 5 = :x d vars → No variables defined
-rw-r--r--internal/rpn/operations_interfaces.go1
-rw-r--r--internal/rpn/operator_registry.go16
-rw-r--r--internal/rpn/rpn_test.go4
3 files changed, 18 insertions, 3 deletions
diff --git a/internal/rpn/operations_interfaces.go b/internal/rpn/operations_interfaces.go
index b6c2baa..0f461f0 100644
--- a/internal/rpn/operations_interfaces.go
+++ b/internal/rpn/operations_interfaces.go
@@ -54,6 +54,7 @@ type VariableOperator interface {
ClearVariables()
AssignLeft(stack *Stack) error
AssignRight(stack *Stack) error
+ DeleteVariable(name string) error
}
// ConstantOperator defines the interface for constant operations.
diff --git a/internal/rpn/operator_registry.go b/internal/rpn/operator_registry.go
index f2ea64f..9f8e9c8 100644
--- a/internal/rpn/operator_registry.go
+++ b/internal/rpn/operator_registry.go
@@ -54,7 +54,21 @@ func NewOperatorRegistry(op Operator) *OperatorRegistry {
registry.registerStandardOperator("swap", func(stack *Stack) error { return op.Swap(stack) })
registry.registerStandardOperator("pop", func(stack *Stack) error { return op.Pop(stack) })
registry.registerStandardOperator("d", func(stack *Stack) error {
- return fmt.Errorf("'d' command not supported as standalone token")
+ val, err := popStack(stack, "d")
+ if err != nil {
+ return err
+ }
+ // Extract variable name from the value
+ var name string
+ switch v := val.(type) {
+ case *Symbol:
+ name = v.Name()
+ case *StringNum:
+ name = v.String()
+ default:
+ return fmt.Errorf("delete expects a variable name, got %T", val)
+ }
+ return op.DeleteVariable(name)
})
// Commands that return immediately
diff --git a/internal/rpn/rpn_test.go b/internal/rpn/rpn_test.go
index 494e377..6f7deee 100644
--- a/internal/rpn/rpn_test.go
+++ b/internal/rpn/rpn_test.go
@@ -522,9 +522,9 @@ func TestParseAndEvaluateEvaluateErrors(t *testing.T) {
expectedError: "invalid assignment syntax",
},
{
- name: "'d' command not supported",
+ name: "'d' command without operand",
input: "d",
- expectedError: "'d' command not supported as standalone token",
+ expectedError: "insufficient operands for d",
},
{
name: "empty result after evaluation",