Adds readme and gitignore
This commit is contained in:
parent
ee522262c0
commit
6476189c1c
|
@ -0,0 +1 @@
|
||||||
|
gnums
|
|
@ -0,0 +1,39 @@
|
||||||
|
# gnums
|
||||||
|
|
||||||
|
gnums is the gui version of my program <a href="https://tildegit.org/sloum/nums" target="_blank">nums</a> (ie. gui/graphical nums). It is a <a href="https://en.wikipedia.org/wiki/Reverse_Polish_notation" target="_blank">reverse polish notation</a> calculator.
|
||||||
|
|
||||||
|
![screenshot of the gnums calculator interface](gnums.png)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
On initial load some sensible defaults will be set up. Other options are avialable in the settings menu. You will see a stack view on the left, the calculator buttons on the right, and the main input/output at the top. The main input/output will show what you are typing as you type it and will show the current TOS/total after performing an operation (but before more numerical entry), similar to a regular calculator. The stack view will show the full input stack and allow for more complex operations.
|
||||||
|
|
||||||
|
At present there is no keyboard input. This is on the TODO list and should get added in the near future (after all, who really wants to use a mouse for anything?).
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Go >= 1.16
|
||||||
|
- OSX
|
||||||
|
- xcode-select (`xcode-select --install`)
|
||||||
|
- Windows
|
||||||
|
- <a href="https://github.com/brechtsanders/winlibs_mingw/releases/tag/10.2.0-11.0.0-8.0.0-r8" target="_blank">mingw</a>
|
||||||
|
- Debian/derivatives (package names may vary for other distros)
|
||||||
|
- `apt install libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libglx-dev libgl1-mesa-dev libxxf86vm-dev`
|
||||||
|
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Minor build variations can be found for each system. Using `upx` will reduce binary size by a good bit for any of these systems. After running the build command, and optionally running upx, move the resulting binary onto your path and you are good to go. Makefile coming soon<sup>TM</sup>.
|
||||||
|
|
||||||
|
### OSX
|
||||||
|
|
||||||
|
`go build -ldflags "-s -w" .`
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
`go build -ldflags "-s -w -H=windowsgui -extldflags=-static" .`
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
`go build`
|
||||||
|
|
|
@ -0,0 +1,245 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stack struct {
|
||||||
|
ptr int
|
||||||
|
data [100]float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) String() string {
|
||||||
|
if stackStyle == TopOfStack {
|
||||||
|
if s.ptr < 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strconv.FormatFloat(s.data[s.ptr], 'f', -1, 64)
|
||||||
|
} else if stackStyle == TopThree {
|
||||||
|
strArr := make([]string, 0, 3)
|
||||||
|
if stackSort == Dsc {
|
||||||
|
target := s.ptr-2
|
||||||
|
if target < 0 {
|
||||||
|
target = 0
|
||||||
|
}
|
||||||
|
for i := s.ptr; i >= target; i-- {
|
||||||
|
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := range s.data {
|
||||||
|
if i >= 3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(strArr, ",\n")
|
||||||
|
} else {
|
||||||
|
format := "[%d]{\n\t%s\n}"
|
||||||
|
strArr := make([]string, 0, s.ptr+1)
|
||||||
|
if stackSort == Dsc {
|
||||||
|
for i := s.ptr; i >= 0; i-- {
|
||||||
|
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := range s.data {
|
||||||
|
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(format, s.ptr+1, strings.Join(strArr, ",\n\t"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Push(v float64) {
|
||||||
|
if s.ptr >= 99 {
|
||||||
|
s.Clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.ptr++
|
||||||
|
s.data[s.ptr] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Pop() (float64, error) {
|
||||||
|
if s.ptr < 0 {
|
||||||
|
s.Clear()
|
||||||
|
return 0.0, fmt.Errorf("Stack underflow")
|
||||||
|
}
|
||||||
|
s.ptr--
|
||||||
|
return s.data[s.ptr+1], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Clear() {
|
||||||
|
s.ptr = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stack) Len() int {
|
||||||
|
return s.ptr+1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stack) Peek() float64 {
|
||||||
|
if s.Len() > 0 {
|
||||||
|
return s.data[s.ptr]
|
||||||
|
}
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Add() {
|
||||||
|
n2, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n1, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(n1+n2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Sub() {
|
||||||
|
n2, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n1, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(n1-n2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Mul() {
|
||||||
|
n2, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n1, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(n1*n2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Div() {
|
||||||
|
n2, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n1, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(n1/n2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Pow() {
|
||||||
|
exp, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
base, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(math.Pow(base, exp))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *stack) Floor() {
|
||||||
|
n, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(math.Floor(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Ceil() {
|
||||||
|
n, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(math.Ceil(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Round() {
|
||||||
|
decimals, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
num, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(math.Round(num*math.Pow(10, decimals)) / math.Pow(10, decimals))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Abs() {
|
||||||
|
n, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if n < 0 {
|
||||||
|
s.Push(n*-1)
|
||||||
|
} else {
|
||||||
|
s.Push(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Inv() {
|
||||||
|
n, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(n*-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Sqt() {
|
||||||
|
n, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Push(math.Sqrt(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Dup() {
|
||||||
|
val, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(val)
|
||||||
|
s.Push(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Ovr() {
|
||||||
|
tos, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cpy, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(cpy)
|
||||||
|
s.Push(tos)
|
||||||
|
s.Push(cpy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Swp() {
|
||||||
|
tos, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newTos, err := s.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Push(tos)
|
||||||
|
s.Push(newTos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stack) Drp() {
|
||||||
|
s.Pop()
|
||||||
|
}
|
237
main.go
237
main.go
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -19,242 +18,6 @@ const (
|
||||||
Asc
|
Asc
|
||||||
)
|
)
|
||||||
|
|
||||||
type stack struct {
|
|
||||||
ptr int
|
|
||||||
data [100]float64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) String() string {
|
|
||||||
if stackStyle == TopOfStack {
|
|
||||||
if s.ptr < 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strconv.FormatFloat(s.data[s.ptr], 'f', -1, 64)
|
|
||||||
} else if stackStyle == TopThree {
|
|
||||||
strArr := make([]string, 0, 3)
|
|
||||||
if stackSort == Dsc {
|
|
||||||
target := s.ptr-2
|
|
||||||
if target < 0 {
|
|
||||||
target = 0
|
|
||||||
}
|
|
||||||
for i := s.ptr; i >= target; i-- {
|
|
||||||
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i := range s.data {
|
|
||||||
if i >= 3 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(strArr, ",\n")
|
|
||||||
} else {
|
|
||||||
format := "[%d]{\n\t%s\n}"
|
|
||||||
strArr := make([]string, 0, s.ptr+1)
|
|
||||||
if stackSort == Dsc {
|
|
||||||
for i := s.ptr; i >= 0; i-- {
|
|
||||||
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i := range s.data {
|
|
||||||
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(format, s.ptr+1, strings.Join(strArr, ",\n\t"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Push(v float64) {
|
|
||||||
if s.ptr >= 99 {
|
|
||||||
s.Clear()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.ptr++
|
|
||||||
s.data[s.ptr] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Pop() (float64, error) {
|
|
||||||
if s.ptr < 0 {
|
|
||||||
s.Clear()
|
|
||||||
return 0.0, fmt.Errorf("Stack underflow")
|
|
||||||
}
|
|
||||||
s.ptr--
|
|
||||||
return s.data[s.ptr+1], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Clear() {
|
|
||||||
s.ptr = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stack) Len() int {
|
|
||||||
return s.ptr+1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s stack) Peek() float64 {
|
|
||||||
if s.Len() > 0 {
|
|
||||||
return s.data[s.ptr]
|
|
||||||
}
|
|
||||||
return 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Add() {
|
|
||||||
n2, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n1, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(n1+n2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Sub() {
|
|
||||||
n2, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n1, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(n1-n2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Mul() {
|
|
||||||
n2, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n1, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(n1*n2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Div() {
|
|
||||||
n2, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n1, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(n1/n2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Pow() {
|
|
||||||
exp, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(math.Pow(base, exp))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func (s *stack) Floor() {
|
|
||||||
n, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(math.Floor(n))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Ceil() {
|
|
||||||
n, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(math.Ceil(n))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Round() {
|
|
||||||
decimals, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
num, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(math.Round(num*math.Pow(10, decimals)) / math.Pow(10, decimals))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Abs() {
|
|
||||||
n, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
s.Push(n*-1)
|
|
||||||
} else {
|
|
||||||
s.Push(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Inv() {
|
|
||||||
n, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(n*-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Sqt() {
|
|
||||||
n, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Push(math.Sqrt(n))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Dup() {
|
|
||||||
val, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(val)
|
|
||||||
s.Push(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Ovr() {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cpy, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(cpy)
|
|
||||||
s.Push(tos)
|
|
||||||
s.Push(cpy)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Swp() {
|
|
||||||
tos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
newTos, err := s.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.Push(tos)
|
|
||||||
s.Push(newTos)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) Drp() {
|
|
||||||
s.Pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Input struct {
|
type Input struct {
|
||||||
buf strings.Builder
|
buf strings.Builder
|
||||||
|
|
Loading…
Reference in New Issue