Beispiel #1
0
// Sum
func SumFunc(ctx expr.EvalContext, vals ...value.Value) (value.NumberValue, bool) {

	//u.Debugf("Sum: %v", vals)
	sumval := float64(0)
	for _, val := range vals {
		if val == nil || val.Nil() || val.Err() {
			// we don't need to evaluate if nil or error
		} else {
			switch valValue := val.(type) {
			case value.StringsValue:
				//u.Debugf("Nice, we have strings: %v", valValue)
				for _, sv := range valValue.Value().([]string) {
					if fv, ok := value.ToFloat64(reflect.ValueOf(sv)); ok && !math.IsNaN(fv) {
						sumval += fv
					}
				}
			default:
				//u.Debugf("Sum:  %T tofloat=%v  %v", value.ToFloat64(val.Rv()), value.ToFloat64(val.Rv()), val.Rv())
				if fv, ok := value.ToFloat64(val.Rv()); ok && !math.IsNaN(fv) {
					sumval += fv
				}
			}
		}
	}
	if sumval == float64(0) {
		return value.NumberNaNValue, false
	}
	//u.Debugf("Sum() about to return?  %v  Nan?%v", sumval, sumval == math.NaN())
	return value.NewNumberValue(sumval), true
}
Beispiel #2
0
// <= Less Than or Equal
//  Must be able to convert items to Floats or else not ok
//
func LeFunc(ctx expr.EvalContext, lv, rv value.Value) (value.BoolValue, bool) {
	left, _ := value.ToFloat64(lv.Rv())
	right, _ := value.ToFloat64(rv.Rv())
	if math.IsNaN(left) || math.IsNaN(right) {
		return value.BoolValueFalse, false
	}
	return value.NewBoolValue(left <= right), true
}
Beispiel #3
0
// < Less Than
//  Must be able to convert items to Floats or else not ok
//
func LtFunc(ctx expr.EvalContext, lv, rv value.Value) (value.BoolValue, bool) {
	left := value.ToFloat64(lv.Rv())
	right := value.ToFloat64(rv.Rv())
	if left == math.NaN() || right == math.NaN() {
		return value.BoolValueFalse, false
	}

	return value.NewBoolValue(left < right), true
}
Beispiel #4
0
// Convert to Number:   Best attempt at converting to integer
//
//   tonumber("5") => 5.0
//   tonumber("5.75") => 5.75
//   tonumber("5,555") => 5555
//   tonumber("$5") => 5.00
//   tonumber("5,555.00") => 5555
//
func ToNumber(ctx expr.EvalContext, item value.Value) (value.NumberValue, bool) {
	fv, ok := value.ToFloat64(reflect.ValueOf(item.Value()))
	if !ok {
		return value.NewNumberValue(0), false
	}
	return value.NewNumberValue(fv), true
}
Beispiel #5
0
// Pow
func PowFunc(ctx EvalContext, val, toPower value.Value) (value.NumberValue, bool) {
	//Pow(x, y float64) float64
	//u.Infof("powFunc:  %T:%v %T:%v ", val, val.Value(), toPower, toPower.Value())
	if val.Err() || val.Nil() {
		return value.NewNumberValue(0), false
	}
	if toPower.Err() || toPower.Nil() {
		return value.NewNumberValue(0), false
	}
	fv, pow := value.ToFloat64(val.Rv()), value.ToFloat64(toPower.Rv())
	if fv == math.NaN() || pow == math.NaN() {
		return value.NewNumberValue(0), false
	}
	fv = math.Pow(fv, pow)
	//u.Infof("pow ???   vals=[%v]", fv, pow)
	return value.NewNumberValue(fv), true
}
Beispiel #6
0
// creates a new Value with a nil group and given value.
// TODO:  convert this to an interface method on nodes called Value()
func numberNodeToValue(t *expr.NumberNode) (v value.Value) {
	//u.Debugf("nodeToValue()  isFloat?%v", t.IsFloat)
	if t.IsInt {
		v = value.NewIntValue(t.Int64)
	} else if t.IsFloat {
		v = value.NewNumberValue(value.ToFloat64(reflect.ValueOf(t.Text)))
	} else {
		u.Errorf("Could not find type? %v", t.Type())
	}
	//u.Debugf("return nodeToValue()	%v  %T  arg:%T", v, v, t)
	return v
}
Beispiel #7
0
// creates a new Value with a nil group and given value.
// TODO:  convert this to an interface method on nodes called Value()
func numberNodeToValue(t *expr.NumberNode) (value.Value, bool) {
	//u.Debugf("nodeToValue()  isFloat?%v", t.IsFloat)
	var v value.Value
	if t.IsInt {
		v = value.NewIntValue(t.Int64)
	} else if t.IsFloat {
		fv, ok := value.ToFloat64(reflect.ValueOf(t.Text))
		if !ok {
			u.Warnf("Could not perform numeric conversion for %q", t.Text)
			return value.NilValueVal, false
		}
		v = value.NewNumberValue(fv)
	} else {
		u.Warnf("Could not find numeric conversion for %v", t.Type())
		return value.NilValueVal, false
	}
	//u.Debugf("return nodeToValue()	%v  %T  arg:%T", v, v, t)
	return v, true
}