Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn NameFunction into an attribute so that custom function objects can implement support for it #3430

Merged
merged 1 commit into from
May 4, 2019
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
100 changes: 47 additions & 53 deletions lib/function.g
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,48 @@ DeclareCategoryKernel( "IsOperation",
IS_OPERATION );


#############################################################################
##
#O NameFunction( <func> ) . . . . . . . . . . . . . . . name of a function
##
## <#GAPDoc Label="NameFunction">
## <ManSection>
## <Attr Name="NameFunction" Arg='func'/>
##
## <Description>
## returns the name of a function. For operations, this is the name used in
## their declaration. For functions, this is the variable name they were
## first assigned to. (For some internal functions, this might be a name
## <E>different</E> from the name that is documented.)
## If no such name exists, the string <C>"unknown"</C> is returned.
## <P/>
## <Example><![CDATA[
## gap> NameFunction(SylowSubgroup);
## "SylowSubgroup"
## gap> Blubberflutsch:=x->x;;
## gap> HasNameFunction(Blubberflutsch);
## true
## gap> NameFunction(Blubberflutsch);
## "Blubberflutsch"
## gap> a:=Blubberflutsch;;
## gap> NameFunction(a);
## "Blubberflutsch"
## gap> SetNameFunction(a, "f");
## gap> NameFunction(a);
## "f"
## gap> HasNameFunction(x->x);
## false
## gap> NameFunction(x->x);
## "unknown"
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
##
DeclareAttributeKernel("NameFunction", IS_OBJECT, NAME_FUNC);


#############################################################################
##
#V FunctionsFamily . . . . . . . . . . . . . . . . . . . family of functions
Expand Down Expand Up @@ -105,6 +147,8 @@ BIND_GLOBAL( "FunctionsFamily", NewFamily( "FunctionsFamily", IsFunction ) );
##
BIND_GLOBAL( "TYPE_FUNCTION", NewType( FunctionsFamily,
IsFunction and IsInternalRep ) );
BIND_GLOBAL( "TYPE_FUNCTION_WITH_NAME", NewType( FunctionsFamily,
IsFunction and IsInternalRep and HasNameFunction ) );


#############################################################################
Expand All @@ -122,59 +166,9 @@ BIND_GLOBAL( "TYPE_OPERATION",
NewType( FunctionsFamily,
IsFunction and IsOperation and IsInternalRep ) );


#############################################################################
##
#O NameFunction( <func> ) . . . . . . . . . . . . . . . name of a function
##
## <#GAPDoc Label="NameFunction">
## <ManSection>
## <Oper Name="NameFunction" Arg='func'/>
##
## <Description>
## returns the name of a function. For operations, this is the name used in
## their declaration. For functions, this is the variable name they were
## first assigned to. (For some internal functions, this might be a name
## <E>different</E> from the name that is documented.)
## If no such name exists, the string <C>"unknown"</C> is returned.
## <P/>
## <Example><![CDATA[
## gap> NameFunction(SylowSubgroup);
## "SylowSubgroup"
## gap> Blubberflutsch:=x->x;;
## gap> NameFunction(Blubberflutsch);
## "Blubberflutsch"
## gap> a:=Blubberflutsch;;
## gap> NameFunction(a);
## "Blubberflutsch"
## gap> NameFunction(x->x);
## "unknown"
## gap> NameFunction(NameFunction);
## "NameFunction"
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
##
DeclareOperationKernel("NameFunction", [IS_OBJECT], NAME_FUNC);


#############################################################################
##
#O SetNameFunction( <func>, <name> ) . . . . . . . .set name of a function
##
## <ManSection>
## <Oper Name="SetNameFunction" Arg='func, name'/>
##
## <Description>
## changes the name of a function. This only changes the name stored in
## the function and used (for instance) in profiling. It does not change
## any assignments to global variables.
## </Description>
## </ManSection>
##
DeclareOperationKernel( "SetNameFunction", [IS_OBJECT, IS_STRING], SET_NAME_FUNC );
BIND_GLOBAL( "TYPE_OPERATION_WITH_NAME",
NewType( FunctionsFamily,
IsFunction and IsOperation and IsInternalRep and HasNameFunction ) );


#############################################################################
Expand Down
2 changes: 2 additions & 0 deletions lib/function.gi
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,5 @@ InstallMethod( ViewString,
function(op)
return VIEW_STRING_OPERATION(op);
end);

