diff --git a/lib/function.g b/lib/function.g index a48381e293..cb5f39e4bd 100644 --- a/lib/function.g +++ b/lib/function.g @@ -75,6 +75,48 @@ DeclareCategoryKernel( "IsOperation", IS_OPERATION ); +############################################################################# +## +#O NameFunction( ) . . . . . . . . . . . . . . . name of a function +## +## <#GAPDoc Label="NameFunction"> +## +## +## +## +## 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 +## different from the name that is documented.) +## If no such name exists, the string "unknown" is returned. +##

+## 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" +## ]]> +## +## +## <#/GAPDoc> +## +## +DeclareAttributeKernel("NameFunction", IS_OBJECT, NAME_FUNC); + + ############################################################################# ## #V FunctionsFamily . . . . . . . . . . . . . . . . . . . family of functions @@ -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 ) ); ############################################################################# @@ -122,59 +166,9 @@ BIND_GLOBAL( "TYPE_OPERATION", NewType( FunctionsFamily, IsFunction and IsOperation and IsInternalRep ) ); - -############################################################################# -## -#O NameFunction( ) . . . . . . . . . . . . . . . name of a function -## -## <#GAPDoc Label="NameFunction"> -## -## -## -## -## 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 -## different from the name that is documented.) -## If no such name exists, the string "unknown" is returned. -##

-## 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" -## ]]> -## -## -## <#/GAPDoc> -## -## -DeclareOperationKernel("NameFunction", [IS_OBJECT], NAME_FUNC); - - -############################################################################# -## -#O SetNameFunction( , ) . . . . . . . .set name of a function -## -## -## -## -## -## 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. -## -## -## -DeclareOperationKernel( "SetNameFunction", [IS_OBJECT, IS_STRING], SET_NAME_FUNC ); +BIND_GLOBAL( "TYPE_OPERATION_WITH_NAME", + NewType( FunctionsFamily, + IsFunction and IsOperation and IsInternalRep and HasNameFunction ) ); ############################################################################# diff --git a/lib/function.gi b/lib/function.gi index 6b7ca161b1..9d02cc8e69 100644 --- a/lib/function.gi +++ b/lib/function.gi @@ -112,3 +112,5 @@ InstallMethod( ViewString, function(op) return VIEW_STRING_OPERATION(op); end); + +InstallMethod( SetNameFunction, [IsFunction and IsInternalRep, IS_STRING], SET_NAME_FUNC ); diff --git a/src/calls.c b/src/calls.c index 7667755b8c..453453ad84 100644 --- a/src/calls.c +++ b/src/calls.c @@ -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( ) . . . . . . . . . . . . . . . print a function @@ -1224,12 +1228,12 @@ static Obj FuncCALL_FUNC_LIST_WRAP(Obj self, Obj func, Obj list) /**************************************************************************** ** -*F FuncNAME_FUNC( , ) . . . . . . . . . . . name of a function +*F AttrNAME_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; @@ -1243,7 +1247,7 @@ static Obj FuncNAME_FUNC(Obj self, Obj func) return name; } else { - return DoOperation1Args( self, func ); + return DoAttribute( self, func ); } } @@ -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 @@ -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), @@ -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 ); @@ -1777,10 +1795,11 @@ static Int InitKernel ( ** *F InitLibrary( ) . . . . . . . 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 ); diff --git a/tst/testinstall/callfunc.tst b/tst/testinstall/callfunc.tst index a94faf38bb..23d245e7cd 100644 --- a/tst/testinstall/callfunc.tst +++ b/tst/testinstall/callfunc.tst @@ -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); +gap> HasNameFunction(o); +false gap> NameFunction(o); "myName" +gap> HasNameFunction(o); +true gap> NamesLocalVariablesFunction(o); [ "arg" ] gap> NumberArgumentsFunction(o);