summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-25 23:35:48 +0200
committerPaul Buetow <paul@buetow.org>2026-03-25 23:35:48 +0200
commita4be06a2cc2f59414458312e8aeae313fe233050 (patch)
treebde5bb8a7cdfa44e1ddbaa170608ef7ca72ca290
parentf6713b9dbd0cdfdf6f0cc05ef86c1dd328133bf3 (diff)
rpn: fix x =: stack-based variable assignment
-rw-r--r--internal/rpn/rpn_parse.go23
1 files changed, 20 insertions, 3 deletions
diff --git a/internal/rpn/rpn_parse.go b/internal/rpn/rpn_parse.go
index f8f5738..095b917 100644
--- a/internal/rpn/rpn_parse.go
+++ b/internal/rpn/rpn_parse.go
@@ -84,12 +84,29 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) {
// For := (right assignment): name value := - first token is always a variable name
// For =: (left assignment): value name =: - token before =: is a variable name
shouldPushName := false
+
if i+1 < len(tokens) {
nextToken := tokens[i+1]
if nextToken == ":=" || nextToken == "=:" {
- // This token is a variable name
- // Only push as StringNum if it's not a number
- if _, err := strconv.ParseFloat(token, 64); err != nil {
+ // Check if this is a stack assignment (e.g., "x =:" or "x :=")
+ // Stack assignment: exactly 2 tokens, first is variable name, second is operator
+ if len(tokens) == 2 && i == 0 {
+ // This is a stack assignment. Pop the value from stack and assign to variable.
+ // Don't push the name as StringNum because the operator expects stack: [value, name]
+ // but for stack assignment, the value is already on stack and we just have the name token.
+ // Instead, we handle it inline: pop value, assign to name (from token).
+ val, err := stack.Pop()
+ if err != nil {
+ return "", fmt.Errorf("insufficient operands for %s: stack is empty", nextToken)
+ }
+ if err := r.vars.SetVariable(token, val.Float64()); err != nil {
+ return "", fmt.Errorf("failed to set variable %q: %w", token, err)
+ }
+ // Skip the operator token (next one) since we handled it inline
+ // We've consumed both tokens, so we're done
+ return "", nil
+ } else if _, err := strconv.ParseFloat(token, 64); err != nil {
+ // This token is a variable name (not a number)
shouldPushName = true
}
}