// 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 }