Perl Array PMC
Synopsis
new P0, .PerlArray # PMC creation
set P0, 5 # set array size
set I1, P0 # get array size
set P0[4], "foo" # set array position 4
set P0[-1], "gah!" # set last array element
push P0, 3 # add 3 to the end of the array
pop N0, P0 # remove last element of the array
shift P0, 2 # add 2 in the beginning of the array
unshift I0, P0 # remove first element of the array
defined I0, P0[1] # check if element is defined
exists I0, P0[4] # check if element exists
clone P1, P0 # copy/clone PMC
Creation
To create a new PMC with a PerlArray in register P0
use:
new P0, .PerlArray
Size
Perl array size can be initialized. For example, the empty array (size 0) is set using:
set P0, 0
and we can check the PerlArray size, putting the value on register I0
using
set I0, P0
Arrays can be initialized with any size:
set P0, 5
In fact, size is almost non-interesting because these arrays grow as soon as you access an index out of bounds or ask explicitly.
Indexed access
You can set the value 3 on the position 5 from the array using
set P0[5], 3
In the same mood, to access the element use
set I0, P0[5]
As in Perl, negative indexes are seen as indexes from the end of the array. This way, you can set the last element of the array to the value 7 using
set P0[-1], 7
Note that these arrays are polymorphic: array elements can store any kind of element.
Multidimensional arrays
You can use Perl arrays inside Perl arrays:
new P0, .PerlArray
new P1, .PerlArray
set P1[0], "el1"
set P1[1], "el2"
set P0[0], P1 # First element for P0 is a perl array.
clone P2, P1
set P0[1], P2 # Second element for P0 is a perl array.
This code creates a table like this:
el1 el2
el1 el2
TODO: (bellow)
Will this be possible? At the moment, gives an 'Array index out of bounds!'
While you can do this manually, as shown in the above example, it is possible to use the following syntax:
new P0, .PerlArray
set P0[0;0], "el1"
set P0[0;1], "el2"
set P0[1;0], "el1"
set P0[1;1], "el2"
This code would construct the same table. To fetch the elements you can use the same syntax:
set S0, P0[0;1]
Stacking
You can use the Perl arrays as stacks, where elements are added to higher positions on the array:
new P0, .PerlArray
push P0, 2 # set P0[0], 2
push P0, 3 # set P0[1], 3
pop I0, P0 # sets I0 to P0[1] and removes this element from
# the array
Shifting
If you want to add or remove elements from the beginning of the array, use the shift or unshift commands:
new P0, .PerlArray
unshift P0, 2 # set P0[0], 2
unshift P0, 3 # set P0[1], 2; set P0[0], 3
shift I0, P0 # sets I0, P0[0], and moves all elements one
# index down
Trueness
You can get a boolean value from a Perl Array. If you use an empty Perl Array in a condition, it will return false (no elements).
new P0, .PerlArray
if P0, JUMP # This will never succeed
After adding a value (for example, P0[0] = 1), it will return a true value (the Perl Array has elements).
new P0, .PerlArray
set P0, 0, 1
if P0, JUMP # This will succeed
If you don't add a value, but force a size different from zero the the array, it will return a true value:
new P0, .PerlArray
set P0, 1
if P0, JUMP # This will succeed
You can test if there is a defined element on some array position using
defined I0, P0[1]
for the position you want to test. On the other hand, if you want only to test if there is an element (rather than testing if it is defines) you should use the exists
keyword:
exists I0, P0[0]
If you set the size of an array to something larger than its current value, extra elements do not exists. This means that:
new P0, .PerlArray
set P0, 2
set P0[0], 4
exists I0, P0[0] # I0 == 1
exists I0, P0[1] # I0 == 0
Cloning
As other PMCs, you can clone Perl arrays. If you try something like
new P0, .PerlArray
set P0[0], 1
set P0[1], 2
clone P1, P0
P1
is a copy of P0
, where you can do whatever you want without changing the other array.
TODO:
Apparently, the copy will be deep. This means that copying an array of arrays you will get a new array with copies of arrays. Cool!
The problem is: how do you shallow copy?
TODO
- explain splicing;
- add multidimentional arrays on synopsis, as soon we know if they
work directly;