twostack

package module
v0.0.0-...-58751ae Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 24, 2021 License: Apache-2.0 Imports: 7 Imported by: 0

README

TwoStack library

TwoStack library is a Golang implementation of 2-dimentional double-ended stack data primitive. The core of this data structure is a double-ended stack With "Front" node and "Back" node. Each node of this stack, called a "Global stack" is a double-ended stack, again with "Front" and "Back". This stack is called a "Cell stack"

TwoStack

How two-dimentional stack works.

Two-dimentional stack is working exactly like a common stack that you are accustom to. Depending on the stack mode, that could be "Normal" or "Reverse" data is pushed to the back or the front of the Cell stack which are at the back or front of the Global stack. At each particular moment, you are working with a single Cell Stack, but you can rotate Global stack in ether left or right direction. .Set or .Put operation will store data to the Cell stack, .Add will add a new Cell stack to the Global stack, .Left or .Right will rotate global stack, .Get or .G will read data from the Cell stack and .Take or .T will take data from ether front or back of the stack.

Data type layer of TwoStack

There are "raw" or "typed" access to data stored in TwoStack data structure. .Set/.Get/.Take operates with stack in the "raw" mode, so you can store any data type or structure that you like. .Put/.G/.T are used a "datatype layer" of the TwoStack and stored typed data, represented by special structure as a values in the stack. This structure and associated functions is just a "sugar" which takes away details of how you will handle a supported data types. Currently "data type layer" supports boolean, int64, int, float64, float32 and string. In addition to the data, "data type layer" also stored the name of the value and optional labels.

Show me the code

Create TwoStack, store and then retrive the raw values.
import (
    "fmt"
    . "github.com/vulogov/twostack"
)
func main() {
    ts := Init()
    ts.Set("42")
    r, err := ts.Get()
    if err != nil {
        fmt.Printf("Error: %v\n", err)
    } else {
        fmt.Printf("Value: %v\n", r)
    }
}

In this sample, we are storing a raw string in the node of the Cell stack and then reading it. Operation .Get doesn't change the state of the stack (unlike .Take) and the node storing that string still stays at the end of the stack (since our stack is in .Normal mode). As we see, the .Get or .Take operations will return an error as well as a value.

Show me how to work with stack mode
import (
    "fmt"
    . "github.com/vulogov/twostack"
)
func main() {
    ts := Init()
	ts.Set("42")
	ts.Set("41")
    // Pushing data to stack, 42 followed by 41
	ts.Reverse()  // Changing mode. Will read from the front
	r, _ := ts.Get()
    // Now, we will expect 42 since we are reading from the front of the stack
	ts.Normal()   // Changing mode. Will read from the back
	r, _ = ts.Get()
    // Now we will expect 41 as we are reading from the back.
}

While looking at this sample, you have to keep in mind few things:

  • TwoStack is in Normal mode by default. Cell stack is accessing the back of the Cell stack and Global stack is also accessing the back node.
  • .Normal and .Reverse change TwoStack behavor globally
  • TwoStack is essentially LIFO stack.
Show me how to operate with different Cell stacks
import (
    "fmt"
    . "github.com/vulogov/twostack"
)
func main() {
    ts := Init()
    ts.Set("42")     // Pushing data to the Cell stack
	ts.Add()         // Adding new Cell stack to the back of global stack
	ts.Set("41")     // Pushing data to the second Cell stack
	ts.Left()        // Rotating global stack to the left
	r, _ := ts.Get()    // Expecting to read "42" here since after rotation, Cell stack with "42" become at the back of the global stack
	ts.Right()          // Rotating global stack to the right. Cell stack with "41" becomes the back node with global stack
	r, _ = ts.Get()	 // Now, we are expecting to have "41"
}

Here, we haved to note a few things:

  • .Left and .Right will rotate global stack. Cell stacks will remain unchanged.
  • Rotation of the stack doesn't effect the TwoStack mode.
  • .Add have effect over global stack. Global stack is a storage for the Cell stacks. Cell stack is a storage for the data.
Show me, how to operate with "data type layer"

As I've mentioned before, "data type layer" is just a "sugar" designed to simplify handling of the typed data, by taking all conversions to and from interface{} (that is what Cell stack storing as data).

import (
    "fmt"
    . "github.com/vulogov/twostack"
)
func main() {
    ts := Init()
    if !ts.Put(3.14, "pi") {
		// Putting float value with name "pi" had failed
	}
	r, err := ts.G() // Expecting to have 3.14   
}

You may note a few things here:

  • .Put is different from .Set as it will store the data alongside with necessary information for conversion
  • "data type layer" do have a name for each value. If you do not care about name, pass an empty string ""
  • If you have a string representation of your data, "data type layer" provides you with .MakeInt, .MakeBool, MakeFloat, .MakeString primitives.
  • If you know data type at the top of the stack, you can use .GetBool, .GetInt, .GetFloat and .GetString primitives.
