190 lines
3.9 KiB
Go
190 lines
3.9 KiB
Go
package cli
|
||
|
||
import (
|
||
"regexp"
|
||
"strconv"
|
||
|
||
"gitea.zaclys.com/bvaudour/gob/option"
|
||
"gitea.zaclys.net/bvaudour/go-calc/calc"
|
||
)
|
||
|
||
var (
|
||
otherFunctions = map[string]func() option.Option[error]{
|
||
"h": printHelp,
|
||
"q": quit,
|
||
}
|
||
|
||
calcFunctions = map[string]calc.CalcFunc{
|
||
"op": printOption,
|
||
"of": fixPrecision(true),
|
||
"oa": fixPrecision(false),
|
||
"p": printLast,
|
||
"P": printStack,
|
||
"c": calc.Pop,
|
||
"C": calc.Reset,
|
||
"d": calc.Duplicate,
|
||
"D": calc.DuplicateStack,
|
||
"r": calc.Reverse,
|
||
"R": calc.ReverseStack,
|
||
"s": calc.Sort,
|
||
"S": calc.SortDesc,
|
||
":P": printRegistries,
|
||
":C": calc.ResetRegistries,
|
||
";C": calc.ResetMacros,
|
||
"|": calc.Abs,
|
||
"++": calc.Inc,
|
||
"--": calc.Dec,
|
||
"inv": calc.Inv,
|
||
"+": calc.Add,
|
||
"-": calc.Sub,
|
||
"−": calc.Sub,
|
||
"*": calc.Mul,
|
||
"×": calc.Mul,
|
||
"/": calc.Div,
|
||
"÷": calc.Div,
|
||
"//": calc.Quo,
|
||
"%": calc.Rem,
|
||
"²": calc.Square,
|
||
"^": calc.Pow,
|
||
"v": calc.Sqrt,
|
||
"√": calc.Sqrt,
|
||
"vn": calc.Sqrtn,
|
||
"!": calc.Fact,
|
||
"<=>": calc.Cmp,
|
||
"=": calc.Eq,
|
||
"<>": calc.Ne,
|
||
"≠": calc.Ne,
|
||
">": calc.Gt,
|
||
">=": calc.Ge,
|
||
"≥": calc.Ge,
|
||
"<=": calc.Le,
|
||
"≤": calc.Le,
|
||
"cb": calc.ToBase(2),
|
||
"co": calc.ToBase(8),
|
||
"cx": calc.ToBase(16),
|
||
"ci": calc.ToInteger[uint](),
|
||
"cd": calc.ToDecimal[uint](),
|
||
"cs": calc.ToScientific[uint](),
|
||
"cf": calc.ToFraction[uint](),
|
||
">>": calc.Rsh,
|
||
"<<": calc.Lsh,
|
||
"min": calc.Min,
|
||
"max": calc.Max,
|
||
"sum": calc.Sum,
|
||
"moy": calc.Mean,
|
||
"med": calc.Median,
|
||
"mod": calc.Mode,
|
||
"var": calc.Variance,
|
||
"dev": calc.StdDeviation,
|
||
"l": func(c *calc.Calc) (err option.Option[error]) {
|
||
c.Len()
|
||
return
|
||
},
|
||
"n": calc.NoAction,
|
||
}
|
||
|
||
wordCalcFunctions = map[string]calc.WordCalcFunc{
|
||
`^:p\w+$`: printRegistry,
|
||
`^:c\w+$`: calc.ResetRegistry,
|
||
`^:l\w+$`: calc.Load,
|
||
`^:s\w+$`: calc.Store,
|
||
`^:S\w+$`: calc.StoreStack,
|
||
`^;x\w+$`: execMacro,
|
||
}
|
||
|
||
intCalcFunctions = map[string]calc.IntCalcFunc[uint64]{
|
||
`^c\d+$`: func(base ...uint64) calc.CalcFunc {
|
||
if len(base) > 0 {
|
||
return calc.ToBase(base[0])
|
||
}
|
||
return func(c *calc.Calc) (err option.Option[error]) { return }
|
||
},
|
||
`^ci\d+$`: calc.ToInteger[uint64],
|
||
`^cd\d+$`: calc.ToDecimal[uint64],
|
||
`^cs\d+$`: calc.ToScientific[uint64],
|
||
`^cf\d+$`: calc.ToFraction[uint64],
|
||
`^of\d+$`: precision[uint64](true),
|
||
`^oa\d+$`: precision[uint64](false),
|
||
}
|
||
|
||
cliFunctions = map[string]CliFunc{
|
||
";P": printMacros,
|
||
"[": startMacro,
|
||
"?": startAlt,
|
||
}
|
||
|
||
wordCliFunctions = map[string]WordCliFunc{
|
||
`^;p\w+$`: printMacro,
|
||
`^;c\w+$`: resetMacro,
|
||
`^\]\w+$`: endMacro,
|
||
}
|
||
|
||
needExec = map[string]bool{
|
||
"[": true,
|
||
`^\]\w+$`: true,
|
||
}
|
||
)
|
||
|
||
func searchWordCalcFunction(arg string) (cb calc.CalcFunc, ok bool) {
|
||
for k, f := range wordCalcFunctions {
|
||
if ok = regexp.MustCompile(k).MatchString(arg); ok {
|
||
cb = f(arg[2:])
|
||
break
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func searchIntCalcFunction(arg string) (cb calc.CalcFunc, ok bool) {
|
||
for k, f := range intCalcFunctions {
|
||
if ok = regexp.MustCompile(k).MatchString(arg); ok {
|
||
var d uint64
|
||
var err error
|
||
if d, err = strconv.ParseUint(arg[1:], 10, 64); err != nil {
|
||
d, _ = strconv.ParseUint(arg[2:], 10, 64)
|
||
}
|
||
cb = f(d)
|
||
break
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func searchWordCliFunction(arg string) (cb CliFunc, ok, execNow bool) {
|
||
for k, f := range wordCliFunctions {
|
||
if ok = regexp.MustCompile(k).MatchString(arg); ok {
|
||
if arg[0] == ']' {
|
||
cb = f(arg[1:])
|
||
} else {
|
||
cb = f(arg[2:])
|
||
}
|
||
execNow = needExec[k]
|
||
break
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func searchCalcFunction(arg string) (cb calc.CalcFunc, ok bool) {
|
||
if cb, ok = calcFunctions[arg]; !ok {
|
||
if cb, ok = searchWordCalcFunction(arg); !ok {
|
||
cb, ok = searchIntCalcFunction(arg)
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func searchCliFunction(arg string) (cb CliFunc, ok, execNow bool) {
|
||
if cb, ok = cliFunctions[arg]; !ok {
|
||
cb, ok, execNow = searchWordCliFunction(arg)
|
||
} else {
|
||
execNow = needExec[arg]
|
||
}
|
||
|
||
return
|
||
}
|