Documentation ¶
Index ¶
- Variables
- type Action
- type OrderedMap
- type Pair
- type Stack
- type StackOperator
- func (so *StackOperator) DefWord(def []string) (message string, err error)
- func (so *StackOperator) ExecuteToken(token string) (toPrint string, err error)
- func (so *StackOperator) Fail(message string, values ...float64) error
- func (so *StackOperator) MakePromptFunc(format string, fmtChar byte) error
- func (so *StackOperator) ParseInput(input string) (err error)
Constants ¶
This section is empty.
Variables ¶
var Add = &Action{ func(so *StackOperator) (toPrint string, err error) { so.Stack.Push(so.Stack.Pop() + so.Stack.Pop()) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the result of 'a' + 'b'", }
Add is an Action with the following description: pop 'a', 'b'; push the result of 'a' + 'b'
var Average = &Action{ func(so *StackOperator) (toPrint string, err error) { n := float64(len(so.Stack.Values)) Sum.Call(so) so.Stack.Push(so.Stack.Pop() / n) return so.Stack.Display(), nil }, 1, 1, "pop all values in the stack; push their average", }
Average is an Action with the following description: pop all values in the stack; push their average.
var Ceiling = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(math.Ceil(so.Stack.Pop())) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the least integer value greater than or equal to 'a'", }
Ceiling is an Action with the following description: pop 'a'; push the least integer value greater than or equal to 'a'.
var Clear = &Action{ func(so *StackOperator) (string, error) { var c byte n := len(so.Stack.Values) if n != 1 { c = 's' } so.Stack.Values = make([]float64, 0, cap(so.Stack.Values)) return fmt.Sprintf("cleared %d value%c\n", n, c), nil }, 0, 0, "pop all values in the stack", }
Clear is an Action with the following description: pop all values in the stack.
var ClearScreen = &Action{ func(so *StackOperator) (string, error) { return "\x1b[2J\x1b[H", nil }, 0, 0, "clear the terminal screen", }
ClearScreen is an Action with the following description: clear the terminal screen.
var Clip = &Action{ func(so *StackOperator) (toPrint string, err error) { c := cap(so.Stack.Values) so.Stack.Values = slices.Clip(so.Stack.Values) return fmt.Sprintf("clipped %d capacity\n", c-cap(so.Stack.Values)), nil }, 0, 0, "DEBUG; clip unused stack capacity", }
var Cosine = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(math.Cos(so.Stack.Pop())) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the cosine of 'a' in radians", }
Cosine is an Action with the following description: pop 'a'; push the cosine of 'a' in radians.
var Degrees = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(so.Stack.Pop() * 180 / math.Pi) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the result of converting 'a' from radians to degrees", }
Degrees is an Action with the following description: pop 'a'; push the result of converting 'a' from radians to degrees.
var Display = &Action{ func(so *StackOperator) (string, error) { sBuf := make([]string, len(so.Stack.Values)) for i, f := range so.Stack.Values { sBuf[i] = fmt.Sprint(f) } return fmt.Sprintf("[ %s ]\n", strings.Join(sBuf, " ")), nil }, 0, 0, "display all values in the stack", }
Display is an Action with the following description: display all values in the stack.
var Divide = &Action{ func(so *StackOperator) (string, error) { divisor := so.Stack.Pop() if divisor == 0 { return "", so.Fail("cannot divide by 0", divisor) } so.Stack.Push(so.Stack.Pop() / divisor) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the result of 'b' / 'a'", }
Divide is an Action with the following description: pop 'a', 'b'; push the result of 'b' / 'a'
var Factorial = &Action{ func(so *StackOperator) (string, error) { x := so.Stack.Pop() if x != float64(int(x)) { return "", so.Fail("cannot take factorial of non-integer", x) } if x < 0 { return "", so.Fail("cannot take factorial of negative number", x) } p := 1 for i := 2; i <= int(x); i++ { p *= i } so.Stack.Push(float64(p)) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the factorial of 'a'", }
Factorial is an Action with the following description: pop 'a'; push the factorial of 'a'.
var Fill = &Action{ func(so *StackOperator) (toPrint string, err error) { for i := 0; i < cap(so.Stack.Values); i++ { if i > len(so.Stack.Values)-1 { so.Stack.Values = append(so.Stack.Values, float64(rand.Intn(255))) } } return so.Stack.Display(), nil }, 0, 0, "DEBUG; fill stack with random values", }
Fill is an Action with the following description: DEBUG: fill stack with random values
var Floor = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(math.Floor(so.Stack.Pop())) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the greatest integer value less than or equal to 'a'", }
Floor is an Action with the following description: pop 'a'; push the greatest integer value less than or equal to 'a'.
var Froll = &Action{ func(so *StackOperator) (string, error) { newVals := make([]float64, 0, cap(so.Stack.Values)) l := len(so.Stack.Values) newVals = append(newVals, so.Stack.Values[l-1]) for _, f := range so.Stack.Values[:l-1] { newVals = append(newVals, f) } so.Stack.Values = newVals return so.Stack.Display(), nil }, 2, 2, "roll the stack to the right one position", }
Froll is an Action with the following description: roll the stack to the right one position.
var Grow = &Action{ func(so *StackOperator) (toPrint string, err error) { if cap(so.Stack.Values) == 0 { so.Stack.Values = slices.Grow(so.Stack.Values, 1) return fmt.Sprintf("new stack capacity is %d\n", cap(so.Stack.Values)), nil } if len(so.Stack.Values) == 0 { return "", nil } n := so.Stack.Pop() if n != float64(int(n)) { return "", so.Fail("cannot grow stack by non-integer value", n) } if n < 0 { return "", so.Fail("cannot grow stack by negative value", n) } so.Stack.Push(n) so.Stack.Values = slices.Grow(so.Stack.Values, int(n)) return fmt.Sprintf("new stack capacity is %d\n", cap(so.Stack.Values)), nil }, 0, 0, "DEBUG; pop 'a'; push 'a'; grow stack to accomadate 'a' more values", }
Grow is an Action with the following description: DEBUG: pop 'a'; push 'a'; grow stack to accomadate 'a' more values. Will commit blasphemy and grow stack by 1 if cap(Stack.Values) == 0.
var Help = &Action{ func(so *StackOperator) (string, error) { header := "operator" maxLen := len(header) for p := so.Actions.Next(); p != nil; p = so.Actions.Next() { if len(p.Key) > maxLen { maxLen = len(p.Key) } } so.Actions.Reset() sb := new(strings.Builder) pad := strings.Repeat(" ", maxLen-len(header)) sb.WriteString(fmt.Sprintf("%s%s | %s\n", pad, header, "description")) for p := so.Actions.Next(); p != nil; p = so.Actions.Next() { pad := strings.Repeat(" ", maxLen-len(p.Key)) sb.WriteString(fmt.Sprintf("%s%s : %s\n", pad, p.Key, p.Value.Help)) } so.Actions.Reset() return sb.String(), nil }, 0, 0, "display this information screen", }
Help is an Action with the following description: display this information screen.
var Ln = &Action{ func(so *StackOperator) (string, error) { x := so.Stack.Pop() if x <= 0 { return "", so.Fail("cannot take logarithm of non-positive number", x) } so.Stack.Push(math.Log(x)) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the natural logarithm of 'a'", }
Ln is an Action with the following description: pop 'a'; push the natural logarithm of 'a'.
var Log = &Action{ func(so *StackOperator) (string, error) { x := so.Stack.Pop() if x <= 0 { return "", so.Fail("cannot take logarithm of non-positive number", x) } so.Stack.Push(math.Log10(x)) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the logarithm base 10 of 'a'", }
Log is an Action with the following description: pop 'a'; push the logarithm base 10 of 'a'.
var Modulo = &Action{ func(so *StackOperator) (string, error) { divisor := so.Stack.Pop() if divisor == 0 { return "", so.Fail("cannot divide by 0", divisor) } so.Stack.Push(math.Mod(so.Stack.Pop(), divisor)) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the remainder of 'b' / 'a'", }
Modulo is an Action with the following description: pop 'a', 'b'; push the remainder of 'b' / 'a'.
var Multiply = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(so.Stack.Pop() * so.Stack.Pop()) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the result of 'a' * 'b'", }
Multiply is an Action with the following description: pop 'a', 'b'; push the result of 'a' * 'b'
var Pop = &Action{ func(so *StackOperator) (string, error) { so.Stack.Pop() return so.Stack.Display(), nil }, 1, 0, "pop 'a'", }
Pop is an Action with the following description: pop 'a'.
var Power = &Action{ func(so *StackOperator) (string, error) { exponent := so.Stack.Pop() base := so.Stack.Pop() if base == 0 && exponent < 0 { return "", so.Fail("cannot raise 0 to negative power", base, exponent) } if base < 0 && exponent != float64(int(exponent)) { return "", so.Fail("cannot raise negative number to non-integer power", base, exponent) } so.Stack.Push(math.Pow(base, exponent)) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the result of 'b' ^ 'a'", }
Power is an Action with the following description: pop 'a', 'b'; push the result of 'b' ^ 'a'.
var Pull = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(so.Stack.Stash) return so.Stack.Display(), nil }, 0, 1, "push the value in the stash", }
Pull is an Action with the following description: push the value in the stash.
var Radians = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(so.Stack.Pop() * math.Pi / 180) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the result of converting 'a' from degrees to radians", }
Radians is an Action with the following description: pop 'a'; push the result of converting 'a' from degrees to radians.
var Random = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(rand.Float64()) return so.Stack.Display(), nil }, 0, 1, "push a random number between 0 and 1", }
Random is an Action with the following description: push a random number between 0 and 1.
var Round = &Action{ func(so *StackOperator) (string, error) { precision := so.Stack.Pop() if precision < 0 || precision != float64(int(precision)) { return "", so.Fail("precision must be non-negative integer") } ratio := math.Pow(10, precision) so.Stack.Push(math.Round(so.Stack.Pop()*ratio) / ratio) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the result of rounding 'b' to 'a' decimal places", }
Round is an Action with the following description: pop 'a', 'b'; push the result of rounding 'b' to 'a' decimal places.
var Rroll = &Action{ func(so *StackOperator) (string, error) { newVals := make([]float64, 0, cap(so.Stack.Values)) for _, f := range so.Stack.Values[1:] { newVals = append(newVals, f) } newVals = append(newVals, so.Stack.Values[0]) so.Stack.Values = newVals return so.Stack.Display(), nil }, 2, 2, "roll the stack to the left one position", }
Rroll is an Action with the following description: roll the stack to the left one position.
var Sine = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(math.Sin(so.Stack.Pop())) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the sine of 'a' in radians", }
Sine is an Action with the following description: pop 'a'; push the sine of 'a' in radians.
var Stash = &Action{ func(so *StackOperator) (string, error) { so.Stack.Stash = so.Stack.Pop() return so.Stack.Display(), nil }, 1, 0, "pop 'a'; stash 'a'", }
Stash is an Action with the following description: pop 'a'; stash 'a'.
var Subtract = &Action{ func(so *StackOperator) (string, error) { x := so.Stack.Pop() y := so.Stack.Pop() so.Stack.Push(y - x) return so.Stack.Display(), nil }, 2, 1, "pop 'a', 'b'; push the result of 'b' - 'a'", }
Subtract is an Action with the following description:
var Sum = &Action{ func(so *StackOperator) (toPrint string, err error) { var sum float64 for len(so.Stack.Values) > 0 { sum += so.Stack.Pop() } so.Stack.Push(sum) return so.Stack.Display(), nil }, 1, 1, "pop all values in the stack; push their sum", }
Sum is an Action with the following description: pop all values in the stack; push their sum.
var Swap = &Action{ func(so *StackOperator) (string, error) { x := so.Stack.Pop() y := so.Stack.Pop() so.Stack.Push(x) so.Stack.Push(y) return so.Stack.Display(), nil }, 2, 2, "pop 'a', 'b'; push 'b', 'a'", }
Swap is an Action with the following description: pop 'a', 'b'; push 'b', 'a'.
var Tangent = &Action{ func(so *StackOperator) (string, error) { so.Stack.Push(math.Tan(so.Stack.Pop())) return so.Stack.Display(), nil }, 1, 1, "pop 'a'; push the tangent of 'a' in radians", }
Tangent is an Action with the following description: pop 'a'; push the tangent of 'a' in radians.
var Words = &Action{ func(so *StackOperator) (string, error) { keys := make([]string, 0, len(so.Words)) header := "word" maxLen := len(header) for k := range so.Words { keys = append(keys, k) if len(k) > maxLen { maxLen = len(k) } } slices.SortFunc(keys, func(a string, b string) int { if len(a) > len(b) { return -1 } if len(a) < len(b) { return 1 } if a > b { return 1 } if a < b { return -1 } return 0 }) sb := new(strings.Builder) pad := strings.Repeat(" ", maxLen-len(header)) sb.WriteString(fmt.Sprintf("%s%s | definition\n", pad, header)) for _, k := range keys { pad := strings.Repeat(" ", maxLen-len(k)) sb.WriteString(fmt.Sprintf("%s%s : %s\n", pad, k, so.Words[k])) } return sb.String(), nil }, 0, 0, "display all defined words", }
Words is an Action with the following description: display all defined words.
Functions ¶
This section is empty.
Types ¶
type Action ¶
type OrderedMap ¶ added in v1.1.0
type OrderedMap[K comparable, V any] struct { Pairs map[K]*Pair[K, V] Current int // contains filtered or unexported fields }
OrderedMap contains a generic map of values, and an auxilary list to get items from in an ordered fashion.
func NewOrderedMap ¶ added in v1.1.0
func NewOrderedMap[K comparable, V any]() *OrderedMap[K, V]
NewOrderedMap returns a pointer to an OrderedMap with initialized values that is ready to use.
func (*OrderedMap[K, V]) Get ¶ added in v1.1.0
func (om *OrderedMap[K, V]) Get(key K) (pair *Pair[K, V], present bool)
Get returns the Pair at OrderedMap[key], and whether key is present in the OrderedMap.
func (*OrderedMap[K, V]) Next ¶ added in v1.1.0
func (om *OrderedMap[K, V]) Next() (pair *Pair[K, V])
Next returns the next Pair in OrderedMap sequentially, from the first one set to the last.
for p := om.Next(); p != nil; p = om.next() {...}
func (*OrderedMap[K, V]) Reset ¶ added in v1.1.0
func (om *OrderedMap[K, V]) Reset()
Reset sets the value of OrderedMap.Current to 0.
func (*OrderedMap[K, V]) Set ¶ added in v1.1.0
func (om *OrderedMap[K, V]) Set(key K, val V)
Set sets OrderedMap[key] = Pair{Key: key, Value: val} and panics if the key is already present in the OrderedMap.
type Pair ¶ added in v1.1.0
type Pair[K comparable, V any] struct { Key K Value V }
Pair contains a Key of type K and Value of type V.
type Stack ¶
type Stack struct { Values []float64 Stash float64 // Expandable signifies whether stack capacity can be increased or not. Expandable bool // contains filtered or unexported fields }
Stack contains a slice of float64 and methods to operate on that slice.
func (*Stack) Display ¶
Display returns a string of all values in the stack according to Stack.displayFmt
type StackOperator ¶
type StackOperator struct { Actions *OrderedMap[string, *Action] Words map[string]string Stack *Stack Interactive bool Prompt func() (prompt string) PrintBuf []byte // contains filtered or unexported fields }
StackOperator contains a map for converting string tokens into operations that can be called to operate on the stack.
func NewStackOperator ¶
func NewStackOperator(actions *OrderedMap[string, *Action], maxStack int, interactive bool, noDisplay bool, strict bool) *StackOperator
NewStackOperator returns a pointer to a new StackOperator, initialized to given arguments and a default set of defined words and formatters.
func (*StackOperator) DefWord ¶
func (so *StackOperator) DefWord(def []string) (message string, err error)
DefWord adds a word to StackOperator.Words with the key being def[0] and the value being the rest of the slice. It deletes def[0] from StackOperator.Words if len(def) == 1. It returns a string and nil if the operator was successful and an empty string and an error if not.
func (*StackOperator) ExecuteToken ¶
func (so *StackOperator) ExecuteToken(token string) (toPrint string, err error)
ExecuteToken determines if `token` is an Action token or defined word and executes it accordingly. Returns the string and error from doing what it needs to do.
func (*StackOperator) Fail ¶
func (so *StackOperator) Fail(message string, values ...float64) error
Fail pushes all values to the stack and returns an error containing `message`. It also prints Stack.Display if the StackOperator is interactive
func (*StackOperator) MakePromptFunc ¶
func (so *StackOperator) MakePromptFunc(format string, fmtChar byte) error
MakePromptFunc sets the StackOperator.prompt value that will execute any functions needed to build the prompt and will return a new string every time it is called. This function returns an error if it could not make the prompt function (should always return nil).
func (*StackOperator) ParseInput ¶
func (so *StackOperator) ParseInput(input string) (err error)
ParseInput splits an input string into words and interprets each word as a token. It stops executing tokens if it encounters an '=' or the execution of the token returns an error, and returns that error. ParseInput fills PrintBuf with the message returned by the execution of the last token.