Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] Add List.join(sep="") method. #260

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 46 additions & 18 deletions src/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,26 @@ static void _collectMethods(PKVM* vm, List* list, Class* cls) {
_collectMethods(vm, list, cls->super_class);
}

static void _listJoinImpl(PKVM* vm, List* list, String* sep) {
pkByteBuffer buff;
pkByteBufferInit(&buff);

for (uint32_t i = 0; i < list->elements.count; i++) {
String* str = varToString(vm, list->elements.data[i], false);
if (str == NULL) RET(VAR_NULL);
vmPushTempRef(vm, &str->_super); // elem
if (sep != NULL && i != 0) {
pkByteBufferAddString(&buff, vm, sep->data, sep->length);
}
pkByteBufferAddString(&buff, vm, str->data, str->length);
vmPopTempRef(vm); // elem
}

String* str = newStringLength(vm, (const char*)buff.data, buff.count);
pkByteBufferClear(&buff, vm);
RET(VAR_OBJ(str));
}

/*****************************************************************************/
/* CORE BUILTIN FUNCTIONS */
/*****************************************************************************/
Expand Down Expand Up @@ -654,29 +674,22 @@ DEF(coreListAppend,
RET(VAR_OBJ(list));
}

// TODO: currently it takes one argument (to test string interpolation).
// Add join delimeter as an optional argument.
DEF(coreListJoin,
"list_join(self:List) -> String",
"list_join(self:List [, sep:String=""]) -> String",
"Concatinate the elements of the list and return as a string.") {

List* list;
if (!validateArgList(vm, 1, &list)) return;
int argc = ARGC;
if (argc != 1 && argc != 2) {
RET_ERR(newString(vm, "Invalid argument count."));
}

pkByteBuffer buff;
pkByteBufferInit(&buff);
List* list;
String* sep = NULL;

for (uint32_t i = 0; i < list->elements.count; i++) {
String* str = varToString(vm, list->elements.data[i], false);
if (str == NULL) RET(VAR_NULL);
vmPushTempRef(vm, &str->_super); // elem
pkByteBufferAddString(&buff, vm, str->data, str->length);
vmPopTempRef(vm); // elem
}
if (!validateArgList(vm, 1, &list)) return;
if (argc == 2) sep = varToString(vm, ARG(2), false);

String* str = newStringLength(vm, (const char*)buff.data, buff.count);
pkByteBufferClear(&buff, vm);
RET(VAR_OBJ(str));
_listJoinImpl(vm, list, sep);
}

static void initializeBuiltinFN(PKVM* vm, Closure** bfn, const char* name,
Expand Down Expand Up @@ -712,7 +725,7 @@ static void initializeBuiltinFunctions(PKVM* vm) {

// List functions.
INITIALIZE_BUILTIN_FN("list_append", coreListAppend, 2);
INITIALIZE_BUILTIN_FN("list_join", coreListJoin, 1);
INITIALIZE_BUILTIN_FN("list_join", coreListJoin, -1);

#undef INITIALIZE_BUILTIN_FN
}
Expand Down Expand Up @@ -1240,6 +1253,20 @@ DEF(_listFind,
RET(VAR_NUM(-1));
}

DEF(_listJoin,
"List.join([sep:String=""]) -> String",
"Concatinate the elements of the list and return as a string.") {

ASSERT(IS_OBJ_TYPE(SELF, OBJ_LIST), OOPS);
List* list = (List*)AS_OBJ(SELF);
String* sep = NULL;

if (!pkCheckArgcRange(vm, ARGC, 0, 1)) return;
if (ARGC == 1) sep = varToString(vm, ARG(1), false);

_listJoinImpl(vm, list, sep);
}

DEF(_listClear,
"List.clear() -> Null",
"Removes all the entries in the list.") {
Expand Down Expand Up @@ -1471,6 +1498,7 @@ static void initializePrimitiveClasses(PKVM* vm) {
ADD_METHOD(PK_LIST, "append", _listAppend, 1);
ADD_METHOD(PK_LIST, "pop", _listPop, -1);
ADD_METHOD(PK_LIST, "insert", _listInsert, 2);
ADD_METHOD(PK_LIST, "join", _listJoin, -1);

ADD_METHOD(PK_MAP, "clear", _mapClear, 0);
ADD_METHOD(PK_MAP, "get", _mapGet, -1);
Expand Down
2 changes: 2 additions & 0 deletions tests/lang/basics.pk
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ l1 = [] + [1]; assert(l1.length == 1); assert(l1[0] == 1)
l1 = [1] + []; assert(l1.length == 1); assert(l1[0] == 1)
l2 = l1 + [1,2,3]; assert(l2.length == 4); assert(l2 == [1,1,2,3])
l3 = l2 + l1 + l2; assert(l3 == [1,1,2,3,1,1,1,2,3])
assert(l3.join() == '112311123')
assert(l3.join(',') == '1,1,2,3,1,1,1,2,3')

## list references are shared.
l1 = [1];l2 = l1;l1 += [2]
Expand Down