From 442e1038c375dca39d2fdd1c703f68b73f98060f Mon Sep 17 00:00:00 2001 From: Steve Linton Date: Wed, 6 Jun 2018 13:16:25 +0100 Subject: [PATCH] Reorder methods after new implications are added Many GAP methods get rank adjustments based on the rank of some filter, e.g, `RankFilter(IsAbelian)`. However, these ranks may change when new implications are added, e.g. when certain packages are loaded. But those method rank adjustments then won't be updated, which can ultimately lead to the effect that loading a package changes which methods get executed in otherwise identical code. This PR helps avoid that, by making it possible to set "dynamic" rank adjustments which get updated as new implications are added. Some cleverness is needed to make this work efficiently when loading packages. - Record rank adjustment in METHODS_OPERATION - Add RECALCULATE_ALL_METHOD_RANKS function which does what it says. - Adjust MethodsOperation to include base rank - Increase size of HIDDEN_IMPS_CACHE and WITH_IMPS_CACHE to speed up RECALCULATE_ALL_METHOD_RANKS() - Make sure RANK_FILTERS is always set promptly, then remove the test for it being unset in RankFilter - Automatically reorder methods after library or package loading, or InstallTrueMethod - Use COPY_LIST_ENTRIES in method installation to avoid making an intermediate list - Support passing a function of no arguments as the rank adjustment to InstallMethod - Reset reordering status on quit from break loop. Fixes #2513 --- doc/ref/methsel.xml | 1 + lib/error.g | 3 + lib/filter.g | 73 ++++++++ lib/init.g | 3 + lib/oper.g | 130 +++++++++++++- lib/oper1.g | 28 ++- lib/package.gi | 14 +- src/c_oper1.c | 247 +++++++++++++++++--------- src/c_type1.c | 4 +- src/hpc/c_oper1.c | 225 ++++++++++++++++------- src/opers.c | 9 +- tst/testinstall/method-rankfns.tst | 21 +++ tst/testinstall/method-reordering.tst | 35 ++++ tst/testinstall/triviso.tst | 4 +- tst/testinstall/varargs.tst | 2 +- 15 files changed, 630 insertions(+), 169 deletions(-) create mode 100644 tst/testinstall/method-rankfns.tst create mode 100644 tst/testinstall/method-reordering.tst diff --git a/doc/ref/methsel.xml b/doc/ref/methsel.xml index 17543a9549e..de75cfd1ac6 100644 --- a/doc/ref/methsel.xml +++ b/doc/ref/methsel.xml @@ -252,6 +252,7 @@ one can install also immediate methods. Logical Implications <#Include Label="InstallTrueMethod"> +<#Include Label="MethodReordering"> diff --git a/lib/error.g b/lib/error.g index 74bc7694504..ff636977d10 100644 --- a/lib/error.g +++ b/lib/error.g @@ -32,6 +32,9 @@ BIND_GLOBAL( "OnQuit", # care to ensure it always has a definition. - GG until IsEmpty(OptionsStack); Info(InfoWarning,1,"Options stack has been reset"); fi; + if IsBound(ResetMethodReordering) and IsFunction(ResetMethodReordering) then + ResetMethodReordering(); + fi; end); diff --git a/lib/filter.g b/lib/filter.g index 17c06c84640..5fa698e1bbf 100644 --- a/lib/filter.g +++ b/lib/filter.g @@ -171,6 +171,64 @@ BIND_GLOBAL( "InstallTrueMethodNewFilter", function ( tofilt, from ) end ); +############################################################################# +## +#F SuspendMethodReordering( ) +#F ResumeMethodReordering( ) +#F ResetMethodReordering( ) +## +## <#GAPDoc Label="MethodReordering"> +## +## +## +## +## +## +## These functions control whether the method reordering process described +## in is invoked or not. Since this process +## can be comparatively time-consuming, it is usually suspended when a lot +## of implications are due to be installed, for instance when loading the +## library, or a package. This is done by calling +## SuspendMethodReordering() once the installations are done, +## ResumeMethodReordering() should be called. These pairs of calls +## can be nested. When the outermost pair is complete, method reordering +## takes place and is enabled in InstallTrueMethod thereafter. +## +## ResetMethodReordering() effectively exits all nested suspensions, +## resuming reordering immediately. This function is mainly provided for +## error recovery and similar purposes and is called on quitting from a +## break loop. +## +## +## <#/GAPDoc> + +# +# This function will be defined in oper.g +# +RECALCULATE_ALL_METHOD_RANKS := fail; + +REORDER_METHODS_SUSPENSION_LEVEL := 1; + +BIND_GLOBAL( "SuspendMethodReordering", function() + REORDER_METHODS_SUSPENSION_LEVEL := REORDER_METHODS_SUSPENSION_LEVEL + 1; +end); + + +BIND_GLOBAL( "ResumeMethodReordering", function() + if REORDER_METHODS_SUSPENSION_LEVEL > 0 then + REORDER_METHODS_SUSPENSION_LEVEL := REORDER_METHODS_SUSPENSION_LEVEL - 1; + fi; + if REORDER_METHODS_SUSPENSION_LEVEL <= 0 then + RECALCULATE_ALL_METHOD_RANKS(); + fi; +end); + +BIND_GLOBAL( "ResetMethodReordering", function() + REORDER_METHODS_SUSPENSION_LEVEL := 0; + RECALCULATE_ALL_METHOD_RANKS(); +end); + + ############################################################################# ## #F InstallTrueMethod( , ) @@ -210,10 +268,19 @@ end ); ## one can rely on the fact that every object in the filter ## IsGroup and IsCyclic will also be in the filter ## . +##

