4 Commits

Author SHA1 Message Date
4846691c46 revert exists(), unused 2023-11-12 20:41:06 +01:00
T.v.Dein
2f56761bf1 Feature/commands (#18)
* re-organized command structure
* added 'dup' command
2023-11-12 20:29:10 +01:00
T.v.Dein
0782b0920b Merge pull request #17 from TLINDEN/feature/add-disable-swiches
added no versions of batch debug and showstack toggles
2023-11-10 15:44:07 +01:00
40c4cf0e45 added no versions of batch debug and showstack toggles 2023-11-10 15:38:05 +01:00
5 changed files with 307 additions and 79 deletions

169
calc.go
View File

@@ -20,8 +20,8 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"os"
"regexp" "regexp"
"sort"
"strconv" "strconv"
"strings" "strings"
@@ -48,24 +48,17 @@ type Calc struct {
Funcalls Funcalls Funcalls Funcalls
BatchFuncalls Funcalls BatchFuncalls Funcalls
// different kinds of commands, displays nicer in help output
StackCommands Commands
SettingsCommands Commands
ShowCommands Commands
Commands Commands
Vars map[string]float64 Vars map[string]float64
} }
// help for lua functions will be added dynamically // help for lua functions will be added dynamically
const Help string = `Available commands: const Help string = `
batch toggle batch mode
debug toggle debug output
show show the last 5 items of the stack
dump display the stack contents
clear clear the whole stack
shift remove the last element of the stack
reverse reverse the stack elements
swap exchange the last two elements
vars show list of variables
history display calculation history
help|? show this message
quit|exit|c-d|c-c exit program
Operators: Operators:
basic operators: + - x * / ^ (* is an alias of x) basic operators: + - x * / ^ (* is an alias of x)
@@ -94,7 +87,7 @@ Register variables:
// commands, constants and operators, defined here to feed completion // commands, constants and operators, defined here to feed completion
// and our mode switch in Eval() dynamically // and our mode switch in Eval() dynamically
const ( const (
Commands string = `dump reverse debug undebug clear batch shift undo help history manual exit quit swap show vars` //Commands string = `dump reverse clear shift undo help history manual exit quit swap debug undebug nodebug batch nobatch showstack noshowstack vars`
Constants string = `Pi Phi Sqrt2 SqrtE SqrtPi SqrtPhi Ln2 Log2E Ln10 Log10E` Constants string = `Pi Phi Sqrt2 SqrtE SqrtPi SqrtPhi Ln2 Log2E Ln10 Log10E`
) )
@@ -107,7 +100,6 @@ func GetCompleteCustomFunctions() func(string) []string {
completions = append(completions, luafunc) completions = append(completions, luafunc)
} }
completions = append(completions, strings.Split(Commands, " ")...)
completions = append(completions, strings.Split(Constants, " ")...) completions = append(completions, strings.Split(Constants, " ")...)
return completions return completions
@@ -126,6 +118,22 @@ func (c *Calc) GetCompleteCustomFuncalls() func(string) []string {
completions = append(completions, function) completions = append(completions, function)
} }
for command := range c.SettingsCommands {
completions = append(completions, command)
}
for command := range c.ShowCommands {
completions = append(completions, command)
}
for command := range c.StackCommands {
completions = append(completions, command)
}
for command := range c.Commands {
completions = append(completions, command)
}
return completions return completions
} }
@@ -151,6 +159,8 @@ func NewCalc() *Calc {
// pre-calculate mode switching arrays // pre-calculate mode switching arrays
c.Constants = strings.Split(Constants, " ") c.Constants = strings.Split(Constants, " ")
c.SetCommands()
return &c return &c
} }
@@ -274,65 +284,32 @@ func (c *Calc) Eval(line string) {
continue continue
} }
// management commands // internal commands
if _, ok := c.Commands[item]; ok {
c.Commands[item].Func(c)
continue
}
if _, ok := c.ShowCommands[item]; ok {
c.ShowCommands[item].Func(c)
continue
}
if _, ok := c.StackCommands[item]; ok {
c.StackCommands[item].Func(c)
continue
}
if _, ok := c.SettingsCommands[item]; ok {
c.SettingsCommands[item].Func(c)
continue
}
switch item { switch item {
case "?": case "?":
fallthrough fallthrough
case "help": case "help":
fmt.Println(Help) c.PrintHelp()
if len(LuaFuncs) > 0 {
fmt.Println("Lua functions:")
for name, function := range LuaFuncs {
fmt.Printf("%-20s %s\n", name, function.help)
}
}
case "dump":
c.stack.Dump()
case "debug":
c.ToggleDebug()
case "undebug":
c.debug = false
case "batch":
c.ToggleBatch()
case "clear":
c.stack.Backup()
c.stack.Clear()
case "shift":
c.stack.Backup()
c.stack.Shift()
case "reverse":
c.stack.Backup()
c.stack.Reverse()
case "swap":
if c.stack.Len() < 2 {
fmt.Println("stack too small, can't swap")
} else {
c.stack.Backup()
c.stack.Swap()
}
case "undo":
c.stack.Restore()
case "history":
for _, entry := range c.history {
fmt.Println(entry)
}
case "show":
c.ToggleShow()
case "exit":
fallthrough
case "quit":
os.Exit(0)
case "manual":
man()
case "vars":
if len(c.Vars) > 0 {
fmt.Printf("%-20s %s\n", "VARIABLE", "VALUE")
for k, v := range c.Vars {
fmt.Printf("%-20s -> %.2f\n", k, v)
}
} else {
fmt.Println("no vars registered")
}
default: default:
fmt.Println("unknown command or operator!") fmt.Println("unknown command or operator!")
@@ -519,3 +496,51 @@ func (c *Calc) GetVar(name string) {
fmt.Println("variable doesn't exist") fmt.Println("variable doesn't exist")
} }
} }
func sortcommands(hash Commands) []string {
keys := make([]string, 0, len(hash))
for key := range hash {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
func (c *Calc) PrintHelp() {
fmt.Println("Available configuration commands:")
for _, name := range sortcommands(c.SettingsCommands) {
fmt.Printf("%-20s %s\n", name, c.SettingsCommands[name].Help)
}
fmt.Println()
fmt.Println("Available show commands:")
for _, name := range sortcommands(c.ShowCommands) {
fmt.Printf("%-20s %s\n", name, c.ShowCommands[name].Help)
}
fmt.Println()
fmt.Println("Available stack manipulation commands:")
for _, name := range sortcommands(c.StackCommands) {
fmt.Printf("%-20s %s\n", name, c.StackCommands[name].Help)
}
fmt.Println()
fmt.Println("Other commands:")
for _, name := range sortcommands(c.Commands) {
fmt.Printf("%-20s %s\n", name, c.Commands[name].Help)
}
fmt.Println()
fmt.Println(Help)
// append lua functions, if any
if len(LuaFuncs) > 0 {
fmt.Println("Lua functions:")
for name, function := range LuaFuncs {
fmt.Printf("%-20s %s\n", name, function.help)
}
}
}

201
command.go Normal file
View File

@@ -0,0 +1,201 @@
/*
Copyright © 2023 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"fmt"
"os"
)
type CommandFunction func(*Calc)
type Command struct {
Help string
Func CommandFunction
}
type Commands map[string]*Command
func NewCommand(help string, function CommandFunction) *Command {
return &Command{
Help: help,
Func: function,
}
}
// define all management (that is: non calculation) commands
func (c *Calc) SetCommands() {
c.SettingsCommands = Commands{
// Toggles
"debug": NewCommand(
"toggle debugging",
func(c *Calc) {
c.ToggleDebug()
},
),
"nodebug": NewCommand(
"disable debugging",
func(c *Calc) {
c.debug = false
c.stack.debug = false
},
),
"batch": NewCommand(
"toggle batch mode",
func(c *Calc) {
c.ToggleBatch()
},
),
"nobatch": NewCommand(
"disable batch mode",
func(c *Calc) {
c.batch = false
},
),
"showstack": NewCommand(
"toggle show last 5 items of the stack",
func(c *Calc) {
c.ToggleShow()
},
),
"noshowstack": NewCommand(
"disable display of the stack",
func(c *Calc) {
c.showstack = false
},
),
}
c.ShowCommands = Commands{
// Display commands
"dump": NewCommand(
"display the stack contents",
func(c *Calc) {
c.stack.Dump()
},
),
"history": NewCommand(
"display calculation history",
func(c *Calc) {
for _, entry := range c.history {
fmt.Println(entry)
}
},
),
"vars": NewCommand(
"show list of variables",
func(c *Calc) {
if len(c.Vars) > 0 {
fmt.Printf("%-20s %s\n", "VARIABLE", "VALUE")
for k, v := range c.Vars {
fmt.Printf("%-20s -> %.2f\n", k, v)
}
} else {
fmt.Println("no vars registered")
}
},
),
}
c.StackCommands = Commands{
"clear": NewCommand(
"clear the whole stack",
func(c *Calc) {
c.stack.Backup()
c.stack.Clear()
},
),
"shift": NewCommand(
"remove the last element of the stack",
func(c *Calc) {
c.stack.Backup()
c.stack.Shift()
},
),
"reverse": NewCommand(
"reverse the stack elements",
func(c *Calc) {
c.stack.Backup()
c.stack.Reverse()
},
),
"swap": NewCommand(
"exchange the last two elements",
func(c *Calc) {
if c.stack.Len() < 2 {
fmt.Println("stack too small, can't swap")
} else {
c.stack.Backup()
c.stack.Swap()
}
},
),
"undo": NewCommand(
"undo last operation",
func(c *Calc) {
c.stack.Restore()
},
),
"dup": NewCommand(
"duplicate last stack item",
func(c *Calc) {
item := c.stack.Last()
if len(item) == 1 {
c.stack.Backup()
c.stack.Push(item[0])
} else {
fmt.Println("stack empty")
}
},
),
}
// general commands
c.Commands = Commands{
"exit": NewCommand(
"exit program",
func(c *Calc) {
os.Exit(0)
},
),
"manual": NewCommand(
"show manual",
func(c *Calc) {
man()
},
),
}
// aliases
c.Commands["quit"] = c.Commands["exit"]
c.SettingsCommands["undebug"] = c.SettingsCommands["nodebug"]
c.SettingsCommands["show"] = c.SettingsCommands["showstack"]
}

View File

@@ -30,7 +30,7 @@ import (
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
) )
const VERSION string = "2.0.7" const VERSION string = "2.0.9"
const Usage string = `This is rpn, a reverse polish notation calculator cli. const Usage string = `This is rpn, a reverse polish notation calculator cli.

7
rpn.go
View File

@@ -152,14 +152,15 @@ DESCRIPTION
Commands: Commands:
batch toggle batch mode [no]batch toggle batch mode (nobatch turns it off)
debug toggle debug output [no]debug toggle debug output (nodebug turns it off)
[no]showstack show the last 5 items of the stack (noshowtack turns it off)
dump display the stack contents dump display the stack contents
clear clear the whole stack clear clear the whole stack
shift remove the last element of the stack shift remove the last element of the stack
reverse reverse the stack elements reverse reverse the stack elements
swap exchange the last two stack elements swap exchange the last two stack elements
show show the last 5 items of the stack dup duplicate last stack item
history display calculation history history display calculation history
help|? show this message help|? show this message
quit|exit|c-d|c-c exit program quit|exit|c-d|c-c exit program

View File

@@ -159,14 +159,15 @@ Math functions:
Commands: Commands:
batch toggle batch mode [no]batch toggle batch mode (nobatch turns it off)
debug toggle debug output [no]debug toggle debug output (nodebug turns it off)
[no]showstack show the last 5 items of the stack (noshowtack turns it off)
dump display the stack contents dump display the stack contents
clear clear the whole stack clear clear the whole stack
shift remove the last element of the stack shift remove the last element of the stack
reverse reverse the stack elements reverse reverse the stack elements
swap exchange the last two stack elements swap exchange the last two stack elements
show show the last 5 items of the stack dup duplicate last stack item
history display calculation history history display calculation history
help|? show this message help|? show this message
quit|exit|c-d|c-c exit program quit|exit|c-d|c-c exit program