@@ -5750,3 +5750,153 @@ temp _ int = track()
57505750 // but since we're returning an error, we can't check the count.
57515751 // This test verifies that ensure doesn't prevent error propagation.
57525752}
5753+
5754+ // ============================================================================
5755+ // Range with Negative Step Tests (#1095)
5756+ // ============================================================================
5757+
5758+ func TestRangeWithNegativeStep (t * testing.T ) {
5759+ input := `
5760+ temp sum int = 0
5761+ for i in range(10, 0, -1) {
5762+ sum = sum + i
5763+ }
5764+ sum
5765+ `
5766+ evaluated := testEval (input )
5767+ // 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 55
5768+ testIntegerObject (t , evaluated , 55 )
5769+ }
5770+
5771+ func TestRangeWithNegativeStepBy2 (t * testing.T ) {
5772+ input := `
5773+ temp sum int = 0
5774+ for i in range(10, 0, -2) {
5775+ sum = sum + i
5776+ }
5777+ sum
5778+ `
5779+ evaluated := testEval (input )
5780+ // 10 + 8 + 6 + 4 + 2 = 30
5781+ testIntegerObject (t , evaluated , 30 )
5782+ }
5783+
5784+ func TestRangeNegativeStepCollectsValues (t * testing.T ) {
5785+ input := `
5786+ temp first int = 0
5787+ temp second int = 0
5788+ temp third int = 0
5789+ temp idx int = 0
5790+ for i in range(5, 2, -1) {
5791+ if idx == 0 { first = i }
5792+ if idx == 1 { second = i }
5793+ if idx == 2 { third = i }
5794+ idx = idx + 1
5795+ }
5796+ first * 100 + second * 10 + third
5797+ `
5798+ evaluated := testEval (input )
5799+ // first=5, second=4, third=3 -> 543
5800+ testIntegerObject (t , evaluated , 543 )
5801+ }
5802+
5803+ func TestRangeNegativeStepMismatchError (t * testing.T ) {
5804+ // Negative step with ascending bounds should error
5805+ input := `
5806+ for i in range(0, 10, -1) {
5807+ temp _ int = i
5808+ }
5809+ `
5810+ evaluated := testEval (input )
5811+ if ! isError (evaluated ) {
5812+ t .Fatalf ("expected error for mismatched step direction, got %T" , evaluated )
5813+ }
5814+ errObj := evaluated .(* Error )
5815+ if errObj .Code != "E9005" {
5816+ t .Errorf ("expected error code E9005, got %s" , errObj .Code )
5817+ }
5818+ }
5819+
5820+ func TestRangePositiveStepMismatchError (t * testing.T ) {
5821+ // Positive step (default) with descending bounds should error
5822+ input := `
5823+ for i in range(10, 0) {
5824+ temp _ int = i
5825+ }
5826+ `
5827+ evaluated := testEval (input )
5828+ if ! isError (evaluated ) {
5829+ t .Fatalf ("expected error for mismatched step direction, got %T" , evaluated )
5830+ }
5831+ errObj := evaluated .(* Error )
5832+ if errObj .Code != "E9005" {
5833+ t .Errorf ("expected error code E9005, got %s" , errObj .Code )
5834+ }
5835+ }
5836+
5837+ func TestRangeZeroStepError (t * testing.T ) {
5838+ input := `
5839+ for i in range(0, 10, 0) {
5840+ temp _ int = i
5841+ }
5842+ `
5843+ evaluated := testEval (input )
5844+ if ! isError (evaluated ) {
5845+ t .Fatalf ("expected error for zero step, got %T" , evaluated )
5846+ }
5847+ errObj := evaluated .(* Error )
5848+ if errObj .Code != "E9003" {
5849+ t .Errorf ("expected error code E9003, got %s" , errObj .Code )
5850+ }
5851+ }
5852+
5853+ func TestRangeNegativeStepInOperator (t * testing.T ) {
5854+ tests := []struct {
5855+ name string
5856+ input string
5857+ expected bool
5858+ }{
5859+ {
5860+ name : "value in descending range - true" ,
5861+ input : `5 in range(10, 0, -1)` ,
5862+ expected : true ,
5863+ },
5864+ {
5865+ name : "value at start of descending range - true" ,
5866+ input : `10 in range(10, 0, -1)` ,
5867+ expected : true ,
5868+ },
5869+ {
5870+ name : "value at end of descending range - false (exclusive)" ,
5871+ input : `0 in range(10, 0, -1)` ,
5872+ expected : false ,
5873+ },
5874+ {
5875+ name : "value below descending range - false" ,
5876+ input : `-1 in range(10, 0, -1)` ,
5877+ expected : false ,
5878+ },
5879+ {
5880+ name : "value above descending range - false" ,
5881+ input : `15 in range(10, 0, -1)` ,
5882+ expected : false ,
5883+ },
5884+ {
5885+ name : "value in descending range with step -2 - on step" ,
5886+ input : `6 in range(10, 0, -2)` ,
5887+ expected : true ,
5888+ },
5889+ {
5890+ name : "value in descending range with step -2 - off step" ,
5891+ input : `5 in range(10, 0, -2)` ,
5892+ expected : false ,
5893+ },
5894+ }
5895+
5896+ for _ , tt := range tests {
5897+ t .Run (tt .name , func (t * testing.T ) {
5898+ evaluated := testEval (tt .input )
5899+ testBooleanObject (t , evaluated , tt .expected )
5900+ })
5901+ }
5902+ }
0 commit comments