Skip to content

Commit

Permalink
libgap-api: add NEW_RANGE and GAP_NewRange
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin committed Jul 29, 2021
1 parent 98ec243 commit b3eb056
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 43 deletions.
8 changes: 1 addition & 7 deletions src/exprs.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,7 @@ static Obj EvalRangeExpr(Expr expr)
ErrorQuit("Range: the length of a range must be a small integer",
0, 0);
}
if ( 0 < inc )
range = NEW_RANGE_SSORT();
else
range = NEW_RANGE_NSORT();
SET_LEN_RANGE( range, (high-low) / inc + 1 );
SET_LOW_RANGE( range, low );
SET_INC_RANGE( range, inc );
range = NEW_RANGE((high - low) / inc + 1, low, inc);
}

/* return the range */
Expand Down
8 changes: 1 addition & 7 deletions src/intrprtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2221,13 +2221,7 @@ void IntrListExprEnd(
0, 0);
}

if ( 0 < inc )
list = NEW_RANGE_SSORT();
else
list = NEW_RANGE_NSORT();
SET_LEN_RANGE( list, (high-low) / inc + 1 );
SET_LOW_RANGE( list, low );
SET_INC_RANGE( list, inc );
list = NEW_RANGE((high - low) / inc + 1, low, inc);
}

/* push the list again */
Expand Down
17 changes: 17 additions & 0 deletions src/libgap-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "opers.h"
#include "plist.h"
#include "precord.h"
#include "range.h"
#include "records.h"
#include "streams.h"
#include "stringobj.h"
Expand Down Expand Up @@ -416,6 +417,22 @@ Obj GAP_NewPlist(Int capacity)
return NEW_PLIST(T_PLIST_EMPTY, capacity);
}

static BOOL fitsInIntObj(Int i)
{
return INT_INTOBJ_MIN <= i && i <= INT_INTOBJ_MAX;
}

Obj GAP_NewRange(Int len, Int low, Int inc)
{
if (!inc) return GAP_Fail;
if (!fitsInIntObj(len)) return GAP_Fail;
if (!fitsInIntObj(low)) return GAP_Fail;
if (!fitsInIntObj(inc)) return GAP_Fail;
Int high = low + (len - 1) * inc;
if (!fitsInIntObj(high)) return GAP_Fail;
return NEW_RANGE(len, low, inc);
}


////
//// matrix obj
Expand Down
9 changes: 9 additions & 0 deletions src/libgap-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,15 @@ Obj GAP_ElmList(Obj list, UInt pos);
// Returns a new empty plain list with capacity <capacity>
Obj GAP_NewPlist(Int capacity);

// Returns a new range with <len> elements, starting at <low>, and proceeding
// in increments of <inc>. So the final element in the range will be equal to
// <high> := <low> + <inc> * (<len> - 1).
//
// Note that <inc> must be non-zero, and all three arguments as
// well as the value <high> must fit into a GAP small integer.
// If any of these conditions is violated, then GAP_Fail is returned.
Obj GAP_NewRange(Int len, Int low, Int inc);


////
//// matrix obj
Expand Down
39 changes: 20 additions & 19 deletions src/range.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ static Obj TypeRangeSSort(Obj list)
}


Obj NEW_RANGE(Int len, Int low, Int inc)
{
Obj range;

if (0 < inc)
range = NewBag(T_RANGE_SSORT, 3 * sizeof(Obj));
else
range = NewBag(T_RANGE_NSORT, 3 * sizeof(Obj));
SET_LEN_RANGE(range, len);
SET_LOW_RANGE(range, low);
SET_INC_RANGE(range, inc);

return range;
}


#if !defined(USE_THREADSAFE_COPYING)

/****************************************************************************
Expand Down Expand Up @@ -394,14 +410,8 @@ static Obj ElmsRange(Obj list, Obj poss)
}

/* make the result range */
if ( 0 < inc * GET_INC_RANGE(list) )
elms = NEW_RANGE_SSORT();
else
elms = NEW_RANGE_NSORT();
SET_LEN_RANGE( elms, lenPoss );
SET_LOW_RANGE( elms, INT_INTOBJ( GET_ELM_RANGE( list, pos ) ) );
SET_INC_RANGE( elms, inc * GET_INC_RANGE( list ) );

