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 */
298 for ( i=0 ; i<=dimv1; i++ ) {
299 myval = SvIV( *av_fetch(my_array, i, 0) );
300 val1 = SvIV( *av_fetch(v1_array, i, 0) );
301 val2 = SvIV( *av_fetch(v2_array, i, 0) );
302 if ( myval < val1 || myval > val2 ) {
303 XPUSHs( sv_2mortal( newSViv(0) ) );
307 XPUSHs( sv_2mortal( newSViv(1) ) );
316 # my $vec = $v1->_add($v2);
317 # my $vec = $v1 + $v2;
319 # Return a new LBVXS object, which is the result of $v1 plus $v2.
322 _add( v1, v2, variant )
327 IV dimv1, dimv2, i, val1, val2;
334 /* fetch the underlying array of the object */
335 v1_array = (AV*)SvRV(v1);
336 v2_array = (AV*)SvRV(v2);
337 dimv1 = av_len(v1_array);
338 dimv2 = av_len(v2_array);
341 if ( dimv1 != dimv2 )
342 croak("uneven dimensions in vector addition!");
344 /* create the new array and populate it */
346 for ( i=0 ; i<=dimv1; i++ ) {
347 val1 = SvIV( *av_fetch(v1_array, i, 0) );
348 val2 = SvIV( *av_fetch(v2_array, i, 0) );
349 av_push( my_array, newSViv(val1+val2) );
352 /* return a blessed reference to the AV */
353 self = newRV_noinc( (SV*)my_array );
354 stash = SvSTASH( (SV*)v1_array );
355 sv_bless( (SV*)self, stash );
362 # my $vec = $v1->_substract($v2);
363 # my $vec = $v1 - $v2;
365 # Return a new LBVXS object, which is the result of $v1 minus $v2.
368 _substract( v1, v2, variant )
373 IV dimv1, dimv2, i, val1, val2;
380 /* fetch the underlying array of the object */
381 v1_array = (AV*)SvRV(v1);
382 v2_array = (AV*)SvRV(v2);
383 dimv1 = av_len(v1_array);
384 dimv2 = av_len(v2_array);
387 if ( dimv1 != dimv2 )
388 croak("uneven dimensions in vector addition!");
390 /* create the new array and populate it */
392 for ( i=0 ; i<=dimv1; i++ ) {
393 val1 = SvIV( *av_fetch(v1_array, i, 0) );
394 val2 = SvIV( *av_fetch(v2_array, i, 0) );
395 av_push( my_array, newSViv(val1-val2) );
398 /* return a blessed reference to the AV */
399 self = newRV_noinc( (SV*)my_array );
400 stash = SvSTASH( (SV*)v1_array );
401 sv_bless( (SV*)self, stash );
408 # my $vec = $v1->_invert;
411 # Subtract $v1 from the origin. Effectively, gives the inverse of the
412 # original vector. The new vector is the same distance from the origin,
413 # in the opposite direction.
416 _invert( v1, v2, variant )
427 /* fetch the underlying array of the object */
428 v1_array = (AV*)SvRV(v1);
429 dim = av_len(v1_array);
431 /* create the new array and populate it */
433 for ( i=0 ; i<=dim; i++ ) {
434 val = SvIV( *av_fetch(v1_array, i, 0) );
435 av_push( my_array, newSViv(-val) );
438 /* return a blessed reference to the AV */
439 self = newRV_noinc( (SV*)my_array );
440 stash = SvSTASH( (SV*)v1_array );
441 sv_bless( (SV*)self, stash );
451 # $v1->_add_inplace($v2);
454 # Adds $v2 to $v1, and stores the result back into $v1.
457 _add_inplace( v1, v2, variant )
462 IV dimv1, dimv2, i, val1, val2;
466 /* fetch the underlying array of the object */
467 v1_array = (AV*)SvRV(v1);
468 v2_array = (AV*)SvRV(v2);
469 dimv1 = av_len(v1_array);
470 dimv2 = av_len(v2_array);
473 if ( dimv1 != dimv2 )
474 croak("uneven dimensions in vector addition!");
476 /* update the array slots */
477 for ( i=0 ; i<=dimv1; i++ ) {
478 val1 = SvIV( *av_fetch(v1_array, i, 0) );
479 val2 = SvIV( *av_fetch(v2_array, i, 0) );
480 av_store( v1_array, i, newSViv(val1+val2) );
487 # $v1->_substract_inplace($v2);
490 # Substract $v2 to $v1, and stores the result back into $v1.
493 _substract_inplace( v1, v2, variant )
498 IV dimv1, dimv2, i, val1, val2;
502 /* fetch the underlying array of the object */
503 v1_array = (AV*)SvRV(v1);
504 v2_array = (AV*)SvRV(v2);
505 dimv1 = av_len(v1_array);
506 dimv2 = av_len(v2_array);
509 if ( dimv1 != dimv2 )
510 croak("uneven dimensions in vector addition!");
512 /* update the array slots */
513 for ( i=0 ; i<=dimv1; i++ ) {
514 val1 = SvIV( *av_fetch(v1_array, i, 0) );
515 val2 = SvIV( *av_fetch(v2_array, i, 0) );
516 av_store( v1_array, i, newSViv(val1-val2) );
525 # my $bool = $v1->_compare($v2);
526 # my $bool = $v1 <=> $v2;
528 # Check whether the vectors both point at the same spot. Return 0 if they
529 # do, 1 if they don't.
532 _compare( v1, v2, variant )
538 IV dimv1, dimv2, i, val1, val2;
542 /* fetch the underlying array of the object */
543 v1_array = (AV*)SvRV(v1);
544 v2_array = (AV*)SvRV(v2);
545 dimv1 = av_len(v1_array);
546 dimv2 = av_len(v2_array);
549 if ( dimv1 != dimv2 )
550 croak("uneven dimensions in bounds check!");
552 /* compare the arrays */
553 for ( i=0 ; i<=dimv1; i++ ) {
554 val1 = SvIV( *av_fetch(v1_array, i, 0) );
555 val2 = SvIV( *av_fetch(v2_array, i, 0) );
556 if ( val1 != val2 ) {
557 XPUSHs( sv_2mortal( newSViv(1) ) );
561 XPUSHs( sv_2mortal( newSViv(0) ) );