// Calc passes input to clac and returns the calculated result. func Calc(in, out *bort.Message) error { out.Type = bort.PrivMsg cl.Reset() cmdReader := strings.NewReader(in.Args) isHex := false for { tok := "" if _, err := fmt.Fscan(cmdReader, &tok); err != nil { if err != io.EOF { return err } break } switch tok { // special cases case "help": out.Target = in.Nick out.Text = helpStr return nil case "hex": isHex = true continue } num, err := clac.ParseNum(tok) if err == nil { if err = cl.Exec(func() error { return cl.Push(num) }); err != nil { return fmt.Errorf("push: %s", err) } continue } if cmd, ok := cmdMap[tok]; ok { if err = cl.Exec(cmd); err != nil { return fmt.Errorf("calc: %s: invalid input", tok) } continue } return fmt.Errorf("calc: %s: invalid input", tok) } stack := cl.Stack() if len(stack) == 0 { return errors.New("empty stack") } ans := "" for i := range stack { val := stack[len(stack)-i-1] if isHex { if math.Abs(val) >= 1<<53 { ans += "overflow" } else { ans += fmt.Sprintf("%#x", int64(val)) } } else { ans += fmt.Sprintf("%g", val) } if i < len(stack)-1 { ans += " " } } out.Text = ans return nil }
// Flip draws the "emoji table flip guy" flipping the given text, or a table if // no text is provided. func Flip(in, out *bort.Message) error { flipped := "" if len(in.Args) > 0 { flipped = flip(in.Args) } else { flipped = table } out.Type = bort.PrivMsg out.Text = cfg.Flipper + flipped return nil }
// Forecast returns a pretty-printed forecast for the given location. The // location may be anything understood by OpenStreetMap's Nominatim service. func Forecast(in, out *bort.Message) error { loc := regexp.MustCompile("\\s+").ReplaceAllLiteralString(in.Args, "+") outp, err := http.Get(fmt.Sprintf(locURLFmt, loc)) if err != nil { return errLoc } defer outp.Body.Close() if outp.StatusCode != 200 { return errLoc } dec := json.NewDecoder(outp.Body) locs := []location{} dec.Decode(&locs) if len(locs) == 0 { return errLoc } fc, err := forecast(locs[0]) if err != nil { return errFc } out.Type = bort.PrivMsg out.Text = fc return nil }