249 lines
3.4 KiB
Go
249 lines
3.4 KiB
Go
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 {
|
|
if i > s.ptr {
|
|
break
|
|
}
|
|
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()
|
|
}
|