diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2023-07-29 10:43:19 -0230 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2023-07-29 10:43:19 -0230 |
| commit | c12813975d7529f864199b876bc3ee3b470c1c18 (patch) | |
| tree | e489a39a706f7e71bc6f02c0d91c39ce1e54fe63 /calc.go | |
| parent | 88bf9516752558207bd34c4fec73ce2632c22b2c (diff) | |
| download | pfc-c12813975d7529f864199b876bc3ee3b470c1c18.zip | |
rename calculator.go -> calc.go
Diffstat (limited to 'calc.go')
| -rw-r--r-- | calc.go | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -0,0 +1,63 @@ +package main + +import ( + "strconv" + "strings" +) + +type Calculator struct { + stack Stack + buf string +} + +// swap swaps the values of the buffer and the bottom element of the stack. If +// the buffer is empty this simply pops from the stack. If the stack is empty, +// this simply pushes to the stack. +func (c *Calculator) swap() { + st := c.stack.pop() + if con := parseConstant(c.buf); con != nil { + c.stack.push(*con) + } else if f, err := strconv.ParseFloat(c.buf, 64); err == nil { + c.stack.push(f) + } + if st != nil { + c.buf = strings.TrimSpace(printNum(*st)) + } else { + c.buf = "" + } +} + +// negate negates the number in the buffer, if any; or the bottom number on the +// stack, if any. +func (c *Calculator) negate() { + if con := parseConstant(c.buf); con != nil { + c.buf = strings.TrimSpace(printNum(-*con)) + } else if f, err := strconv.ParseFloat(c.buf, 64); err == nil { + c.buf = strings.TrimSpace(printNum(-f)) + } else if len(c.buf) == 0 && len(c.stack) > 0 { + c.stack[len(c.stack)-1] = -c.stack[len(c.stack)-1] + } +} + +// performOp performs the specified arithmetic operation and returns nil or +// OpError if op is not a valid operator. +func (c *Calculator) performOp(op byte) error { + if len(c.stack) < 1 { + return nil + } + + fn, err := parseOp(op) + if err != nil { + return err + } + + if con := parseConstant(c.buf); con != nil { + fn(&c.stack[len(c.stack)-1], *con) + } else if fl, err := strconv.ParseFloat(c.buf, 64); err == nil { + fn(&c.stack[len(c.stack)-1], fl) + } else if len(c.stack) > 1 { + fn(&c.stack[len(c.stack)-2], *c.stack.pop()) + } + c.buf = "" + return nil +} |