list.pop() is really useful
This commit is contained in:
parent
fee817c3b7
commit
78c5503341
@ -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"
|
||||
|
@ -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__()
|
||||
|
@ -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
56
vm.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user