@@ -1001,12 +1001,12 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
1001
1001
p .push (num (float64 (length )))
1002
1002
1003
1003
case compiler .BuiltinLengthArg :
1004
- s := p .toString ( p . peekTop () )
1004
+ s := p .peekTop ()
1005
1005
var length int
1006
1006
if p .chars {
1007
- length = utf8 . RuneCountInString ( s )
1007
+ length = len ( s . runes ( p . convertFormat ) )
1008
1008
} else {
1009
- length = len (s )
1009
+ length = len (p . toString ( s ) )
1010
1010
}
1011
1011
p .replaceTop (num (float64 (length )))
1012
1012
@@ -1066,9 +1066,18 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
1066
1066
sValue , posValue := p .peekPop ()
1067
1067
pos := int (posValue .num ())
1068
1068
s := p .toString (sValue )
1069
- var substr string
1069
+ var substr value
1070
1070
if p .chars {
1071
- substr = substrChars (s , pos )
1071
+ runes := sValue .runes (p .convertFormat )
1072
+ if pos > len (runes ) {
1073
+ pos = len (runes ) + 1
1074
+ }
1075
+ if pos < 1 {
1076
+ pos = 1
1077
+ }
1078
+ length := len (runes ) - pos + 1
1079
+ runes = runes [pos - 1 : pos - 1 + length ]
1080
+ substr = strFromRunes (runes )
1072
1081
} else {
1073
1082
if pos > len (s ) {
1074
1083
pos = len (s ) + 1
@@ -1077,19 +1086,34 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
1077
1086
pos = 1
1078
1087
}
1079
1088
length := len (s ) - pos + 1
1080
- substr = s [pos - 1 : pos - 1 + length ]
1089
+ substr = str ( s [pos - 1 : pos - 1 + length ])
1081
1090
}
1082
- p .replaceTop (str ( substr ) )
1091
+ p .replaceTop (substr )
1083
1092
1084
1093
case compiler .BuiltinSubstrLength :
1085
1094
posValue , lengthValue := p .popTwo ()
1086
1095
length := int (lengthValue .num ())
1087
1096
pos := int (posValue .num ())
1088
- s := p .toString ( p . peekTop () )
1089
- var substr string
1097
+ sValue := p .peekTop ()
1098
+ var substr value
1090
1099
if p .chars {
1091
- substr = substrLengthChars (s , pos , length )
1100
+ runes := sValue .runes (p .convertFormat )
1101
+ if pos > len (runes ) {
1102
+ pos = len (runes ) + 1
1103
+ }
1104
+ if pos < 1 {
1105
+ pos = 1
1106
+ }
1107
+ maxLength := len (runes ) - pos + 1
1108
+ if length < 0 {
1109
+ length = 0
1110
+ }
1111
+ if length > maxLength {
1112
+ length = maxLength
1113
+ }
1114
+ substr = strFromRunes (runes [pos - 1 : pos - 1 + length ])
1092
1115
} else {
1116
+ s := p .toString (sValue )
1093
1117
if pos > len (s ) {
1094
1118
pos = len (s ) + 1
1095
1119
}
@@ -1103,9 +1127,9 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
1103
1127
if length > maxLength {
1104
1128
length = maxLength
1105
1129
}
1106
- substr = s [pos - 1 : pos - 1 + length ]
1130
+ substr = str ( s [pos - 1 : pos - 1 + length ])
1107
1131
}
1108
- p .replaceTop (str ( substr ) )
1132
+ p .replaceTop (substr )
1109
1133
1110
1134
case compiler .BuiltinSystem :
1111
1135
if p .noExec {
0 commit comments