import (
    "fmt"
    . "github.com/vulogov/twostack"
)
func main() {
    ts := Init()
    ts.MakeInt("42", "answer")    // Making value from the string and storing it in TwoStack 
	res, err := ts.GetInt()       // We do know what data type are at the top of the stack
	// Expecting to have 42
}

Applying functions to data in Cell Stack

TwoStack provides you with convinient interface for applying custom functions to the data stored in Cell Stack. There are three types of functions:

  • Generator. This function doesn't require any data to be in stack, but will add single element to the stack.
  • Function. This function takes on element from the stack, perform operation with this element and push result back to stack as single element.
  • Operator. This function takes two elements from stack, perform operations with those two elements and push result as single element back to stack.
Show me the code
import (
    "fmt"
    . "github.com/vulogov/twostack"
)
func main() {
    ts := Init()
	ts.Put(42)
	_, err := ts.ApplyFun(NumericIncrease)  // Applying function NumericIncrease to the value on top of the stack. This function will convert numeric values to float and increase value to 1.0 
	if err != nil {
		t.Errorf("Error: %v", err)
	}
	res, _ := ts.G()
	// Expecing res to be 43.0
}

If you want to apply functions to values in Global stack, you can perform .Gzip() operation.

What is practical application for TwoStack data structure ?

Two-dimentional stack designed to overcome a few issues (as I see them) with one-dimentional stacks.

  • Data isolation. Every time when you are storing data for the later use them in the stack, you can end-up in the situation, when you badly-behaving code will not only get an access to the data that it should, but beyond that. TwoStack solved that problem. You can store the data in different Cell stacks for a different computations.
  • Arguments isolation. With languages of the FORT family, defining the arity of the function is very important step, as you do not want that function takes a deeper dive to the stack than it should. This is an extention of the Data isolation.
  • More natural representation of the matrixes or . You can have a separate stack with data for each row of the data.

Installation.

Just do it:

go get github.com/vulogov/twostack

Also, feel free to clone/branch source code:

git clone https://github.com/vulogov/twostack

Running make in the cloned directory will download all required modules and run tests.

Documentation

Index

Constants

View Source
const (
	Bool_t     = 0
	Int_t      = 1
	Float_t    = 2
	String_t   = 3
	Duration_t = 4
	Call_t     = 5
	None_t     = 99
)
View Source
const (
	GT  = 10
	GTE = 11
	LS  = 20
	LSE = 21
	EQ  = 0
	NEQ = 1
	IDK = 99
)

Variables

This section is empty.

Functions

func BoolFromString

func BoolFromString(d string) interface{}

func BoolToString

func BoolToString(e *Elem) string

func CallFromString

func CallFromString(d string) interface{}

func CallToString

func CallToString(e *Elem) string

func FloatFromString

func FloatFromString(d string) interface{}

func FloatToString

func FloatToString(e *Elem) string

func GenericFunFun

func GenericFunFun(ts *TwoStack, e1 *Elem, f FunFun) error

func GenericGenFun

func GenericGenFun(ts *TwoStack, f GenFun) error

func GenericOpFun

func GenericOpFun(ts *TwoStack, e1 *Elem, e2 *Elem, f OpFun) error

func IntFromString

func IntFromString(d string) interface{}

func IntToString

func IntToString(e *Elem) string

func IterPost

func IterPost(ts *TwoStack) bool

func IterPre

func IterPre(ts *TwoStack) bool

func NoneFromString

func NoneFromString(d string) interface{}

func NoneToString

func NoneToString(e *Elem) string

func OnlyIf42

func OnlyIf42(e1 *Elem) bool

func PassthroughFilter

func PassthroughFilter(e1 *Elem) bool

func StringFromString

func StringFromString(d string) interface{}

func StringToString

func StringToString(e *Elem) string

func TSCellIterator

func TSCellIterator(ts *TwoStack, fpre TSIterp_f, f TSIter_f, fpost TSIterp_f) bool

func TSGlobalIterator

func TSGlobalIterator(ts *TwoStack, fpre TSIterp_f, f TSIter_f, fpost TSIterp_f) bool

func TSGlobalTaker

func TSGlobalTaker(ts *TwoStack, fpre TSIterp_f, f TSIter_f, fpost TSIterp_f) bool

func TSIterator

func TSIterator(ts *TwoStack, q *deque.Deque, fpre TSIterp_f, f TSIter_f, fpost TSIterp_f)

Types

type ApplyFunFun

type ApplyFunFun func(ts *TwoStack, e1 *Elem, f FunFun) error

type ApplyGenFun

