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, ... )
52 /* create the object and populate it */
54 for ( i=0; i<ix_array; i++ ) {
55 val = newSViv( array[i] );
56 av_push(my_array, val);
59 /* Return a blessed reference to the AV */
60 self = newRV_noinc( (SV*)my_array );
61 stash = gv_stashpv( class, TRUE );
62 sv_bless( (SV*)self, stash );
69 # my $vec = Language::Befunge::Vector::XS->new_zeroes( $dims );
71 # Create a new vector of dimension $dims, set to the origin (all
72 # zeroes). LBVXS->new_zeroes(2) is exactly equivalent to LBVXS->new(0, 0).
75 new_zeroes( class, dim )
85 /* create the object and populate it */
87 for ( i=0; i<dim; i++ ) {
89 av_push(my_array, zero);
92 /* return a blessed reference to the AV */
93 self = newRV_noinc( (SV*)my_array );
94 stash = gv_stashpv( class, TRUE );
95 sv_bless( (SV*)self, stash );
102 # my $vec = $v->copy;
104 # Return a new LBVXS object, which has the same dimensions and
117 /* fetch the underlying array of the object */
118 vec_array = (AV*)SvRV(vec);
120 /* create the object and populate it */
122 for ( i=0; i<=av_len(vec_array); i++ ) {
123 val = newSViv( SvIV(*av_fetch(vec_array, i, 0)) );
124 av_push(my_array, val);
127 /* return a blessed reference to the AV */
128 self = newRV_noinc( (SV*)my_array );
129 stash = SvSTASH( (SV*)vec_array );
130 sv_bless( (SV*)self, stash );
141 # my $dims = $vec->get_dims;
143 # Return the number of dimensions, an integer.
151 /* fetch the underlying array of the object */
152 my_array = (AV*)SvRV(self);
154 RETVAL = av_len(my_array) + 1;
160 # my $val = $vec->get_component($dim);
162 # Return the value for dimension $dim.
165 get_component( self, dim )
171 /* fetch the underlying array of the object */
172 my_array = (AV*)SvRV(self);
175 if ( dim < 0 || dim > av_len(my_array) )
176 croak( "No such dimension!" );
178 RETVAL = SvIV( *av_fetch(my_array, dim, 0) );
184 # my @vals = $vec->get_all_components;
186 # Get the values for all dimensions, in order from 0..N.
189 get_all_components( self )
195 /* fetch the underlying array of the object */
196 my_array = (AV*)SvRV(self);
197 dim = av_len(my_array);
199 /* extend the return stack and populate it */
201 for ( i=0; i<=dim; i++ ) {
202 val = SvIV( *av_fetch(my_array, i, 0) );
203 PUSHs( sv_2mortal( newSViv(val) ) );
212 # Set the vector back to the origin, all 0's.
221 /* fetch the underlying array of the object */
222 my_array = (AV*)SvRV(self);
223 dim = av_len(my_array);
225 /* clear each slot */
226 for ( i=0; i<=dim; i++ ) {
228 av_store(my_array, i, zero);
233 # my $val = $vec->set_component( $dim, $value );
235 # Set the value for dimension $dim to $value.
238 set_component( self, dim, value )
245 /* fetch the underlying array of the object */
246 my_array = (AV*)SvRV(self);
249 if ( dim < 0 || dim > av_len(my_array) )
250 croak( "No such dimension!" );
252 /* storing new value */
253 av_store(my_array, dim, newSViv(value));
259 # my $is_within = $vec->bounds_check($begin, $end);
261 # Check whether $vec is within the box defined by $begin and $end.
262 # Return 1 if vector is contained within the box, and 0 otherwise.
265 bounds_check( self, v1, v2 )
270 IV i, mydim, dimv1, dimv2, myval, val1, val2;
275 /* fetch the underlying array of the object */
276 my_array = (AV*)SvRV(self);
277 v1_array = (AV*)SvRV(v1);
278 v2_array = (AV*)SvRV(v2);
279 mydim = av_len(my_array);
280 dimv1 = av_len(v1_array);
281 dimv2 = av_len(v2_array);
284 if ( mydim != dimv1 || mydim != dimv2 )
285 croak("uneven dimensions in bounds check!");
287 /* compare the arrays */
288 for ( i=0 ; i<=dimv1; i++ ) {
289 myval = SvIV( *av_fetch(my_array, i, 0) );
290 val1 = SvIV( *av_fetch(v1_array, i, 0) );
291 val2 = SvIV( *av_fetch(v2_array, i, 0) );
292 if ( myval < val1 || myval > val2 ) {
293 XPUSHs( sv_2mortal( newSViv(0) ) );
297 XPUSHs( sv_2mortal( newSViv(1) ) );
306 # my $vec = $v1->_add($v2);
307 # my $vec = $v1 + $v2;
309 # Return a new LBVXS object, which is the result of $v1 plus $v2.
312 _add( v1, v2, variant )
317 IV dimv1, dimv2, i, val1, val2;
324 /* fetch the underlying array of the object */
325 v1_array = (AV*)SvRV(v1);
326 v2_array = (AV*)SvRV(v2);
327 dimv1 = av_len(v1_array);
328 dimv2 = av_len(v2_array);
331 if ( dimv1 != dimv2 )
332 croak("uneven dimensions in vector addition!");
334 /* create the new array and populate it */
336 for ( i=0 ; i<=dimv1; i++ ) {
337 val1 = SvIV( *av_fetch(v1_array, i, 0) );
338 val2 = SvIV( *av_fetch(v2_array, i, 0) );
339 av_push( my_array, newSViv(val1+val2) );
342 /* return a blessed reference to the AV */
343 self = newRV_noinc( (SV*)my_array );
344 stash = SvSTASH( (SV*)v1_array );
345 sv_bless( (SV*)self, stash );
352 # my $vec = $v1->_substract($v2);
353 # my $vec = $v1 - $v2;
355 # Return a new LBVXS object, which is the result of $v1 minus $v2.
358 _substract( v1, v2, variant )
363 IV dimv1, dimv2, i, val1, val2;
370 /* fetch the underlying array of the object */
371 v1_array = (AV*)SvRV(v1);
372 v2_array = (AV*)SvRV(v2);
373 dimv1 = av_len(v1_array);
374 dimv2 = av_len(v2_array);
377 if ( dimv1 != dimv2 )
378 croak("uneven dimensions in vector addition!");
380 /* create the new array and populate it */
382 for ( i=0 ; i<=dimv1; i++ ) {
383 val1 = SvIV( *av_fetch(v1_array, i, 0) );
384 val2 = SvIV( *av_fetch(v2_array, i, 0) );
385 av_push( my_array, newSViv(val1-val2) );
388 /* return a blessed reference to the AV */
389 self = newRV_noinc( (SV*)my_array );
390 stash = SvSTASH( (SV*)v1_array );
391 sv_bless( (SV*)self, stash );
398 # my $vec = $v1->_invert;
401 # Subtract $v1 from the origin. Effectively, gives the inverse of the
402 # original vector. The new vector is the same distance from the origin,
403 # in the opposite direction.
406 _invert( v1, v2, variant )
417 /* fetch the underlying array of the object */
418 v1_array = (AV*)SvRV(v1);
419 dim = av_len(v1_array);
421 /* create the new array and populate it */
423 for ( i=0 ; i<=dim; i++ ) {
424 val = SvIV( *av_fetch(v1_array, i, 0) );
425 av_push( my_array, newSViv(-val) );
428 /* return a blessed reference to the AV */
429 self = newRV_noinc( (SV*)my_array );
430 stash = SvSTASH( (SV*)v1_array );
431 sv_bless( (SV*)self, stash );
441 # $v1->_add_inplace($v2);
444 # Adds $v2 to $v1, and stores the result back into $v1.
447 _add_inplace( v1, v2, variant )
452 IV dimv1, dimv2, i, val1, val2;
456 /* fetch the underlying array of the object */
457 v1_array = (AV*)SvRV(v1);
458 v2_array = (AV*)SvRV(v2);
459 dimv1 = av_len(v1_array);
460 dimv2 = av_len(v2_array);
463 if ( dimv1 != dimv2 )
464 croak("uneven dimensions in vector addition!");
466 /* update the array slots */
467 for ( i=0 ; i<=dimv1; i++ ) {
468 val1 = SvIV( *av_fetch(v1_array, i, 0) );
469 val2 = SvIV( *av_fetch(v2_array, i, 0) );
470 av_store( v1_array, i, newSViv(val1+val2) );
477 # $v1->_substract_inplace($v2);
480 # Substract $v2 to $v1, and stores the result back into $v1.
483 _substract_inplace( v1, v2, variant )
488 IV dimv1, dimv2, i, val1, val2;
492 /* fetch the underlying array of the object */
493 v1_array = (AV*)SvRV(v1);
494 v2_array = (AV*)SvRV(v2);
495 dimv1 = av_len(v1_array);
496 dimv2 = av_len(v2_array);
499 if ( dimv1 != dimv2 )
500 croak("uneven dimensions in vector addition!");
502 /* update the array slots */
503 for ( i=0 ; i<=dimv1; i++ ) {
504 val1 = SvIV( *av_fetch(v1_array, i, 0) );
505 val2 = SvIV( *av_fetch(v2_array, i, 0) );
506 av_store( v1_array, i, newSViv(val1-val2) );
515 # my $bool = $v1->_compare($v2);
516 # my $bool = $v1 <=> $v2;
518 # Check whether the vectors both point at the same spot. Return 0 if they
519 # do, 1 if they don't.
522 _compare( v1, v2, variant )
528 IV dimv1, dimv2, i, val1, val2;
532 /* fetch the underlying array of the object */
533 v1_array = (AV*)SvRV(v1);
534 v2_array = (AV*)SvRV(v2);
535 dimv1 = av_len(v1_array);
536 dimv2 = av_len(v2_array);
539 if ( dimv1 != dimv2 )
540 croak("uneven dimensions in bounds check!");
542 /* compare the arrays */
543 for ( i=0 ; i<=dimv1; i++ ) {
544 val1 = SvIV( *av_fetch(v1_array, i, 0) );
545 val2 = SvIV( *av_fetch(v2_array, i, 0) );
546 if ( val1 != val2 ) {
547 XPUSHs( sv_2mortal( newSViv(1) ) );
551 XPUSHs( sv_2mortal( newSViv(0) ) );