inc *= GET_INC_RANGE(list);
elms = NEW_RANGE(lenPoss, INT_INTOBJ( GET_ELM_RANGE( list, pos ) ), inc);
}

return elms;
Expand Down Expand Up @@ -765,10 +775,7 @@ Obj Range2Check (
SET_ELM_PLIST( range, 1, first );
}
else {
range = NEW_RANGE_SSORT();
SET_LEN_RANGE( range, (l-f) + 1 );
SET_LOW_RANGE( range, f );
SET_INC_RANGE( range, 1 );
range = NEW_RANGE((l-f) + 1, f, 1);
}
return range;
}
Expand Down Expand Up @@ -805,13 +812,7 @@ Obj Range3Check (
SET_ELM_PLIST( range, 1, first );
}
else {
if ( 0 < i )
range = NEW_RANGE_SSORT();
else
range = NEW_RANGE_NSORT();
SET_LEN_RANGE( range, (l - f) / i + 1 );
SET_LOW_RANGE( range, f );
SET_INC_RANGE( range, i );
range = NEW_RANGE((l - f) / i + 1, f, i);
}
return range;
}
Expand Down
12 changes: 2 additions & 10 deletions src/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,10 @@
**
*F NEW_RANGE() . . . . . . . . . . . . . . . . . . . . . . make a new range
**
** 'NEW_RANGE' returns a new range. Note that you must set the length, the
** low value, and the increment before you can use the range.
** 'NEW_RANGE' returns a new range.
*/
EXPORT_INLINE Obj NEW_RANGE_NSORT(void)
{
return NewBag(T_RANGE_NSORT, 3 * sizeof(Obj));
}
Obj NEW_RANGE(Int len, Int low, Int inc);

EXPORT_INLINE Obj NEW_RANGE_SSORT(void)
{
return NewBag(T_RANGE_SSORT, 3 * sizeof(Obj));
}

/****************************************************************************
**
Expand Down
40 changes: 40 additions & 0 deletions tst/testlibgap/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,42 @@ void lists(void)
assert(ret == 0);
}

void ranges(void)
{
const int len = 5;
int i;
Obj r, val;

r = GAP_NewRange(len, 1, 1); // [1..5]
assert(GAP_IsList(r));
assert(GAP_LenList(r) == len);
for (i = 1; i <= len; ++i) {
val = GAP_ElmList(r, i);
assert(GAP_IsSmallInt(val));
assert(GAP_EQ(val, GAP_NewObjIntFromInt(i)));
}

r = GAP_NewRange(len, 1, 3); // [1,4..16]
assert(GAP_IsList(r));
assert(GAP_LenList(r) == len);
for (i = 1; i <= len; ++i) {
val = GAP_ElmList(r, i);
assert(GAP_IsSmallInt(val));
assert(GAP_EQ(val, GAP_NewObjIntFromInt(1 + (i-1) * 3)));
}


r = GAP_NewRange(len, 10, -2); // [10,8..2]
assert(GAP_IsList(r));
assert(GAP_LenList(r) == len);
for (i = 1; i <= len; ++i) {
val = GAP_ElmList(r, i);
assert(GAP_IsSmallInt(val));
assert(GAP_EQ(val, GAP_NewObjIntFromInt(10 - 2*(i-1))));
}

}

void matrices(void)
{
Obj mat, val, row, ret;
Expand Down Expand Up @@ -213,6 +249,10 @@ int main(int argc, char ** argv)
lists();
printf("success\n");

printf("# Testing ranges... ");
ranges();
printf("success\n");

printf("# Testing matrices... ");
matrices();
printf("success\n");
Expand Down
1 change: 1 addition & 0 deletions tst/testlibgap/api.expect
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Testing strings... success
# Testing records... success
# Testing lists... success
# Testing ranges... success
# Testing matrices... success
# Testing integers... success
# Testing operations... success
Expand Down

0 comments on commit b3eb056

Please sign in to comment.