diff --git a/src/libgap-api.c b/src/libgap-api.c index 6d9ea40683..d0662aeeae 100644 --- a/src/libgap-api.c +++ b/src/libgap-api.c @@ -13,6 +13,7 @@ #include #include "libgap-api.h" +#include "libgap_intern.h" #include "ariths.h" #include "bool.h" @@ -27,6 +28,7 @@ #include "integer.h" #include "lists.h" #include "macfloat.h" +#include "modules.h" #include "opers.h" #include "plist.h" #include "precord.h" @@ -332,6 +334,59 @@ Obj GAP_NewPlist(Int capacity) return NEW_PLIST(T_PLIST_EMPTY, capacity); } + +//// +//// matrix obj +//// + +static Obj IsMatrixObjFilt; +static Obj NrRowsAttr; +static Obj NrColsAttr; + +// Returns 1 if is a GAP matrix obj, 0 if not. +int GAP_IsMatrixObj(Obj obj) +{ + return obj && DoFilter(IsMatrixObjFilt, obj) == True; +} + +// Returns the number of rows of the given GAP matrix obj. +// If is not a GAP matrix obj, an error may be raised. +UInt GAP_NrRows(Obj mat) +{ + Obj nrows = CALL_1ARGS(NrRowsAttr, mat); + return UInt_ObjInt(nrows); +} + +// Returns the number of columns of the given GAP matrix obj. +// If is not a GAP matrix obj, an error may be raised. +UInt GAP_NrCols(Obj mat) +{ + Obj ncols = CALL_1ARGS(NrColsAttr, mat); + return UInt_ObjInt(ncols); +} + +// Assign at position into the GAP matrix obj . +// If is zero, then this unbinds the list entry. +// If is not a GAP matrix obj, an error may be raised. +void GAP_AssMat(Obj mat, UInt row, UInt col, Obj val) +{ + Obj r = ObjInt_UInt(row); + Obj c = ObjInt_UInt(col); + ASS_MAT(mat, r, c, val); +} + +// Returns the element at the , in the GAP matrix obj . +// Returns 0 if or are out of bounds, i.e., if either +// is zero, or larger than the number of rows respectively columns of the list. +// If is not a GAP matrix obj, an error may be raised. +Obj GAP_ElmMat(Obj mat, UInt row, UInt col) +{ + Obj r = ObjInt_UInt(row); + Obj c = ObjInt_UInt(col); + return ELM_MAT(mat, r, c); +} + + //// //// records //// @@ -465,3 +520,34 @@ void GAP_Error_Postjmp_Returning_(void) EnterStackCount = -EnterStackCount; } } + + +/**************************************************************************** +** +*F InitKernel( ) . . . . . . . . initialise kernel data structures +*/ +static Int InitKernel(StructInitInfo * module) +{ + ImportFuncFromLibrary("IsMatrixObj", &IsMatrixObjFilt); + ImportFuncFromLibrary("NrRows", &NrRowsAttr); + ImportFuncFromLibrary("NrCols", &NrColsAttr); + + return 0; +} + +/**************************************************************************** +** +*F InitInfoLibGapApi() . . . . . . . . . . . . . . . table of init functions +*/ +static StructInitInfo module = { + // init struct using C99 designated initializers; for a full list of + // fields, please refer to the definition of StructInitInfo + .type = MODULE_BUILTIN, + .name = "libgap", + .initKernel = InitKernel, +}; + +StructInitInfo * InitInfoLibGapApi ( void ) +{ + return &module; +} diff --git a/src/libgap-api.h b/src/libgap-api.h index 41b21e1792..071bce5b8f 100644 --- a/src/libgap-api.h +++ b/src/libgap-api.h @@ -325,7 +325,7 @@ UInt GAP_LenList(Obj list); // If is not a GAP list, an error may be raised. void GAP_AssList(Obj list, UInt pos, Obj val); -// Returns the element at the position in the list . +// Returns the element at the position in the GAP list . // Returns 0 if there is no entry at the given position. // Also returns 0 if is out of bounds, i.e., if is zero, // or larger than the length of the list. @@ -336,6 +336,33 @@ Obj GAP_ElmList(Obj list, UInt pos); Obj GAP_NewPlist(Int capacity); +//// +//// matrix obj +//// + +// Returns 1 if is a GAP matrix obj, 0 if not. +int GAP_IsMatrixObj(Obj obj); + +// Returns the number of rows of the given GAP matrix obj. +// If is not a GAP matrix obj, an error may be raised. +UInt GAP_NrRows(Obj mat); + +// Returns the number of columns of the given GAP matrix obj. +// If is not a GAP matrix obj, an error may be raised. +UInt GAP_NrCols(Obj mat); + +// Assign at position into the GAP matrix obj . +// If is zero, then this unbinds the list entry. +// If is not a GAP matrix obj, an error may be raised. +void GAP_AssMat(Obj mat, UInt row, UInt col, Obj val); + +// Returns the element at the , in the GAP matrix obj . +// Returns 0 if or are out of bounds, i.e., if either +// is zero, or larger than the number of rows respectively columns of the list. +// If is not a GAP matrix obj, an error may be raised. +Obj GAP_ElmMat(Obj mat, UInt row, UInt col); + + //// //// records //// diff --git a/src/libgap_intern.h b/src/libgap_intern.h new file mode 100644 index 0000000000..294c9d9744 --- /dev/null +++ b/src/libgap_intern.h @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** This file is part of GAP, a system for computational discrete algebra. +** +** Copyright of GAP belongs to its developers, whose names are too numerous +** to list here. Please refer to the COPYRIGHT file for details. +** +** SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef LIBGAP_INTERN_H +#define LIBGAP_INTERN_H + +#include "system.h" + + +/**************************************************************************** +** +*F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * * +*/ + +/**************************************************************************** +** +*F InitInfoLibGapApi() . . . . . . . . . . . . . . . table of init functions +*/ +StructInitInfo * InitInfoLibGapApi(void); + + +#endif // LIBGAP_INTERN_H diff --git a/src/modules_builtin.c b/src/modules_builtin.c index 3d34bc1c6e..ec4b582f3b 100644 --- a/src/modules_builtin.c +++ b/src/modules_builtin.c @@ -16,6 +16,7 @@ #include "info.h" #include "intfuncs.h" #include "iostream.h" +#include "libgap_intern.h" #include "objccoll.h" #include "objset.h" #include "profile.h" @@ -139,6 +140,9 @@ const InitInfoFunc InitFuncsBuiltinModules[] = { InitInfoThreadAPI, InitInfoAObjects, InitInfoSerialize, +#else + // libgap API + InitInfoLibGapApi, #endif 0 diff --git a/tst/testlibgap/api.c b/tst/testlibgap/api.c index 894601aa54..6b5598eb0f 100644 --- a/tst/testlibgap/api.c +++ b/tst/testlibgap/api.c @@ -9,8 +9,11 @@ * TODO: Test error handling * */ + #include "common.h" +#include + void records(void) { @@ -20,9 +23,9 @@ void records(void) nam = GAP_MakeString("key"); val = GAP_MakeString("value"); - assert(GAP_IsRecord(r) != 0); - assert(GAP_IsRecord(0) == 0); - assert(GAP_IsRecord(val) == 0); + assert(GAP_IsRecord(r)); + assert(!GAP_IsRecord(0)); + assert(!GAP_IsRecord(val)); GAP_AssRecord(r, nam, val); ret = GAP_ElmRecord(r, nam); @@ -40,9 +43,9 @@ void lists(void) val = GAP_MakeString("value"); val2 = GAP_NewPrecord(5); - assert(GAP_IsList(r) != 0); - assert(GAP_IsList(0) == 0); - assert(GAP_IsList(val2) == 0); + assert(GAP_IsList(r)); + assert(!GAP_IsList(0)); + assert(!GAP_IsList(val2)); GAP_AssList(r, 1, val); ret = GAP_ElmList(r, 1); @@ -56,21 +59,44 @@ void lists(void) assert(ret == 0); } +void matrices(void) +{ + Obj mat, val, row, ret; + + mat = GAP_NewPlist(1); + val = INTOBJ_INT(42); + + assert(!GAP_IsMatrixObj(mat)); // empty list, not yet a matrix + assert(!GAP_IsMatrixObj(0)); + assert(!GAP_IsMatrixObj(val)); + + row = GAP_NewPlist(2); + GAP_AssList(row, 1, INTOBJ_INT(1)); + GAP_AssList(row, 2, INTOBJ_INT(2)); + GAP_AssList(mat, 1, row); + assert(!GAP_IsMatrixObj(row)); + assert(GAP_IsMatrixObj(mat)); + + GAP_AssMat(mat, 1, 1, val); + ret = GAP_ElmMat(mat, 1, 1); + assert(ret == val); +} + void strings(void) { const char *ts = "Hello, world!"; Obj r, r2; - assert(GAP_IsString(0) == 0); + assert(!GAP_IsString(0)); r = GAP_MakeString(ts); assert(GAP_LenString(r) == strlen(ts)); - assert(GAP_IsString(r) != 0); + assert(GAP_IsString(r)); assert(strcmp(GAP_CSTR_STRING(r),ts) == 0); r2 = GAP_MakeImmString(ts); assert(GAP_LenString(r2) == strlen(ts)); - assert(GAP_IsString(r2) != 0); + assert(GAP_IsString(r2)); assert(strcmp(GAP_CSTR_STRING(r2),ts) == 0); } @@ -79,21 +105,21 @@ void integers(void) Obj i1,i2,o; o = GAP_MakeString("test"); - assert(GAP_IsInt(o) == 0); - assert(GAP_IsSmallInt(o) == 0); - assert(GAP_IsLargeInt(o) == 0); + assert(!GAP_IsInt(o)); + assert(!GAP_IsSmallInt(o)); + assert(!GAP_IsLargeInt(o)); const UInt limbs[1] = { 0 }; i1 = GAP_MakeObjInt(limbs, 1); - assert(GAP_IsInt(i1) != 0); - assert(GAP_IsSmallInt(i1) != 0); - assert(GAP_IsLargeInt(i1) == 0); + assert(GAP_IsInt(i1)); + assert(GAP_IsSmallInt(i1)); + assert(!GAP_IsLargeInt(i1)); const UInt limbs2[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; i2 = GAP_MakeObjInt(limbs2, -8); - assert(GAP_IsInt(i2) != 0); - assert(GAP_IsSmallInt(i2) == 0); - assert(GAP_IsLargeInt(i2) != 0); + assert(GAP_IsInt(i2)); + assert(!GAP_IsSmallInt(i2)); + assert(GAP_IsLargeInt(i2)); assert(GAP_SizeInt(i2) == -8); assert(memcmp(GAP_AddrInt(i2), limbs2, sizeof(UInt) * 8) == 0); @@ -112,15 +138,15 @@ void operations(void) b = GAP_MakeObjInt(limbs2, -8); l = GAP_NewPlist(2); - assert(GAP_EQ(a, a) != 0); - assert(GAP_EQ(a, b) == 0); + assert(GAP_EQ(a, a)); + assert(!GAP_EQ(a, b)); - assert(GAP_LT(a, b) == 0); - assert(GAP_LT(b, a) != 0); + assert(!GAP_LT(a, b)); + assert(GAP_LT(b, a)); - assert(GAP_IN(a, l) == 0); + assert(!GAP_IN(a, l)); - assert(GAP_EQ(GAP_SUM(a, b), GAP_SUM(b,a)) != 0); + assert(GAP_EQ(GAP_SUM(a, b), GAP_SUM(b,a))); // TODO: More sensible test than just executing? // TODO: More objects? @@ -145,7 +171,7 @@ void globalvars(void) // Hopefully this always exists. a = GAP_ValueGlobalVariable("GAPInfo"); - assert(GAP_IsRecord(a) != 0); + assert(GAP_IsRecord(a)); x = GAP_CanAssignGlobalVariable("GAPInfo"); assert(x == 0); @@ -175,6 +201,10 @@ int main(int argc, char ** argv) lists(); printf("success\n"); + printf("# Testing matrices... "); + matrices(); + printf("success\n"); + printf("# Testing integers... "); integers(); printf("success\n"); diff --git a/tst/testlibgap/api.expect b/tst/testlibgap/api.expect index de0af79e74..8c7c622fe2 100644 --- a/tst/testlibgap/api.expect +++ b/tst/testlibgap/api.expect @@ -2,6 +2,7 @@ # Testing strings... success # Testing records... success # Testing lists... success +# Testing matrices... success # Testing integers... success # Testing operations... success # Testing global variables... success