Skip to content

Commit

Permalink
Merge pull request #100 from skx/98-range
Browse files Browse the repository at this point in the history
Fix the range-operator for "backwards" ranges.
  • Loading branch information
skx authored Nov 22, 2023
2 parents 2aa97a9 + 6bb0866 commit 6c4e83f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
21 changes: 19 additions & 2 deletions evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,29 @@ func evalIntegerInfixExpression(operator string, left, right object.Object) obje
case "!=":
return nativeBoolToBooleanObject(leftVal != rightVal)
case "..":
len := int(rightVal-leftVal) + 1
// The start and end might not be ascending, so the size
// will be the span
diff := float64(rightVal - leftVal)
len := int(math.Abs(diff)) + 1

// Step is generally +1, but if we're going to
// express the range "10..0" it will be -1 to allow
// us to count down via subtraction
var step int64
step = 1.0

if rightVal < leftVal {
step = -1.0
}

// Make an array to hold the return value
array := make([]object.Object, len)

// Now make the range of integers, counting via the step.
i := 0
for i < len {
array[i] = &object.Integer{Value: leftVal}
leftVal++
leftVal += step
i++
}
return &object.Array{Elements: array}
Expand Down
24 changes: 24 additions & 0 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,3 +721,27 @@ if (match( "+", name) ) { puts( "Hello\n" ); }
}

}

func TestRangeOperator(t *testing.T) {
tests := []struct {
input string
expected string
}{
// normal
{"return 0..3;", "[0, 1, 2, 3]"},
{"return 0..1;", "[0, 1]"},
{"return 0..0;", "[0]"},
{"a = -3; b = 3; return a..b;", "[-3, -2, -1, 0, 1, 2, 3]"},
// reversed
{"return 3..0;", "[3, 2, 1, 0]"},
{"return 1..0;", "[1, 0]"},
{"return 0..0;", "[0]"},
{"return 3..-5;", "[3, 2, 1, 0, -1, -2, -3, -4, -5]"},
}
for _, tt := range tests {
evaluated := testEval(tt.input)
if tt.expected != evaluated.Inspect() {
t.Fatalf("unexpected output for range operator, got %s for input %s", evaluated.Inspect(), tt.input)
}
}
}

0 comments on commit 6c4e83f

Please sign in to comment.