() = evalfile ("./inc.sl"); testing_feature ("lists"); static variable L = list_new (); list_insert (L, "f0"); if ("f0" != L[0]) failed ("L[0]"); list_append (L, "f1"); if ("f1" != L[1]) failed ("L[1]"); list_append (L, "f2", 1); if ("f2" != L[2]) failed ("L[2]"); if (length (L) != 3) failed ("list length"); list_delete (L, 0); if (L[0] != "f1") failed ("list_delete (L,0)"); list_delete (L, -1); if (L[0] != "f1") failed ("list_delete (L,-1)"); list_delete (L, 0); if (length (L)) failed ("list_delete to empty list"); L = 0; L = {}; L = {L, "100", [1:10]}; if (length (L) != 3) failed ("list with an empty list"); if (0 == _eqs(L[0], {})) failed ("list {}"); L = {"200", L, 3.14}; if ((L[0] != "200") or (L[2] != 3.14) or (L[-1] != 3.14)) failed ("list {with list elements}"); L = {20, 30, {40, {}, 50}}; if ((L[0] != 20) or (L[1] != 30) or (L[2][0] != 40) or (L[2][2] != 50)) failed ("list { {} }"); static variable L1 = @L; if (__is_same (L1, L)) failed ("@L"); if (0 == _eqs (L1, L)) failed ("_eqs(@L,L)"); _for (1, 10000, 1) { $1 = (); list_append(L, $1); } L = {}; _for (1, 100, 1) { $1 = (); list_append (L, {$1, "$1"$}); } $1 = 0; foreach $2 (L) { $1++; if (($2[0] != $1) or ($2[1] != "$1"$)) failed ("foreach list"); } if (($1 != length (L)) or ($1 != 100)) failed ("foreach length"); L = {}; _for $1 (0, 10, 1) L = {L,$1}; if (L[1] != 10) failed ("L[1]"); private define test_push_pop_list () { variable list = __pop_list (_NARGS); variable d0 = _stkdepth (); __push_list (list); variable d1 = _stkdepth (); if (d1 - d0 != _NARGS) failed ("push/pop_list"); loop (_NARGS) { variable a = list_pop (list, -1); variable b = (); if (not __is_same (a, b)) failed ("push/pop_list failed sameness test"); } } test_push_pop_list ("A", 1, 4, PI, Array_Type[3]); test_push_pop_list (); test_push_pop_list ("A"); test_push_pop_list ({}); test_push_pop_list ("A", {}); private define test_complex_list () { variable l = {}; variable n1 = 0; variable s0 = "string"; variable z0 = 1; #ifexists Complex_Type z0 += 2i; #endif variable n = 20; loop (n) { list_append (l, z0); list_append (l, s0); } variable za, sa, zl, sl; zl = l[[::2]]; sl = l[[1::2]]; za = list_to_array (zl); sa = list_to_array (sl); if (any(za != z0)) failed ("list of complex numbers with array indexing"); if (any (sa != s0)) failed ("list of strings with array indexing"); % LHS = array l[[::2]] = sa; l[[1::2]] = za; sa = list_to_array (l[[::2]]); za = list_to_array (l[[1::2]]); if (any(za != z0)) failed ("aput complex with array LHS"); if (any (sa != s0)) failed ("aput string with array LHS"); % LHS = list l[[::2]] = zl; l[[1::2]] = sl; sa = list_to_array (l[[::2]]); za = list_to_array (l[[1::2]]); if (any(za != z0)) failed ("aput complex with array LHS"); if (any (sa != s0)) failed ("aput string with array LHS"); } test_complex_list (); private define make_big_list (len) { variable l = {}; _for (0, len-1, 1) { variable i = (); list_append (l, i); } return l; } private define random_indices (num, cd) { variable i = int (urand () * num); variable j = int (urand () * num); return i, j; } private define forward_indices (num, last_ip) { variable i = (@last_ip + 1) mod num; variable j = (i + 1) mod num; @last_ip = i; return i, j; } private define reverse_indices (num, last_ip) { variable i = (num + (@last_ip - 1)) mod num; variable j = (num + (i - 1)) mod num; @last_ip = i; return i, j; } private define test_indexing (type, num, nloops, index_fun, cd) { variable l = make_big_list (num); loop (nloops) { variable i, j; (i, j) = (@index_fun)(num, cd); if (l[i] != i) failed ("%s list indexing", type); list_insert (l, -j, j); if (l[j] != -j) failed ("%s list indexing with insertion", type); if (i < j) { if (l[i] != i) failed ("%s list indexing before insertion", type); } else if (i > j) { if (l[i] != i-1) failed ("%s list indexing after insertion", type); } list_delete (l, j); if (l[i] != i) failed ("%s list indexing with deletion", type); } } private define run_index_tests () { variable cd; foreach ([1, 100, 127, 128, 129, 255, 256, 257, 1024, 8192, 8193]) { variable num = (); test_indexing ("random", num, 1000, &random_indices, NULL); cd = -1; test_indexing ("forward", num, num, &forward_indices, &cd); cd = num+1; test_indexing ("reverse", num, num, &reverse_indices, &cd); } } run_index_tests (); private define test_append_join () { variable da = {PI, "foo", 2.1, Array_Type[4]}; variable ab = {}; variable ab_concat = {}; variable ab_join = {}; variable obj; variable N = 31; loop (N) { ab_concat = list_concat (ab, da); list_join (ab_join, da); foreach obj (da) list_append (ab, obj); } variable num = N*length(da); if (num != length (ab)) failed ("list_append failed to produce a list of the expected length"); if (num != length (ab_concat)) failed ("list_concat failed to produce a list of the expected length"); if (num != length (ab_join)) failed ("list_join failed to produce a list of the expected length"); _for (0, num-1, 1) { variable i = (); ifnot (_eqs (ab[i], ab_concat[i])) failed ("list_concat failure: %S != %S", ab[i], ab_concat[i]); ifnot (_eqs (ab[i], ab_join[i])) failed ("list_join failure: %S != %S", ab[i], ab_join[i]); } } test_append_join (); private define test_api_list () { variable list = {"string", 10, PI, #ifexists Complex_Type 3i, #endif &failed, [1:10], Struct_Type[12], Assoc_Type[]}; variable clist = api_create_list (__push_list (list)); if (length (clist) != length (list)) failed ("api_create_list length test"); variable i; _for i (0, length(list)-1, 1) { ifnot (__is_same (clist[i], list[i])) failed ("api_create_list __is_same test: %S != %S", clist[i], list[i]); } api_list_insert (clist, 0, "start"); api_list_append (clist, -1, "end"); if (clist[0] != "start") failed ("api_list_insert"); if (clist[-1] != "end") failed ("api_list_append"); } loop (10) test_api_list (); test_api_push_and_pop_list (); % entirely defined in list.c private define test_api_pop_and_push_list () { variable l1 = { 1, PI, #ifexists Complex_Type 2+3i, #endif "foobar", [1,2,3,4], struct {foo, bar}, Assoc_Type[Integer_Type, 42] }; l1; variable l2 = api_pop_and_push_list (); ifnot (__is_same (l1, l2)) { failed ("api_push_and_pop_list"); } } test_api_pop_and_push_list (); private define test_size_hint (n) { variable l = list_new (n); while (length(l) < 1024) { list_append (l, "foo"); } l = {"a", "b"}; while (length(l) < 1024) { list_append (l, "foo"); } } loop (3) test_size_hint (0); loop (3) test_size_hint (1); loop (3) test_size_hint (2); loop (3) test_size_hint (127); loop (3) test_size_hint (128); loop (3) test_size_hint (129); loop (3) test_size_hint (500); private define test_list_reverse () { variable l = make_big_list (10); variable lrev = @l; list_reverse (lrev); variable a, b; loop (length (l)) { if (list_pop (l) != list_pop (lrev, -1)) failed ("list_reverse"); } } test_list_reverse (); print ("Ok\n"); exit (0);