Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' of git@github.com:rakudo/rakudo
  • Loading branch information
pmichaud committed Apr 9, 2009
2 parents 85ab143 + 0a9dd6d commit a2bb078
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 12 deletions.
38 changes: 35 additions & 3 deletions src/classes/Array.pir
Expand Up @@ -48,7 +48,10 @@ Remove items from an array.
shorten_loop:
if $I0 < 0 goto shorten_end
$P0 = self[$I0]
unless null $P0 goto shorten_end
if null $P0 goto do_shorten
$I1 = $P0.'defined'()
if $I1 goto shorten_end
do_shorten:
delete self[$I0]
dec $I0
goto shorten_loop
Expand Down Expand Up @@ -133,7 +136,6 @@ Remove the last item from the array and return it.

.sub 'pop' :method :multi() :subid('array_pop')
.local pmc x
'!SIGNATURE_BIND'()
unless self goto empty
x = pop self
goto done
Expand Down Expand Up @@ -161,10 +163,22 @@ Add C<args> to the end of the Array.

.sub 'push' :method :multi() :subid('array_push')
.param pmc args :slurpy
.local pmc type, it
type = self.'of'()
args.'!flatten'()
it = iter args
it_loop:
unless it goto it_loop_end
$P0 = shift it
$I0 = type.'ACCEPTS'($P0)
unless $I0 goto type_error
goto it_loop
it_loop_end:
$I0 = elements self
splice self, args, $I0, 0
.tailcall self.'elems'()
type_error:
'die'('Type check failure in push')
.end
.sub '' :init :load
.local pmc block, signature
Expand Down Expand Up @@ -213,9 +227,21 @@ Adds C<args> to the beginning of the Array.

.sub 'unshift' :method :multi() :subid('array_unshift')
.param pmc args :slurpy
.local pmc type, it
type = self.'of'()
args.'!flatten'()
it = iter args
it_loop:
unless it goto it_loop_end
$P0 = shift it
$I0 = type.'ACCEPTS'($P0)
unless $I0 goto type_error
goto it_loop
it_loop_end:
splice self, args, 0, 0
.tailcall self.'elems'()
type_error:
'die'('Type check failure in push')
.end
.sub '' :init :load
.local pmc block, signature
Expand Down Expand Up @@ -302,7 +328,8 @@ Store things into an Array (e.g., upon assignment)
.namespace ['Perl6Array']
.sub '!STORE' :method
.param pmc source
.local pmc array, it
.local pmc array, it, type
type = self.'of'()
## we create a new array here instead of emptying self in case
## the source argument contains self or elements of self.
array = new 'ResizablePMCArray'
Expand All @@ -311,14 +338,19 @@ Store things into an Array (e.g., upon assignment)
array_loop:
unless it goto array_done
$P0 = shift it
$I0 = type.'ACCEPTS'($P0)
unless $I0 goto type_error
$P0 = '!CALLMETHOD'('Scalar',$P0)
$P0 = clone $P0
setprop $P0, 'type', type
push array, $P0
goto array_loop
array_done:
$I0 = elements self
splice self, array, 0, $I0
.return (self)
type_error:
'die'("Type mismatch in assignment to Array.")
.end

=back
Expand Down
9 changes: 6 additions & 3 deletions src/classes/Associative.pir
Expand Up @@ -52,10 +52,11 @@ Returns a list element or slice.

=cut

.sub 'postcircumfix:{ }' :method
.sub 'postcircumfix:{ }' :method :outer('_associative_role_body')
.param pmc args :slurpy
.param pmc options :slurpy :named
.local pmc result
.local pmc result, type
type = find_lex 'T'
if args goto do_index
## return complete invocant as a list
.tailcall self.'list'()
Expand All @@ -66,7 +67,8 @@ Returns a list element or slice.
$S0 = args[0]
result = self[$S0]
unless null result goto end
result = new 'Failure'
result = 'undef'()
setprop result, 'type', type
self[$S0] = result
goto end
slice:
Expand All @@ -78,6 +80,7 @@ Returns a list element or slice.
elem = self[$S0]
unless null elem goto slice_elem
elem = 'undef'()
setprop elem, 'type', type
self[$S0] = elem
slice_elem:
push result, elem
Expand Down
28 changes: 27 additions & 1 deletion src/classes/Hash.pir
Expand Up @@ -110,8 +110,17 @@ Store a value into a hash.
.param pmc source
## we create a new hash here instead of emptying self in case
## the source argument contains self or elements of self.
.local pmc hash, it
.local pmc hash, it, type
hash = new 'Perl6Hash'

## Need to preserve typing.
type = self.'of'()
if type == "Object" goto untyped
$P0 = get_hll_global 'Associative'
$P0 = $P0.'!select'(type)
'infix:does'(hash, $P0)
untyped:
source = 'list'(source)
it = iter source
iter_loop:
Expand All @@ -130,6 +139,8 @@ Store a value into a hash.
key = elem.'key'()
value = elem.'value'()
iter_kv:
$I0 = type.'ACCEPTS'(value)
unless $I0 goto type_error
value = '!CALLMETHOD'('Scalar', value)
hash[key] = value
goto iter_loop
Expand All @@ -140,6 +151,8 @@ Store a value into a hash.
unless hashiter goto hashiter_done
$S0 = shift hashiter
value = elem[$S0]
$I0 = type.'ACCEPTS'(value)
unless $I0 goto type_error
value = '!CALLMETHOD'('Scalar', value)
value = clone value
hash[$S0] = value
Expand All @@ -148,10 +161,23 @@ Store a value into a hash.
goto iter_loop
iter_done:
copy self, hash
# Since copy calls clone which is deep and loses properties, need to now
# re-apply type.
it = iter self
prop_set_loop:
unless it goto prop_set_loop_end
$S0 = shift it
value = self[$S0]
setprop value, 'type', type
goto prop_set_loop
prop_set_loop_end:
.return (self)
err_odd_list:
die "Odd number of elements found where hash expected"
type_error:
'die'("Type mismatch in assignment to Hash.")
.end
Expand Down
23 changes: 18 additions & 5 deletions src/classes/Positional.pir
Expand Up @@ -52,10 +52,11 @@ Returns a list element or slice.

=cut

.sub 'postcircumfix:[ ]' :method
.sub 'postcircumfix:[ ]' :method :outer('_positional_role_body')
.param pmc args :slurpy
.param pmc options :slurpy :named
.local pmc result
.local pmc result, type
type = find_lex 'T'
if args goto do_index
## return complete invocant as a list
.tailcall self.'list'()
Expand All @@ -73,9 +74,15 @@ Returns a list element or slice.
result_fetch:
result = self[$I0]
unless null result goto end
.local int cur_elems
cur_elems = elements self
viv_loop:
if cur_elems > $I0 goto end
result = 'undef'()
self[$I0] = result
goto end
setprop result, 'type', type
self[cur_elems] = result
inc cur_elems
goto viv_loop
result_whatever:
result = 'list'(self)
goto end
Expand All @@ -95,8 +102,14 @@ Returns a list element or slice.
slice_index:
elem = self[$I0]
unless null elem goto slice_elem
cur_elems = elements self
viv_loop_slice:
if cur_elems > $I0 goto slice_elem
elem = 'undef'()
self[$I0] = elem
setprop elem, 'type', type
self[cur_elems] = elem
inc cur_elems
goto viv_loop_slice
slice_elem:
push result, elem
goto slice_loop
Expand Down

0 comments on commit a2bb078

Please sign in to comment.