/**************************************************************************** ** *F FuncRNamObj(<self>,<obj>) . . . . convert an object to a record name ** ** 'FuncRNamObj' implements the internal function 'RNamObj'. ** ** 'RNamObj( <obj> )' ** ** 'RNamObj' returns the record name corresponding to the object <obj>, ** which currently must be a string or an integer. */ static Obj FuncRNamObj(Obj self, Obj obj) { return INTOBJ_INT( RNamObj( obj ) ); }
UInt RNamName ( const Char * name ) { Obj rnam; /* record name (as imm intobj) */ UInt pos; /* hash position */ UInt len; /* length of name */ Char namx [1024]; /* temporary copy of <name> */ Obj string; /* temporary string object <name> */ Obj table; /* temporary copy of <HashRNam> */ Obj rnam2; /* one element of <table> */ const Char * p; /* loop variable */ UInt i; /* loop variable */ /* start looking in the table at the following hash position */ pos = 0; len = 0; for ( p = name; *p != '\0'; p++ ) { pos = 65599 * pos + *p; len++; } pos = (pos % SizeRNam) + 1; if(len >= 1023) { // Note: We can't pass 'name' here, as it might get moved by garbage collection ErrorQuit("Record names must consist of less than 1023 characters", 0, 0); } /* look through the table until we find a free slot or the global */ while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0 && strncmp( NAME_RNAM( INT_INTOBJ(rnam) ), name, 1023 ) ) { pos = (pos % SizeRNam) + 1; } /* if we did not find the global variable, make a new one and enter it */ /* (copy the name first, to avoid a stale pointer in case of a GC) */ if ( rnam == 0 ) { CountRNam++; rnam = INTOBJ_INT(CountRNam); SET_ELM_PLIST( HashRNam, pos, rnam ); strlcpy( namx, name, sizeof(namx) ); C_NEW_STRING_DYN(string, namx); GROW_PLIST( NamesRNam, CountRNam ); SET_LEN_PLIST( NamesRNam, CountRNam ); SET_ELM_PLIST( NamesRNam, CountRNam, string ); CHANGED_BAG( NamesRNam ); } /* if the table is too crowed, make a larger one, rehash the names */ if ( SizeRNam < 3 * CountRNam / 2 ) { table = HashRNam; SizeRNam = 2 * SizeRNam + 1; HashRNam = NEW_PLIST( T_PLIST, SizeRNam ); SET_LEN_PLIST( HashRNam, SizeRNam ); for ( i = 1; i <= (SizeRNam-1)/2; i++ ) { rnam2 = ELM_PLIST( table, i ); if ( rnam2 == 0 ) continue; pos = 0; for ( p = NAME_RNAM( INT_INTOBJ(rnam2) ); *p != '\0'; p++ ) { pos = 65599 * pos + *p; } pos = (pos % SizeRNam) + 1; while ( ELM_PLIST( HashRNam, pos ) != 0 ) { pos = (pos % SizeRNam) + 1; } SET_ELM_PLIST( HashRNam, pos, rnam2 ); } } /* return the record name */ return INT_INTOBJ(rnam); }
/* handler for function 2 */ static Obj HdlrFunc2 ( Obj self ) { Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; Obj t_4 = 0; Obj t_5 = 0; Obj t_6 = 0; Bag oldFrame; /* allocate new stack frame */ SWITCH_TO_NEW_FRAME(self,0,0,oldFrame); /* Print( 1, "\n" ); */ t_1 = GF_Print; t_2 = MakeString( "\n" ); CALL_2ARGS( t_1, INTOBJ_INT(1), t_2 ); /* Print( "abc", "\n" ); */ t_1 = GF_Print; t_2 = MakeString( "abc" ); t_3 = MakeString( "\n" ); CALL_2ARGS( t_1, t_2, t_3 ); /* Print( (1,2)(5,6), "\n" ); */ t_1 = GF_Print; t_2 = IdentityPerm; t_4 = NEW_PLIST( T_PLIST, 2 ); SET_LEN_PLIST( t_4, 2 ); t_3 = NEW_PLIST( T_PLIST, 2 ); SET_LEN_PLIST( t_3, 2 ); SET_ELM_PLIST( t_4, 1, t_3 ); CHANGED_BAG( t_4 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(1) ); CHANGED_BAG( t_3 ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(2) ); CHANGED_BAG( t_3 ); t_3 = NEW_PLIST( T_PLIST, 2 ); SET_LEN_PLIST( t_3, 2 ); SET_ELM_PLIST( t_4, 2, t_3 ); CHANGED_BAG( t_4 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(5) ); CHANGED_BAG( t_3 ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(6) ); CHANGED_BAG( t_3 ); t_2 = Array2Perm( t_4 ); t_3 = MakeString( "\n" ); CALL_2ARGS( t_1, t_2, t_3 ); /* Print( [ 1, "abc" ], "\n" ); */ t_1 = GF_Print; t_2 = NEW_PLIST( T_PLIST, 2 ); SET_LEN_PLIST( t_2, 2 ); SET_ELM_PLIST( t_2, 1, INTOBJ_INT(1) ); t_3 = MakeString( "abc" ); SET_ELM_PLIST( t_2, 2, t_3 ); CHANGED_BAG( t_2 ); t_3 = MakeString( "\n" ); CALL_2ARGS( t_1, t_2, t_3 ); /* Print( Group( (1,2,3) ), "\n" ); */ t_1 = GF_Print; t_3 = GF_Group; t_4 = IdentityPerm; t_6 = NEW_PLIST( T_PLIST, 1 ); SET_LEN_PLIST( t_6, 1 ); t_5 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_5, 3 ); SET_ELM_PLIST( t_6, 1, t_5 ); CHANGED_BAG( t_6 ); SET_ELM_PLIST( t_5, 1, INTOBJ_INT(1) ); CHANGED_BAG( t_5 ); SET_ELM_PLIST( t_5, 2, INTOBJ_INT(2) ); CHANGED_BAG( t_5 ); SET_ELM_PLIST( t_5, 3, INTOBJ_INT(3) ); CHANGED_BAG( t_5 ); t_4 = Array2Perm( t_6 ); t_2 = CALL_1ARGS( t_3, t_4 ); CHECK_FUNC_RESULT( t_2 ) t_3 = MakeString( "\n" ); CALL_2ARGS( t_1, t_2, t_3 ); /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; }
/* handler for function 6 */ static Obj HdlrFunc6 ( Obj self ) { Obj t_1 = 0; Bag oldFrame; /* allocate new stack frame */ SWITCH_TO_NEW_FRAME(self,0,0,oldFrame); /* f1( 2 ); */ t_1 = GF_f1; CALL_1ARGS( t_1, INTOBJ_INT(2) ); /* f2( 2, 3 ); */ t_1 = GF_f2; CALL_2ARGS( t_1, INTOBJ_INT(2), INTOBJ_INT(3) ); /* f3( ); */ t_1 = GF_f3; CALL_0ARGS( t_1 ); /* f3( 2 ); */ t_1 = GF_f3; CALL_1ARGS( t_1, INTOBJ_INT(2) ); /* f3( 2, 3, 4 ); */ t_1 = GF_f3; CALL_3ARGS( t_1, INTOBJ_INT(2), INTOBJ_INT(3), INTOBJ_INT(4) ); /* f4( 1 ); */ t_1 = GF_f4; CALL_1ARGS( t_1, INTOBJ_INT(1) ); /* f4( 1, 2 ); */ t_1 = GF_f4; CALL_2ARGS( t_1, INTOBJ_INT(1), INTOBJ_INT(2) ); /* f4( 1, 2, 3 ); */ t_1 = GF_f4; CALL_3ARGS( t_1, INTOBJ_INT(1), INTOBJ_INT(2), INTOBJ_INT(3) ); /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; }
/**************************************************************************** ** *F RNamObjHandler(<self>,<obj>) . . . . convert an object to a record name ** ** 'RNamObjHandler' implements the internal function 'RNamObj'. ** ** 'RNamObj( <obj> )' ** ** 'RNamObj' returns the record name corresponding to the object <obj>, ** which currently must be a string or an integer. */ Obj RNamObjHandler ( Obj self, Obj obj ) { return INTOBJ_INT( RNamObj( obj ) ); }
static void UnbRecObject(Obj obj, UInt rnam) { DoOperation2Args( UnbRecOper, obj, INTOBJ_INT(rnam) ); }
static Obj PREC_MPD(Obj self, Obj f) { return INTOBJ_INT(mpd_get_prec(GET_MPD(f))); }
Obj UNIX_Realtime( Obj self ) /* Time since beginning in seconds */ { static time_t time_since_start = -1; if (time_since_start == (time_t)-1) time_since_start = time(NULL); /* Some non-POSIX UNIX's could have problem with the S-2^31 problem. :-) */ return INTOBJ_INT( time(NULL) - time_since_start ); }
/* handler for function 2 */ static Obj HdlrFunc2 ( Obj self ) { Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; Bag oldFrame; /* allocate new stack frame */ SWITCH_TO_NEW_FRAME(self,0,0,oldFrame); /* Print( AssertionLevel( ), "\n" ); */ t_1 = GF_Print; t_3 = GF_AssertionLevel; t_2 = CALL_0ARGS( t_3 ); CHECK_FUNC_RESULT( t_2 ) t_3 = MakeString( "\n" ); CALL_2ARGS( t_1, t_2, t_3 ); /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(1)) ) { t_2 = False; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { t_2 = MakeString( "fail-A" ); if ( t_2 != (Obj)(UInt)0 ){ if ( IS_STRING_REP ( t_2 ) ) PrintString1( t_2); else PrintObj(t_2); } } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(1)) ) { t_2 = False; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { ErrorReturnVoid("Assertion failure",0L,0L,"you may 'return;'"); } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(0)) ) { t_2 = True; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { t_2 = MakeString( "fail-B" ); if ( t_2 != (Obj)(UInt)0 ){ if ( IS_STRING_REP ( t_2 ) ) PrintString1( t_2); else PrintObj(t_2); } } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(0)) ) { t_2 = True; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { ErrorReturnVoid("Assertion failure",0L,0L,"you may 'return;'"); } } /* SetAssertionLevel( 2 ); */ t_1 = GF_SetAssertionLevel; CALL_1ARGS( t_1, INTOBJ_INT(2) ); /* Print( AssertionLevel( ), "\n" ); */ t_1 = GF_Print; t_3 = GF_AssertionLevel; t_2 = CALL_0ARGS( t_3 ); CHECK_FUNC_RESULT( t_2 ) t_3 = MakeString( "\n" ); CALL_2ARGS( t_1, t_2, t_3 ); /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(3)) ) { t_2 = False; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { t_2 = MakeString( "fail-C" ); if ( t_2 != (Obj)(UInt)0 ){ if ( IS_STRING_REP ( t_2 ) ) PrintString1( t_2); else PrintObj(t_2); } } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(3)) ) { t_2 = False; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { ErrorReturnVoid("Assertion failure",0L,0L,"you may 'return;'"); } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(2)) ) { t_2 = True; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { t_2 = MakeString( "fail-D" ); if ( t_2 != (Obj)(UInt)0 ){ if ( IS_STRING_REP ( t_2 ) ) PrintString1( t_2); else PrintObj(t_2); } } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(2)) ) { t_2 = True; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { ErrorReturnVoid("Assertion failure",0L,0L,"you may 'return;'"); } } /* Assert( ... ); */ if ( ! LT(CurrentAssertionLevel, INTOBJ_INT(2)) ) { t_2 = False; t_1 = (Obj)(UInt)(t_2 != False); if ( ! t_1 ) { t_2 = MakeString( "pass!\n" ); if ( t_2 != (Obj)(UInt)0 ){ if ( IS_STRING_REP ( t_2 ) ) PrintString1( t_2); else PrintObj(t_2); } } } /* Print( "end of function\n" ); */ t_1 = GF_Print; t_2 = MakeString( "end of function\n" ); CALL_1ARGS( t_1, t_2 ); /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; }
Obj MPIcomm_size( Obj self ) { int size; MPI_Comm_size(MPI_COMM_WORLD, &size); return INTOBJ_INT( size ); }
Obj UNIX_Getpid( Obj self ) { return INTOBJ_INT( getpid() ); }
Obj MPIget_tag( Obj self ) { return INTOBJ_INT(last_status.MPI_TAG); }
Obj MPIget_source( Obj self ) { return INTOBJ_INT(last_status.MPI_SOURCE); }
Obj MPIcomm_rank( Obj self ) { int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); return INTOBJ_INT( rank ); }
static Int IsbRecObject(Obj obj, UInt rnam) { return (DoOperation2Args( IsbRecOper, obj, INTOBJ_INT(rnam) ) == True); }
/* handler for function 4 */ static Obj HdlrFunc4 ( Obj self ) { Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; Obj t_4 = 0; Obj t_5 = 0; Bag oldFrame; /* allocate new stack frame */ SWITCH_TO_NEW_FRAME(self,0,0,oldFrame); /* BreakOnError := false; */ t_1 = False; AssGVar( G_BreakOnError, t_1 ); /* CALL_WITH_CATCH( range2, [ 1, 2 ^ 80 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range2; CHECK_BOUND( t_2, "range2" ) t_3 = NEW_PLIST( T_PLIST, 2 ); SET_LEN_PLIST( t_3, 2 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(1) ); t_4 = POW( INTOBJ_INT(2), INTOBJ_INT(80) ); SET_ELM_PLIST( t_3, 2, t_4 ); CHANGED_BAG( t_3 ); CALL_2ARGS( t_1, t_2, t_3 ); /* CALL_WITH_CATCH( range2, [ - 2 ^ 80, 0 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range2; CHECK_BOUND( t_2, "range2" ) t_3 = NEW_PLIST( T_PLIST, 2 ); SET_LEN_PLIST( t_3, 2 ); t_5 = POW( INTOBJ_INT(2), INTOBJ_INT(80) ); C_AINV_FIA( t_4, t_5 ) SET_ELM_PLIST( t_3, 1, t_4 ); CHANGED_BAG( t_3 ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(0) ); CALL_2ARGS( t_1, t_2, t_3 ); /* CALL_WITH_CATCH( range3, [ 1, 2, 2 ^ 80 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range3; CHECK_BOUND( t_2, "range3" ) t_3 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_3, 3 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(1) ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(2) ); t_4 = POW( INTOBJ_INT(2), INTOBJ_INT(80) ); SET_ELM_PLIST( t_3, 3, t_4 ); CHANGED_BAG( t_3 ); CALL_2ARGS( t_1, t_2, t_3 ); /* CALL_WITH_CATCH( range3, [ - 2 ^ 80, 0, 1 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range3; CHECK_BOUND( t_2, "range3" ) t_3 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_3, 3 ); t_5 = POW( INTOBJ_INT(2), INTOBJ_INT(80) ); C_AINV_FIA( t_4, t_5 ) SET_ELM_PLIST( t_3, 1, t_4 ); CHANGED_BAG( t_3 ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(0) ); SET_ELM_PLIST( t_3, 3, INTOBJ_INT(1) ); CALL_2ARGS( t_1, t_2, t_3 ); /* CALL_WITH_CATCH( range3, [ 0, 2 ^ 80, 2 ^ 81 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range3; CHECK_BOUND( t_2, "range3" ) t_3 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_3, 3 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(0) ); t_4 = POW( INTOBJ_INT(2), INTOBJ_INT(80) ); SET_ELM_PLIST( t_3, 2, t_4 ); CHANGED_BAG( t_3 ); t_4 = POW( INTOBJ_INT(2), INTOBJ_INT(81) ); SET_ELM_PLIST( t_3, 3, t_4 ); CHANGED_BAG( t_3 ); CALL_2ARGS( t_1, t_2, t_3 ); /* Display( [ 1, 2 .. 2 ] ); */ t_1 = GF_Display; t_2 = Range3Check( INTOBJ_INT(1), INTOBJ_INT(2), INTOBJ_INT(2) ); CALL_1ARGS( t_1, t_2 ); /* CALL_WITH_CATCH( range3, [ 2, 2, 2 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range3; CHECK_BOUND( t_2, "range3" ) t_3 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_3, 3 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(2) ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(2) ); SET_ELM_PLIST( t_3, 3, INTOBJ_INT(2) ); CALL_2ARGS( t_1, t_2, t_3 ); /* Display( [ 2, 4 .. 6 ] ); */ t_1 = GF_Display; t_2 = Range3Check( INTOBJ_INT(2), INTOBJ_INT(4), INTOBJ_INT(6) ); CALL_1ARGS( t_1, t_2 ); /* CALL_WITH_CATCH( range3, [ 2, 4, 7 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range3; CHECK_BOUND( t_2, "range3" ) t_3 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_3, 3 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(2) ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(4) ); SET_ELM_PLIST( t_3, 3, INTOBJ_INT(7) ); CALL_2ARGS( t_1, t_2, t_3 ); /* Display( [ 2, 4 .. 2 ] ); */ t_1 = GF_Display; t_2 = Range3Check( INTOBJ_INT(2), INTOBJ_INT(4), INTOBJ_INT(2) ); CALL_1ARGS( t_1, t_2 ); /* Display( [ 2, 4 .. 0 ] ); */ t_1 = GF_Display; t_2 = Range3Check( INTOBJ_INT(2), INTOBJ_INT(4), INTOBJ_INT(0) ); CALL_1ARGS( t_1, t_2 ); /* CALL_WITH_CATCH( range3, [ 4, 2, 1 ] ); */ t_1 = GF_CALL__WITH__CATCH; t_2 = GC_range3; CHECK_BOUND( t_2, "range3" ) t_3 = NEW_PLIST( T_PLIST, 3 ); SET_LEN_PLIST( t_3, 3 ); SET_ELM_PLIST( t_3, 1, INTOBJ_INT(4) ); SET_ELM_PLIST( t_3, 2, INTOBJ_INT(2) ); SET_ELM_PLIST( t_3, 3, INTOBJ_INT(1) ); CALL_2ARGS( t_1, t_2, t_3 ); /* Display( [ 4, 2 .. 0 ] ); */ t_1 = GF_Display; t_2 = Range3Check( INTOBJ_INT(4), INTOBJ_INT(2), INTOBJ_INT(0) ); CALL_1ARGS( t_1, t_2 ); /* Display( [ 4, 2 .. 8 ] ); */ t_1 = GF_Display; t_2 = Range3Check( INTOBJ_INT(4), INTOBJ_INT(2), INTOBJ_INT(8) ); CALL_1ARGS( t_1, t_2 ); /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; /* return; */ SWITCH_TO_OLD_FRAME(oldFrame); return 0; }
static void AssRecObject(Obj obj, UInt rnam, Obj val) { DoOperation3Args( AssRecOper, obj, INTOBJ_INT(rnam), val ); }
Obj FuncSTRING_MACFLOAT( Obj self, Obj f) /* backwards compatibility */ { return FuncSTRING_DIGITS_MACFLOAT(self,INTOBJ_INT(PRINTFDIGITS),f); }
UInt RNamNameWithLen(const Char * name, UInt len) { Obj rnam; /* record name (as imm intobj) */ UInt pos; /* hash position */ Char namx [1024]; /* temporary copy of <name> */ Obj string; /* temporary string object <name> */ Obj table; /* temporary copy of <HashRNam> */ Obj rnam2; /* one element of <table> */ UInt i; /* loop variable */ UInt sizeRNam; if (len > 1023) { // Note: We can't pass 'name' here, as it might get moved by garbage collection ErrorQuit("Record names must consist of at most 1023 characters", 0, 0); } /* start looking in the table at the following hash position */ const UInt hash = HashString( name, len ); #ifdef HPCGAP HPC_LockNames(0); /* try a read lock first */ #endif /* look through the table until we find a free slot or the global */ sizeRNam = LEN_PLIST(HashRNam); pos = (hash % sizeRNam) + 1; while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0 && !EqString( NAME_RNAM( INT_INTOBJ(rnam) ), name, len ) ) { pos = (pos % sizeRNam) + 1; } if (rnam != 0) { #ifdef HPCGAP HPC_UnlockNames(); #endif return INT_INTOBJ(rnam); } #ifdef HPCGAP if (!PreThreadCreation) { HPC_UnlockNames(); /* switch to a write lock */ HPC_LockNames(1); /* look through the table until we find a free slot or the global */ sizeRNam = LEN_PLIST(HashRNam); pos = (hash % sizeRNam) + 1; while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0 && !EqString( NAME_RNAM( INT_INTOBJ(rnam) ), name, len ) ) { pos = (pos % sizeRNam) + 1; } } if (rnam != 0) { HPC_UnlockNames(); return INT_INTOBJ(rnam); } #endif /* if we did not find the global variable, make a new one and enter it */ /* (copy the name first, to avoid a stale pointer in case of a GC) */ memcpy( namx, name, len ); namx[len] = 0; string = MakeImmString(namx); const UInt countRNam = PushPlist(NamesRNam, string); rnam = INTOBJ_INT(countRNam); SET_ELM_PLIST( HashRNam, pos, rnam ); /* if the table is too crowded, make a larger one, rehash the names */ if ( sizeRNam < 3 * countRNam / 2 ) { table = HashRNam; sizeRNam = 2 * sizeRNam + 1; HashRNam = NEW_PLIST( T_PLIST, sizeRNam ); SET_LEN_PLIST( HashRNam, sizeRNam ); #ifdef HPCGAP /* The list is briefly non-public, but this is safe, because * the mutex protects it from being accessed by other threads. */ MakeBagPublic(HashRNam); #endif for ( i = 1; i <= (sizeRNam-1)/2; i++ ) { rnam2 = ELM_PLIST( table, i ); if ( rnam2 == 0 ) continue; string = NAME_RNAM( INT_INTOBJ(rnam2) ); pos = HashString( CONST_CSTR_STRING( string ), GET_LEN_STRING( string) ); pos = (pos % sizeRNam) + 1; while ( ELM_PLIST( HashRNam, pos ) != 0 ) { pos = (pos % sizeRNam) + 1; } SET_ELM_PLIST( HashRNam, pos, rnam2 ); } } #ifdef HPCGAP HPC_UnlockNames(); #endif /* return the record name */ return INT_INTOBJ(rnam); }
Obj CollectPolycyc ( Obj pcp, Obj list, Obj word ) { Int ngens = INT_INTOBJ( ADDR_OBJ(pcp)[ PC_NUMBER_OF_GENERATORS ] ); Obj commute = ADDR_OBJ(pcp)[ PC_COMMUTE ]; Obj gens = ADDR_OBJ(pcp)[ PC_GENERATORS ]; Obj igens = ADDR_OBJ(pcp)[ PC_INVERSES ]; Obj pow = ADDR_OBJ(pcp)[ PC_POWERS ]; Obj ipow = ADDR_OBJ(pcp)[ PC_INVERSEPOWERS ]; Obj exp = ADDR_OBJ(pcp)[ PC_EXPONENTS ]; Obj wst = ADDR_OBJ(pcp)[ PC_WORD_STACK ]; Obj west = ADDR_OBJ(pcp)[ PC_WORD_EXPONENT_STACK ]; Obj sst = ADDR_OBJ(pcp)[ PC_SYLLABLE_STACK ]; Obj est = ADDR_OBJ(pcp)[ PC_EXPONENT_STACK ]; Obj conj=0, iconj=0; /*QQ initialize to please compiler */ Int st, bottom = INT_INTOBJ( ADDR_OBJ(pcp)[ PC_STACK_POINTER ] ); Int g, syl, h, hh; Obj e, ee, ge, mge, we, s, t; Obj w, x = (Obj)0, y = (Obj)0; if( LEN_PLIST(word) == 0 ) return (Obj)0; if( LEN_PLIST(list) < ngens ) { ErrorQuit( "vector too short", 0L, 0L ); return (Obj)0; } if( LEN_PLIST(word) % 2 != 0 ) { ErrorQuit( "Length of word odd", 0L, 0L ); return (Obj)0; } st = bottom; PUSH_STACK( word, INTOBJ_INT(1) ); while( st > bottom ) { w = ELM_PLIST( wst, st ); syl = INT_INTOBJ( ELM_PLIST( sst, st ) ); g = INT_INTOBJ( ELM_PLIST( w, syl ) ); if( st > bottom+1 && syl==1 && g == GET_COMMUTE(g) ) { /* Collect word^exponent in one go. */ e = ELM_PLIST( west, st ); /* Add in. */ AddIn( list, w, e ); /* Reduce. */ for( h = g; h <= ngens; h++ ) { s = ELM_PLIST( list, h ); if( IS_INT_ZERO( s ) ) continue; y = (Obj)0; if( (e = GET_EXPONENT( h )) != (Obj)0 ) { if( !LtInt( s, e ) ) { t = ModInt( s, e ); SET_ELM_PLIST( list, h, t ); CHANGED_BAG( list ); if( (y = GET_POWER( h )) ) e = QuoInt( s, e ); } else if( LtInt( s, INTOBJ_INT(0) ) ) { t = ModInt( s, e ); SET_ELM_PLIST( list, h, t ); CHANGED_BAG( list ); if( (y = GET_IPOWER( h )) ) { e = QuoInt( s, e ); if( !IS_INT_ZERO( t ) ) e = DiffInt( e, INTOBJ_INT(1) ); e = AInvInt(e); } } } if( y != (Obj)0 ) AddIn( list, y, e ); } st--; } else { if( g == GET_COMMUTE( g ) ) { s = ELM_PLIST( list, g ); t = ELM_PLIST( est, st ); C_SUM_FIA( ge, s, t ); SET_ELM_PLIST( est, st, INTOBJ_INT(0) ); } else { /* Assume that the top of the exponent stack is non-zero. */ e = ELM_PLIST( est, st ); if( LtInt( INTOBJ_INT(0), e ) ) { C_DIFF_FIA( ee, e, INTOBJ_INT(1) ); e = ee; SET_ELM_PLIST( est, st, e ); conj = ADDR_OBJ(pcp)[PC_CONJUGATES]; iconj = ADDR_OBJ(pcp)[PC_INVERSECONJUGATES]; C_SUM_FIA( ge, ELM_PLIST( list, g ), INTOBJ_INT(1) ); } else { C_SUM_FIA( ee, e, INTOBJ_INT(1) ); e = ee; SET_ELM_PLIST( est, st, e ); conj = ADDR_OBJ(pcp)[PC_CONJUGATESINVERSE]; iconj = ADDR_OBJ(pcp)[PC_INVERSECONJUGATESINVERSE]; C_DIFF_FIA( ge, ELM_PLIST( list, g ), INTOBJ_INT(1) ); } } SET_ELM_PLIST( list, g, ge ); CHANGED_BAG( list ); /* Reduce the exponent. We delay putting the power onto the stack until all the conjugates are on the stack. The power is stored in y, its exponent in ge. */ y = (Obj)0; if( (e = GET_EXPONENT( g )) ) { if( !LtInt( ge, e ) ) { mge = ModInt( ge, e ); SET_ELM_PLIST( list, g, mge ); CHANGED_BAG( list ); if( (y = GET_POWER( g )) ) ge = QuoInt( ge, e ); } else if( LtInt( ge, INTOBJ_INT(0) ) ) { mge = ModInt( ge, e ); SET_ELM_PLIST( list, g, mge ); CHANGED_BAG( list ); if( (y = GET_IPOWER( g )) ) { ge = QuoInt( ge, e ); if( !IS_INT_ZERO( mge ) ) ge = DiffInt( ge, INTOBJ_INT(1) ); ge = AInvInt(ge); } } } hh = h = GET_COMMUTE( g ); /* Find the place where we start to collect. */ for( ; h > g; h-- ) { e = ELM_PLIST( list, h ); if( !IS_INT_ZERO(e) ) { if( LtInt( INTOBJ_INT(0), e ) ) { if( GET_CONJ( h, g ) ) break; } else { if( GET_ICONJ( h, g ) ) break; } } } /* Put those onto the stack, if necessary. */ if( h > g || y != (Obj)0 ) for( ; hh > h; hh-- ) { e = ELM_PLIST( list, hh ); if( !IS_INT_ZERO(e) ) { SET_ELM_PLIST( list, hh, INTOBJ_INT(0) ); if( LtInt( INTOBJ_INT(0), e ) ) { x = ELM_PLIST( gens, hh ); } else { x = ELM_PLIST( igens, hh ); C_PROD_FIA( ee, e, INTOBJ_INT(-1) ); e = ee; } PUSH_STACK( x, e ); } } for( ; h > g; h-- ) { e = ELM_PLIST( list, h ); if( !IS_INT_ZERO(e) ) { SET_ELM_PLIST( list, h, INTOBJ_INT(0) ); x = (Obj)0; if( LtInt( INTOBJ_INT(0), e ) ) x = GET_CONJ( h, g ); else x = GET_ICONJ( h, g ); if( x == (Obj)0 ) { if( LtInt( INTOBJ_INT(0), e ) ) x = ELM_PLIST( gens, h ); else x = ELM_PLIST( igens, h ); } if( LtInt( e, INTOBJ_INT(0) ) ) { C_PROD_FIA( ee, e, INTOBJ_INT(-1) ); e = ee; } PUSH_STACK( x, e ); } } if( y != (Obj)0 ) PUSH_STACK( y, ge ); } while( st > bottom && IS_INT_ZERO( ELM_PLIST( est, st ) ) ) { w = ELM_PLIST( wst, st ); syl = INT_INTOBJ( ELM_PLIST( sst, st ) ) + 2; if( syl > LEN_PLIST( w ) ) { we = DiffInt( ELM_PLIST( west, st ), INTOBJ_INT(1) ); if( EqInt( we, INTOBJ_INT(0) ) ) { st--; } else { SET_ELM_PLIST( west, st, we ); SET_ELM_PLIST( sst, st, INTOBJ_INT(1) ); SET_ELM_PLIST( est, st, ELM_PLIST( w, 2 ) ); CHANGED_BAG( west ); CHANGED_BAG( est ); } } else { SET_ELM_PLIST( sst, st, INTOBJ_INT(syl) ); SET_ELM_PLIST( est, st, ELM_PLIST( w, syl+1 )); CHANGED_BAG( est ); } } } ADDR_OBJ(pcp)[ PC_STACK_POINTER ] = INTOBJ_INT( bottom ); return (Obj)0; }