+## Adding logical implications can change the rank of filters (see +## ) and consequently the rank, and so choice of +## methods for operations (see ). +## By default InstallTrueMethod adjusts the method selection data +## structures to take care of this, but this process can be time-consuming, +## so functions and +## are provided to allow control of this process. ## ## ## <#/GAPDoc> ## + BIND_GLOBAL( "InstallTrueMethod", function ( tofilt, from ) InstallTrueMethodNewFilter( tofilt, from ); @@ -221,6 +288,12 @@ BIND_GLOBAL( "InstallTrueMethod", function ( tofilt, from ) # clear the caches because we do not know if filter is new CLEAR_HIDDEN_IMP_CACHE( from ); CLEAR_IMP_CACHE(); + + # maybe rerank methods to take account of new implication + if REORDER_METHODS_SUSPENSION_LEVEL = 0 then + RECALCULATE_ALL_METHOD_RANKS(); + fi; + end ); diff --git a/lib/init.g b/lib/init.g index ecbb1ed552a..5d7ec86ab31 100644 --- a/lib/init.g +++ b/lib/init.g @@ -1008,6 +1008,9 @@ fi; ## ## Read init files, run a shell, and do exit-time processing. ## + +ResumeMethodReordering(); + InstallAndCallPostRestore( function() local i, status; for i in [1..Length(GAPInfo.InitFiles)] do diff --git a/lib/oper.g b/lib/oper.g index c06b0a43f47..cf9f81c4fb6 100644 --- a/lib/oper.g +++ b/lib/oper.g @@ -1931,7 +1931,7 @@ end); fi; -if BASE_SIZE_METHODS_OPER_ENTRY <> 5 then +if BASE_SIZE_METHODS_OPER_ENTRY <> 6 then Error("MethodsOperation must be updated for new BASE_SIZE_METHODS_OPER_ENTRY"); fi; @@ -1952,6 +1952,7 @@ BIND_GLOBAL("MethodsOperation", function(oper, nargs) func := meths[i + nargs + 2], rank := meths[i + nargs + 3], info := meths[i + nargs + 4], + rankbase := meths[i + nargs + 6], ); ADD_LIST(result, m); if IsBound(meths[i + nargs + 5]) then @@ -1961,6 +1962,133 @@ BIND_GLOBAL("MethodsOperation", function(oper, nargs) return result; end ); +############################################################################# +## +#F RECALCULATE_ALL_METHOD_RANKS() . . reorder methods after new implications +## +## Installing new implications (including hidden implications) can change the +## rank of existing filters, and so of existing methods for operations. +## +## This function recalculates all such ranks and adjusts the method ordering +## where needed. If the ordering changes, the relevant caches are flushed. +## +## If PRINT_REORDERED_METHODS is true, it prints some diagnostics (this is a +## bit too low-level for Info). +## +## + + +# +# We had to install a placeholder for this in filter.g +# +Unbind(RECALCULATE_ALL_METHOD_RANKS); + +PRINT_REORDERED_METHODS := false; + +BIND_GLOBAL( "RECALCULATE_ALL_METHOD_RANKS", function() + local oper, n, changed, meths, nmethods, i, base, rank, j, req, + req2, k, l; + + for oper in OPERATIONS do + for n in [0..6] do + changed := false; + meths := METHODS_OPERATION(oper, n); + nmethods := LENGTH(meths)/(BASE_SIZE_METHODS_OPER_ENTRY+n); + if IS_CONSTRUCTOR(oper) and n > 0 then + for i in [nmethods,nmethods-1..1] do + base := (i-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n); + # data for this method is meths{[base+1..base+BASE_SIZE_METHODS_OPER_ENTRY + n]} + rank := meths[base+6+n]; + if IS_FUNCTION(rank) then + rank := rank(); + fi; + rank := rank - RankFilter(WITH_IMPS_FLAGS(meths[base+2])); + if rank <> meths[base+n+3] then + if IsHPCGAP and not changed then + meths := SHALLOW_COPY_OBJ(meths); + fi; + changed := true; + meths[base+n+3] := rank; + fi; + # compare to rank of succeding method + if i = nmethods or rank >= meths[base+BASE_SIZE_METHODS_OPER_ENTRY + 2*n + 3] then + continue; + fi; + k := i+2; + while k <= nmethods and meths[(k-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n) + n + 3] < rank do + k := k+1; + od; + k := k-1; + if PRINT_REORDERED_METHODS then + Print("Constructor ",NAME_FUNC(oper), " ", n," args. Moving method ",i," (", + meths[base+n+4]," from ",meths[base+n+5][1],":", meths[base+n+5][2], + ") to position ",k,"\n"); + fi; + l := meths{[base+1..base+n+BASE_SIZE_METHODS_OPER_ENTRY]}; + COPY_LIST_ENTRIES(meths, 1 + i*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + meths, 1 +(i-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + (k-i)*(n+BASE_SIZE_METHODS_OPER_ENTRY)); + meths{[1 + (k-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY).. + k*(n+BASE_SIZE_METHODS_OPER_ENTRY)]} := l; + od; + else + for i in [1 ..nmethods] do + base := (i-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n); + # data for this method is meths{[base+1..base+BASE_SIZE_METHODS_OPER_ENTRY + n]} + rank := meths[base+6+n]; + if IS_FUNCTION(rank) then + rank := rank(); + fi; + + + for j in [1..n] do + req := meths[base+1+j]; + rank := rank+RankFilter(WITH_IMPS_FLAGS(req)); + od; + + if rank <> meths[base+n+3] then + if IsHPCGAP and not changed then + meths := SHALLOW_COPY_OBJ(meths); + fi; + changed := true; + meths[base+n+3] := rank; + fi; + + # compare to rank of preceding method + if i = 1 or rank <= meths[base-BASE_SIZE_METHODS_OPER_ENTRY+3] then + continue; + fi; + + k := i-2; + while k > 1 and meths[(k-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n) + n + 3] < rank do + k := k-1; + od; + k := k+1; + if PRINT_REORDERED_METHODS then + Print(NAME_FUNC(oper), " ", n," args. Moving method ",i," (", + meths[base+n+4]," from ",meths[base+n+5][1],":", meths[base+n+5][2], + ") to position ",k,"\n"); + fi; + l := meths{[base+1..base+n+BASE_SIZE_METHODS_OPER_ENTRY]}; + COPY_LIST_ENTRIES(meths, 1 + (k-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + meths, 1 + k*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + (i-k)*(n+BASE_SIZE_METHODS_OPER_ENTRY)); + meths{[1 + (k-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY).. + k*(n+BASE_SIZE_METHODS_OPER_ENTRY)]} := l; + od; + fi; + if changed then + if IsHPCGAP then + SET_METHODS_OPERATION(oper,n,MakeReadOnlySingleObj(meths)); + else + CHANGED_METHODS_OPERATION(oper,n); + fi; + fi; + od; + od; +end ); + + ############################################################################# ## #E diff --git a/lib/oper1.g b/lib/oper1.g index 71067774e07..cfcf9931c4b 100644 --- a/lib/oper1.g +++ b/lib/oper1.g @@ -143,8 +143,8 @@ fi; #F INSTALL_METHOD_FLAGS( , , , , , ) . ## BIND_GLOBAL( "INSTALL_METHOD_FLAGS", - function( opr, info, rel, flags, rank, method ) - local methods, narg, i, k, tmp, replace, match, j, lk; + function( opr, info, rel, flags, baserank, method ) + local methods, narg, i, k, tmp, replace, match, j, lk, rank; if IsHPCGAP then # TODO: once the GAP compiler supports 'atomic', use that @@ -152,6 +152,11 @@ BIND_GLOBAL( "INSTALL_METHOD_FLAGS", lk := WRITE_LOCK(METHODS_OPERATION_REGION); fi; # add the number of filters required for each argument + if IS_FUNCTION(baserank) then + rank := baserank(); + else + rank := baserank; + fi; if IS_CONSTRUCTOR(opr) then if 0 = LEN_LIST(flags) then Error(NAME_FUNC(opr),": constructors must have at least one argument"); @@ -262,6 +267,9 @@ BIND_GLOBAL( "INSTALL_METHOD_FLAGS", methods[i+(narg+4)] := IMMUTABLE_COPY_OBJ(info); if BASE_SIZE_METHODS_OPER_ENTRY >= 5 then methods[i+(narg+5)] := MakeImmutable([INPUT_FILENAME(), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER()]); + if BASE_SIZE_METHODS_OPER_ENTRY >= 6 then + methods[i+(narg+6)] := baserank; + fi; fi; # flush the cache @@ -290,9 +298,11 @@ end ); ## if supplied info should be a short but informative string ## that describes for what situation the method is installed, ## famp should be a function to be applied to the families -## of the arguments, -## and val should be an integer that measures the priority -## of the method. +## of the arguments. +## aval should be an integer that measures the priority +## of the method, or a function of no arguments which should return such an +## integer and will be called each time method order is being recalculated, +## (see ). ##

