feat: implement subscript operator for lists with negative index and bounds checking

Add list_subscript primitive that supports integer indexing with negative indices counting from the end, returns null for out-of-bounds access, non-integer indices, and non-numeric argument types. Register the `[ ]` operator on the List class in loadCore and include comprehensive test coverage in test/list_subscript.wren.
This commit is contained in:
Bob Nystrom
2013-11-25 03:08:46 +00:00
parent cc117912fa
commit b098c60f7c
2 changed files with 48 additions and 0 deletions
+23
View File
@@ -91,6 +91,28 @@ DEF_PRIMITIVE(list_count)
return NUM_VAL(list->count);
}
DEF_PRIMITIVE(list_subscript)
{
// TODO(bob): Instead of returning null here, all of these failure cases
// should signal an error explicitly somehow.
if (!IS_NUM(args[1])) return NULL_VAL;
double indexNum = AS_NUM(args[1]);
int index = (int)indexNum;
// Make sure the index is an integer.
if (indexNum != index) return NULL_VAL;
ObjList* list = AS_LIST(args[0]);
// Negative indices count from the end.
if (index < 0) index = list->count + index;
// Check bounds.
if (index < 0 || index >= list->count) return NULL_VAL;
return list->elements[index];
}
DEF_PRIMITIVE(num_abs)
{
return NUM_VAL(fabs(AS_NUM(args[0])));
@@ -319,6 +341,7 @@ void loadCore(VM* vm)
vm->listClass = AS_CLASS(findGlobal(vm, "List"));
PRIMITIVE(vm->listClass, "count", list_count);
PRIMITIVE(vm->listClass, "[ ]", list_subscript);
vm->nullClass = AS_CLASS(findGlobal(vm, "Null"));