summaryrefslogtreecommitdiff
path: root/internal/rpn
diff options
context:
space:
mode:
Diffstat (limited to 'internal/rpn')
-rw-r--r--internal/rpn/number.go30
-rw-r--r--internal/rpn/rpn_parse.go8
2 files changed, 34 insertions, 4 deletions
diff --git a/internal/rpn/number.go b/internal/rpn/number.go
index bb6f765..2915a2a 100644
--- a/internal/rpn/number.go
+++ b/internal/rpn/number.go
@@ -186,7 +186,8 @@ func (f *Float) Mod(other Number) (Number, error) {
// IsZero returns true if the float is zero.
// For boolean values, false (0) is zero, true (1) is not zero.
func (f *Float) IsZero() bool {
- return f.Float64() == 0
+ val, _ := f.Float64()
+ return val == 0
}
// IsNegative returns true if the float is negative.
@@ -194,6 +195,16 @@ func (f *Float) IsNegative() bool {
return f.n < 0
}
+// IsString returns true if this number represents a string value.
+func (f *Float) IsString() bool {
+ return false
+}
+
+// IsSymbol returns true if this number represents a symbol.
+func (f *Float) IsSymbol() bool {
+ return false
+}
+
// Compare returns -1, 0, or 1 if this float is less than, equal to, or greater than another.
func (f *Float) Compare(other Number) (int, error) {
otherF, err := other.Float64()
@@ -373,6 +384,16 @@ func (r *Rat) IsNegative() bool {
return r.n.Sign() < 0
}
+// IsString returns true if this number represents a string value.
+func (r *Rat) IsString() bool {
+ return false
+}
+
+// IsSymbol returns true if this number represents a symbol.
+func (r *Rat) IsSymbol() bool {
+ return false
+}
+
// Compare returns -1, 0, or 1 if this rational is less than, equal to, or greater than another.
func (r *Rat) Compare(other Number) (int, error) {
otherRat, ok := other.(*Rat)
@@ -393,7 +414,8 @@ func ToRat(n Number) *big.Rat {
// ToFloat converts a Number to float64.
func ToFloat(n Number) float64 {
- return n.Float64()
+ val, _ := n.Float64()
+ return val
}
// StringNum represents a string value on the stack for variable names.
@@ -433,6 +455,7 @@ func (s *StringNum) IsNegative() bool { return false }
func (s *StringNum) Compare(other Number) (int, error) { return 0, fmt.Errorf("string not supported for comparison") }
func (s *StringNum) Bool() (bool, error) { return false, fmt.Errorf("string not supported for Bool()") }
func (s *StringNum) IsBool() bool { return false }
+func (s *StringNum) IsSymbol() bool { return false }
// Symbol represents a variable symbol on the stack.
// Symbols are created when:
@@ -493,6 +516,9 @@ func (s *Symbol) IsZero() bool {
func (s *Symbol) IsNegative() bool {
return false
}
+func (s *Symbol) IsString() bool {
+ return false
+}
func (s *Symbol) Compare(other Number) (int, error) {
return 0, fmt.Errorf("symbol not supported for comparison")
}
diff --git a/internal/rpn/rpn_parse.go b/internal/rpn/rpn_parse.go
index bf9a613..19e35fa 100644
--- a/internal/rpn/rpn_parse.go
+++ b/internal/rpn/rpn_parse.go
@@ -345,13 +345,17 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) {
if err != nil {
return "", fmt.Errorf("insufficient operands for %s: stack is empty", nextToken)
}
- if err := r.vars.SetVariable(token, val.Float64()); err != nil {
+ valF, err := val.Float64()
+ if err != nil {
+ return "", fmt.Errorf("failed to get float64 value for variable %q: %w", token, err)
+ }
+ if err := r.vars.SetVariable(token, valF); 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 confirmation message showing the assignment
- return fmt.Sprintf("%s = %.10g", token, val.Float64()), nil
+ return fmt.Sprintf("%s = %.10g", token, valF), nil
} else if _, err := strconv.ParseFloat(token, 64); err != nil && isValidIdentifier(token) {
// This token is a variable name (not a number)
shouldPushName = true