InstallMethod( SetNameFunction, [IsFunction and IsInternalRep, IS_STRING], SET_NAME_FUNC );
37 changes: 28 additions & 9 deletions src/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,14 +965,18 @@ Obj ArgStringToList(const Char *nams_c) {
*/
static Obj TYPE_FUNCTION;
static Obj TYPE_OPERATION;
static Obj TYPE_FUNCTION_WITH_NAME;
static Obj TYPE_OPERATION_WITH_NAME;

static Obj TypeFunction(Obj func)
{
return ( IS_OPERATION(func) ? TYPE_OPERATION : TYPE_FUNCTION );
if (NAME_FUNC(func) == 0)
return (IS_OPERATION(func) ? TYPE_OPERATION : TYPE_FUNCTION);
else
return (IS_OPERATION(func) ? TYPE_OPERATION_WITH_NAME : TYPE_FUNCTION_WITH_NAME);
}



/****************************************************************************
**
*F PrintFunction( <func> ) . . . . . . . . . . . . . . . print a function
Expand Down Expand Up @@ -1224,12 +1228,12 @@ static Obj FuncCALL_FUNC_LIST_WRAP(Obj self, Obj func, Obj list)

/****************************************************************************
**
*F FuncNAME_FUNC( <self>, <func> ) . . . . . . . . . . . name of a function
*F AttrNAME_FUNC( <self>, <func> ) . . . . . . . . . . . name of a function
*/
static Obj NAME_FUNC_Oper;
static Obj NameFuncAttr;
static Obj SET_NAME_FUNC_Oper;

static Obj FuncNAME_FUNC(Obj self, Obj func)
static Obj AttrNAME_FUNC(Obj self, Obj func)
{
Obj name;

Expand All @@ -1243,7 +1247,7 @@ static Obj FuncNAME_FUNC(Obj self, Obj func)
return name;
}
else {
return DoOperation1Args( self, func );
return DoAttribute( self, func );
}
}

Expand Down Expand Up @@ -1659,6 +1663,18 @@ static StructGVarFilt GVarFilts [] = {
};


/****************************************************************************
**
*V GVarAttrs . . . . . . . . . . . . . . . . . list of attributes to export
*/
static StructGVarAttr GVarAttrs [] = {

GVAR_ATTR(NAME_FUNC, "func", &NameFuncAttr),
{ 0, 0, 0, 0, 0 }

};


/****************************************************************************
**
*V GVarOpers . . . . . . . . . . . . . . . . . list of operations to export
Expand All @@ -1667,7 +1683,6 @@ static StructGVarOper GVarOpers [] = {

GVAR_OPER(CALL_FUNC_LIST, 2, "func, list", &CallFuncListOper),
GVAR_OPER(CALL_FUNC_LIST_WRAP, 2, "func, list", &CallFuncListWrapOper),
GVAR_OPER(NAME_FUNC, 1, "func", &NAME_FUNC_Oper),
GVAR_OPER(SET_NAME_FUNC, 2, "func, name", &SET_NAME_FUNC_Oper),
GVAR_OPER(NARG_FUNC, 1, "func", &NARG_FUNC_Oper),
GVAR_OPER(NAMS_FUNC, 1, "func", &NAMS_FUNC_Oper),
Expand Down Expand Up @@ -1722,10 +1737,13 @@ static Int InitKernel (
/* install the type functions */
ImportGVarFromLibrary( "TYPE_FUNCTION", &TYPE_FUNCTION );
ImportGVarFromLibrary( "TYPE_OPERATION", &TYPE_OPERATION );
ImportGVarFromLibrary( "TYPE_FUNCTION_WITH_NAME", &TYPE_FUNCTION_WITH_NAME );
ImportGVarFromLibrary( "TYPE_OPERATION_WITH_NAME", &TYPE_OPERATION_WITH_NAME );
TypeObjFuncs[ T_FUNCTION ] = TypeFunction;

/* init filters and functions */
InitHdlrFiltsFromTable( GVarFilts );
InitHdlrAttrsFromTable( GVarAttrs );
InitHdlrOpersFromTable( GVarOpers );
InitHdlrFuncsFromTable( GVarFuncs );

Expand Down Expand Up @@ -1777,10 +1795,11 @@ static Int InitKernel (
**
*F InitLibrary( <module> ) . . . . . . . initialise library data structures
*/
static Int InitLibrary (
StructInitInfo * module ){
static Int InitLibrary(StructInitInfo * module)
{
/* init filters and functions */
InitGVarFiltsFromTable( GVarFilts );
InitGVarAttrsFromTable( GVarAttrs );
InitGVarOpersFromTable( GVarOpers );
InitGVarFuncsFromTable( GVarFuncs );

Expand Down
10 changes: 7 additions & 3 deletions tst/testinstall/callfunc.tst
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,23 @@ true
# test overloading CallFuncList
gap> fam := NewFamily("CustomFunctionFamily");;
gap> cat := NewCategory("IsCustomFunction", IsFunction);;
gap> type := NewType(fam, cat and IsPositionalObjectRep);;
gap> type := NewType(fam, cat and IsAttributeStoringRep);;
gap> result := fail;;
gap> InstallMethod(CallFuncList,[cat,IsList],function(func,args) result:=args; return args; end);
gap> InstallMethod(NameFunction, [cat], f -> f![1]);
gap> InstallMethod(NameFunction, [cat], f -> "myName");
gap> InstallMethod(NamesLocalVariablesFunction, [cat], f -> ["arg"]);
gap> InstallMethod(NumberArgumentsFunction, [cat], f -> -1);

#
gap> o := Objectify(type,["myName"]);;
gap> o := Objectify(type, rec());;
gap> Display(o);
<object>
gap> HasNameFunction(o);
false
gap> NameFunction(o);
"myName"
gap> HasNameFunction(o);
true
gap> NamesLocalVariablesFunction(o);
[ "arg" ]
gap> NumberArgumentsFunction(o);
Expand Down