Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions lib/filter.g
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,7 @@ end);
## We handle IsObject as a special case, as it is equal to ReturnTrue,
## as all objects satisfy IsObject!
##
BIND_GLOBAL( "IsFilter",
x -> IS_IDENTICAL_OBJ(x, IS_OBJECT)
or ( IS_OPERATION( x ) and NARG_FUNC( x ) = 1
and ( (FLAG1_FILTER( x ) <> 0 and FLAGS_FILTER(x) <> false)
or IS_ELEMENTARY_FILTER(x) ) ) );
BIND_GLOBAL( "IsFilter", IS_FILTER );


## Global Rank declarations
Expand Down
32 changes: 19 additions & 13 deletions src/opers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,7 @@ Obj NewFilter (
flags = NEW_FLAGS( flag1 );
SET_ELM_FLAGS( flags, flag1, True );
SET_FLAGS_FILT(getter, flags);
SET_IS_FILTER(getter);
CHANGED_BAG(getter);

setter = NewSetterFilter( getter );
Expand All @@ -1205,6 +1206,11 @@ Obj NewFilter (
return getter;
}

Obj FuncIS_FILTER(Obj self, Obj obj)
{
return IS_FILTER(obj) ? True : False;
}


/****************************************************************************
**
Expand Down Expand Up @@ -1248,6 +1254,9 @@ Obj NewAndFilter (
if ( oper2 == ReturnTrueFilter )
return oper1;

if ( oper1 == oper2 )
return oper1;

str_len = GET_LEN_STRING(NAME_FUNC(oper1)) + GET_LEN_STRING(NAME_FUNC(oper2)) + 8;
str = NEW_STRING(str_len);
s = CSTR_STRING(str);
Expand All @@ -1267,6 +1276,7 @@ Obj NewAndFilter (
SET_FLAGS_FILT(getter, flags);
SET_SETTR_FILT(getter, INTOBJ_INT(0xBADBABE));
SET_TESTR_FILT(getter, INTOBJ_INT(0xBADBABE));
SET_IS_FILTER(getter);
CHANGED_BAG(getter);

return getter;
Expand All @@ -1289,12 +1299,6 @@ Obj ReturnTrueFilter;
**
*F NewReturnTrueFilter() . . . . . . . . . . create a new return true filter
*/
Obj TesterReturnTrueFilter (
Obj getter )
{
return getter;
}

Obj DoSetReturnTrueFilter (
Obj self,
Obj obj,
Expand Down Expand Up @@ -1334,7 +1338,6 @@ Obj NewReturnTrueFilter ( void )
{
Obj getter;
Obj setter;
Obj tester;
Obj flags;

getter = NewFunctionT( T_FUNCTION, sizeof(OperBag),
Expand All @@ -1344,15 +1347,15 @@ Obj NewReturnTrueFilter ( void )
SET_FLAG2_FILT(getter, INTOBJ_INT(0));
flags = NEW_FLAGS( 0 );
SET_FLAGS_FILT(getter, flags);
SET_IS_FILTER(getter);
CHANGED_BAG(getter);

setter = SetterReturnTrueFilter( getter );
SET_SETTR_FILT(getter, setter);
CHANGED_BAG(getter);

tester = TesterReturnTrueFilter( getter );
SET_TESTR_FILT(getter, tester);
CHANGED_BAG(getter);
// the tester also returns true, so we can reuse the getter
SET_TESTR_FILT(getter, getter);

return getter;
}
Expand Down Expand Up @@ -2810,6 +2813,7 @@ static Obj MakeTester( Obj name, Int flag1, Int flag2)
SET_FLAGS_FILT(tester, flags);
SET_SETTR_FILT(tester, 0);
SET_TESTR_FILT(tester, ReturnTrueFilter);
SET_IS_FILTER(tester);
CHANGED_BAG(tester);
return tester;
}
Expand Down Expand Up @@ -3105,7 +3109,8 @@ Obj NewProperty (
SET_FLAGS_FILT(getter, flags);
SET_SETTR_FILT(getter, setter);
SET_TESTR_FILT(getter, tester);
SET_ENABLED_ATTR(getter,1);
SET_ENABLED_ATTR(getter, 1);
SET_IS_FILTER(getter);
CHANGED_BAG(getter);

/*N 1996/06/28 mschoene bad hack see comment in <setter> */
Expand Down Expand Up @@ -3214,7 +3219,7 @@ void SaveOperationExtras (
SaveSubObj(header->flags);
SaveSubObj(header->setter);
SaveSubObj(header->tester);
SaveSubObj(header->enabled);
SaveSubObj(header->extra);
for (UInt i = 0; i <= 7; i++)
SaveSubObj(header->methods[i]);
#ifdef HPCGAP
Expand Down Expand Up @@ -3245,7 +3250,7 @@ void LoadOperationExtras (
header->flags = LoadSubObj();
header->setter = LoadSubObj();
header->tester = LoadSubObj();
header->enabled = LoadSubObj();
header->extra = LoadSubObj();
for (UInt i = 0; i <= 7; i++)
header->methods[i] = LoadSubObj();
#ifdef HPCGAP
Expand Down Expand Up @@ -3990,6 +3995,7 @@ static StructGVarFunc GVarFuncs [] = {
GVAR_FUNC(CLEAR_CACHE_INFO, 0, ""),
GVAR_FUNC(SET_ATTRIBUTE_STORING, 2, "attr, val"),
GVAR_FUNC(DO_NOTHING_SETTER, 2, "obj, val"),
GVAR_FUNC(IS_FILTER, 1, "obj"),
GVAR_FUNC(IS_AND_FILTER, 1, "filter"),
GVAR_FUNC(IS_CONSTRUCTOR, 1, "x"),
GVAR_FUNC(COMPACT_TYPE_IDS, 0, ""),
Expand Down
60 changes: 51 additions & 9 deletions src/opers.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,20 @@ typedef struct {
// cache of an operation
Obj cache[8];

// 1 if the operation is an attribute and storing is enabled (default) else 0
Obj enabled;
// small integer encoding a set of bit flags with information about the
// operation, see OperExtras below
//
// note: this is encoded as an integer object, and not just stored
// directly as C bitfield, to avoid the need for a custom marking function
// which does not call 'MarkBag' on this field (while that would be safe
// to do with GASMAN, it may not be in alternate GC implementations)
Obj extra;
} OperBag;

enum OperExtras {
OPER_IS_ATTR_STORING = (1 << 0),
OPER_IS_FILTER = (1 << 1),
};

/****************************************************************************
**
Expand All @@ -63,9 +73,9 @@ extern Obj TRY_NEXT_METHOD;
**
*F IS_OPERATION( <obj> ) . . . . . . . . . . check if object is an operation
*/
static inline Int IS_OPERATION(Obj func)
static inline Int IS_OPERATION(Obj obj)
{
return TNUM_OBJ(func) == T_FUNCTION && SIZE_OBJ(func) == sizeof(OperBag);
return TNUM_OBJ(obj) == T_FUNCTION && SIZE_OBJ(obj) == sizeof(OperBag);
}


Expand Down Expand Up @@ -202,19 +212,51 @@ static inline void SET_CACHE_OPER(Obj oper, Int i, Obj x)
*/
static inline Int ENABLED_ATTR(Obj oper)
{
Obj val = CONST_OPER(oper)->enabled;
return val ? INT_INTOBJ(val) : 0;
Obj val = CONST_OPER(oper)->extra;
Int v = val ? INT_INTOBJ(val) : 0;
return v & OPER_IS_ATTR_STORING;
}


/****************************************************************************
**
*F SET_ENABLED_ATTR( <oper>, <new> ) . set a new value that records whether
*F SET_ENABLED_ATTR( <oper>, <on> ) . set a new value that records whether
** storing is enabled for an operation
*/
static inline void SET_ENABLED_ATTR(Obj oper, Int x)
static inline void SET_ENABLED_ATTR(Obj oper, Int on)
{
Obj val = CONST_OPER(oper)->extra;
Int v = val ? INT_INTOBJ(val) : 0;
if (on)
v |= OPER_IS_ATTR_STORING;
else
v &= ~OPER_IS_ATTR_STORING;
OPER(oper)->extra = INTOBJ_INT(v);
}

/****************************************************************************
**
*F IS_FILTER( <oper> ) . . . . . . . . . . . . . check if object is a filter
*/
static inline Int IS_FILTER(Obj oper)
{
if (!IS_OPERATION(oper))
return 0;
Obj val = CONST_OPER(oper)->extra;
Int v = val ? INT_INTOBJ(val) : 0;
return v & OPER_IS_FILTER;
}

/****************************************************************************
**
*F SET_IS_FILTER( <oper> ) . . . . . . . . . . . mark operation as a filter
*/
static inline void SET_IS_FILTER(Obj oper)
{
OPER(oper)->enabled = INTOBJ_INT(x);
Obj val = CONST_OPER(oper)->extra;
Int v = val ? INT_INTOBJ(val) : 0;
v |= OPER_IS_FILTER;
OPER(oper)->extra = INTOBJ_INT(v);
}


Expand Down