From ea3cfa05bd81d0411bc413a3c5647a82de92c586 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Fri, 14 Feb 2014 20:10:41 -0800 Subject: [PATCH] Allow [0..-1] and [0...0] to work on empty lists. --- builtin/core.wren | 5 +---- src/wren_core.c | 17 +++++++++++++---- test/list/subscript_range.wren | 4 ++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/builtin/core.wren b/builtin/core.wren index 0906afa0..1fd024de 100644 --- a/builtin/core.wren +++ b/builtin/core.wren @@ -10,10 +10,7 @@ class List { } + that { - var result = [] - for (element in this) { - result.add(element) - } + var result = this[0..-1] for (element in that) { result.add(element) } diff --git a/src/wren_core.c b/src/wren_core.c index 7081e30b..6db28350 100644 --- a/src/wren_core.c +++ b/src/wren_core.c @@ -53,10 +53,7 @@ static const char* libSource = " }\n" "\n" " + that {\n" -" var result = []\n" -" for (element in this) {\n" -" result.add(element)\n" -" }\n" +" var result = this[0..-1]\n" " for (element in that) {\n" " result.add(element)\n" " }\n" @@ -389,6 +386,18 @@ DEF_NATIVE(list_subscript) ObjRange* range = AS_RANGE(args[1]); + // TODO: This code is pretty hairy. Is there a more elegant way? + // Corner case: an empty range at zero is allowed on an empty list. + // This way, list[0..-1] and list[0...list.count] can be used to copy a list + // even when empty. + if (list->count == 0) { + if ((range->from == 0 && range->to == -1 && range->isInclusive) || + (range->from == 0 && range->to == 0 && !range->isInclusive)) + { + RETURN_OBJ(wrenNewList(vm, 0)); + } + } + int from = validateIndexValue(vm, args, list->count, range->from, "Range start"); if (from == -1) return PRIM_ERROR; diff --git a/test/list/subscript_range.wren b/test/list/subscript_range.wren index 6c7d1f2f..08a03a44 100644 --- a/test/list/subscript_range.wren +++ b/test/list/subscript_range.wren @@ -29,3 +29,7 @@ IO.print(list[1..-2]) // expect: [b, c, d] IO.print(list[2...-1]) // expect: [c, d] IO.print(list[4..-5]) // expect: [e, d, c, b, a] IO.print(list[3...-6]) // expect: [d, c, b, a] + +// An empty range at zero is allowed on an empty list. +IO.print([][0...0]) // expect: [] +IO.print([][0..-1]) // expect: []