diff options
author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-19 13:48:15 +0100 |
---|---|---|
committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-19 13:48:15 +0100 |
commit | d3d17484012dc603ae326bec419cff990898e6a0 (patch) | |
tree | 44aa5b05b6aa3f9b988e6cd59ddacec04660ff32 /subex/arithmetic.go | |
parent | 58d50737702adc48604f0a709080dcc587d7145f (diff) | |
download | stred-go-d3d17484012dc603ae326bec419cff990898e6a0.tar |
Adds the reciprocal operator
Diffstat (limited to 'subex/arithmetic.go')
-rw-r--r-- | subex/arithmetic.go | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/subex/arithmetic.go b/subex/arithmetic.go index ff30a58..4404a1c 100644 --- a/subex/arithmetic.go +++ b/subex/arithmetic.go @@ -118,3 +118,37 @@ func negateValues(atoms []walk.Atom) ([]walk.Atom, error) { } return negatedNumbers, nil } + +// If all are castable to numbers, takes reciprocals of all and returns them +// Else errors +func reciprocalValues(atoms []walk.Atom) ([]walk.Atom, error) { + var reciprocals []walk.Atom + values, err := walk.MemoryCompound(atoms) + if err != nil { + return nil, err + } + for _, value := range values { + switch v := value.(type) { + case walk.ValueNull: + return nil, errors.New("Tried to take reciprocal of null") + case walk.ValueBool: + if bool(v) { + reciprocals = append(reciprocals, walk.ValueNumber(1)) + } else { + return nil, errors.New("Tried to take reciprocal of false") + } + case walk.ValueNumber: + reciprocals = append(reciprocals, walk.ValueNumber(1 / v)) + case walk.ValueString: + num, err := strconv.ParseFloat(string(v), 64) + if err == nil { + reciprocals = append(reciprocals, walk.ValueNumber(1 / num)) + } else { + return nil, errors.New("Tried to take reciprocal of non-castable string") + } + default: + return nil, errors.New("Tried to take reciprocal of non-number") + } + } + return reciprocals, nil +} |