1
0
Fork 0

Initial commit

This commit is contained in:
sloum 2021-06-23 20:19:19 -07:00
commit ee522262c0
3 changed files with 547 additions and 0 deletions

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module tildegit.org/sloum/gnums
go 1.16
require github.com/AllenDang/giu v0.5.4

29
go.sum Normal file
View File

@ -0,0 +1,29 @@
github.com/AllenDang/giu v0.5.4 h1:OuSgcTZYH9buug1yWsJAvUr57aQwiJK7hjk+JYtv4tM=
github.com/AllenDang/giu v0.5.4/go.mod h1:1CyOLkJREGGWFVx+p2z5+1KMhY3H7Zbl8gQ/huzThsI=
github.com/AllenDang/imgui-go v1.12.1-0.20210509113325-c0e4c78e7a88 h1:dXpshnNwPl+QjFOiJNFlQrtOz1oA565EO9FUseKvlhU=
github.com/AllenDang/imgui-go v1.12.1-0.20210509113325-c0e4c78e7a88/go.mod h1:+pYwstqlGGlU2lI1FREPlVAKP2nwV+bNhAlMrbQynhQ=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q=
github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M=
github.com/go-gl/gl v0.0.0-20210315015930-ae072cafe09d/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
github.com/go-gl/gl v0.0.0-20210501111010-69f74958bac0 h1:7xNa69TzlTrKtlBtE4yyNRFP9oqAneXAs9oKJkVOECs=
github.com/go-gl/gl v0.0.0-20210501111010-69f74958bac0/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb h1:T6gaWBvRzJjuOrdCtg8fXXjKai2xSDqWTcKFUPuw8Tw=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-resty/resty/v2 v2.3.0 h1:JOOeAvjSlapTT92p8xiS19Zxev1neGikoHsXJeOq8So=
github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

513
main.go Normal file
View File

