3 # This file is part of Language::Befunge::Vector::XS.
4 # Copyright (c) 2008 Jerome Quelin, all rights reserved.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the same terms as Perl itself.
20 /* used for constructor new() */
22 void* intArrayPtr(int num) {
24 mortal = sv_2mortal( NEWSV(0, num * sizeof(intArray)) );
30 MODULE = Language::Befunge::Vector::XS PACKAGE = Language::Befunge::Vector::XS
36 # my $vec = LB::Vector->new( $x [, $y, ...] );
38 # Create a new vector. The arguments are the actual vector data; one
39 # integer per dimension.
42 new( class, array, ... )
54 croak("Usage: %s->new($x,...)", class);
56 /* create the object and populate it */
58 for ( i=0; i<ix_array; i++ ) {
59 val = newSViv( array[i] );
60 av_push(my_array, val);
63 /* Return a blessed reference to the AV */
64 self = newRV_noinc( (SV*)my_array );
65 stash = gv_stashpv( class, TRUE );
66 sv_bless( (SV*)self, stash );
73 # my $vec = Language::Befunge::Vector::XS->new_zeroes( $dims );
75 # Create a new vector of dimension $dims, set to the origin (all
76 # zeroes). LBVXS->new_zeroes(2) is exactly equivalent to LBVXS->new(0, 0).
79 new_zeroes( class, dim )
91 croak("Usage: %s->new_zeroes($dims)", class);
93 /* create the object and populate it */
95 for ( i=0; i<dim; i++ ) {
97 av_push(my_array, zero);
100 /* return a blessed reference to the AV */
101 self = newRV_noinc( (SV*)my_array );
102 stash = gv_stashpv( class, TRUE );
103 sv_bless( (SV*)self, stash );
110 # my $vec = $v->copy;
112 # Return a new LBVXS object, which has the same dimensions and
126 /* fetch the underlying array of the object */
127 vec_array = (AV*)SvRV(vec);
129 /* create the object and populate it */
131 for ( i=0; i<=av_len(vec_array); i++ ) {
132 val = newSViv( SvIV(*av_fetch(vec_array, i, 0)) );
133 av_push(my_array, val);
136 /* return a blessed reference to the AV */
137 self = newRV_noinc( (SV*)my_array );
138 stash = SvSTASH( (SV*)vec_array );
139 sv_bless( (SV*)self, stash );
150 # my $dims = $vec->get_dims;
152 # Return the number of dimensions, an integer.
160 /* fetch the underlying array of the object */
161 my_array = (AV*)SvRV(self);
163 RETVAL = av_len(my_array) + 1;
169 # my $val = $vec->get_component($dim);
171 # Return the value for dimension $dim.
174 get_component( self, dim )
180 /* fetch the underlying array of the object */
181 my_array = (AV*)SvRV(self);
184 if ( dim < 0 || dim > av_len(my_array) )
185 croak( "No such dimension!" );
187 RETVAL = SvIV( *av_fetch(my_array, dim, 0) );
193 # my @vals = $vec->get_all_components;
195 # Get the values for all dimensions, in order from 0..N.
198 get_all_components( self )
204 /* fetch the underlying array of the object */
205 my_array = (AV*)SvRV(self);
206 dim = av_len(my_array);
208 /* extend the return stack and populate it */
210 for ( i=0; i<=dim; i++ ) {
211 val = SvIV( *av_fetch(my_array, i, 0) );
212 PUSHs( sv_2mortal( newSViv(val) ) );
221 # Set the vector back to the origin, all 0's.
231 /* fetch the underlying array of the object */
232 my_array = (AV*)SvRV(self);
233 dim = av_len(my_array);
235 /* clear each slot */
236 for ( i=0; i<=dim; i++ ) {
238 av_store(my_array, i, zero);
243 # my $val = $vec->set_component( $dim, $value );
245 # Set the value for dimension $dim to $value.
248 set_component( self, dim, value )
255 /* fetch the underlying array of the object */
256 my_array = (AV*)SvRV(self);
259 if ( dim < 0 || dim > av_len(my_array) )
260 croak( "No such dimension!" );
262 /* storing new value */
263 av_store(my_array, dim, newSViv(value));
269 # my $is_within = $vec->bounds_check($begin, $end);
271 # Check whether $vec is within the box defined by $begin and $end.
272 # Return 1 if vector is contained within the box, and 0 otherwise.
275 bounds_check( self, v1, v2 )
280 IV i, mydim, dimv1, dimv2, myval, val1, val2;
285 /* fetch the underlying array of the object */
286 my_array = (AV*)SvRV(self);
287 v1_array = (AV*)SvRV(v1);
288 v2_array = (AV*)SvRV(v2);
289 mydim = av_len(my_array);
290 dimv1 = av_len(v1_array);
291 dimv2 = av_len(v2_array);
294 if ( mydim != dimv1 || mydim != dimv2 )
295 croak("uneven dimensions in bounds check!");
297 /* compare the arrays */
299 for ( i=0 ; i<=dimv1; i++ ) {
300 myval = SvIV( *av_fetch(my_array, i, 0) );
301 val1 = SvIV( *av_fetch(v1_array, i, 0) );
302 val2 = SvIV( *av_fetch(v2_array, i, 0) );
303 if ( myval < val1 || myval > val2 ) {
318 # my $vec = $v1->_add($v2);
319 # my $vec = $v1 + $v2;
321 # Return a new LBVXS object, which is the result of $v1 plus $v2.
324 _add( v1, v2, variant )
329 IV dimv1, dimv2, i, val1, val2;
336 /* fetch the underlying array of the object */
337 v1_array = (AV*)SvRV(v1);
338 v2_array = (AV*)SvRV(v2);
339 dimv1 = av_len(v1_array);
340 dimv2 = av_len(v2_array);
343 if ( dimv1 != dimv2 )
344 croak("uneven dimensions in vector addition!");
346 /* create the new array and populate it */
348 for ( i=0 ; i<=dimv1; i++ ) {
349 val1 = SvIV( *av_fetch(v1_array, i, 0) );
350 val2 = SvIV( *av_fetch(v2_array, i, 0) );
351 av_push( my_array, newSViv(val1+val2) );
354 /* return a blessed reference to the AV */
355 self = newRV_noinc( (SV*)my_array );
356 stash = SvSTASH( (SV*)v1_array );
357 sv_bless( (SV*)self, stash );
364 # my $vec = $v1->_substract($v2);
365 # my $vec = $v1 - $v2;
367 # Return a new LBVXS object, which is the result of $v1 minus $v2.
370 _substract( v1, v2, variant )
375 IV dimv1, dimv2, i, val1, val2;
382 /* fetch the underlying array of the object */
383 v1_array = (AV*)SvRV(v1);
384 v2_array = (AV*)SvRV(v2);
385 dimv1 = av_len(v1_array);
386 dimv2 = av_len(v2_array);
389 if ( dimv1 != dimv2 )
390 croak("uneven dimensions in vector addition!");
392 /* create the new array and populate it */
394 for ( i=0 ; i<=dimv1; i++ ) {
395 val1 = SvIV( *av_fetch(v1_array, i, 0) );
396 val2 = SvIV( *av_fetch(v2_array, i, 0) );
397 av_push( my_array, newSViv(val1-val2) );
400 /* return a blessed reference to the AV */
401 self = newRV_noinc( (SV*)my_array );
402 stash = SvSTASH( (SV*)v1_array );
403 sv_bless( (SV*)self, stash );
410 # my $vec = $v1->_invert;
413 # Subtract $v1 from the origin. Effectively, gives the inverse of the
414 # original vector. The new vector is the same distance from the origin,
415 # in the opposite direction.
418 _invert( v1, v2, variant )
429 /* fetch the underlying array of the object */
430 v1_array = (AV*)SvRV(v1);
431 dim = av_len(v1_array);
433 /* create the new array and populate it */
435 for ( i=0 ; i<=dim; i++ ) {
436 val = SvIV( *av_fetch(v1_array, i, 0) );
437 av_push( my_array, newSViv(-val) );
440 /* return a blessed reference to the AV */
441 self = newRV_noinc( (SV*)my_array );
442 stash = SvSTASH( (SV*)v1_array );
443 sv_bless( (SV*)self, stash );
453 # $v1->_add_inplace($v2);
456 # Adds $v2 to $v1, and stores the result back into $v1.
459 _add_inplace( v1, v2, variant )
464 IV dimv1, dimv2, i, val1, val2;
468 /* fetch the underlying array of the object */
469 v1_array = (AV*)SvRV(v1);
470 v2_array = (AV*)SvRV(v2);
471 dimv1 = av_len(v1_array);
472 dimv2 = av_len(v2_array);
475 if ( dimv1 != dimv2 )
476 croak("uneven dimensions in vector addition!");
478 /* update the array slots */
479 for ( i=0 ; i<=dimv1; i++ ) {
480 val1 = SvIV( *av_fetch(v1_array, i, 0) );
481 val2 = SvIV( *av_fetch(v2_array, i, 0) );
482 av_store( v1_array, i, newSViv(val1+val2) );
489 # $v1->_substract_inplace($v2);
492 # Substract $v2 to $v1, and stores the result back into $v1.
495 _substract_inplace( v1, v2, variant )
500 IV dimv1, dimv2, i, val1, val2;
504 /* fetch the underlying array of the object */
505 v1_array = (AV*)SvRV(v1);
506 v2_array = (AV*)SvRV(v2);
507 dimv1 = av_len(v1_array);
508 dimv2 = av_len(v2_array);
511 if ( dimv1 != dimv2 )
512 croak("uneven dimensions in vector addition!");
514 /* update the array slots */
515 for ( i=0 ; i<=dimv1; i++ ) {
516 val1 = SvIV( *av_fetch(v1_array, i, 0) );
517 val2 = SvIV( *av_fetch(v2_array, i, 0) );
518 av_store( v1_array, i, newSViv(val1-val2) );
527 # my $bool = $v1->_compare($v2);
528 # my $bool = $v1 <=> $v2;
530 # Check whether the vectors both point at the same spot. Return 0 if they
531 # do, 1 if they don't.
534 _compare( v1, v2, variant )
540 IV dimv1, dimv2, i, val1, val2;
544 /* fetch the underlying array of the object */
545 v1_array = (AV*)SvRV(v1);
546 v2_array = (AV*)SvRV(v2);
547 dimv1 = av_len(v1_array);
548 dimv2 = av_len(v2_array);
551 if ( dimv1 != dimv2 )
552 croak("uneven dimensions in bounds check!");
554 /* compare the arrays */
556 for ( i=0 ; i<=dimv1; i++ ) {
557 val1 = SvIV( *av_fetch(v1_array, i, 0) );
558 val2 = SvIV( *av_fetch(v2_array, i, 0) );
559 if ( val1 != val2 ) {