type ApplyGenFun func(ts *TwoStack, f GenFun) error

type ApplyOpFun

type ApplyOpFun func(ts *TwoStack, e1 *Elem, e2 *Elem, f OpFun) error

type Elem

type Elem struct {
	Type       int
	V          interface{}
	Name       string
	Labels     mapset.Set
	FromString FromStringFun
	ToString   ToStringFun
	Op         ApplyOpFun
	F          ApplyFunFun
	G          ApplyGenFun
}

func Answer

func Answer() (*Elem, error)

func Bool

func Bool(name string, v bool, labels ...string) *Elem

func Call

func Call(name string, v string, labels ...string) *Elem

func Float

func Float(name string, v float64, labels ...string) *Elem

func GiveAnswer

func GiveAnswer(kv *cmap.Cmap, p *mapset.Set) (*Elem, error)

func Int

func Int(name string, v int, labels ...string) *Elem

func Int64

func Int64(name string, v int64, labels ...string) *Elem

func MakeBool

func MakeBool(name string, p string, labels ...string) *Elem

func MakeCall

func MakeCall(name string, p string, labels ...string) *Elem

func MakeFloat

func MakeFloat(name string, p string, labels ...string) *Elem

func MakeInt

func MakeInt(name string, p string, labels ...string) *Elem

func MakeNone

func MakeNone(name string, p string, labels ...string) *Elem

func MakeString

func MakeString(name string, p string, labels ...string) *Elem

func NewElem

func NewElem(name string, t int, val interface{}, labels ...string) *Elem

func None

func None(name string, labels ...string) *Elem

func NumericAdd

func NumericAdd(e1 *Elem, e2 *Elem) (*Elem, error)

func NumericIncrease

func NumericIncrease(e1 *Elem) (*Elem, error)

func NumericIncreaseIfNum

func NumericIncreaseIfNum(e1 *Elem) (*Elem, error)

func Passthrough

func Passthrough(e1 *Elem) (*Elem, error)

func String

func String(name string, v string, labels ...string) *Elem

func (*Elem) Duplicate

func (e *Elem) Duplicate() *Elem

func (*Elem) Float

func (e *Elem) Float() float64

func (*Elem) String

func (e *Elem) String() string

type EvalFun

type EvalFun func(kv *cmap.Cmap, p *mapset.Set) (*Elem, error)

type FilterFun

type FilterFun func(e1 *Elem) bool

type FromStringFun

type FromStringFun func(d string) interface{}

type FunFun

type FunFun func(e1 *Elem) (*Elem, error)

type GenFun

type GenFun func() (*Elem, error)

type NS

type NS struct {
	Name    string
	ID      string
	IsTemp  bool
	IsRoot  bool
	TS      *TwoStack
	RootNS  *NS
	NSstack deque.Deque
	NScat   cmap.Cmap
	EFun    cmap.Cmap
	GFun    cmap.Cmap
	FFun    cmap.Cmap
	OFun    cmap.Cmap
	IFun    cmap.Cmap
	IFFun   cmap.Cmap
}

func NewNS

func NewNS(name string) (*NS, error)

func (*NS) Current

func (ns *NS) Current() (*NS, error)

func (*NS) EndNS

func (ns *NS) EndNS() error

func (*NS) Get

func (ns *NS) Get() (interface{}, error)

func (*NS) NewNS

func (ns *NS) NewNS(name string) (*NS, error)

func (*NS) NewTempNS

func (ns *NS) NewTempNS() (*NS, error)

func (*NS) Put

func (ns *NS) Put(v interface{}, labels ...string) error

func (*NS) Take

func (ns *NS) Take() (interface{}, error)

type OpFun

type OpFun func(e1 *Elem, e2 *Elem) (*Elem, error)

type TSIter_f

type TSIter_f func(ts *TwoStack, f *Elem)

type TSIterp_f

type TSIterp_f func(ts *TwoStack) bool

type ToStringFun

type ToStringFun func(e *Elem) string

type TwoStack

type TwoStack struct {
	R deque.Deque
	C cmap.Cmap

	ID     string
	Status bool
	Mode   bool
	IsIF   bool
	InstF  FunFun
	IsFF   bool
	InstFF FilterFun
	// contains filtered or unexported fields
}

func Init

func Init() *TwoStack

Initialize new 2-dimentional stack structure

func (*TwoStack) Add

func (ts *TwoStack) Add()

func (*TwoStack) ApplyFun

func (ts *TwoStack) ApplyFun(f FunFun) (*Elem, error)

func (*TwoStack) ApplyFunAll

func (ts *TwoStack) ApplyFunAll(f FunFun) (*Elem, error)

func (*TwoStack) ApplyGen

func (ts *TwoStack) ApplyGen(f GenFun) (*Elem, error)

