5 src/classes/CardinalArray.pir - Cardinal CardinalArray class and related functions
14 .namespace ['CardinalArray']
16 .sub 'onload' :anon :load :init
17 .local pmc cardinalmeta, arrayproto
18 cardinalmeta = get_hll_global ['CardinalObject'], '!CARDINALMETA'
19 arrayproto = cardinalmeta.'new_class'('CardinalArray', 'parent'=>'ResizablePMCArray CardinalObject')
20 cardinalmeta.'register'('ResizablePMCArray', 'parent'=>'CardinalObject', 'protoobject'=>arrayproto)
24 =item get_string() (vtable method)
26 Return the elements of the list concatenated.
30 .sub 'get_string' :vtable :method
39 Return a CardinalString representing the Array.
44 $S0 = self.get_string()
45 $P0 = new 'CardinalString'
50 =item clone() (vtable method)
56 .sub 'clone' :vtable :method
66 .sub 'ACCEPTS' :method
72 if what == "CardinalArray" goto acc_list
76 # Smartmatch against another list. Smartmatch each
78 .local int count_1, count_2
79 count_1 = elements self
80 count_2 = elements topic
81 if count_1 != count_2 goto no_match
84 if i >= count_1 goto list_cmp_loop_end
85 .local pmc elem_1, elem_2
88 ($I0) = elem_1.ACCEPTS(elem_2)
89 unless $I0 goto no_match
96 $P0 = get_hll_global ['Bool'], 'False'
99 $P0 = get_hll_global ['Bool'], 'True'
106 Return the number of elements in the list.
115 =item unshift(ELEMENTS)
117 Prepends ELEMENTS to the front of the list.
121 .sub 'unshift' :method
122 .param pmc args :slurpy
131 if i == narg goto done
141 Returns a CardinalArray containing the keys of the CardinalArray.
151 res = new 'CardinalArray'
156 if i == len goto done
158 elem = new 'CardinalInteger'
171 Returns a CardinalArray containing the values of the CardinalArray.
175 .sub 'values' :method
181 res = new 'CardinalArray'
186 if i == len goto done
188 elem = new 'CardinalInteger'
201 Shifts the first item off the list and returns it.
213 Treats the list as a stack, popping the last item off the list and returning it.
223 if len == 0 goto empty
237 Treats the list as a stack, pushing ELEMENTS onto the end of the list. Returns the new length of the list.
242 .param pmc args :slurpy
251 if i == len goto done
261 =item join(SEPARATOR)
263 Returns a string comprised of all of the list, separated by the string SEPARATOR. Given an empty list, join returns the empty string.
277 if len == 0 goto done
283 if i == len goto last
302 Returns a list of the elements in revese order.
306 .sub 'reverse' :method
311 res = new 'CardinalArray'
314 if len == 0 goto done
319 if len == 0 goto done
334 Deletes the given elements from the CardinalArray, replacing them with Undef. Returns a CardinalArray of removed elements.
339 .param pmc indices :slurpy
349 res = new 'CardinalArray'
351 # Index of the last element in the array
355 len = elements indices
359 if i == len goto done
363 if ind == -1 goto endofarray
364 if ind == last goto endofarray
368 # If we're at the end of the array, remove the element entirely
374 # Replace the element with undef.
389 Checks to see if the specified index or indices have been assigned to. Returns a Bool value.
394 .param pmc indices :slurpy
402 len = elements indices
406 if i == len goto done
410 test = exists self[ind]
411 if test == 0 goto done
417 .return 'prefix:?'(test)
430 res = new 'CardinalArray'
435 if i == len goto done
437 elem = new 'CardinalInteger'
463 res = new 'CardinalArray'
468 if i == len goto done
470 key = new 'CardinalInteger'
500 retv = new 'CardinalArray'
505 if i == narg goto done
508 newclosure block, test
509 block_res = block(block_arg)
511 if block_res goto grepped
515 retv.'push'(block_arg)
543 if i == narg goto nomatch
546 newclosure block, test
547 block_res = block(block_arg)
549 if block_res goto matched
569 Run C<block> once for each item in C<self>, with the item passed as an arg.
575 $P0 = new 'Iterator', self
577 unless $P0 goto each_loop_end
609 Build a CardinalArray from its arguments.
616 .param pmc args :slurpy
617 .local pmc list, item
618 list = new 'CardinalArray'
620 unless args goto args_end
623 unless $I0 goto add_item
624 $I0 = isa item, 'CardinalArray'
626 $I0 = does item, 'array'
627 unless $I0 goto add_item
628 splice args, item, 0, 0
638 =item C<infix:,(...)>
640 Operator form for building a list from its arguments.
645 .param pmc args :slurpy
646 .return 'list'(args :flat)
650 =item C<infix:Z(...)>
657 .param pmc args :slurpy
659 num_args = elements args
661 # Empty list of no arguments.
662 if num_args > 0 goto has_args
663 $P0 = new 'CardinalArray'
667 # Get minimum element count - what we'll zip to.
672 min_elem = elements $P0
674 if i >= num_args goto min_elems_loop_end
677 unless $I0 < min_elem goto not_min
684 # Now build result list of lists.
686 res = new 'CardinalArray'
689 if i >= min_elem goto zip_loop_end
691 cur_list = new 'CardinalArray'
695 if j >= num_args goto zip_elem_loop_end
711 =item C<infix:X(...)>
713 The non-hyper cross operator.
718 .param pmc args :slurpy
720 res = new 'CardinalArray'
722 # Algorithm: we'll maintain a list of counters for each list, incrementing
723 # the counter for the right-most list and, when it we reach its final
724 # element, roll over the counter to the next list to the left as we go.
726 .local pmc list_elements
728 counters = new 'FixedIntegerCardinalArray'
729 list_elements = new 'FixedIntegerCardinalArray'
730 num_args = elements args
732 list_elements = num_args
734 # Get element count for each list.
739 if i >= num_args goto elem_get_loop_end
741 $I0 = elements cur_list
742 list_elements[i] = $I0
747 # Now we'll start to produce them.
752 # Start out by building list at current counters.
754 new_list = new 'CardinalArray'
757 if i >= num_args goto cur_perm_loop_end
765 res[res_count] = new_list
768 # Now increment counters.
772 $I1 = list_elements[i]
776 # In simple case, we just increment this and we're done.
777 if $I0 < $I1 goto inc_counter_loop_end
779 # Otherwise we have to carry.
782 # If we're on the first element, all done.
783 if i == 0 goto all_done
787 goto inc_counter_loop
788 inc_counter_loop_end:
796 =item C<infix:min(...)>
803 .param pmc args :slurpy
805 # If we have no arguments, undefined.
807 elems = elements args
808 if elems > 0 goto have_args
819 if i >= elems goto find_min_loop_end
821 $I0 = 'infix:cmp'($P0, cur_min)
822 if $I0 != -1 goto not_min
833 =item C<infix:max(...)>
840 .param pmc args :slurpy
842 # If we have no arguments, undefined.
844 elems = elements args
845 if elems > 0 goto have_args
856 if i >= elems goto find_max_loop_end
858 $I0 = 'infix:cmp'($P0, cur_max)
859 if $I0 != 1 goto not_max
869 =item C<reverse(LIST)>
871 Returns the elements of LIST in the opposite order.
876 .param pmc list :slurpy
885 if len > 1 goto islist
887 # If we're not a list, check if we're a string.
891 # This is a bit of a work around - some operators (ie. ~) return
892 # a String object instead of a CardinalString.
893 eq type, 'String', parrotstring
894 eq type, 'CardinalString', perl6string
900 elem = new 'CardinalString'
904 retv = elem.'reverse'()
908 retv = new 'CardinalArray'
912 if i == len goto done
922 .sub keys :multi('CardinalArray')
925 .return list.'keys'()
928 .sub values :multi('CardinalArray')
931 .return list.'values'()
934 .sub delete :multi('CardinalArray')
936 .param pmc indices :slurpy
938 .return list.'delete'(indices :flat)
941 .sub exists :multi('CardinalArray')
943 .param pmc indices :slurpy
945 .return list.'exists'(indices :flat)
948 .sub kv :multi('CardinalArray')
954 .sub pairs :multi('CardinalArray')
957 .return list.'pairs'()
960 .sub grep :multi(_,'CardinalArray')
962 .param pmc list :slurpy
964 .return list.'grep'(test)
967 .sub first :multi(_,'CardinalArray')
969 .param pmc list :slurpy
971 .return list.'first'(test)
974 ## TODO: join map reduce sort zip
984 # vim: expandtab shiftwidth=4 ft=pir: