[WIP] Disallow floating point indexing (waiting for #116)

This commit is contained in:
Stanisław Barzowski 2017-10-09 16:11:39 -04:00 committed by Dave Cunningham
parent bb8d424f73
commit 10d377f068
7 changed files with 79 additions and 11 deletions

View File

@ -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)))
}
}

View File

@ -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:

View File

@ -1 +1,10 @@
0
RUNTIME ERROR: Expected an integer, but got 1e+30
-------------------------------------------------
testdata/bitwise_and3:1:1-10 $
1e30 & 42
-------------------------------------------------
During evaluation

View File

@ -0,0 +1,8 @@
RUNTIME ERROR: Expected an integer, but got 2.5
-------------------------------------------------
<builtin> builtin function <makeArray>
-------------------------------------------------
During evaluation

View File

@ -0,0 +1 @@
std.makeArray(2.5, function(i) i)

View File

@ -0,0 +1,8 @@
RUNTIME ERROR: Expected an integer, but got 1e+100
-------------------------------------------------
<builtin> builtin function <makeArray>
-------------------------------------------------
During evaluation

View File

@ -0,0 +1 @@
std.makeArray(1e100, error "shouldn't happen")