list.pop() is really useful

This commit is contained in:
K. Lange 2021-01-10 20:49:01 +09:00
parent fee817c3b7
commit 78c5503341
4 changed files with 62 additions and 7 deletions

View File

@ -5,6 +5,8 @@ const char krk_builtinsSrc[] =
" 'Resizable array with direct constant-time indexing.'\n"
" def extend(i):\n"
" 'Add all entries from an iterable to the end of this list.'\n"
" if isinstance(i,list):\n"
" return self._extend_fast(i)\n"
" for v in i:\n"
" self.append(v)\n"
" return self.__len__()\n"

View File

@ -4,6 +4,8 @@ class list():
'Resizable array with direct constant-time indexing.'
def extend(i):
'Add all entries from an iterable to the end of this list.'
if isinstance(i,list):
return self._extend_fast(i)
for v in i:
self.append(v)
return self.__len__()

View File

@ -41,15 +41,14 @@ for bag in descriptions.keys():
print("There are", count, "bags that can contain a shiny gold bag, eventually.")
def find_depth(bag):
if not len(descriptions[bag]):
if not descriptions[bag]:
return 0
let to_scan = descriptions[bag]
let count = 0
while len(to_scan):
let i = to_scan[0]
to_scan = to_scan[1:]
while to_scan:
let i = to_scan.pop(0)
count += 1
to_scan.extend(descriptions[i])
to_scan._extend_fast(descriptions[i])
return count
print("A shiny gold bag contains", find_depth('shiny gold'), "bags.")

56
vm.c
View File

@ -478,6 +478,25 @@ static KrkValue _list_append(int argc, KrkValue argv[]) {
return NONE_VAL();
}
/**
* list.extend but only for lists...
*/
static KrkValue _list_extend_fast(int argc, KrkValue argv[]) {
KrkValue _list_internal_self = OBJECT_VAL(AS_INSTANCE(argv[0])->_internal);
KrkValue _list_internal_them = OBJECT_VAL(AS_INSTANCE(argv[1])->_internal);
size_t totalSize = AS_LIST(_list_internal_self)->count + AS_LIST(_list_internal_them)->count;
if (AS_LIST(_list_internal_self)->capacity < totalSize) {
size_t old = AS_LIST(_list_internal_self)->capacity;
AS_LIST(_list_internal_self)->capacity = totalSize;
AS_LIST(_list_internal_self)->values = GROW_ARRAY(KrkValue, AS_LIST(_list_internal_self)->values, old, totalSize);
}
memcpy(&AS_LIST(_list_internal_self)->values[AS_LIST(_list_internal_self)->count],
AS_LIST(_list_internal_them)->values, sizeof(KrkValue) * AS_LIST(_list_internal_them)->count);
AS_LIST(_list_internal_self)->count = totalSize;
return INTEGER_VAL(totalSize);
}
/**
* list.__len__
*/
@ -535,8 +554,12 @@ KrkValue krk_list_of(int argc, KrkValue argv[]) {
krk_tableSet(&outList->fields, vm.specialMethodNames[METHOD_LIST_INT], OBJECT_VAL(listContents));
outList->_internal = (KrkObj*)listContents;
krk_tableSet(&outList->fields, vm.specialMethodNames[METHOD_INREPR], INTEGER_VAL(0));
for (int ind = 0; ind < argc; ++ind) {
krk_writeValueArray(&listContents->chunk.constants, argv[ind]);
if (argc) {
listContents->chunk.constants.capacity = argc;
listContents->chunk.constants.values = GROW_ARRAY(KrkValue, listContents->chunk.constants.values, 0, argc);
memcpy(listContents->chunk.constants.values, argv, sizeof(KrkValue) * argc);
listContents->chunk.constants.count = argc;
}
KrkValue out = OBJECT_VAL(outList);
krk_pop(); /* listContents */
@ -601,6 +624,33 @@ static KrkValue _list_slice(int argc, KrkValue argv[]) {
return krk_list_of(len, &AS_LIST(_list_internal)->values[start]);
}
/**
* list.pop()
*/
static KrkValue _list_pop(int argc, KrkValue argv[]) {
long index = 0;
if (argc > 1) {
index = AS_INTEGER(argv[1]);
}
KrkValue _list_internal = OBJECT_VAL(AS_INSTANCE(argv[0])->_internal);
if (index < 0 || index >= (long)AS_LIST(_list_internal)->count) {
krk_runtimeError(vm.exceptions.indexError, "list index out of range: %d", (int)index);
return NONE_VAL();
}
KrkValue outItem = AS_LIST(_list_internal)->values[index];
if (index == (long)AS_LIST(_list_internal)->count-1) {
AS_LIST(_list_internal)->count--;
return outItem;
} else {
/* Need to move up */
size_t remaining = AS_LIST(_list_internal)->count - index - 1;
memmove(&AS_LIST(_list_internal)->values[index], &AS_LIST(_list_internal)->values[index+1],
sizeof(KrkValue) * remaining);
AS_LIST(_list_internal)->count--;
return outItem;
}
}
/**
* __builtins__.set_tracing(mode)
*
@ -2788,6 +2838,8 @@ void krk_initVM(int flags) {
krk_defineNative(&_class->methods, ".__getslice__", _list_slice);
krk_defineNative(&_class->methods, ".__iter__", _list_iter);
krk_defineNative(&_class->methods, ".append", _list_append);
krk_defineNative(&_class->methods, ".pop", _list_pop);
krk_defineNative(&_class->methods, "._extend_fast", _list_extend_fast);
krk_finalizeClass(_class);
krk_tableGet(&vm.builtins->fields,OBJECT_VAL(S("dict")),&val);