Exemple #1
0
// EvalUnary evaluates a unary operator.
func (c *Context) EvalUnary(op string, right value.Value) value.Value {
	right = right.Eval(c)
	fn := c.UnaryFn[op]
	if fn == nil {
		return value.Unary(c, op, right)
	}
	if fn.Body == nil {
		value.Errorf("unary %q undefined", op)
	}
	c.push()
	defer c.pop()
	c.assignLocal(fn.Right, right)
	var v value.Value
	for _, e := range fn.Body {
		v = e.Eval(c)
	}
	if v == nil {
		value.Errorf("no value returned by %q", op)
	}
	return v
}
Exemple #2
0
// put writes to out a version of the value that will recreate it when parsed.
func put(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:
		// 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.
		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
		}
		digits := int(float64(val.Prec()) * 0.301029995664) // 10 log 2.
		fmt.Fprintf(out, "%.*g", digits, val.Float)
	case value.Vector:
		if val.AllChars() {
			fmt.Fprintf(out, "%q", val)
			return
		}
		for i, v := range val {
			if i > 0 {
				fmt.Fprint(out, " ")
			}
			put(out, v)
		}
	case value.Matrix:
		put(out, val.Shape())
		fmt.Fprint(out, " rho ")
		put(out, val.Data())
	default:
		value.Errorf("internal error: can't save type %T", val)
	}
}