Skip to content

Commit 6c0ad0b

Browse files
committed
feat: add string.split
1 parent 1d16529 commit 6c0ad0b

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

src/langlib/string/kllib_string.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99

1010

1111
static KlException kllib_string_join_raw(KlState* state, size_t nval, KlValue* vals, KlValue* result);
12-
static KlException kllib_string_sub(KlState* state);
12+
static KlException kllib_string_slice(KlState* state);
1313
static KlException kllib_string_find(KlState* state);
1414
static KlException kllib_string_join(KlState* state);
15+
static KlException kllib_string_split(KlState* state);
1516

1617
static KlException kllib_string_utf8idx(KlState* state);
1718
static KlException kllib_string_utf8len(KlState* state);
1819

1920
static inline size_t kllib_string_utf8charlen(const unsigned char* str) {
20-
unsigned ch = *str;
21+
unsigned char ch = *str;
2122
if (ch < 0xC0) return 1;
2223
if (ch < 0xE0) return 2;
2324
if (ch < 0xF0) return 3;
@@ -45,8 +46,12 @@ KlException KLCONFIG_LIBRARY_STRING_ENTRYFUNCNAME(KlState* state) {
4546
klapi_setcfunc(state, -1, kllib_string_join);
4647
KLAPI_PROTECT(klapi_class_newshared_method(state, strclass, klapi_getstring(state, -2)));
4748

48-
KLAPI_PROTECT(klapi_setstring(state, -2, "sub"));
49-
klapi_setcfunc(state, -1, kllib_string_sub);
49+
KLAPI_PROTECT(klapi_setstring(state, -2, "slice"));
50+
klapi_setcfunc(state, -1, kllib_string_slice);
51+
KLAPI_PROTECT(klapi_class_newshared_method(state, strclass, klapi_getstring(state, -2)));
52+
53+
KLAPI_PROTECT(klapi_setstring(state, -2, "split"));
54+
klapi_setcfunc(state, -1, kllib_string_split);
5055
KLAPI_PROTECT(klapi_class_newshared_method(state, strclass, klapi_getstring(state, -2)));
5156

5257
KLAPI_PROTECT(klapi_setstring(state, -2, "utf8len"));
@@ -60,7 +65,7 @@ KlException KLCONFIG_LIBRARY_STRING_ENTRYFUNCNAME(KlState* state) {
6065
return klapi_return(state, 0);
6166
}
6267

63-
static KlException kllib_string_sub(KlState* state) {
68+
static KlException kllib_string_slice(KlState* state) {
6469
if (kl_unlikely(klapi_narg(state) != 2 && klapi_narg(state) != 3))
6570
return klapi_throw_internal(state, KL_E_ARGNO, "expected two or three arguments");
6671
if (kl_unlikely(!klapi_checktypeb(state, 0, KL_STRING)))
@@ -124,6 +129,34 @@ static KlException kllib_string_join(KlState* state) {
124129
return klapi_return(state, 1);
125130
}
126131

132+
static KlException kllib_string_split(KlState* state) {
133+
if (klapi_narg(state) != 2)
134+
return klapi_throw_internal(state, KL_E_ARGNO, "expected two arguments");
135+
if (!klapi_checktype(state, -2, KL_STRING) || !klapi_checktype(state, -2, KL_STRING))
136+
return klapi_throw_internal(state, KL_E_ARGNO, "expected two strings, got %s, %s",
137+
klstring_content(klapi_typename(state, klapi_access(state, -2))),
138+
klstring_content(klapi_typename(state, klapi_access(state, -1))));
139+
KlString* self = klapi_getstring(state, -2);
140+
KlString* delim = klapi_getstring(state, -1);
141+
const char* self_raw = klstring_content(self);
142+
const char* delim_raw = klstring_content(delim);
143+
size_t selflen = klstring_length(self);
144+
size_t delimlen = klstring_length(delim);
145+
const char* begin = self_raw;
146+
const char* end;
147+
size_t nret = 0;
148+
while ((end = strstr(begin, delim_raw))) {
149+
++nret;
150+
KLAPI_PROTECT(klapi_checkstack(state, 1));
151+
KLAPI_PROTECT(klapi_pushstring_buf(state, begin, end - begin));
152+
begin = end + delimlen;
153+
}
154+
++nret;
155+
KLAPI_PROTECT(klapi_checkstack(state, 1));
156+
KLAPI_PROTECT(klapi_pushstring_buf(state, begin, self_raw + selflen - begin));
157+
return klapi_return(state, nret);
158+
}
159+
127160
static KlException kllib_string_join_raw(KlState* state, size_t nval, KlValue* vals, KlValue* result) {
128161
size_t totallen = 0;
129162
for (KlValue* val = vals; val != vals + nval; ++val) {

0 commit comments

Comments
 (0)