## The default values for info, famp, and val are ## the empty string, @@ -455,9 +465,11 @@ BIND_GLOBAL( "INSTALL_METHOD", # Check the rank. if not IsBound( arglist[ pos ] ) then Error( "the method is missing in " ); - elif IS_INT( arglist[ pos ] ) then - rank:= arglist[ pos ]; - pos:= pos + 1; + elif IS_INT( arglist[ pos ] ) or + (IS_FUNCTION( arglist[ pos ] ) and NARG_FUNC( arglist[ pos ] ) = 0 + and pos < LEN_LIST(arglist)) then + rank := arglist[ pos ]; + pos := pos+1; else rank:= 0; fi; diff --git a/lib/package.gi b/lib/package.gi index db61cfdbdfe..8f3b3e2ce81 100644 --- a/lib/package.gi +++ b/lib/package.gi @@ -1519,6 +1519,10 @@ InstallGlobalFunction( LoadPackage, function( arg ) return path; fi; + # Suspend reordering of methods following InstallTrueMethod + # because it would slow things down too much + SuspendMethodReordering(); + # Compute the order in which the packages are loaded. # For each set of packages with cyclic dependencies, # we will first read all `init.g' files @@ -1617,6 +1621,8 @@ InstallGlobalFunction( LoadPackage, function( arg ) LogPackageLoadingMessage( PACKAGE_DEBUG, "return from LoadPackage", Name ); GAPInfo.LoadPackageLevel:= GAPInfo.LoadPackageLevel - 1; + + ResumeMethodReordering(); return true; end ); @@ -1626,11 +1632,13 @@ InstallGlobalFunction( LoadPackage, function( arg ) #F LoadAllPackages() ## InstallGlobalFunction( LoadAllPackages, function() + SuspendMethodReordering(); if ValueOption( "reversed" ) = true then - List( Reversed( RecNames( GAPInfo.PackagesInfo ) ), LoadPackage ); + List( Reversed( RecNames( GAPInfo.PackagesInfo ) ), LoadPackage ); else - List( RecNames( GAPInfo.PackagesInfo ), LoadPackage ); - fi; + List( RecNames( GAPInfo.PackagesInfo ), LoadPackage ); + fi; + ResumeMethodReordering(); end ); diff --git a/src/c_oper1.c b/src/c_oper1.c index aeb413b27f2..718553be203 100644 --- a/src/c_oper1.c +++ b/src/c_oper1.c @@ -1,7 +1,7 @@ #ifndef AVOID_PRECOMPILED /* C file produced by GAC */ #include "compiled.h" -#define FILE_CRC "32938550" +#define FILE_CRC "37165935" /* global variables used in handlers */ static GVar G_REREADING; @@ -82,6 +82,8 @@ static GVar G_LEN__LIST; static Obj GF_LEN__LIST; static GVar G_APPEND__LIST__INTR; static Obj GF_APPEND__LIST__INTR; +static GVar G_COPY__LIST__ENTRIES; +static Obj GF_COPY__LIST__ENTRIES; static GVar G_CONV__STRING; static Obj GF_CONV__STRING; static GVar G_Print; @@ -601,7 +603,7 @@ static Obj HdlrFunc3 ( Obj a_info, Obj a_rel, Obj a_flags, - Obj a_rank, + Obj a_baserank, Obj a_method ) { Obj l_methods = 0; @@ -613,6 +615,7 @@ static Obj HdlrFunc3 ( Obj l_match = 0; Obj l_j = 0; Obj l_lk = 0; + Obj l_rank = 0; Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; @@ -630,6 +633,7 @@ static Obj HdlrFunc3 ( (void)l_match; (void)l_j; (void)l_lk; + (void)l_rank; Bag oldFrame; OLD_BRK_CURR_STAT @@ -638,6 +642,31 @@ static Obj HdlrFunc3 ( REM_BRK_CURR_STAT(); SET_BRK_CURR_STAT(0); + /* if IS_FUNCTION( baserank ) then */ + t_3 = GF_IS__FUNCTION; + t_2 = CALL_1ARGS( t_3, a_baserank ); + CHECK_FUNC_RESULT( t_2 ) + CHECK_BOOL( t_2 ) + t_1 = (Obj)(UInt)(t_2 != False); + if ( t_1 ) { + + /* rank := baserank( ); */ + CHECK_FUNC( a_baserank ) + t_1 = CALL_0ARGS( a_baserank ); + CHECK_FUNC_RESULT( t_1 ) + l_rank = t_1; + + } + + /* else */ + else { + + /* rank := baserank; */ + l_rank = a_baserank; + + } + /* fi */ + /* if IS_CONSTRUCTOR( opr ) then */ t_3 = GF_IS__CONSTRUCTOR; t_2 = CALL_1ARGS( t_3, a_opr ); @@ -669,8 +698,8 @@ static Obj HdlrFunc3 ( C_ELM_LIST_FPL( t_4, a_flags, INTOBJ_INT(1) ) t_2 = CALL_1ARGS( t_3, t_4 ); CHECK_FUNC_RESULT( t_2 ) - C_DIFF_FIA( t_1, a_rank, t_2 ) - a_rank = t_1; + C_DIFF_FIA( t_1, l_rank, t_2 ) + l_rank = t_1; } @@ -704,8 +733,8 @@ static Obj HdlrFunc3 ( t_7 = GF_RankFilter; t_6 = CALL_1ARGS( t_7, l_i ); CHECK_FUNC_RESULT( t_6 ) - C_SUM_FIA( t_5, a_rank, t_6 ) - a_rank = t_5; + C_SUM_FIA( t_5, l_rank, t_6 ) + l_rank = t_5; } /* od */ @@ -784,13 +813,13 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, l_i, t_6 ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(LT( a_rank, t_4 )); + t_3 = (Obj)(UInt)(LT( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; - /* i := i + (narg + 5); */ - C_SUM_FIA( t_2, l_narg, INTOBJ_INT(5) ) + /* i := i + (narg + 6); */ + C_SUM_FIA( t_2, l_narg, INTOBJ_INT(6) ) C_SUM_FIA( t_1, l_i, t_2 ) l_i = t_1; @@ -823,7 +852,7 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, t_6, INTOBJ_INT(3) ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(EQ( a_rank, t_4 )); + t_3 = (Obj)(UInt)(EQ( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; @@ -898,9 +927,9 @@ static Obj HdlrFunc3 ( } /* fi */ - /* k := k + narg + 5; */ + /* k := k + narg + 6; */ C_SUM_FIA( t_2, l_k, l_narg ) - C_SUM_FIA( t_1, t_2, INTOBJ_INT(5) ) + C_SUM_FIA( t_1, t_2, INTOBJ_INT(6) ) l_k = t_1; } @@ -923,23 +952,31 @@ static Obj HdlrFunc3 ( } if ( t_1 ) { - /* methods{[ narg + 5 + i + 1 .. narg + 5 + LEN_LIST( methods ) ]} := methods{[ i + 1 .. LEN_LIST( methods ) ]}; */ - C_SUM_FIA( t_4, l_narg, INTOBJ_INT(5) ) - C_SUM_FIA( t_3, t_4, l_i ) - C_SUM_FIA( t_2, t_3, INTOBJ_INT(1) ) - C_SUM_FIA( t_4, l_narg, INTOBJ_INT(5) ) - t_6 = GF_LEN__LIST; - t_5 = CALL_1ARGS( t_6, l_methods ); - CHECK_FUNC_RESULT( t_5 ) - C_SUM_FIA( t_3, t_4, t_5 ) - t_1 = Range2Check( t_2, t_3 ); - C_SUM_FIA( t_4, l_i, INTOBJ_INT(1) ) - t_6 = GF_LEN__LIST; - t_5 = CALL_1ARGS( t_6, l_methods ); - CHECK_FUNC_RESULT( t_5 ) - t_3 = Range2Check( t_4, t_5 ); - t_2 = ElmsListCheck( l_methods, t_3 ); - AsssListCheck( l_methods, t_1, t_2 ); + /* COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 6 + i + 1, 1, LEN_LIST( methods ) - i ); */ + t_1 = GF_COPY__LIST__ENTRIES; + t_2 = NEW_PLIST( T_PLIST, 7 ); + SET_LEN_PLIST( t_2, 7 ); + SET_ELM_PLIST( t_2, 1, l_methods ); + CHANGED_BAG( t_2 ); + C_SUM_FIA( t_3, l_i, INTOBJ_INT(1) ) + SET_ELM_PLIST( t_2, 2, t_3 ); + CHANGED_BAG( t_2 ); + SET_ELM_PLIST( t_2, 3, INTOBJ_INT(1) ); + SET_ELM_PLIST( t_2, 4, l_methods ); + CHANGED_BAG( t_2 ); + C_SUM_FIA( t_5, l_narg, INTOBJ_INT(6) ) + C_SUM_FIA( t_4, t_5, l_i ) + C_SUM_FIA( t_3, t_4, INTOBJ_INT(1) ) + SET_ELM_PLIST( t_2, 5, t_3 ); + CHANGED_BAG( t_2 ); + SET_ELM_PLIST( t_2, 6, INTOBJ_INT(1) ); + t_5 = GF_LEN__LIST; + t_4 = CALL_1ARGS( t_5, l_methods ); + CHECK_FUNC_RESULT( t_4 ) + C_DIFF_FIA( t_3, t_4, l_i ) + SET_ELM_PLIST( t_2, 7, t_3 ); + CHANGED_BAG( t_2 ); + CALL_XARGS( t_1, t_2 ); } /* fi */ @@ -1193,7 +1230,7 @@ static Obj HdlrFunc3 ( C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(3) ) C_SUM_FIA( t_1, l_i, t_2 ) CHECK_INT_POS( t_1 ) - C_ASS_LIST_FPL( l_methods, t_1, a_rank ) + C_ASS_LIST_FPL( l_methods, t_1, l_rank ) /* methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); */ C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(4) ) @@ -1204,8 +1241,8 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) - /* if 5 >= 5 then */ - t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(5)) >= ((Int)INTOBJ_INT(5))); + /* if 6 >= 5 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(6)) >= ((Int)INTOBJ_INT(5))); if ( t_1 ) { /* methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); */ @@ -1233,6 +1270,19 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) + /* if 6 >= 6 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(6)) >= ((Int)INTOBJ_INT(6))); + if ( t_1 ) { + + /* methods[i + (narg + 6)] := baserank; */ + C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(6) ) + C_SUM_FIA( t_1, l_i, t_2 ) + CHECK_INT_POS( t_1 ) + C_ASS_LIST_FPL( l_methods, t_1, a_baserank ) + + } + /* fi */ + } /* fi */ @@ -1725,14 +1775,41 @@ static Obj HdlrFunc6 ( } - /* elif IS_INT( arglist[pos] ) then */ + /* elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then */ else { - t_3 = GF_IS__INT; - C_ELM_LIST_FPL( t_4, a_arglist, l_pos ) - t_2 = CALL_1ARGS( t_3, t_4 ); - CHECK_FUNC_RESULT( t_2 ) - CHECK_BOOL( t_2 ) - t_1 = (Obj)(UInt)(t_2 != False); + t_4 = GF_IS__INT; + C_ELM_LIST_FPL( t_5, a_arglist, l_pos ) + t_3 = CALL_1ARGS( t_4, t_5 ); + CHECK_FUNC_RESULT( t_3 ) + CHECK_BOOL( t_3 ) + t_2 = (Obj)(UInt)(t_3 != False); + t_1 = t_2; + if ( ! t_1 ) { + t_7 = GF_IS__FUNCTION; + C_ELM_LIST_FPL( t_8, a_arglist, l_pos ) + t_6 = CALL_1ARGS( t_7, t_8 ); + CHECK_FUNC_RESULT( t_6 ) + CHECK_BOOL( t_6 ) + t_5 = (Obj)(UInt)(t_6 != False); + t_4 = t_5; + if ( t_4 ) { + t_8 = GF_NARG__FUNC; + C_ELM_LIST_FPL( t_9, a_arglist, l_pos ) + t_7 = CALL_1ARGS( t_8, t_9 ); + CHECK_FUNC_RESULT( t_7 ) + t_6 = (Obj)(UInt)(EQ( t_7, INTOBJ_INT(0) )); + t_4 = t_6; + } + t_3 = t_4; + if ( t_3 ) { + t_7 = GF_LEN__LIST; + t_6 = CALL_1ARGS( t_7, a_arglist ); + CHECK_FUNC_RESULT( t_6 ) + t_5 = (Obj)(UInt)(LT( l_pos, t_6 )); + t_3 = t_5; + } + t_1 = t_3; + } if ( t_1 ) { /* rank := arglist[pos]; */ @@ -2693,8 +2770,8 @@ static Obj HdlrFunc7 ( t_6 = NewFunction( NameFunc[8], 1, 0, HdlrFunc8 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 652); - SET_ENDLINE_BODY(t_7, 670); + SET_STARTLINE_BODY(t_7, 664); + SET_ENDLINE_BODY(t_7, 682); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3297,8 +3374,8 @@ static Obj HdlrFunc11 ( t_1 = NewFunction( NameFunc[12], 1, 0, HdlrFunc12 ); SET_ENVI_FUNC( t_1, STATE(CurrLVars) ); t_2 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_2, 849); - SET_ENDLINE_BODY(t_2, 853); + SET_STARTLINE_BODY(t_2, 861); + SET_ENDLINE_BODY(t_2, 865); SET_FILENAME_BODY(t_2, FileName); SET_BODY_FUNC(t_1, t_2); CHANGED_BAG( STATE(CurrLVars) ); @@ -3377,8 +3454,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[13], 1, 0, HdlrFunc13 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 870); - SET_ENDLINE_BODY(t_7, 870); + SET_STARTLINE_BODY(t_7, 882); + SET_ENDLINE_BODY(t_7, 882); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3440,8 +3517,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[14], 2, 0, HdlrFunc14 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 892); - SET_ENDLINE_BODY(t_7, 915); + SET_STARTLINE_BODY(t_7, 904); + SET_ENDLINE_BODY(t_7, 927); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3489,8 +3566,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[15], 2, 0, HdlrFunc15 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 925); - SET_ENDLINE_BODY(t_7, 933); + SET_STARTLINE_BODY(t_7, 937); + SET_ENDLINE_BODY(t_7, 945); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3551,8 +3628,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[16], 3, 0, HdlrFunc16 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 942); - SET_ENDLINE_BODY(t_7, 955); + SET_STARTLINE_BODY(t_7, 954); + SET_ENDLINE_BODY(t_7, 967); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3925,8 +4002,8 @@ static Obj HdlrFunc17 ( t_4 = NewFunction( NameFunc[18], -1, 0, HdlrFunc18 ); SET_ENVI_FUNC( t_4, STATE(CurrLVars) ); t_5 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_5, 1021); - SET_ENDLINE_BODY(t_5, 1037); + SET_STARTLINE_BODY(t_5, 1033); + SET_ENDLINE_BODY(t_5, 1049); SET_FILENAME_BODY(t_5, FileName); SET_BODY_FUNC(t_4, t_5); CHANGED_BAG( STATE(CurrLVars) ); @@ -4034,9 +4111,14 @@ static Obj HdlrFunc1 ( CHANGED_BAG( STATE(CurrLVars) ); CALL_2ARGS( t_1, t_2, t_3 ); - /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, rank, method ) - local methods, narg, i, k, tmp, replace, match, j, lk; + /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, baserank, method ) + local methods, narg, i, k, tmp, replace, match, j, lk, rank; ; + if IS_FUNCTION( baserank ) then + rank := baserank( ); + else + rank := baserank; + fi; if IS_CONSTRUCTOR( opr ) then if 0 = LEN_LIST( flags ) then Error( NAME_FUNC( opr ), ": constructors must have at least one argument" ); @@ -4061,7 +4143,7 @@ static Obj HdlrFunc1 ( fi; i := 0; while i < LEN_LIST( methods ) and rank < methods[i + (narg + 3)] do - i := i + (narg + 5); + i := i + (narg + 6); od; replace := false; if REREADING then @@ -4078,11 +4160,11 @@ static Obj HdlrFunc1 ( break; fi; fi; - k := k + narg + 5; + k := k + narg + 6; od; fi; if not REREADING or not replace then - methods{[ narg + 5 + i + 1 .. narg + 5 + LEN_LIST( methods ) ]} := methods{[ i + 1 .. LEN_LIST( methods ) ]}; + COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 6 + i + 1, 1, LEN_LIST( methods ) - i ); fi; if rel = true then methods[i + 1] := RETURN_TRUE; @@ -4119,8 +4201,11 @@ static Obj HdlrFunc1 ( fi; methods[i + (narg + 3)] := rank; methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); - if 5 >= 5 then + if 6 >= 5 then methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); + if 6 >= 6 then + methods[i + (narg + 6)] := baserank; + fi; fi; CHANGED_METHODS_OPERATION( opr, narg ); return; @@ -4131,7 +4216,7 @@ static Obj HdlrFunc1 ( SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); SET_STARTLINE_BODY(t_4, 146); - SET_ENDLINE_BODY(t_4, 274); + SET_ENDLINE_BODY(t_4, 282); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4146,8 +4231,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[4], -1, 0, HdlrFunc4 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 321); - SET_ENDLINE_BODY(t_4, 323); + SET_STARTLINE_BODY(t_4, 331); + SET_ENDLINE_BODY(t_4, 333); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4162,8 +4247,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[5], -1, 0, HdlrFunc5 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 348); - SET_ENDLINE_BODY(t_4, 350); + SET_STARTLINE_BODY(t_4, 358); + SET_ENDLINE_BODY(t_4, 360); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4237,7 +4322,7 @@ static Obj HdlrFunc1 ( od; if not IsBound( arglist[pos] ) then Error( "the method is missing in " ); - elif IS_INT( arglist[pos] ) then + elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then rank := arglist[pos]; pos := pos + 1; else @@ -4332,17 +4417,17 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[6], 2, 0, HdlrFunc6 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 361); - SET_ENDLINE_BODY(t_4, 591); + SET_STARTLINE_BODY(t_4, 371); + SET_ENDLINE_BODY(t_4, 603); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); CALL_2ARGS( t_1, t_2, t_3 ); - /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (5 + 2); */ + /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (6 + 2); */ t_2 = GC_LENGTH__SETTER__METHODS__2; CHECK_BOUND( t_2, "LENGTH_SETTER_METHODS_2" ) - C_SUM_INTOBJS( t_3, INTOBJ_INT(5), INTOBJ_INT(2) ) + C_SUM_INTOBJS( t_3, INTOBJ_INT(6), INTOBJ_INT(2) ) C_SUM_FIA( t_1, t_2, t_3 ) AssGVar( G_LENGTH__SETTER__METHODS__2, t_1 ); @@ -4391,8 +4476,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[7], 6, 0, HdlrFunc7 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 610); - SET_ENDLINE_BODY(t_3, 674); + SET_STARTLINE_BODY(t_3, 622); + SET_ENDLINE_BODY(t_3, 686); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4406,8 +4491,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[9], 6, 0, HdlrFunc9 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 677); - SET_ENDLINE_BODY(t_3, 683); + SET_STARTLINE_BODY(t_3, 689); + SET_ENDLINE_BODY(t_3, 695); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4435,8 +4520,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[10], 2, 0, HdlrFunc10 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 696); - SET_ENDLINE_BODY(t_4, 720); + SET_STARTLINE_BODY(t_4, 708); + SET_ENDLINE_BODY(t_4, 732); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4520,8 +4605,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[11], 4, 0, HdlrFunc11 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 845); - SET_ENDLINE_BODY(t_4, 956); + SET_STARTLINE_BODY(t_4, 857); + SET_ENDLINE_BODY(t_4, 968); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4572,8 +4657,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[17], -1, 0, HdlrFunc17 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 991); - SET_ENDLINE_BODY(t_4, 1038); + SET_STARTLINE_BODY(t_4, 1003); + SET_ENDLINE_BODY(t_4, 1050); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4650,6 +4735,7 @@ static Int PostRestore ( StructInitInfo * module ) G_RETURN__FALSE = GVarName( "RETURN_FALSE" ); G_LEN__LIST = GVarName( "LEN_LIST" ); G_APPEND__LIST__INTR = GVarName( "APPEND_LIST_INTR" ); + G_COPY__LIST__ENTRIES = GVarName( "COPY_LIST_ENTRIES" ); G_CONV__STRING = GVarName( "CONV_STRING" ); G_Print = GVarName( "Print" ); G_ViewObj = GVarName( "ViewObj" ); @@ -4766,6 +4852,7 @@ static Int InitKernel ( StructInitInfo * module ) InitCopyGVar( "RETURN_FALSE", &GC_RETURN__FALSE ); InitFopyGVar( "LEN_LIST", &GF_LEN__LIST ); InitFopyGVar( "APPEND_LIST_INTR", &GF_APPEND__LIST__INTR ); + InitFopyGVar( "COPY_LIST_ENTRIES", &GF_COPY__LIST__ENTRIES ); InitFopyGVar( "CONV_STRING", &GF_CONV__STRING ); InitFopyGVar( "Print", &GF_Print ); InitCopyGVar( "ViewObj", &GC_ViewObj ); @@ -4880,7 +4967,7 @@ static Int InitLibrary ( StructInitInfo * module ) static StructInitInfo module = { .type = MODULE_STATIC, .name = "GAPROOT/lib/oper1.g", - .crc = 32938550, + .crc = 37165935, .initKernel = InitKernel, .initLibrary = InitLibrary, .postRestore = PostRestore, diff --git a/src/c_type1.c b/src/c_type1.c index 79a54f99858..387f98010ac 100644 --- a/src/c_type1.c +++ b/src/c_type1.c @@ -3320,10 +3320,10 @@ static Obj HdlrFunc1 ( CHANGED_BAG( STATE(CurrLVars) ); CALL_1ARGS( t_1, t_2 ); - /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (5 + 2); */ + /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (6 + 2); */ t_2 = GC_LENGTH__SETTER__METHODS__2; CHECK_BOUND( t_2, "LENGTH_SETTER_METHODS_2" ) - C_SUM_INTOBJS( t_3, INTOBJ_INT(5), INTOBJ_INT(2) ) + C_SUM_INTOBJS( t_3, INTOBJ_INT(6), INTOBJ_INT(2) ) C_SUM_FIA( t_1, t_2, t_3 ) AssGVar( G_LENGTH__SETTER__METHODS__2, t_1 ); diff --git a/src/hpc/c_oper1.c b/src/hpc/c_oper1.c index 1c5ef2b2abb..c7eaef2ae0a 100644 --- a/src/hpc/c_oper1.c +++ b/src/hpc/c_oper1.c @@ -1,7 +1,7 @@ #ifndef AVOID_PRECOMPILED /* C file produced by GAC */ #include "compiled.h" -#define FILE_CRC "32938550" +#define FILE_CRC "37165935" /* global variables used in handlers */ static GVar G_REREADING; @@ -82,6 +82,8 @@ static GVar G_LEN__LIST; static Obj GF_LEN__LIST; static GVar G_APPEND__LIST__INTR; static Obj GF_APPEND__LIST__INTR; +static GVar G_COPY__LIST__ENTRIES; +static Obj GF_COPY__LIST__ENTRIES; static GVar G_CONV__STRING; static Obj GF_CONV__STRING; static GVar G_Print; @@ -617,7 +619,7 @@ static Obj HdlrFunc3 ( Obj a_info, Obj a_rel, Obj a_flags, - Obj a_rank, + Obj a_baserank, Obj a_method ) { Obj l_methods = 0; @@ -629,6 +631,7 @@ static Obj HdlrFunc3 ( Obj l_match = 0; Obj l_j = 0; Obj l_lk = 0; + Obj l_rank = 0; Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; @@ -646,6 +649,7 @@ static Obj HdlrFunc3 ( (void)l_match; (void)l_j; (void)l_lk; + (void)l_rank; Bag oldFrame; OLD_BRK_CURR_STAT @@ -662,6 +666,31 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_1 ) l_lk = t_1; + /* if IS_FUNCTION( baserank ) then */ + t_3 = GF_IS__FUNCTION; + t_2 = CALL_1ARGS( t_3, a_baserank ); + CHECK_FUNC_RESULT( t_2 ) + CHECK_BOOL( t_2 ) + t_1 = (Obj)(UInt)(t_2 != False); + if ( t_1 ) { + + /* rank := baserank( ); */ + CHECK_FUNC( a_baserank ) + t_1 = CALL_0ARGS( a_baserank ); + CHECK_FUNC_RESULT( t_1 ) + l_rank = t_1; + + } + + /* else */ + else { + + /* rank := baserank; */ + l_rank = a_baserank; + + } + /* fi */ + /* if IS_CONSTRUCTOR( opr ) then */ t_3 = GF_IS__CONSTRUCTOR; t_2 = CALL_1ARGS( t_3, a_opr ); @@ -693,8 +722,8 @@ static Obj HdlrFunc3 ( C_ELM_LIST_FPL( t_4, a_flags, INTOBJ_INT(1) ) t_2 = CALL_1ARGS( t_3, t_4 ); CHECK_FUNC_RESULT( t_2 ) - C_DIFF_FIA( t_1, a_rank, t_2 ) - a_rank = t_1; + C_DIFF_FIA( t_1, l_rank, t_2 ) + l_rank = t_1; } @@ -728,8 +757,8 @@ static Obj HdlrFunc3 ( t_7 = GF_RankFilter; t_6 = CALL_1ARGS( t_7, l_i ); CHECK_FUNC_RESULT( t_6 ) - C_SUM_FIA( t_5, a_rank, t_6 ) - a_rank = t_5; + C_SUM_FIA( t_5, l_rank, t_6 ) + l_rank = t_5; } /* od */ @@ -816,7 +845,7 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, l_i, t_6 ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(LT( a_rank, t_4 )); + t_3 = (Obj)(UInt)(LT( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; @@ -855,7 +884,7 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, t_6, INTOBJ_INT(3) ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(EQ( a_rank, t_4 )); + t_3 = (Obj)(UInt)(EQ( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; @@ -955,23 +984,31 @@ static Obj HdlrFunc3 ( } if ( t_1 ) { - /* methods{[ narg + 5 + i + 1 .. narg + 5 + LEN_LIST( methods ) ]} := methods{[ i + 1 .. LEN_LIST( methods ) ]}; */ - C_SUM_FIA( t_4, l_narg, INTOBJ_INT(5) ) - C_SUM_FIA( t_3, t_4, l_i ) - C_SUM_FIA( t_2, t_3, INTOBJ_INT(1) ) - C_SUM_FIA( t_4, l_narg, INTOBJ_INT(5) ) - t_6 = GF_LEN__LIST; - t_5 = CALL_1ARGS( t_6, l_methods ); - CHECK_FUNC_RESULT( t_5 ) - C_SUM_FIA( t_3, t_4, t_5 ) - t_1 = Range2Check( t_2, t_3 ); - C_SUM_FIA( t_4, l_i, INTOBJ_INT(1) ) - t_6 = GF_LEN__LIST; - t_5 = CALL_1ARGS( t_6, l_methods ); - CHECK_FUNC_RESULT( t_5 ) - t_3 = Range2Check( t_4, t_5 ); - t_2 = ElmsListCheck( l_methods, t_3 ); - AsssListCheck( l_methods, t_1, t_2 ); + /* COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 5 + i + 1, 1, LEN_LIST( methods ) - i ); */ + t_1 = GF_COPY__LIST__ENTRIES; + t_2 = NEW_PLIST( T_PLIST, 7 ); + SET_LEN_PLIST( t_2, 7 ); + SET_ELM_PLIST( t_2, 1, l_methods ); + CHANGED_BAG( t_2 ); + C_SUM_FIA( t_3, l_i, INTOBJ_INT(1) ) + SET_ELM_PLIST( t_2, 2, t_3 ); + CHANGED_BAG( t_2 ); + SET_ELM_PLIST( t_2, 3, INTOBJ_INT(1) ); + SET_ELM_PLIST( t_2, 4, l_methods ); + CHANGED_BAG( t_2 ); + C_SUM_FIA( t_5, l_narg, INTOBJ_INT(5) ) + C_SUM_FIA( t_4, t_5, l_i ) + C_SUM_FIA( t_3, t_4, INTOBJ_INT(1) ) + SET_ELM_PLIST( t_2, 5, t_3 ); + CHANGED_BAG( t_2 ); + SET_ELM_PLIST( t_2, 6, INTOBJ_INT(1) ); + t_5 = GF_LEN__LIST; + t_4 = CALL_1ARGS( t_5, l_methods ); + CHECK_FUNC_RESULT( t_4 ) + C_DIFF_FIA( t_3, t_4, l_i ) + SET_ELM_PLIST( t_2, 7, t_3 ); + CHANGED_BAG( t_2 ); + CALL_XARGS( t_1, t_2 ); } /* fi */ @@ -1225,7 +1262,7 @@ static Obj HdlrFunc3 ( C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(3) ) C_SUM_FIA( t_1, l_i, t_2 ) CHECK_INT_POS( t_1 ) - C_ASS_LIST_FPL( l_methods, t_1, a_rank ) + C_ASS_LIST_FPL( l_methods, t_1, l_rank ) /* methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); */ C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(4) ) @@ -1265,6 +1302,19 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) + /* if 5 >= 6 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(5)) >= ((Int)INTOBJ_INT(6))); + if ( t_1 ) { + + /* methods[i + (narg + 6)] := baserank; */ + C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(6) ) + C_SUM_FIA( t_1, l_i, t_2 ) + CHECK_INT_POS( t_1 ) + C_ASS_LIST_FPL( l_methods, t_1, a_baserank ) + + } + /* fi */ + } /* fi */ @@ -1772,14 +1822,41 @@ static Obj HdlrFunc6 ( } - /* elif IS_INT( arglist[pos] ) then */ + /* elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then */ else { - t_3 = GF_IS__INT; - C_ELM_LIST_FPL( t_4, a_arglist, l_pos ) - t_2 = CALL_1ARGS( t_3, t_4 ); - CHECK_FUNC_RESULT( t_2 ) - CHECK_BOOL( t_2 ) - t_1 = (Obj)(UInt)(t_2 != False); + t_4 = GF_IS__INT; + C_ELM_LIST_FPL( t_5, a_arglist, l_pos ) + t_3 = CALL_1ARGS( t_4, t_5 ); + CHECK_FUNC_RESULT( t_3 ) + CHECK_BOOL( t_3 ) + t_2 = (Obj)(UInt)(t_3 != False); + t_1 = t_2; + if ( ! t_1 ) { + t_7 = GF_IS__FUNCTION; + C_ELM_LIST_FPL( t_8, a_arglist, l_pos ) + t_6 = CALL_1ARGS( t_7, t_8 ); + CHECK_FUNC_RESULT( t_6 ) + CHECK_BOOL( t_6 ) + t_5 = (Obj)(UInt)(t_6 != False); + t_4 = t_5; + if ( t_4 ) { + t_8 = GF_NARG__FUNC; + C_ELM_LIST_FPL( t_9, a_arglist, l_pos ) + t_7 = CALL_1ARGS( t_8, t_9 ); + CHECK_FUNC_RESULT( t_7 ) + t_6 = (Obj)(UInt)(EQ( t_7, INTOBJ_INT(0) )); + t_4 = t_6; + } + t_3 = t_4; + if ( t_3 ) { + t_7 = GF_LEN__LIST; + t_6 = CALL_1ARGS( t_7, a_arglist ); + CHECK_FUNC_RESULT( t_6 ) + t_5 = (Obj)(UInt)(LT( l_pos, t_6 )); + t_3 = t_5; + } + t_1 = t_3; + } if ( t_1 ) { /* rank := arglist[pos]; */ @@ -2756,8 +2833,8 @@ static Obj HdlrFunc7 ( t_6 = NewFunction( NameFunc[8], 1, 0, HdlrFunc8 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 652); - SET_ENDLINE_BODY(t_7, 670); + SET_STARTLINE_BODY(t_7, 664); + SET_ENDLINE_BODY(t_7, 682); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3360,8 +3437,8 @@ static Obj HdlrFunc11 ( t_1 = NewFunction( NameFunc[12], 1, 0, HdlrFunc12 ); SET_ENVI_FUNC( t_1, STATE(CurrLVars) ); t_2 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_2, 849); - SET_ENDLINE_BODY(t_2, 853); + SET_STARTLINE_BODY(t_2, 861); + SET_ENDLINE_BODY(t_2, 865); SET_FILENAME_BODY(t_2, FileName); SET_BODY_FUNC(t_1, t_2); CHANGED_BAG( STATE(CurrLVars) ); @@ -3440,8 +3517,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[13], 1, 0, HdlrFunc13 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 870); - SET_ENDLINE_BODY(t_7, 870); + SET_STARTLINE_BODY(t_7, 882); + SET_ENDLINE_BODY(t_7, 882); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3515,8 +3592,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[14], 2, 0, HdlrFunc14 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 892); - SET_ENDLINE_BODY(t_7, 915); + SET_STARTLINE_BODY(t_7, 904); + SET_ENDLINE_BODY(t_7, 927); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3564,8 +3641,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[15], 2, 0, HdlrFunc15 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 925); - SET_ENDLINE_BODY(t_7, 933); + SET_STARTLINE_BODY(t_7, 937); + SET_ENDLINE_BODY(t_7, 945); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3626,8 +3703,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[16], 3, 0, HdlrFunc16 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 942); - SET_ENDLINE_BODY(t_7, 955); + SET_STARTLINE_BODY(t_7, 954); + SET_ENDLINE_BODY(t_7, 967); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -4000,8 +4077,8 @@ static Obj HdlrFunc17 ( t_4 = NewFunction( NameFunc[18], -1, 0, HdlrFunc18 ); SET_ENVI_FUNC( t_4, STATE(CurrLVars) ); t_5 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_5, 1021); - SET_ENDLINE_BODY(t_5, 1037); + SET_STARTLINE_BODY(t_5, 1033); + SET_ENDLINE_BODY(t_5, 1049); SET_FILENAME_BODY(t_5, FileName); SET_BODY_FUNC(t_4, t_5); CHANGED_BAG( STATE(CurrLVars) ); @@ -4118,9 +4195,14 @@ static Obj HdlrFunc1 ( CHECK_FUNC_RESULT( t_3 ) CALL_2ARGS( t_1, t_2, t_3 ); - /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, rank, method ) - local methods, narg, i, k, tmp, replace, match, j, lk; + /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, baserank, method ) + local methods, narg, i, k, tmp, replace, match, j, lk, rank; lk := WRITE_LOCK( METHODS_OPERATION_REGION ); + if IS_FUNCTION( baserank ) then + rank := baserank( ); + else + rank := baserank; + fi; if IS_CONSTRUCTOR( opr ) then if 0 = LEN_LIST( flags ) then Error( NAME_FUNC( opr ), ": constructors must have at least one argument" ); @@ -4166,7 +4248,7 @@ static Obj HdlrFunc1 ( od; fi; if not REREADING or not replace then - methods{[ narg + 5 + i + 1 .. narg + 5 + LEN_LIST( methods ) ]} := methods{[ i + 1 .. LEN_LIST( methods ) ]}; + COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 5 + i + 1, 1, LEN_LIST( methods ) - i ); fi; if rel = true then methods[i + 1] := RETURN_TRUE; @@ -4205,6 +4287,9 @@ static Obj HdlrFunc1 ( methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); if 5 >= 5 then methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); + if 5 >= 6 then + methods[i + (narg + 6)] := baserank; + fi; fi; SET_METHODS_OPERATION( opr, narg, MakeReadOnlySingleObj( methods ) ); UNLOCK( lk ); @@ -4216,7 +4301,7 @@ static Obj HdlrFunc1 ( SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); SET_STARTLINE_BODY(t_4, 146); - SET_ENDLINE_BODY(t_4, 274); + SET_ENDLINE_BODY(t_4, 282); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4231,8 +4316,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[4], -1, 0, HdlrFunc4 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 321); - SET_ENDLINE_BODY(t_4, 323); + SET_STARTLINE_BODY(t_4, 331); + SET_ENDLINE_BODY(t_4, 333); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4247,8 +4332,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[5], -1, 0, HdlrFunc5 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 348); - SET_ENDLINE_BODY(t_4, 350); + SET_STARTLINE_BODY(t_4, 358); + SET_ENDLINE_BODY(t_4, 360); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4322,7 +4407,7 @@ static Obj HdlrFunc1 ( od; if not IsBound( arglist[pos] ) then Error( "the method is missing in " ); - elif IS_INT( arglist[pos] ) then + elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then rank := arglist[pos]; pos := pos + 1; else @@ -4417,8 +4502,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[6], 2, 0, HdlrFunc6 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 361); - SET_ENDLINE_BODY(t_4, 591); + SET_STARTLINE_BODY(t_4, 371); + SET_ENDLINE_BODY(t_4, 603); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4476,8 +4561,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[7], 6, 0, HdlrFunc7 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 610); - SET_ENDLINE_BODY(t_3, 674); + SET_STARTLINE_BODY(t_3, 622); + SET_ENDLINE_BODY(t_3, 686); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4491,8 +4576,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[9], 6, 0, HdlrFunc9 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 677); - SET_ENDLINE_BODY(t_3, 683); + SET_STARTLINE_BODY(t_3, 689); + SET_ENDLINE_BODY(t_3, 695); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4520,8 +4605,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[10], 2, 0, HdlrFunc10 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 696); - SET_ENDLINE_BODY(t_4, 720); + SET_STARTLINE_BODY(t_4, 708); + SET_ENDLINE_BODY(t_4, 732); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4605,8 +4690,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[11], 4, 0, HdlrFunc11 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 845); - SET_ENDLINE_BODY(t_4, 956); + SET_STARTLINE_BODY(t_4, 857); + SET_ENDLINE_BODY(t_4, 968); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4657,8 +4742,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[17], -1, 0, HdlrFunc17 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 991); - SET_ENDLINE_BODY(t_4, 1038); + SET_STARTLINE_BODY(t_4, 1003); + SET_ENDLINE_BODY(t_4, 1050); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4735,6 +4820,7 @@ static Int PostRestore ( StructInitInfo * module ) G_RETURN__FALSE = GVarName( "RETURN_FALSE" ); G_LEN__LIST = GVarName( "LEN_LIST" ); G_APPEND__LIST__INTR = GVarName( "APPEND_LIST_INTR" ); + G_COPY__LIST__ENTRIES = GVarName( "COPY_LIST_ENTRIES" ); G_CONV__STRING = GVarName( "CONV_STRING" ); G_Print = GVarName( "Print" ); G_ViewObj = GVarName( "ViewObj" ); @@ -4859,6 +4945,7 @@ static Int InitKernel ( StructInitInfo * module ) InitCopyGVar( "RETURN_FALSE", &GC_RETURN__FALSE ); InitFopyGVar( "LEN_LIST", &GF_LEN__LIST ); InitFopyGVar( "APPEND_LIST_INTR", &GF_APPEND__LIST__INTR ); + InitFopyGVar( "COPY_LIST_ENTRIES", &GF_COPY__LIST__ENTRIES ); InitFopyGVar( "CONV_STRING", &GF_CONV__STRING ); InitFopyGVar( "Print", &GF_Print ); InitCopyGVar( "ViewObj", &GC_ViewObj ); @@ -4981,7 +5068,7 @@ static Int InitLibrary ( StructInitInfo * module ) static StructInitInfo module = { .type = MODULE_STATIC, .name = "GAPROOT/lib/oper1.g", - .crc = 32938550, + .crc = 37165935, .initKernel = InitKernel, .initLibrary = InitLibrary, .postRestore = PostRestore, diff --git a/src/opers.c b/src/opers.c index d0b1dcff570..16a64df1d90 100644 --- a/src/opers.c +++ b/src/opers.c @@ -669,7 +669,7 @@ Obj FuncAND_FLAGS ( Obj HIDDEN_IMPS; Obj WITH_HIDDEN_IMPS_FLAGS_CACHE; -enum { HIDDEN_IMPS_CACHE_LENGTH = 2003 }; +enum { HIDDEN_IMPS_CACHE_LENGTH = 20003 }; /* Forward declaration of FuncFLAGS_FILTER */ Obj FuncFLAGS_FILTER(Obj self, Obj oper); @@ -829,7 +829,7 @@ Obj FuncWITH_HIDDEN_IMPS_FLAGS(Obj self, Obj flags) static Obj IMPLICATIONS_SIMPLE; static Obj IMPLICATIONS_COMPOSED; static Obj WITH_IMPS_FLAGS_CACHE; -enum { IMPS_CACHE_LENGTH = 11001 }; +enum { IMPS_CACHE_LENGTH = 21001 }; /**************************************************************************** ** @@ -1912,7 +1912,7 @@ static Obj NEXT_VMETHOD_PRINT_INFO; // Use of 'ALWAYS_INLINE' is critical for performance, see discussion // earlier in this file. enum { - BASE_SIZE_METHODS_OPER_ENTRY = 5, + BASE_SIZE_METHODS_OPER_ENTRY = 6, }; static ALWAYS_INLINE Obj GetMethodUncached( UInt verbose, UInt constructor, UInt n, Obj methods, Int prec, Obj types[]) @@ -1931,6 +1931,9 @@ static ALWAYS_INLINE Obj GetMethodUncached( // entry n+3 is the rank // entry n+4 is the info text // entry n+5 is, if set, the location where the method was installed + // entry n+6 is, if set, the relative rank that was supplied when + // the method was installed, either as a small integer + // or a function of no arguments // check argument filters against the given types Obj filter; diff --git a/tst/testinstall/method-rankfns.tst b/tst/testinstall/method-rankfns.tst new file mode 100644 index 00000000000..36d101ca2c0 --- /dev/null +++ b/tst/testinstall/method-rankfns.tst @@ -0,0 +1,21 @@ +gap> START_TEST("method-rankfns.tst"); +gap> myOp := NewOperation("myOp",[IsObject]);; +gap> myC := NewConstructor("myC",[IsObject]);; +gap> xxx := 1;; +gap> InstallMethod(myOp,"method1",[IsObject],x->1); +gap> InstallMethod(myOp,"method2",[IsObject],{}->xxx,x->2); +gap> InstallMethod(myC,"cons1",[IsObject],x->1); +gap> InstallMethod(myC,"cons2",[IsObject],{}->xxx,x->2); +gap> myOp(3); +2 +gap> myC(IsObject); +2 +gap> xxx := -1;; +gap> RECALCULATE_ALL_METHOD_RANKS(); +gap> myOp(3); +1 +gap> myC(IsObject); +1 +gap> Unbind(myOp); +gap> Unbind(myC); +gap> STOP_TEST("method-rankfns.tst"); diff --git a/tst/testinstall/method-reordering.tst b/tst/testinstall/method-reordering.tst new file mode 100644 index 00000000000..bbaa97c0ed6 --- /dev/null +++ b/tst/testinstall/method-reordering.tst @@ -0,0 +1,35 @@ +gap> START_TEST("method-reordering.tst"); +gap> CheckReorder := function(explicit) +> local f1, f2, f3, myOp, fam, t, o, o2, myC; +> f1 := NewFilter("filter1",100); +> f2 := NewFilter("filter1",10); +> f3 := NewFilter("filter1",1); +> myOp := NewOperation("myOp", [IsObject]); +> myC := NewConstructor("myC", [IsObject]); +> InstallMethod(myOp, "meth1", [f2], x ->1); +> InstallMethod(myOp, "meth2", [f3], x ->2); +> fam := NewFamily("myFam"); +> t := NewType(fam, IsComponentObjectRep and f2 and f3); +> o := Objectify(t, rec()); +> o2 := Objectify(t, rec()); +> InstallMethod(myC, "cons1", [f2], x ->o); +> InstallMethod(myC, "cons2", [f3], x ->o2); +> if myOp(o) <> 1 or not IsIdenticalObj(myC(IsObject),o2) then +> Error("Initial method selection wrong"); +> fi; +> InstallTrueMethod(f1,f3); +> if explicit then +> RECALCULATE_ALL_METHOD_RANKS(); +> fi; +> return IsIdenticalObj(myC(IsObject),o) and myOp(o) = 2; +> end;; +gap> CheckReorder(false); +true +gap> SuspendMethodReordering(); +gap> CheckReorder(false); +false +gap> CheckReorder(true); +true +gap> ResumeMethodReordering(); +gap> Unbind(CheckReorder); +gap> STOP_TEST("method-reordering.tst"); diff --git a/tst/testinstall/triviso.tst b/tst/testinstall/triviso.tst index 5776ddfa3c1..5b7bacb7929 100644 --- a/tst/testinstall/triviso.tst +++ b/tst/testinstall/triviso.tst @@ -9,11 +9,11 @@ gap> START_TEST("triviso.tst"); gap> G := Group(()); Group(()) gap> phi := IsomorphismPermGroup(G); -[ ] -> [ ] +IdentityMapping( Group(()) ) gap> HasIsBijective(phi); true gap> inv := InverseGeneralMapping(phi); -[ ] -> [ ] +IdentityMapping( Group(()) ) gap> HasIsMapping(inv); true gap> STOP_TEST( "triviso.tst", 1); diff --git a/tst/testinstall/varargs.tst b/tst/testinstall/varargs.tst index f31c64b2ac5..52a749bdc30 100644 --- a/tst/testinstall/varargs.tst +++ b/tst/testinstall/varargs.tst @@ -87,7 +87,7 @@ function ( <>, <>, <>, <>, <>, <> ) end gap> Display(InstallMethod); function ( <>... ) - <> + <> end gap> [1..2]; [ 1, 2 ]