@@ -239,6 +239,7 @@ static REBCNT EncodedU32_Size(u32 value) {
239
239
REBCNT n , count , index , tail , tail_new ;
240
240
REBDEC dbl ;
241
241
REBD32 d32 ;
242
+ REBCNT cmd ;
242
243
i32 i , len ;
243
244
u64 u ;
244
245
i64 si ;
@@ -425,8 +426,8 @@ static REBCNT EncodedU32_Size(u32 value) {
425
426
Set_Binary (DS_TOP , Encode_UTF8_Value (next , VAL_LEN (next ), 0 ));
426
427
next = DS_POP ;
427
428
}
428
-
429
- switch (VAL_WORD_CANON ( data ) ) {
429
+ cmd = VAL_WORD_CANON ( data );
430
+ switch (cmd ) {
430
431
case SYM_SI8 :
431
432
case SYM_UI8 :
432
433
if (IS_INTEGER (next ) || IS_CHAR (next )) {
@@ -471,11 +472,13 @@ static REBCNT EncodedU32_Size(u32 value) {
471
472
}
472
473
goto error ;
473
474
case SYM_AT :
475
+ case SYM_ATZ :
474
476
if (IS_INTEGER (next )) {
475
477
if (count > tail ) tail = count ;
476
- // AT is using ABSOLUTE positioning, so it cannot be < 1 (one-indexed)
477
- if (VAL_INT32 (next ) < 1 ) Trap1 (RE_OUT_OF_RANGE , next );
478
- count = VAL_INT32 (next ) - 1 ;
478
+ i = (cmd == SYM_AT ? 1 : 0 );
479
+ // AT is using ABSOLUTE positioning, so it cannot be < 1 (one-indexed) or < 0 (zero-based)
480
+ if (VAL_INT32 (next ) < i ) Trap1 (RE_OUT_OF_RANGE , next );
481
+ count = VAL_INT32 (next ) - i ;
479
482
continue ;
480
483
}
481
484
goto error ;
@@ -584,7 +587,7 @@ static REBCNT EncodedU32_Size(u32 value) {
584
587
value ++ ; //skip optional INDEX word...
585
588
if (
586
589
(VAL_TYPE (value ) != REB_WORD ) ||
587
- (VAL_WORD_CANON (value ) != SYM_INDEX )
590
+ (VAL_WORD_CANON (value ) != SYM_INDEX && VAL_WORD_CANON ( value ) != SYM_INDEXZ )
588
591
) {
589
592
value -- ; //... or revert it
590
593
}
@@ -655,8 +658,8 @@ static REBCNT EncodedU32_Size(u32 value) {
655
658
Set_Binary (DS_TOP , Encode_UTF8_Value (next , VAL_LEN (next ), 0 ));
656
659
next = DS_POP ;
657
660
}
658
-
659
- switch (VAL_WORD_CANON ( data ) ) {
661
+ cmd = VAL_WORD_CANON ( data );
662
+ switch (cmd ) {
660
663
case SYM_UI8 :
661
664
ASSERT_UI_RANGE (next , 0xFF );
662
665
write_ui8 :
@@ -891,7 +894,8 @@ static REBCNT EncodedU32_Size(u32 value) {
891
894
break ;
892
895
893
896
case SYM_AT :
894
- VAL_INDEX (buffer_write ) = VAL_INT32 (next ) - 1 ;
897
+ case SYM_ATZ :
898
+ VAL_INDEX (buffer_write ) = VAL_INT32 (next ) - (cmd == SYM_AT ? 1 : 0 );
895
899
cp = BIN_DATA (bin ) + VAL_INDEX (buffer_write );
896
900
n = 0 ;
897
901
break ;
@@ -1057,7 +1061,6 @@ static REBCNT EncodedU32_Size(u32 value) {
1057
1061
DS_PUSH_NONE ;
1058
1062
temp = DS_TOP ;
1059
1063
REBINT ssp = DSP ; // starting stack pointer
1060
- REBINT cmd ;
1061
1064
1062
1065
for (; NOT_END (value ); value ++ ) {
1063
1066
n = 0 ;
@@ -1452,18 +1455,20 @@ static REBCNT EncodedU32_Size(u32 value) {
1452
1455
VAL_INDEX (buffer_read ) += 4 ;
1453
1456
goto readNBytes ;
1454
1457
case SYM_AT :
1458
+ case SYM_ATZ :
1455
1459
// uses absolute positioning from series HEAD!
1456
1460
next = ++ value ;
1457
1461
if (IS_GET_WORD (next )) next = Get_Var (next );
1458
1462
if (!IS_INTEGER (next )) Trap1 (RE_INVALID_SPEC , value );
1459
- i = VAL_INT32 (next ) - 1 ;
1463
+ i = VAL_INT32 (next ) - ( cmd == SYM_AT ? 1 : 0 ) ;
1460
1464
ASSERT_INDEX_RANGE (buffer_read , i , value );
1461
1465
VAL_INDEX (buffer_read ) = i ;
1462
1466
cp = BIN_DATA (bin ) + VAL_INDEX (buffer_read );
1463
1467
continue ;
1464
1468
case SYM_INDEX :
1469
+ case SYM_INDEXZ :
1465
1470
VAL_SET (temp , REB_INTEGER );
1466
- SET_INT32 (temp , VAL_INDEX (buffer_read ) + 1 );
1471
+ SET_INT32 (temp , VAL_INDEX (buffer_read )) + ( cmd == SYM_INDEX ? 1 : 0 );
1467
1472
n = 0 ;
1468
1473
break ;
1469
1474
case SYM_SKIP :
0 commit comments