felise/stack.go

73 lines
1.3 KiB
Go

/*
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
This source code is available under the terms of the ffsl, or,
Floodgap Free Software License. A copy of the license has been
provided as the file 'LICENSE' in the same folder as this source
code file. If for some reason it is not present, you can find the
terms of version 1 of the FFSL at the following URL:
https://www.floodgap.com/software/ffsl/license.html
*/
package main
import (
"errors"
"fmt"
"strings"
)
type stack struct {
s []token
sp int
}
func (p *stack) Push(t token) error {
p.s[p.sp] = t
p.sp++
if p.sp >= len(p.s) {
p.sp = len(p.s) - 1
return errors.New("Stack overflow")
}
return nil
}
func (p *stack) Pop() (token, error) {
p.sp--
if p.sp < 0 {
p.sp = 0
return token{}, errors.New("Stack underflow")
}
return p.s[p.sp], nil
}
func (p stack) Peek() token {
if p.sp == 0 {
panic("Stack underflow")
}
return p.s[p.sp-1]
}
func (p stack) Depth() int {
return p.sp
}
func (p stack) String() string {
var b strings.Builder
b.WriteString("============TOS.============\n")
for i := p.sp - 1; i >= 0; i-- {
t := p.s[i]
s := toString(t, true)
if len(s) > 15 {
s = s[:15]
}
b.WriteString(fmt.Sprintf(stackFormat, kindToString(t.kind), s))
}
return b.String()
}
func NewStack() stack {
return stack{s: make([]token, STACK_SIZE, STACK_SIZE)}
}