static bool prim_list_instantiate(WrenVM vm, Obj[] args, int stackStart) { args[stackStart] = new ObjList(16); return true; }
static bool prim_list_subscript(WrenVM vm, Obj[] args, int stackStart) { ObjList list = (ObjList)args[stackStart]; if (args[stackStart + 1].Type == ObjType.Num) { int index = (int)args[stackStart + 1].Num; if (index == args[stackStart + 1].Num) { if (index < 0) { index += list.Count(); } if (index >= 0 && index < list.Count()) { args[stackStart] = list.Get(index); return true; } vm.Fiber.Error = Obj.MakeString("Subscript out of bounds."); return false; } vm.Fiber.Error = Obj.MakeString("Subscript must be an integer."); return false; } ObjRange r = args[stackStart + 1] as ObjRange; if (r == null) { vm.Fiber.Error = Obj.MakeString("Subscript must be a number or a range."); return false; } // TODO: This is seriously broken and needs a rewrite int from = (int)r.From; if (from != r.From) { vm.Fiber.Error = Obj.MakeString("Range start must be an integer."); return false; } int to = (int)r.To; if (to != r.To) { vm.Fiber.Error = Obj.MakeString("Range end must be an integer."); return false; } if (from < 0) from += list.Count(); if (to < 0) to += list.Count(); int step = to < from ? -1 : 1; if (step > 0 && r.IsInclusive) to += 1; if (step < 0 && !r.IsInclusive) to += 1; // Handle copying an empty list if (list.Count() == 0 && to == (r.IsInclusive ? -1 : 0)) { to = 0; step = 1; } int count = (to - from) * step + (step < 0 ? 1 : 0); if (to < 0 || from + (count * step) > list.Count()) { vm.Fiber.Error = Obj.MakeString("Range end out of bounds."); return false; } if (from < 0 || (from >= list.Count() && from > 0)) { vm.Fiber.Error = Obj.MakeString("Range start out of bounds."); return false; } ObjList result = new ObjList(count); for (int i = 0; i < count; i++) { result.Add(list.Get(from + (i * step))); } args[stackStart] = result; return true; }
static PrimitiveResult prim_list_subscript(WrenVM vm, ObjFiber fiber, Value[] args) { ObjList list = args[0].Obj as ObjList; if (list == null) return PrimitiveResult.Error; if (args[1].Type == ValueType.Num) { int index = (int)args[1].Num; if (index == args[1].Num) { if (index < 0) { index += list.Count(); } if (index >= 0 && index < list.Count()) { args[0] = list.Get(index); return PrimitiveResult.Value; } args[0] = new Value("Subscript out of bounds."); return PrimitiveResult.Error; } args[0] = new Value("Subscript must be an integer."); return PrimitiveResult.Error; } ObjRange r = args[1].Obj as ObjRange; if (r == null) { args[0] = new Value("Subscript must be a number or a range."); return PrimitiveResult.Error; } // TODO: This is seriously broken and needs a rewrite int from = (int)r.From; if (from != r.From) { args[0] = new Value("Range start must be an integer."); return PrimitiveResult.Error; } int to = (int)r.To; if (to != r.To) { args[0] = new Value("Range end must be an integer."); return PrimitiveResult.Error; } if (from < 0) from += list.Count(); if (to < 0) to += list.Count(); int step = to < from ? -1 : 1; if (step > 0 && r.IsInclusive) to += 1; if (step < 0 && !r.IsInclusive) to += 1; // Handle copying an empty list if (list.Count() == 0 && to == (r.IsInclusive ? -1 : 0)) { to = 0; step = 1; } int count = (to - from) * step + (step < 0 ? 1 : 0); if (to < 0 || from + (count * step) > list.Count()) { args[0] = new Value("Range end out of bounds."); return PrimitiveResult.Error; } if (from < 0 || (from >= list.Count() && from > 0)) { args[0] = new Value("Range start out of bounds."); return PrimitiveResult.Error; } ObjList result = new ObjList(count); for (int i = 0; i < count; i++) { result.Add(list.Get(from + (i * step))); } args[0] = new Value(result); return PrimitiveResult.Value; }