diff --git a/src/builtins/List.pir b/src/builtins/List.pir index be7be4f1708..8e724e4cf6e 100644 --- a/src/builtins/List.pir +++ b/src/builtins/List.pir @@ -173,6 +173,60 @@ always flatten here, even if not marked with the 'flatten' flag. .return (values) .end +=item !STORE(source) + +Performs list assignment using the values from C. + +=cut + +.namespace ['List'] +.sub '!STORE' :method + .param pmc source + + # First, create a flattening Array from C. This + # creates # copies of values in C, in case any lvalue target + # containers in C also happen to be listed as rvalues + # in C. (Creating a copy of everything in C + # likely isn't the most efficient approach to this, but it + # works for now.) + source = '&circumfix:<[ ]>'(source) + $P0 = get_hll_global ['Bool'], 'True' + setprop source, 'flatten', $P0 + + + # Now, loop through targets of C, storing the corresponding + # values from source and flattening any RPAs we encounter. If a + # target is an array or hash, then it will end up consuming all + # of the remaining elements of source. + .local pmc targets + targets = getattribute self, '$!values' + targets = clone targets + store_loop: + unless targets goto store_done + .local pmc cont + cont = shift targets + $I0 = isa cont, ['ResizablePMCArray'] + if $I0 goto store_rpa + $I0 = isa cont, ['Perl6Scalar'] + if $I0 goto store_scalar + $I0 = isa cont, ['Array'] + if $I0 goto store_array + store_scalar: + $P0 = shift source + cont.'!STORE'($P0) + goto store_loop + store_array: + cont.'!STORE'(source) + source = '&circumfix:<[ ]>'() + goto store_loop + store_rpa: + splice targets, cont, 0, 0 + goto store_loop + store_done: + + .return (self) +.end + =back =cut diff --git a/src/builtins/Parcel.pir b/src/builtins/Parcel.pir index 175622131cd..3210a4ebceb 100644 --- a/src/builtins/Parcel.pir +++ b/src/builtins/Parcel.pir @@ -81,6 +81,9 @@ The canonical operator for creating a Parcel. parcel = new ['Parcel'] transform_to_p6opaque parcel splice parcel, args, 0, 0 + # treat parcel itself as rw (for list assignment) + $P0 = get_hll_global ['Bool'], 'True' + setprop parcel, 'rw', $P0 .return (parcel) .end