mirror of
https://github.com/google/go-jsonnet.git
synced 2026-05-05 03:56:11 +02:00
[WIP] Disallow floating point indexing (waiting for #116)
This commit is contained in:
parent
bb8d424f73
commit
10d377f068
17
builtins.go
17
builtins.go
@ -248,7 +248,7 @@ func builtinToString(e *evaluator, xp potentialValue) (value, error) {
|
||||
}
|
||||
|
||||
func builtinMakeArray(e *evaluator, szp potentialValue, funcp potentialValue) (value, error) {
|
||||
sz, err := e.evaluateNumber(szp)
|
||||
sz, err := e.evaluateInt(szp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -256,9 +256,8 @@ func builtinMakeArray(e *evaluator, szp potentialValue, funcp potentialValue) (v
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
num := int(sz.value)
|
||||
var elems []potentialValue
|
||||
for i := 0; i < num; i++ {
|
||||
for i := 0; i < sz; i++ {
|
||||
elem := fun.call(args(&readyValue{intToValue(i)}))
|
||||
elems = append(elems, elem)
|
||||
}
|
||||
@ -274,7 +273,7 @@ func builtinFlatMap(e *evaluator, funcp potentialValue, arrp potentialValue) (va
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
num := int(arr.length())
|
||||
num := arr.length()
|
||||
// Start with capacity of the original array.
|
||||
// This may spare us a few reallocations.
|
||||
// TODO(sbarzowski) verify that it actually helps
|
||||
@ -300,7 +299,7 @@ func builtinFilter(e *evaluator, funcp potentialValue, arrp potentialValue) (val
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
num := int(arr.length())
|
||||
num := arr.length()
|
||||
// Start with capacity of the original array.
|
||||
// This may spare us a few reallocations.
|
||||
// TODO(sbarzowski) verify that it actually helps
|
||||
@ -479,17 +478,15 @@ var builtinExponent = liftNumeric(func(f float64) float64 {
|
||||
|
||||
func liftBitwise(f func(int64, int64) int64) func(*evaluator, potentialValue, potentialValue) (value, error) {
|
||||
return func(e *evaluator, xp, yp potentialValue) (value, error) {
|
||||
x, err := e.evaluateNumber(xp)
|
||||
x, err := e.evaluateInt64(xp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
y, err := e.evaluateNumber(yp)
|
||||
y, err := e.evaluateInt64(yp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
xInt := int64(x.value)
|
||||
yInt := int64(y.value)
|
||||
return makeDoubleCheck(e, float64(f(xInt, yInt)))
|
||||
return makeDoubleCheck(e, float64(f(x, y)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
44
evaluator.go
44
evaluator.go
@ -83,6 +83,50 @@ func (e *evaluator) evaluateNumber(pv potentialValue) (*valueNumber, error) {
|
||||
return e.getNumber(v)
|
||||
}
|
||||
|
||||
func (e *evaluator) getInt(val value) (int, error) {
|
||||
num, err := e.getNumber(val)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// We conservatively convert ot int32, so that it can be machine-sized int
|
||||
// on any machine. And it's used only for indexing anyway.
|
||||
intNum := int(int32(num.value))
|
||||
if float64(intNum) != num.value {
|
||||
return 0, e.Error(fmt.Sprintf("Expected an integer, but got %v", num.value))
|
||||
}
|
||||
return intNum, nil
|
||||
}
|
||||
|
||||
func (e *evaluator) evaluateInt(pv potentialValue) (int, error) {
|
||||
v, err := e.evaluate(pv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return e.getInt(v)
|
||||
}
|
||||
|
||||
func (e *evaluator) getInt64(val value) (int64, error) {
|
||||
num, err := e.getNumber(val)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// We conservatively convert ot int32, so that it can be machine-sized int
|
||||
// on any machine. And it's used only for indexing anyway.
|
||||
intNum := int64(num.value)
|
||||
if float64(intNum) != num.value {
|
||||
return 0, e.Error(fmt.Sprintf("Expected an integer, but got %v", num.value))
|
||||
}
|
||||
return intNum, nil
|
||||
}
|
||||
|
||||
func (e *evaluator) evaluateInt64(pv potentialValue) (int64, error) {
|
||||
v, err := e.evaluate(pv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return e.getInt64(v)
|
||||
}
|
||||
|
||||
func (e *evaluator) getString(val value) (*valueString, error) {
|
||||
switch v := val.(type) {
|
||||
case *valueString:
|
||||
|
||||
11
testdata/bitwise_and3.golden
vendored
11
testdata/bitwise_and3.golden
vendored
@ -1 +1,10 @@
|
||||
0
|
||||
RUNTIME ERROR: Expected an integer, but got 1e+30
|
||||
-------------------------------------------------
|
||||
testdata/bitwise_and3:1:1-10 $
|
||||
|
||||
1e30 & 42
|
||||
|
||||
-------------------------------------------------
|
||||
During evaluation
|
||||
|
||||
|
||||
|
||||
8
testdata/std.makeArray_noninteger.golden
vendored
Normal file
8
testdata/std.makeArray_noninteger.golden
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
RUNTIME ERROR: Expected an integer, but got 2.5
|
||||
-------------------------------------------------
|
||||
<builtin> builtin function <makeArray>
|
||||
|
||||
-------------------------------------------------
|
||||
During evaluation
|
||||
|
||||
|
||||
1
testdata/std.makeArray_noninteger.jsonnet
vendored
Normal file
1
testdata/std.makeArray_noninteger.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.makeArray(2.5, function(i) i)
|
||||
8
testdata/std.makeArray_noninteger_big.golden
vendored
Normal file
8
testdata/std.makeArray_noninteger_big.golden
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
RUNTIME ERROR: Expected an integer, but got 1e+100
|
||||
-------------------------------------------------
|
||||
<builtin> builtin function <makeArray>
|
||||
|
||||
-------------------------------------------------
|
||||
During evaluation
|
||||
|
||||
|
||||
1
testdata/std.makeArray_noninteger_big.jsonnet
vendored
Normal file
1
testdata/std.makeArray_noninteger_big.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.makeArray(1e100, error "shouldn't happen")
|
||||
Loading…
x
Reference in New Issue
Block a user