go-calc/calc/stack.go

137 lines
2.3 KiB
Go

package calc
import (
"gitea.zaclys.com/bvaudour/gob/number"
"gitea.zaclys.com/bvaudour/gob/option"
)
type Number2 struct {
N1, N2 number.Number
}
type Stack []number.Number
func (s *Stack) Len() int { return len(*s) }
func (s *Stack) IsEmpty() bool { return s.Len() == 0 }
func (s *Stack) Clone() (out Stack) {
out = make(Stack, s.Len())
copy(out, *s)
return
}
func (s *Stack) Last() option.Result[number.Number] {
i := s.Len() - 1
if i >= 0 {
return option.Ok((*s)[i])
}
return option.Err[number.Number](ErrIsEmpty(errStack))
}
func (s *Stack) Last2() option.Result[Number2] {
i := s.Len() - 2
if i >= 0 {
return option.Ok(Number2{
N1: (*s)[i],
N2: (*s)[i+1],
})
}
return option.Err[Number2](ErrLenLt2(errStack))
}
func (s *Stack) Pop() (n option.Result[number.Number]) {
if n = s.Last(); n.IsOk() {
*s = (*s)[:s.Len()-1]
}
return
}
func (s *Stack) Pop2() (n option.Result[Number2]) {
if n = s.Last2(); n.IsOk() {
*s = (*s)[:s.Len()-2]
}
return
}
func (s *Stack) Reset() (err option.Option[error]) {
if s.Len() > 0 {
*s = (*s)[:0]
} else {
err = option.Some(ErrIsEmpty(errStack))
}
return
}
func (s *Stack) Push(numbers ...number.Number) { *s = append(*s, numbers...) }
func (s *Stack) Duplicate() (err option.Option[error]) {
result := s.Last()
if n, ok := result.Ok(); ok {
s.Push(n)
} else if e, ok := result.Err(); ok {
err = option.Some(e)
}
return
}
func (s *Stack) DuplicateAll() (err option.Option[error]) {
if s.IsEmpty() {
err = option.Some(ErrIsEmpty(errStack))
} else {
s.Push((*s)...)
}
return
}
func (s *Stack) Swap(i, j int) { (*s)[i], (*s)[j] = (*s)[j], (*s)[i] }
func (s *Stack) Reverse() (err option.Option[error]) {
i := s.Len() - 2
if i >= 0 {
s.Swap(i, i+1)
} else {
err = option.Some(ErrLenLt2(errStack))
}
return
}
func (s *Stack) ReverseAll() (err option.Option[error]) {
if s.IsEmpty() {
err = option.Some(ErrIsEmpty(errStack))
} else {
*s = number.Reverse((*s)...)
}
return
}
func (s *Stack) Sort() (err option.Option[error]) {
if s.IsEmpty() {
err = option.Some(ErrIsEmpty(errStack))
} else {
*s = number.Sort((*s)...)
}
return
}
func (s *Stack) SortDesc() (err option.Option[error]) {
if s.IsEmpty() {
err = option.Some(ErrIsEmpty(errStack))
} else {
*s = number.SortDesc((*s)...)
}
return
}