Add Invocation stack - convenience RAS

This commit is contained in:
BlockChainDev 2019-03-15 22:33:32 +00:00
parent 1ff0caf40e
commit f954e6f2ca
3 changed files with 65 additions and 2 deletions

View file

@ -11,8 +11,6 @@ type Int struct {
// NewInt will convert a big integer into
// a StackInteger
func NewInt(val *big.Int) (*Int, error) {
// TOODO: check it is 32 bytes
return &Int{
abstractItem: &abstractItem{},
val: val,

View file

@ -0,0 +1,53 @@
package stack
import "errors"
// Invocation embeds a Random Access stack
// Providing helper methods for the context object
type Invocation struct{ RandomAccess }
//NewInvocation will return a new
// Invocation stack
func NewInvocation() *Invocation {
return &Invocation{
RandomAccess{
vals: make([]Item, 0, StackAverageSize),
},
}
}
func (i *Invocation) peekContext(n uint16) (*Context, error) {
item, err := i.Peek(n)
if err != nil {
return nil, err
}
ctx, err := item.Context()
if err != nil {
return nil, err
}
return ctx, nil
}
// CurrentContext returns the current context on the invocation stack
func (i *Invocation) CurrentContext() (*Context, error) {
return i.peekContext(0)
}
// CallingContext will return the cntext item
// that will be called next.
func (i *Invocation) CallingContext() (*Context, error) {
if i.Len() < 1 {
return nil, errors.New("Length of invocation stack is < 1, no calling context")
}
return i.peekContext(1)
}
// EntryContext will return the context item that
// started the program
func (i *Invocation) EntryContext() (*Context, error) {
// firstItemIndex refers to the first item
// that was popped on the stack
firstItemIndex := uint16(i.Len() - 1) // N.B. if this overflows because len is zero, then an error will be returned
return i.peekContext(firstItemIndex)
}

View file

@ -119,3 +119,15 @@ func (ras *RandomAccess) Peek(n uint16) (Item, error) {
return ras.vals[index], nil
}
// Convenience Functions
// PopInt will remove the last stack item that was added
// And cast it to an integer
func (ras *RandomAccess) PopInt() (*Int, error) {
item, err := ras.Pop()
if err != nil {
return nil, err
}
return item.Integer()
}