native class StringTokens
(str, separator, discardSeparators, groupSeparators, limit)
satisfies {String+} {
String str;
Boolean separator(Character ch);
Boolean discardSeparators;
Boolean groupSeparators;
Integer? limit;
shared actual native Iterator<String> iterator();
shared actual native Boolean empty;
}
native("js") class StringTokens
(str, separator, discardSeparators, groupSeparators, limit)
satisfies {String+} {
String str;
Boolean separator(Character ch);
Boolean discardSeparators;
Boolean groupSeparators;
Integer? limit;
shared actual native("js") Boolean empty => false;
shared actual native("js") Iterator<String> iterator() {
dynamic str = this.str;
return object satisfies Iterator<String> {
variable value first = true;
variable value lastTokenWasSeparator = false;
variable value count = 0;
variable value index = 0;
Integer currentCodePoint {
dynamic {
return str.codePointAt(index);
}
}
Integer currentCharCode {
dynamic {
return str.codePointAt(index);
}
}
void advanceToEnd() {
dynamic {
index = str.length;
}
}
void advance() {
index += #d800 <= currentCharCode <= #dbff
then 2 else 1;
}
value eof {
dynamic {
return index >= str.length;
}
}
value separator
=> !eof
&& outer.separator(currentCodePoint.character);
value regular
=> !eof
&& !outer.separator(currentCodePoint.character);
String token(Integer start, Boolean separator) {
if (!separator) {
count ++;
}
first = false;
lastTokenWasSeparator = separator;
dynamic {
return str.substring(start, index);
}
}
function emptyToken() {
count ++;
first = false;
lastTokenWasSeparator = false;
return "";
}
shared actual String|Finished next() {
if (!eof) {
if (first || lastTokenWasSeparator,
separator) {
return emptyToken();
}
if (separator) {
value start = index;
advance();
if (groupSeparators) {
while (separator) {
advance();
}
}
if (!discardSeparators) {
return token(start, true);
}
}
value start = index;
if (exists limit, count>=limit) {
advanceToEnd();
}
else {
while (regular) {
advance();
}
}
return token(start, true);
}
else if (lastTokenWasSeparator) {
return emptyToken();
}
else {
return finished;
}
}
};
}
}
native("jvm") class StringTokens
(str, separator, discardSeparators, groupSeparators, limit)
satisfies {String+} {
import java.lang {
JString=String,
JCharacter=Character
}
String str;
Boolean separator(Character ch);
Boolean discardSeparators;
Boolean groupSeparators;
Integer? limit;
shared actual native("jvm") Boolean empty => false;
shared actual native("jvm") Iterator<String> iterator()
=> object satisfies Iterator<String> {
value string = JString(str);
variable value first = true;
variable value lastTokenWasSeparator = false;
variable value count = 0;
variable value index = 0;
void advanceToEnd() {
index = string.length();
}
void advance() {
index += JCharacter.charCount(string.codePointAt(index));
}
value eof => index >= string.length();
value separator
=> !eof
&& outer.separator(string.codePointAt(index).character);
value regular
=> !eof
&& !outer.separator(string.codePointAt(index).character);
String token(Integer start, Boolean separator) {
if (!separator) {
count ++;
}
first = false;
lastTokenWasSeparator = separator;
return string.substring(start, index);
}
String emptyToken() {
count ++;
first = false;
lastTokenWasSeparator = false;
return "";
}
shared actual String|Finished next() {
if (!eof) {
if (first || lastTokenWasSeparator,
separator) {
return emptyToken();
}
if (separator) {
value start = index;
advance();
if (groupSeparators) {
while (separator) {
advance();
}
}
if (!discardSeparators) {
return token(start, true);
}
}
value start = index;
if (exists limit, count>=limit) {
advanceToEnd();
}
else {
while (regular) {
advance();
}
}
return token(start, true);
}
else if (lastTokenWasSeparator) {
return emptyToken();
}
else {
return finished;
}
}
};
}