Skip to content

Commit

Permalink
Added support for index,count and range versions of []=. Tests includ…
Browse files Browse the repository at this point in the history
…ed. Second attempt.

Signed-off-by: Ted Reed <ted.reed@gmail.com>
  • Loading branch information
dtm authored and treed committed Aug 8, 2009
1 parent 34e0fdb commit 58f7557
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 14 deletions.
3 changes: 2 additions & 1 deletion Rakefile
Expand Up @@ -257,6 +257,7 @@ namespace :test do |ns|

namespace :array do
test "array/array.t"
test "array/assign.t"
test "array/at.t"
test "array/clear.t"
test "array/collect.t"
Expand Down Expand Up @@ -289,7 +290,7 @@ namespace :test do |ns|
test "array/values_at.t"
test "array/warray.t"

task :all => [:array, :at, :clear, :collect, :compact, :concat, :delete, :empty, :equals, :fetch, :fill, :first, :flatten, :grep, :include, :index, :insert, :intersection, :join, :mathop, :pop, :push, :reject, :replace, :reverse, :shift, :slice, :sort, :to_s, :uniq, :values_at, :warray]
task :all => [:array, :assign, :at, :clear, :collect, :compact, :concat, :delete, :empty, :equals, :fetch, :fill, :first, :flatten, :grep, :include, :index, :insert, :intersection, :join, :mathop, :pop, :push, :reject, :replace, :reverse, :shift, :slice, :sort, :to_s, :uniq, :values_at, :warray]
end

namespace :file do
Expand Down
99 changes: 89 additions & 10 deletions src/classes/Array.pir
Expand Up @@ -1410,25 +1410,104 @@ Retrieve the number of elements in C<self>
.tailcall '!do_slice_range'(self, range)
.end

.sub '[]=' :method
.param pmc i
.sub '!extend_array'
.param pmc a
.param int from
.param int to
.local int c
.local pmc nil

nil = get_hll_global 'nil'
c = from
loop:
a[c] = nil

inc c
if c < to goto loop
.end

.sub '[]=' :method :multi('CardinalArray', 'CardinalInteger', _)
.param int i
.param pmc v
.local int length
.local pmc nil

length = elements self
if i <= length goto set_value

nil = get_hll_global 'nil'
loop:
self[length] = nil

inc length
if i > length goto loop

$I0 = i + length
if $I0 < 0 goto throw_index_exception

'!extend_array'(self, length, i)

set_value:
self[i] = v
.return (v)

throw_index_exception: # TODO
.return(v)
.end

.sub '[]=' :method :multi('CardinalArray', 'CardinalInteger', 'CardinalInteger', _)
.param int i
.param int c
.param pmc v
.local int length
.local pmc nil

length = elements self

if i >= 0 goto skip_negative

$I0 = i + length
if $I0 < 0 goto throw_index_exception

skip_negative:
if i <= length goto skip_fill

'!extend_array'(self, length, i)

skip_fill:
$I0 = isa v, 'CardinalArray'
if $I0 goto skip_make_array

$P0 = new 'CardinalArray'

$I0 = isa v, 'NilClass'
if $I0 goto do_splice

$P0.'push'(v)

goto do_splice

skip_make_array:
$P0 = v

do_splice:
splice self, $P0, i, c

.return (v)

throw_index_exception: # TODO
.return(v)
.end

.sub '[]=' :method :multi('CardinalArray', 'CardinalRange', _)
.param pmc r
.param pmc v
.local pmc beg
.local pmc end
.local pmc count

beg = r.'from'()
end = r.'to'()

$P0 = getattribute r, '$!to_exclusive'
if $P0 goto skip_exclusive_to
inc end

skip_exclusive_to:
count = end - beg
.tailcall self.'[]='(beg, count, v)
.end

=item zip
Expand Down
10 changes: 8 additions & 2 deletions src/parser/actions.pm
Expand Up @@ -160,14 +160,20 @@ method end($/) {
}

method indexed_assignment($/) {
my $key := $<key>.ast();
my $keys;
my $rhs := $<rhs>.ast();
my $primary := $<basic_primary>.ast();

$keys := $<keys>.ast();

my $past := PAST::Op.new( :name('[]='), :pasttype('callmethod'), :node($/) );

$past.push( $primary );
$past.push( $key );

while $keys[0] {
$past.push( $keys.shift() );
}

$past.push( $rhs );

make $past;
Expand Down
2 changes: 1 addition & 1 deletion src/parser/grammar.pg
Expand Up @@ -86,7 +86,7 @@ rule end {
}

token indexed_assignment {
<basic_primary> '[' <key=arg> ']' <.ws> '=' <.ws> <rhs=arg>
<basic_primary> '[' <keys=args> ']' <.ws> '=' <.ws> <rhs=arg>
{*}
}

Expand Down
34 changes: 34 additions & 0 deletions t/array/assign.t
@@ -0,0 +1,34 @@
require 'Test'
include Test
plan 10

a = [ 1 ]

b = a[0] = 0

is a, [0], 'assignemnt index, simple rhs'
is b, 0, 'assignment simple rhs, return value'

a[3] = 2
is a, [0,nil,nil,2], 'assignment index, simple rhs, with extend'

a[0,2] = [1,2]
is a, [1,2,nil,2], 'assignment index+count, array rhs'

a[0,3] = nil
is a, [2], 'assignment index+count, delete with nil'

a[1,3]=[1,0]
is a, [2,1,0], 'assignment index+count, array rhs'

a[-1]=2
is a, [2,1,2], 'assignment negative index, simple rhs'

a[-2,2]=0
is a, [2,0], 'assignment negative index+count'

a[0..1]=[1,2,3]
is a, [1,2,3], 'assignment range, array rhs'

a[0...1]=[0,0,0]
is a, [0,0,0,2,3], 'assignment range exclusive, array rhs'

0 comments on commit 58f7557

Please sign in to comment.