func (*TwoStack) ApplyOp

func (ts *TwoStack) ApplyOp(f OpFun) (*Elem, error)

func (*TwoStack) ApplyOpAll

func (ts *TwoStack) ApplyOpAll(f OpFun) (*Elem, error)

func (*TwoStack) CLeft

func (ts *TwoStack) CLeft()

func (*TwoStack) CRight

func (ts *TwoStack) CRight()

func (*TwoStack) CZip

func (ts *TwoStack) CZip() error

func (*TwoStack) Del

func (ts *TwoStack) Del()

func (*TwoStack) Eval

func (ts *TwoStack) Eval(f EvalFun) (*Elem, error)

func (*TwoStack) Float

func (ts *TwoStack) Float() float64

func (*TwoStack) G

func (ts *TwoStack) G() (interface{}, error)

func (*TwoStack) GLen

func (ts *TwoStack) GLen() int

func (*TwoStack) GMerge

func (ts *TwoStack) GMerge() error

func (*TwoStack) GZip

func (ts *TwoStack) GZip() error

func (*TwoStack) Get

func (ts *TwoStack) Get() (interface{}, error)

func (*TwoStack) GetBool

func (ts *TwoStack) GetBool() (bool, error)

func (*TwoStack) GetCall

func (ts *TwoStack) GetCall() (string, error)

func (*TwoStack) GetElem

func (ts *TwoStack) GetElem() (*Elem, error)

func (*TwoStack) GetFloat

func (ts *TwoStack) GetFloat() (float64, error)

func (*TwoStack) GetInt

func (ts *TwoStack) GetInt() (int64, error)

func (*TwoStack) GetString

func (ts *TwoStack) GetString() (string, error)

func (*TwoStack) Left

func (ts *TwoStack) Left()

func (*TwoStack) Len

func (ts *TwoStack) Len() int

func (*TwoStack) MakeBool

func (ts *TwoStack) MakeBool(p string, labels ...string)

func (*TwoStack) MakeCall

func (ts *TwoStack) MakeCall(p string, labels ...string)

func (*TwoStack) MakeFloat

func (ts *TwoStack) MakeFloat(p string, labels ...string)

func (*TwoStack) MakeInt

func (ts *TwoStack) MakeInt(p string, labels ...string)

func (*TwoStack) MakeString

func (ts *TwoStack) MakeString(p string, labels ...string)

func (*TwoStack) Normal

func (ts *TwoStack) Normal()

func (*TwoStack) Put

func (ts *TwoStack) Put(d interface{}, labels ...string) bool

func (*TwoStack) Q

func (ts *TwoStack) Q() *deque.Deque

func (*TwoStack) Reverse

func (ts *TwoStack) Reverse()

func (*TwoStack) Right

func (ts *TwoStack) Right()

func (*TwoStack) Set

func (ts *TwoStack) Set(data interface{})

func (*TwoStack) SetBool

func (ts *TwoStack) SetBool(v bool, labels ...string)

func (*TwoStack) SetCall

func (ts *TwoStack) SetCall(v string, labels ...string)

func (*TwoStack) SetElem

func (ts *TwoStack) SetElem(e *Elem)

func (*TwoStack) SetFloat

func (ts *TwoStack) SetFloat(v float64, labels ...string)

func (*TwoStack) SetIF

func (ts *TwoStack) SetIF(f FunFun)

func (*TwoStack) SetIFilter

func (ts *TwoStack) SetIFilter(f FilterFun)

func (*TwoStack) SetInt

func (ts *TwoStack) SetInt(v int, labels ...string)

func (*TwoStack) SetInt64

func (ts *TwoStack) SetInt64(v int64, labels ...string)

func (*TwoStack) SetString

func (ts *TwoStack) SetString(v string, labels ...string)

func (*TwoStack) StopIF

func (ts *TwoStack) StopIF()

func (*TwoStack) StopIFilter

func (ts *TwoStack) StopIFilter()

func (*TwoStack) String

func (ts *TwoStack) String() string

func (*TwoStack) T

func (ts *TwoStack) T() (interface{}, error)

func (*TwoStack) Take

func (ts *TwoStack) Take() (interface{}, error)

func (*TwoStack) TakeBool

func (ts *TwoStack) TakeBool() (bool, error)

func (*TwoStack) TakeCall

func (ts *TwoStack) TakeCall() (string, error)

func (*TwoStack) TakeElem

func (ts *TwoStack) TakeElem() (*Elem, error)

func (*TwoStack) TakeFloat

func (ts *TwoStack) TakeFloat() (float64, error)

func (*TwoStack) TakeInt

func (ts *TwoStack) TakeInt() (int64, error)

func (*TwoStack) TakeString

func (ts *TwoStack) TakeString() (string, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL