Ejemplo n.º 1
0
// put writes to out a version of the value that will recreate it when parsed.
func put(conf *config.Config, out io.Writer, val value.Value) {
	switch val := val.(type) {
	case value.Char:
		fmt.Fprintf(out, "%q", rune(val))
	case value.Int:
		fmt.Fprintf(out, "%d", int(val))
	case value.BigInt:
		fmt.Fprintf(out, "%d", val.Int)
	case value.BigRat:
		fmt.Fprintf(out, "%d/%d", val.Num(), val.Denom())
	case value.BigFloat:
		if val.Sign() == 0 || val.IsInf() {
			// These have prec 0 and are easy.
			// They shouldn't appear anyway, but be safe.
			fmt.Fprintf(out, "%g", val)
			return
		}
		// TODO The actual value might not have the same prec as
		// the configuration, so we might not get this right
		// Probably not important but it would be nice to fix it.
		digits := int(float64(val.Prec()) * 0.301029995664) // 10 log 2.
		fmt.Fprintf(out, "%.*g", digits+1, val.Float)       // Add another digit to be sure.
	case value.Vector:
		if val.AllChars() {
			fmt.Fprintf(out, "%q", val.Sprint(conf))
			return
		}
		for i, v := range val {
			if i > 0 {
				fmt.Fprint(out, " ")
			}
			put(conf, out, v)
		}
	case value.Matrix:
		put(conf, out, val.Shape())
		fmt.Fprint(out, " rho ")
		put(conf, out, val.Data())
	default:
		value.Errorf("internal error: can't save type %T", val)
	}
}