@ -0,0 +1,513 @@
package main
import (
"fmt"
"math"
"os"
"strconv"
"strings"
g "github.com/AllenDang/giu"
)
const (
MasterWidth int = 376
Version string = "0.0.1"
FullStack int = iota
TopThree
TopOfStack
Dsc
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 {
buf strings.Builder
decimal bool
negative bool
}
func (i *Input) String() string {
return i.buf.String()
}
func (i *Input) Append(value rune) {
switch value {
case '.':
if i.decimal {
return
}
if i.buf.Len() == 0 {
i.buf.WriteRune('0')
}
i.decimal = true
i.buf.WriteRune(value)
case '-':
if i.buf.Len() > 0 {
return
}
i.negative = true
i.buf.WriteRune(value)
default:
i.buf.WriteRune(value)
}
inputDisplay = i.String()
SetComboOut()
}
func (i *Input) Store() {
if i.buf.Len() == 0 {
return
}
if i.buf.Len() == 1 && (i.negative || i.decimal) {
i.Reset()
return
}
num, err := strconv.ParseFloat(i.buf.String(), 64)
if err != nil {
panic("Bad input")
}
s.Push(num)
i.Reset()
inputDisplay = ""
}
func (i *Input) Reset() {
i.buf.Reset()
i.decimal = false
i.negative = false
}
func (i *Input) Delete() {
if i.buf.Len() == 0 {
return
}
val := i.buf.String()
popped := val[len(val)-1]
i.buf.Reset()
i.buf.WriteString(val[:len(val)-1])
if popped == '.' {
i.decimal = false
} else if popped == '-' {
i.negative = false
}
inputDisplay = i.String()
SetComboOut()
}
var (
wnd *g.MasterWindow
inputBuffer *Input = &Input{}
s *stack = &stack{-1, [100]float64{}}
stackStyle int = FullStack
inputDisplay string = inputBuffer.String()
outputDisplay string = s.String()
comboDisplay string = inputBuffer.String()
Display *g.InputTextWidget = g.InputText("", &inputDisplay)
Output *g.InputTextMultilineWidget = g.InputTextMultiline("", &outputDisplay)
ComboView *g.InputTextWidget = g.InputText("", &comboDisplay)
ShowStack bool = true
stackSort int = Dsc
stackLabel *g.LabelWidget = g.Label("Stack Output\n[d]{TOS ...}")
)
func callStackWord(f func()) {
inputBuffer.Store()
f()
outputDisplay = s.String()
SetComboOut()
}
func SetComboOut() {
if inputBuffer.buf.Len() > 0 {
comboDisplay = inputBuffer.String()
} else {
comboDisplay = strconv.FormatFloat(s.Peek(), 'f', -1, 64)
}
}
func SetStackLabelWithSort() {
sort := "TOS ..."
if stackSort == Asc {
sort = "... TOS"
}
stackLabel = g.Label(fmt.Sprintf("Stack Output\n[d]{%s}", sort))
}
func loop() {
g.SingleWindowWithMenuBar("gnums - " + Version).Layout(
g.MenuBar().Layout(
g.Menu("File").Layout(
g.MenuItem("Exit").OnClick(Exit),
),
g.Menu("Edit").Layout(
g.MenuItem("Copy TOS"),
g.MenuItem("Copy Stack"),
g.MenuItem("Clear Stack"),
),
g.Menu("Settings").Layout(
g.Checkbox("Show Stack Window", &ShowStack).OnChange(func(){
width := MasterWidth
if ShowStack {
width = MasterWidth + MasterWidth / 2
}
wnd.SetSize(width,400)}),
g.Menu("Output Style").Layout(
g.RadioButton("Full Stack", stackStyle == FullStack).OnChange(func(){stackStyle = FullStack; outputDisplay = s.String()}),
g.RadioButton("Top Three", stackStyle == TopThree).OnChange(func(){stackStyle = TopThree; outputDisplay = s.String()}),
g.RadioButton("Top Of Stack", stackStyle == TopOfStack).OnChange(func(){stackStyle = TopOfStack; outputDisplay = s.String()}),
),
g.Menu("Stack Sort").Layout(
g.RadioButton("TOS ...", stackSort == Dsc).OnChange(func(){stackSort = Dsc; SetStackLabelWithSort()}),
g.RadioButton("... TOS", stackSort == Asc).OnChange(func(){stackSort = Asc; SetStackLabelWithSort()}),
),
),
),
g.Row(
g.Label("gnums v" + Version),
),
g.Dummy(0, 5),
ComboView.Size(-1).Flags(1 << 14),
g.Row(
g.Condition(ShowStack, g.Layout{
g.Row(
g.Child("Left").Layout(
stackLabel,
g.Tooltip("Stack display is\nnewest on top"),
Output.Size(-1, -1).Flags(1 << 14),
).Size(
float32(MasterWidth/2), -1,
),
g.Child("Section").Layout(
g.Row(
g.Button("Clear").Size(50,50).OnClick(func(){callStackWord(s.Clear)}),
g.Button("Delete").Size(50,50).OnClick(func(){inputBuffer.Delete()}),
g.Button("Round").Size(50,50).OnClick(func(){callStackWord(s.Round)}),
g.Button("^").Size(50,50).OnClick(func(){callStackWord(s.Pow)}),
g.Button("÷").Size(50,50).OnClick(func(){callStackWord(s.Div)}),
g.Button("Sqrt").Size(50,50).OnClick(func(){callStackWord(s.Sqt)}),
),
g.Row(
g.Button("Over").Size(50,50).OnClick(func(){callStackWord(s.Ovr)}),
g.Button("7").Size(50,50).OnClick(func(){inputBuffer.Append('7')}),
g.Button("8").Size(50,50).OnClick(func(){inputBuffer.Append('8')}),
g.Button("9").Size(50,50).OnClick(func(){inputBuffer.Append('9')}),
g.Button("×").Size(50,50).OnClick(func(){callStackWord(s.Mul)}),
g.Button("Floor").Size(50,50).OnClick(func(){callStackWord(s.Floor)}),
),
g.Row(
g.Button("Swap").Size(50,50).OnClick(func(){callStackWord(s.Swp)}),
g.Button("4").Size(50,50).OnClick(func(){inputBuffer.Append('4')}),
g.Button("5").Size(50,50).OnClick(func(){inputBuffer.Append('5')}),
g.Button("6").Size(50,50).OnClick(func(){inputBuffer.Append('6')}),
g.Button("-").Size(50,50).OnClick(func(){callStackWord(s.Sub)}),
g.Button("Ceil").Size(50,50).OnClick(func(){callStackWord(s.Ceil)}),
),
g.Row(
g.Button("Dup").Size(50,50).OnClick(func(){callStackWord(s.Dup)}),
g.Button("1").Size(50,50).OnClick(func(){inputBuffer.Append('1')}),
g.Button("2").Size(50,50).OnClick(func(){inputBuffer.Append('2')}),
g.Button("3").Size(50,50).OnClick(func(){inputBuffer.Append('3')}),
g.Button("+").Size(50,50).OnClick(func(){callStackWord(s.Add)}),
g.Button("+/-").Size(50,50).OnClick(func(){callStackWord(s.Inv)}),
),
g.Row(
g.Button("Drop").Size(50,50).OnClick(func(){callStackWord(s.Drp)}),
g.Button(".").Size(50,50).OnClick(func(){inputBuffer.Append('.')}),
g.Button("0").Size(50,50).OnClick(func(){inputBuffer.Append('0')}),
g.Button("Enter").Size(165,50).OnClick(func(){inputBuffer.Store(); outputDisplay = s.String()}),
),
),
),
}, g.Layout{
g.Child("Button Section").Layout(
g.Row(
g.Button("Clear").Size(50,50).OnClick(func(){callStackWord(s.Clear)}),
g.Button("Delete").Size(50,50).OnClick(func(){inputBuffer.Delete()}),
g.Button("Round").Size(50,50).OnClick(func(){callStackWord(s.Round)}),
g.Button("^").Size(50,50).OnClick(func(){callStackWord(s.Pow)}),
g.Button("÷").Size(50,50).OnClick(func(){callStackWord(s.Div)}),
g.Button("Sqrt").Size(50,50).OnClick(func(){callStackWord(s.Sqt)}),
),
g.Row(
g.Button("Over").Size(50,50).OnClick(func(){callStackWord(s.Ovr)}),
g.Button("7").Size(50,50).OnClick(func(){inputBuffer.Append('7')}),
g.Button("8").Size(50,50).OnClick(func(){inputBuffer.Append('8')}),
g.Button("9").Size(50,50).OnClick(func(){inputBuffer.Append('9')}),
g.Button("×").Size(50,50).OnClick(func(){callStackWord(s.Mul)}),
g.Button("Floor").Size(50,50).OnClick(func(){callStackWord(s.Floor)}),
),
g.Row(
g.Button("Swap").Size(50,50).OnClick(func(){callStackWord(s.Swp)}),
g.Button("4").Size(50,50).OnClick(func(){inputBuffer.Append('4')}),
g.Button("5").Size(50,50).OnClick(func(){inputBuffer.Append('5')}),
g.Button("6").Size(50,50).OnClick(func(){inputBuffer.Append('6')}),
g.Button("-").Size(50,50).OnClick(func(){callStackWord(s.Sub)}),
g.Button("Ceil").Size(50,50).OnClick(func(){callStackWord(s.Ceil)}),
),
g.Row(
g.Button("Dup").Size(50,50).OnClick(func(){callStackWord(s.Dup)}),
g.Button("1").Size(50,50).OnClick(func(){inputBuffer.Append('1')}),
g.Button("2").Size(50,50).OnClick(func(){inputBuffer.Append('2')}),
g.Button("3").Size(50,50).OnClick(func(){inputBuffer.Append('3')}),
g.Button("+").Size(50,50).OnClick(func(){callStackWord(s.Add)}),
g.Button("+/-").Size(50,50).OnClick(func(){callStackWord(s.Inv)}),
),
g.Row(
g.Button("Drop").Size(50,50).OnClick(func(){callStackWord(s.Drp)}),
g.Button(".").Size(50,50).OnClick(func(){inputBuffer.Append('.')}),
g.Button("0").Size(50,50).OnClick(func(){inputBuffer.Append('0')}),
g.Button("Enter").Size(165,50).OnClick(func(){inputBuffer.Store(); outputDisplay = s.String()}),
),
),
}),
),
)
}
func Exit() {
os.Exit(0)
}
func main() {
wnd = g.NewMasterWindow("gnums", MasterWidth+MasterWidth/2, 390, g.MasterWindowFlagsNotResizable, nil)
wnd.Run(loop)
}