Esempio n. 1
0
File: calc.go Progetto: voxadam/bort
// 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
}