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 }