38static UBYTE underscore[2] = {
'_',0};
52int CatchDollar(
int par)
55 CBUF *C = cbuf + AC.cbufnum;
56 int error = 0, numterms = 0, numdollar, resetmods = 0;
58 WORD *w, *t, n, nsize, *oldwork = AT.WorkPointer, *dbuffer;
59 WORD oldncmod = AN.ncmod;
61 if ( AN.ncmod && ( ( AC.modmode & ALSODOLLARS ) == 0 ) ) AN.ncmod = 0;
62 if ( AN.ncmod && AN.cmod == 0 ) { SetMods(); resetmods = 1; }
64 numdollar = C->lhs[C->numlhs][2];
66 d = Dollars+numdollar;
68 d->type = DOLUNDEFINED;
69 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
70 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
71 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"$-buffer old");
72 d->size = 0; d->where = &(AM.dollarzero);
73 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
75 if ( resetmods ) UnSetMods();
92 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
97 if (
NewSort(BHEAD0) ) {
if ( !error ) error = 1;
goto onerror; }
100 if ( !error ) error = 1;
103 AN.RepPoint = AT.RepCount + 1;
104 w = C->rhs[C->lhs[C->numlhs][5]];
109 AR.Cnumlhs = C->numlhs;
110 if (
Generator(BHEAD oldwork,C->numlhs) ) { error = 1;
break; }
112 AT.WorkPointer = oldwork;
115 if ( ( retval =
EndSort(BHEAD (WORD *)((
void *)(&dbuffer)),2) ) < 0 ) { error = 1; }
117 if ( retval <= 1 || dbuffer == 0 ) {
119 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"$-buffer old");
120 d->size = 0; d->where = &(AM.dollarzero);
121 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
122 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
127 while ( *w ) { w += *w; numterms++; }
130 newsize = (w-dbuffer)+1;
133 if ( AC.RhsExprInModuleFlag )
138 if ( newsize < MINALLOC ) newsize = MINALLOC;
139 newsize = ((newsize+7)/8)*8;
140 if ( numterms == 0 ) {
144 else if ( numterms == 1 ) {
148 if ( nsize < 0 ) { nsize = -nsize; }
149 if ( nsize == (n-1) ) {
152 if ( *w != 1 )
goto doterms;
153 w++;
while ( w < ( t + n - 1 ) ) {
if ( *w )
break; w++; }
154 if ( w < ( t + n - 1 ) )
goto doterms;
158 else if ( n == 7 && t[6] == 3 && t[5] == 1 && t[4] == 1
159 && t[1] == INDEX && t[2] == 3 ) {
169 cbuf[AM.dbufnum].CanCommu[numdollar] = numcommute(dbuffer,
170 &(cbuf[AM.dbufnum].NumTerms[numdollar]));
172 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"$-buffer old");
173 d->size = newsize; d->where = dbuffer;
175 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
177 if ( C->Pointer > C->rhs[C->numrhs] ) C->Pointer = C->rhs[C->numrhs];
178 C->numlhs--; C->numrhs--;
181 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag )
185 if ( resetmods ) UnSetMods();
207int AssignDollar(PHEAD WORD *term, WORD level)
210 CBUF *C = cbuf+AM.rbufnum;
211 int numterms = 0, numdollar = C->lhs[level][2];
213 DOLLARS d = Dollars + numdollar;
214 WORD *w, *t, n, nsize, *rh = cbuf[C->lhs[level][7]].rhs[C->lhs[level][5]];
216 WORD olddefer, oldcompress, oldncmod = AN.ncmod;
218 int nummodopt, dtype = -1, dw;
220 if ( AN.ncmod && ( ( AC.modmode & ALSODOLLARS ) == 0 ) ) AN.ncmod = 0;
221 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
227 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
228 if ( numdollar == ModOptdollars[nummodopt].number )
break;
230 if ( nummodopt >= NumModOptdollars ) {
231 MLOCK(ErrorMessageLock);
232 MesPrint(
"Illegal attempt to change $-variable in multi-threaded module %l",AC.CModule);
233 MUNLOCK(ErrorMessageLock);
236 dtype = ModOptdollars[nummodopt].type;
237 if ( dtype == MODLOCAL ) {
238 d = ModOptdollars[nummodopt].dstruct+AT.identity;
253 LOCK(d->pthreadslock);
256 case DOLZERO:
goto NoChangeZero;
259 if ( ( dw = d->where[0] ) > 0 && d->where[dw] != 0 ) {
262 if ( dtype == MODMAX && d->where[dw-1] >= 0 )
goto NoChangeZero;
263 if ( dtype == MODMIN && d->where[dw-1] <= 0 )
goto NoChangeZero;
266 numvalue = DolToNumber(BHEAD numdollar);
267 if ( AN.ErrorInDollar != 0 )
break;
268 if ( dtype == MODMAX && numvalue >= 0 )
goto NoChangeZero;
269 if ( dtype == MODMIN && numvalue <= 0 )
goto NoChangeZero;
274 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
275 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
277 CleanDollarFactors(d);
278 UNLOCK(d->pthreadslock);
288 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
289 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
290 CleanDollarFactors(d);
294 else if ( *w == 4 && w[4] == 0 && w[2] == 1 ) {
300 LOCK(d->pthreadslock);
301 if ( d->size < MINALLOC ) {
302 WORD oldsize, *oldwhere, i;
303 oldsize = d->size; oldwhere = d->where;
305 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
306 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
308 for ( i = 0; i < oldsize; i++ ) d->where[i] = oldwhere[i];
310 else d->where[0] = 0;
311 if ( oldwhere && oldwhere != &(AM.dollarzero) ) M_free(oldwhere,
"dollar contents");
316 if ( dtype == MODMAX && w[3] <= 0 )
goto NoChangeOne;
317 if ( dtype == MODMIN && w[3] >= 0 )
goto NoChangeOne;
321 if ( ( dw = d->where[0] ) > 0 && d->where[dw] != 0 ) {
324 if ( dtype == MODMAX &&
CompCoef(d->where,w) >= 0 )
goto NoChangeOne;
325 if ( dtype == MODMIN &&
CompCoef(d->where,w) <= 0 )
goto NoChangeOne;
333 numvalue = DolToNumber(BHEAD numdollar);
334 if ( AN.ErrorInDollar != 0 )
break;
335 if ( numvalue == 0 ) {
338 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
339 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
342 d->where[0] = extraterm[0] = 4;
343 d->where[1] = extraterm[1] = ABS(numvalue);
344 d->where[2] = extraterm[2] = 1;
345 d->where[3] = extraterm[3] = numvalue > 0 ? 3 : -3;
348 if ( dtype == MODMAX &&
CompCoef(extraterm,w) >= 0 )
goto NoChangeOne;
349 if ( dtype == MODMIN &&
CompCoef(extraterm,w) <= 0 )
goto NoChangeOne;
359 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
360 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
362 CleanDollarFactors(d);
363 UNLOCK(d->pthreadslock);
371 if ( d->size < MINALLOC ) {
372 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
374 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
375 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
383 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
384 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
385 CleanDollarFactors(d);
395 LOCK(d->pthreadslock);
397 CleanDollarFactors(d);
417 olddefer = AR.DeferFlag; AR.DeferFlag = 0;
418 oldcompress = AR.NoCompress; AR.NoCompress = 1;
420 n = *w; t = ww = AT.WorkPointer;
426 AR.DeferFlag = olddefer;
433 if ( ( newsize =
EndSort(BHEAD (WORD *)((
void *)(&ss)),2) ) < 0 ) {
437 numterms = 0; t = ss;
while ( *t ) { numterms++; t += *t; }
440 if ( numterms == 0 ) {
445 if ( dtype == MODMAX || dtype == MODMIN ) {
446 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
447 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
453 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
454 d->where = &(AM.dollarzero);
456 cbuf[AM.dbufnum].rhs[numdollar] = 0;
457 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
458 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
461 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
468 if ( dtype == MODMAX || dtype == MODMIN ) {
469 if ( numterms == 1 && ( *ss-1 == ABS(ss[*ss-1]) ) ) {
473 if ( dtype == MODMAX && ss[*ss-1] > 0 )
break;
474 if ( dtype == MODMIN && ss[*ss-1] < 0 )
break;
475 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
476 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
480 if ( ( dw = d->where[0] ) > 0 && d->where[dw] != 0 )
break;
481 if ( dtype == MODMAX &&
CompCoef(ss,d->where) > 0 )
break;
482 if ( dtype == MODMIN &&
CompCoef(ss,d->where) < 0 )
break;
483 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
484 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
488 numvalue = DolToNumber(BHEAD numdollar);
489 if ( AN.ErrorInDollar != 0 )
break;
490 if ( numvalue == 0 ) {
493 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
494 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
497 d->where[0] = extraterm[0] = 4;
498 d->where[1] = extraterm[1] = ABS(numvalue);
499 d->where[2] = extraterm[2] = 1;
500 d->where[3] = extraterm[3] = numvalue > 0 ? 3 : -3;
503 if ( dtype == MODMAX &&
CompCoef(ss,extraterm) > 0 )
break;
504 if ( dtype == MODMIN &&
CompCoef(ss,extraterm) < 0 )
break;
505 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
506 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
512 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
513 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
522 if ( d->where && d->where != &(AM.dollarzero) ) { M_free(d->where,
"dollar contents"); d->where = 0; }
523 d->size = newsize + 1;
525 cbuf[AM.dbufnum].rhs[numdollar] = w = d->where;
527 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
531 if ( numterms == 0 ) {
534 else if ( numterms == 1 ) {
538 if ( nsize < 0 ) { nsize = -nsize; }
539 if ( nsize == (n-1) ) {
543 w++;
while ( w < ( t + n - 1 ) ) {
if ( *w )
break; w++; }
544 if ( w >= ( t + n - 1 ) ) d->type = DOLNUMBER;
547 else if ( n == 7 && t[6] == 3 && t[5] == 1 && t[4] == 1
548 && t[1] == INDEX && t[2] == 3 ) {
553 if ( d->type == DOLTERMS ) {
554 cbuf[AM.dbufnum].CanCommu[numdollar] = numcommute(d->where,
555 &(cbuf[AM.dbufnum].NumTerms[numdollar]));
558 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
559 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
563 UNLOCK(d->pthreadslock);
581UBYTE *WriteDollarToBuffer(WORD numdollar, WORD par)
584 UBYTE *s, *oldcurbufwrt = AO.CurBufWrt;
585 WORD *t, lbrac = 0, first = 0, arg[2], oldOutputMode = AC.OutputMode;
586 WORD oldinfbrack = AO.InFbrack;
588 int dict = AO.CurrentDictionary;
590 AO.DollarOutSizeBuffer = 32;
591 AO.DollarOutBuffer = (UBYTE *)Malloc1(AO.DollarOutSizeBuffer,
"DollarOutBuffer");
592 AO.DollarInOutBuffer = 1;
595 s = AO.DollarOutBuffer;
597 if ( par > 0 && AO.CurDictInDollars == 0 ) {
598 AC.OutputMode = NORMALFORMAT;
599 AO.CurrentDictionary = 0;
602 AO.CurBufWrt = (UBYTE *)underscore;
607 WriteArgument(d->where);
610 WriteSubTerm(d->where,1);
616 if ( WriteTerm(t,&lbrac,first,PRINTON,0) ) {
627 if ( *t ) TokenToLine((UBYTE *)(
","));
631 arg[0] = -INDEX; arg[1] = d->index;
636 AO.DollarInOutBuffer = 1;
640 AO.DollarInOutBuffer = 1;
643 AC.OutputMode = oldOutputMode;
645 AO.InFbrack = oldinfbrack;
646 AO.CurBufWrt = oldcurbufwrt;
647 AO.CurrentDictionary = dict;
649 MLOCK(ErrorMessageLock);
650 MesPrint(
"&Illegal dollar object for writing");
651 MUNLOCK(ErrorMessageLock);
652 M_free(AO.DollarOutBuffer,
"DollarOutBuffer");
653 AO.DollarOutBuffer = 0;
654 AO.DollarOutSizeBuffer = 0;
657 return(AO.DollarOutBuffer);
672UBYTE *WriteDollarFactorToBuffer(WORD numdollar, WORD numfac, WORD par)
675 UBYTE *s, *oldcurbufwrt = AO.CurBufWrt;
676 WORD *t, lbrac = 0, first = 0, n[5], oldOutputMode = AC.OutputMode;
677 WORD oldinfbrack = AO.InFbrack;
679 int dict = AO.CurrentDictionary;
681 if ( numfac > d->nfactors || numfac < 0 ) {
682 MLOCK(ErrorMessageLock);
683 MesPrint(
"&Illegal factor number for this dollar variable: %d",numfac);
684 MesPrint(
"&There are %d factors",d->nfactors);
685 MUNLOCK(ErrorMessageLock);
689 AO.DollarOutSizeBuffer = 32;
690 AO.DollarOutBuffer = (UBYTE *)Malloc1(AO.DollarOutSizeBuffer,
"DollarOutBuffer");
691 AO.DollarInOutBuffer = 1;
694 s = AO.DollarOutBuffer;
697 AC.OutputMode = NORMALFORMAT;
698 AO.CurrentDictionary = 0;
701 AO.CurBufWrt = (UBYTE *)underscore;
705 n[0] = 4; n[1] = d->nfactors; n[2] = 1; n[3] = 3; n[4] = 0; t = n;
707 else if ( numfac == 1 && d->factors == 0 ) {
710 else if ( d->factors[numfac-1].where == 0 ) {
711 if ( d->factors[numfac-1].value < 0 ) {
712 n[0] = 4; n[1] = -d->factors[numfac-1].value; n[2] = 1; n[3] = -3; n[4] = 0; t = n;
715 n[0] = 4; n[1] = d->factors[numfac-1].value; n[2] = 1; n[3] = 3; n[4] = 0; t = n;
718 else { t = d->factors[numfac-1].where; }
720 if ( WriteTerm(t,&lbrac,first,PRINTON,0) ) {
725 AC.OutputMode = oldOutputMode;
727 AO.InFbrack = oldinfbrack;
728 AO.CurBufWrt = oldcurbufwrt;
729 AO.CurrentDictionary = dict;
731 MLOCK(ErrorMessageLock);
732 MesPrint(
"&Illegal dollar object for writing");
733 MUNLOCK(ErrorMessageLock);
734 M_free(AO.DollarOutBuffer,
"DollarOutBuffer");
735 AO.DollarOutBuffer = 0;
736 AO.DollarOutSizeBuffer = 0;
739 return(AO.DollarOutBuffer);
747void AddToDollarBuffer(UBYTE *s)
750 UBYTE *t = s, *u, *newdob;
752 while ( *t ) { t++; }
754 while ( i + AO.DollarInOutBuffer >= AO.DollarOutSizeBuffer ) {
755 j = AO.DollarInOutBuffer;
756 AO.DollarOutSizeBuffer *= 2;
757 t = AO.DollarOutBuffer;
758 newdob = (UBYTE *)Malloc1(AO.DollarOutSizeBuffer,
"DollarOutBuffer");
760 while ( --j >= 0 ) *u++ = *t++;
761 M_free(AO.DollarOutBuffer,
"DollarOutBuffer");
762 AO.DollarOutBuffer = newdob;
764 t = AO.DollarOutBuffer + AO.DollarInOutBuffer-1;
765 while ( t == AO.DollarOutBuffer && ( *s ==
'+' || *s ==
' ' ) ) s++;
767 if ( AO.CurrentDictionary == 0 ) {
769 if ( *s ==
' ' ) { s++;
continue; }
774 while ( *s ) { *t++ = *s++; i++; }
777 AO.DollarInOutBuffer += i;
788void TermAssign(WORD *term)
791 WORD *t, *tstop, *astop, *w, *m;
794 astop = term + *term;
795 tstop = astop - ABS(astop[-1]);
797 while ( t < tstop ) {
798 if ( *t == AM.termfunnum && t[1] == FUNHEAD+2
799 && t[FUNHEAD] == -DOLLAREXPRESSION ) {
800 d = Dollars + t[FUNHEAD+1];
801 newsize = *term - FUNHEAD - 1;
802 if ( newsize < MINALLOC ) newsize = MINALLOC;
803 newsize = ((newsize+7)/8)*8;
804 if ( d->size > 2*newsize && d->size > 1000 ) {
805 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
807 d->where = &(AM.dollarzero);
809 if ( d->size < newsize ) {
810 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
812 d->where = (WORD *)Malloc1(newsize*
sizeof(WORD),
"dollar contents");
814 cbuf[AM.dbufnum].rhs[t[FUNHEAD+1]] = w = d->where;
816 while ( m < t ) *w++ = *m++;
818 while ( m < tstop ) {
819 if ( *m == AM.termfunnum && m[1] == FUNHEAD+2
820 && m[FUNHEAD] == -DOLLAREXPRESSION ) { m += m[1]; }
823 while ( --i >= 0 ) *w++ = *m++;
826 while ( m < astop ) *w++ = *m++;
827 *(d->where) = w - d->where;
831 while ( m < astop ) *w++ = *m++;
837 if ( t >= tstop )
return;
848int PutTermInDollar(WORD *term, WORD numdollar)
852 if ( term == 0 || *term == 0 ) {
856 if ( d->size < *term || d->size > 2*term[0] || d->where == 0 ) {
857 if ( d->size > 0 && d->where ) {
858 M_free(d->where,
"dollar contents");
860 d->where = Malloc1((term[0]+1)*
sizeof(WORD),
"dollar contents");
864 for ( i = 0; i < term[0]; i++ ) d->where[i] = term[i];
876void WildDollars(PHEAD WORD *term)
880 WORD *m, *t, *w, *ww, *orig = 0, *wildvalue, *wildstop;
887 m = wildvalue = AN.WildValue;
888 wildstop = AN.WildStop;
891 ww = term + *term; ww -= ABS(ww[-1]); w = term+1;
892 while ( w < ww && *w != SUBEXPRESSION ) w += w[1];
893 if ( w >= ww )
return;
898 while ( m < wildstop ) {
899 if ( *m != LOADDOLLAR ) { m += m[1];
continue; }
901 while ( *t == LOADDOLLAR || *t == FROMSET || *t == SETTONUM ) t -= 4;
902 if ( t < wildvalue ) {
903 MLOCK(ErrorMessageLock);
904 MesPrint(
"&Serious bug in wildcard prototype. Found in WildDollars");
905 MUNLOCK(ErrorMessageLock);
909 d = Dollars + numdollar;
914 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
915 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
916 if ( numdollar == ModOptdollars[nummodopt].number )
break;
918 if ( nummodopt < NumModOptdollars ) {
919 dtype = ModOptdollars[nummodopt].type;
920 if ( dtype == MODLOCAL ) {
921 d = ModOptdollars[nummodopt].dstruct+AT.identity;
924 MLOCK(ErrorMessageLock);
925 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
926 DOLLARNAME(Dollars,numdollar),AC.CModule);
927 MUNLOCK(ErrorMessageLock);
948 orig = cbuf[AT.ebufnum].rhs[t[3]];
949 w = orig;
while ( *w ) w += *w;
950 weneed = w - orig + 1;
961 orig = cbuf[AT.ebufnum].rhs[t[3]];
962 if ( *orig > 0 ) weneed = *orig+2;
964 w = orig+1;
while ( *w ) { NEXTARG(w) }
965 weneed = w - orig + 1;
972 if ( weneed < MINALLOC ) weneed = MINALLOC;
973 weneed = ((weneed+7)/8)*8;
974 if ( d->size > 2*weneed && d->size > 1000 ) {
975 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollarspace");
976 d->where = &(AM.dollarzero);
979 if ( d->size < weneed ) {
980 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollarspace");
981 d->where = (WORD *)Malloc1(weneed*
sizeof(WORD),
"dollarspace");
989 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
990 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
992 cbuf[AM.dbufnum].rhs[numdollar] = (WORD *)(1);
1001 d->where[0] = 4; d->where[2] = 1;
1002 if ( t[3] >= 0 ) { d->where[1] = t[3]; d->where[3] = 3; }
1003 else { d->where[1] = -t[3]; d->where[3] = -3; }
1004 if ( t[3] == 0 ) { d->type = DOLZERO; d->where[0] = 0; }
1005 else { d->type = DOLNUMBER; d->where[4] = 0; }
1022 i = *orig;
while ( --i >= 0 ) *w++ = *orig++;
1030 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[3];
1031 *w++ = 1; *w++ = 1; *w++ = -3; *w = 0;
1034 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[3];
1035 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1038 d->type = DOLINDEX; d->index = t[3]; *w = 0;
1041 *w++ = FUNHEAD+4; *w++ = t[3]; *w++ = FUNHEAD;
1043 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1046 if ( *orig > 0 ) ww = orig + *orig + 1;
1048 ww = orig+1;
while ( *ww ) { NEXTARG(ww) }
1050 while ( orig < ww ) *w++ = *orig++;
1052 d->type = DOLWILDARGS;
1055 d->type = DOLUNDEFINED;
1067WORD DolToTensor(PHEAD WORD numdollar)
1070 DOLLARS d = Dollars + numdollar;
1073 int nummodopt, dtype = -1;
1074 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1075 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1076 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1078 if ( nummodopt < NumModOptdollars ) {
1079 dtype = ModOptdollars[nummodopt].type;
1080 if ( dtype == MODLOCAL ) {
1081 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1084 LOCK(d->pthreadslock);
1089 AN.ErrorInDollar = 0;
1090 if ( d->type == DOLTERMS && d->where[0] == FUNHEAD+4 &&
1091 d->where[FUNHEAD+4] == 0 && d->where[FUNHEAD+3] == 3 &&
1092 d->where[FUNHEAD+2] == 1 && d->where[FUNHEAD+1] == 1 &&
1093 d->where[1] >= FUNCTION && d->where[1] < FUNCTION+WILDOFFSET
1094 && functions[d->where[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1095 retval = d->where[1];
1097 else if ( d->type == DOLARGUMENT &&
1098 d->where[0] <= -FUNCTION && d->where[0] > -FUNCTION-WILDOFFSET
1099 && functions[-d->where[0]-FUNCTION].spec >= TENSORFUNCTION ) {
1100 retval = -d->where[0];
1102 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1103 && d->where[1] <= -FUNCTION && d->where[1] > -FUNCTION-WILDOFFSET
1105 && functions[-d->where[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1106 retval = -d->where[1];
1108 else if ( d->type == DOLSUBTERM &&
1109 d->where[0] >= FUNCTION && d->where[0] < FUNCTION+WILDOFFSET
1110 && functions[d->where[0]-FUNCTION].spec >= TENSORFUNCTION ) {
1111 retval = d->where[0];
1114 AN.ErrorInDollar = 1;
1118 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1128WORD DolToFunction(PHEAD WORD numdollar)
1131 DOLLARS d = Dollars + numdollar;
1134 int nummodopt, dtype = -1;
1135 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1136 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1137 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1139 if ( nummodopt < NumModOptdollars ) {
1140 dtype = ModOptdollars[nummodopt].type;
1141 if ( dtype == MODLOCAL ) {
1142 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1145 LOCK(d->pthreadslock);
1150 AN.ErrorInDollar = 0;
1151 if ( d->type == DOLTERMS && d->where[0] == FUNHEAD+4 &&
1152 d->where[FUNHEAD+4] == 0 && d->where[FUNHEAD+3] == 3 &&
1153 d->where[FUNHEAD+2] == 1 && d->where[FUNHEAD+1] == 1 &&
1154 d->where[1] >= FUNCTION && d->where[1] < FUNCTION+WILDOFFSET ) {
1155 retval = d->where[1];
1157 else if ( d->type == DOLARGUMENT &&
1158 d->where[0] <= -FUNCTION && d->where[0] > -FUNCTION-WILDOFFSET ) {
1159 retval = -d->where[0];
1161 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1162 && d->where[1] <= -FUNCTION && d->where[1] > -FUNCTION-WILDOFFSET
1163 && d->where[2] == 0 ) {
1164 retval = -d->where[1];
1166 else if ( d->type == DOLSUBTERM &&
1167 d->where[0] >= FUNCTION && d->where[0] < FUNCTION+WILDOFFSET ) {
1168 retval = d->where[0];
1171 AN.ErrorInDollar = 1;
1175 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1185WORD DolToVector(PHEAD WORD numdollar)
1188 DOLLARS d = Dollars + numdollar;
1191 int nummodopt, dtype = -1;
1192 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1193 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1194 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1196 if ( nummodopt < NumModOptdollars ) {
1197 dtype = ModOptdollars[nummodopt].type;
1198 if ( dtype == MODLOCAL ) {
1199 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1202 LOCK(d->pthreadslock);
1207 AN.ErrorInDollar = 0;
1208 if ( d->type == DOLINDEX && d->index < 0 ) {
1211 else if ( d->type == DOLARGUMENT && ( d->where[0] == -VECTOR
1212 || d->where[0] == -MINVECTOR ) ) {
1213 retval = d->where[1];
1215 else if ( d->type == DOLSUBTERM && d->where[0] == INDEX
1216 && d->where[1] == 3 && d->where[2] < 0 ) {
1217 retval = d->where[2];
1219 else if ( d->type == DOLTERMS && d->where[0] == 7 &&
1220 d->where[7] == 0 && d->where[6] == 3 &&
1221 d->where[5] == 1 && d->where[4] == 1 &&
1222 d->where[1] >= INDEX && d->where[3] < 0 ) {
1223 retval = d->where[3];
1225 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1226 && ( d->where[1] == -VECTOR || d->where[1] == -MINVECTOR )
1227 && d->where[3] == 0 ) {
1228 retval = d->where[2];
1230 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1231 && d->where[1] < 0 ) {
1232 retval = d->where[1];
1235 AN.ErrorInDollar = 1;
1239 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1249WORD DolToNumber(PHEAD WORD numdollar)
1252 DOLLARS d = Dollars + numdollar;
1254 int nummodopt, dtype = -1;
1255 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1256 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1257 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1259 if ( nummodopt < NumModOptdollars ) {
1260 dtype = ModOptdollars[nummodopt].type;
1261 if ( dtype == MODLOCAL ) {
1262 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1267 AN.ErrorInDollar = 0;
1268 if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1269 && d->where[0] == 4 &&
1270 d->where[4] == 0 && ( d->where[3] == 3 || d->where[3] == -3 )
1271 && d->where[2] == 1 && ( d->where[1] & TOPBITONLY ) == 0 ) {
1272 if ( d->where[3] > 0 )
return(d->where[1]);
1273 else return(-d->where[1]);
1275 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER ) {
1276 return(d->where[1]);
1278 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1279 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1280 return(d->where[1]);
1282 else if ( d->type == DOLZERO )
return(0);
1283 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1284 && d->where[1] == -SNUMBER && d->where[3] == 0 ) {
1285 return(d->where[2]);
1287 else if ( d->type == DOLINDEX && d->index >= 0 && d->index < AM.OffsetIndex ) {
1290 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1291 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1292 return(d->where[1]);
1294 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1295 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0
1296 && d->where[2] < AM.OffsetIndex ) {
1297 return(d->where[2]);
1299 AN.ErrorInDollar = 1;
1308WORD DolToSymbol(PHEAD WORD numdollar)
1311 DOLLARS d = Dollars + numdollar;
1314 int nummodopt, dtype = -1;
1315 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1316 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1317 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1319 if ( nummodopt < NumModOptdollars ) {
1320 dtype = ModOptdollars[nummodopt].type;
1321 if ( dtype == MODLOCAL ) {
1322 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1325 LOCK(d->pthreadslock);
1330 AN.ErrorInDollar = 0;
1331 if ( d->type == DOLTERMS && d->where[0] == 8 &&
1332 d->where[8] == 0 && d->where[7] == 3 && d->where[6] == 1
1333 && d->where[5] == 1 && d->where[4] == 1 && d->where[1] == SYMBOL ) {
1334 retval = d->where[3];
1336 else if ( d->type == DOLARGUMENT && d->where[0] == -SYMBOL ) {
1337 retval = d->where[1];
1339 else if ( d->type == DOLSUBTERM && d->where[0] == SYMBOL
1340 && d->where[1] == 4 && d->where[3] == 1 ) {
1341 retval = d->where[2];
1343 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1344 && d->where[1] == -SYMBOL && d->where[3] == 0 ) {
1345 retval = d->where[2];
1348 AN.ErrorInDollar = 1;
1352 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1362WORD DolToIndex(PHEAD WORD numdollar)
1365 DOLLARS d = Dollars + numdollar;
1368 int nummodopt, dtype = -1;
1369 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1370 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1371 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1373 if ( nummodopt < NumModOptdollars ) {
1374 dtype = ModOptdollars[nummodopt].type;
1375 if ( dtype == MODLOCAL ) {
1376 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1379 LOCK(d->pthreadslock);
1384 AN.ErrorInDollar = 0;
1385 if ( d->type == DOLTERMS && d->where[0] == 7 &&
1386 d->where[7] == 0 && d->where[6] == 3 && d->where[5] == 1
1387 && d->where[4] == 1 && d->where[1] == INDEX && d->where[3] >= 0 ) {
1388 retval = d->where[3];
1390 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER
1391 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1392 retval = d->where[1];
1394 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1395 && d->where[1] >= 0 ) {
1396 retval = d->where[1];
1398 else if ( d->type == DOLZERO )
return(0);
1399 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1400 && d->where[1] == -SNUMBER && d->where[3] == 0 && d->where[2] >= 0
1401 && d->where[2] < AM.OffsetIndex ) {
1402 retval = d->where[2];
1404 else if ( d->type == DOLINDEX && d->index >= 0 ) {
1407 else if ( d->type == DOLNUMBER && d->where[0] == 4 && d->where[2] == 1
1408 && d->where[3] == 3 && d->where[4] == 0 && d->where[1] < AM.OffsetIndex ) {
1409 retval = d->where[1];
1411 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1412 && d->where[1] >= 0 ) {
1413 retval = d->where[1];
1415 else if ( d->type == DOLSUBTERM && d->where[0] == INDEX
1416 && d->where[1] == 3 && d->where[2] >= 0 ) {
1417 retval = d->where[2];
1419 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1420 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0 ) {
1421 retval = d->where[2];
1424 AN.ErrorInDollar = 1;
1428 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1443DOLLARS DolToTerms(PHEAD WORD numdollar)
1447 DOLLARS d = Dollars + numdollar, newd;
1450 int nummodopt, dtype = -1;
1451 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1452 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1453 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1455 if ( nummodopt < NumModOptdollars ) {
1456 dtype = ModOptdollars[nummodopt].type;
1457 if ( dtype == MODLOCAL ) {
1458 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1463 AN.ErrorInDollar = 0;
1464 switch ( d->type ) {
1470 if ( t[0] <= -FUNCTION ) {
1471 *w++ = FUNHEAD+4; *w++ = -t[0];
1472 *w++ = FUNHEAD; FILLFUN(w)
1473 *w++ = 1; *w++ = 1; *w++ = 3;
1475 else if ( t[0] == -SYMBOL ) {
1476 *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = t[1];
1477 *w++ = 1; *w++ = 1; *w++ = 1; *w++ = 3;
1479 else if ( t[0] == -VECTOR || t[0] == -INDEX ) {
1480 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[1];
1481 *w++ = 1; *w++ = 1; *w++ = 3;
1483 else if ( t[0] == -MINVECTOR ) {
1484 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[1];
1485 *w++ = 1; *w++ = 1; *w++ = -3;
1487 else if ( t[0] == -SNUMBER ) {
1490 *w++ = -t[1]; *w++ = 1; *w++ = -3;
1493 *w++ = t[1]; *w++ = 1; *w++ = 3;
1496 *w = 0; size = w - AT.WorkPointer;
1504 while ( *t ) t += *t;
1505 size = t - d->where;
1511 *w++ = size+4; t = d->where; NCOPY(w,t,size)
1512 *w++ = 1; *w++ = 1; *w++ = 3;
1513 w = AT.WorkPointer; size = d->where[1]+4;
1517 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = d->index;
1518 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1519 w = AT.WorkPointer; size = 7;
1526 if ( *t == 0 )
return(0);
1529 MLOCK(ErrorMessageLock);
1530 MesPrint(
"Trying to convert a $ with an argument field into an expression");
1531 MUNLOCK(ErrorMessageLock);
1538 if ( *t < 0 )
goto ShortArgument;
1539 size = *t - ARGHEAD;
1543 MLOCK(ErrorMessageLock);
1544 MesPrint(
"Trying to use an undefined $ in an expression");
1545 MUNLOCK(ErrorMessageLock);
1549 if ( d->where ) { d->where[0] = 0; }
1550 else d->where = &(AM.dollarzero);
1557 newd = (
DOLLARS)Malloc1(
sizeof(
struct DoLlArS)+(size+1)*
sizeof(WORD),
1558 "Copy of dollar variable");
1559 t = (WORD *)(newd+1);
1561 newd->name = d->name;
1562 newd->node = d->node;
1563 newd->type = DOLTERMS;
1565 newd->numdummies = d->numdummies;
1567 INIRECLOCK(newd->pthreadslock);
1571 newd->nfactors = d->nfactors;
1572 if ( d->nfactors > 1 ) {
1573 newd->factors = (
FACDOLLAR *)Malloc1(d->nfactors*
sizeof(
FACDOLLAR),
"Dollar factors");
1574 for ( i = 0; i < d->nfactors; i++ ) {
1575 newd->factors[i].where = 0;
1576 newd->factors[i].size = 0;
1577 newd->factors[i].type = DOLUNDEFINED;
1578 newd->factors[i].value = d->factors[i].value;
1581 else { newd->factors = 0; }
1590LONG DolToLong(PHEAD WORD numdollar)
1593 DOLLARS d = Dollars + numdollar;
1596 int nummodopt, dtype = -1;
1597 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1598 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1599 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1601 if ( nummodopt < NumModOptdollars ) {
1602 dtype = ModOptdollars[nummodopt].type;
1603 if ( dtype == MODLOCAL ) {
1604 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1609 AN.ErrorInDollar = 0;
1610 if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1611 && d->where[0] == 4 &&
1612 d->where[4] == 0 && ( d->where[3] == 3 || d->where[3] == -3 )
1613 && d->where[2] == 1 && ( d->where[1] & TOPBITONLY ) == 0 ) {
1615 if ( d->where[3] > 0 )
return(x);
1618 else if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1619 && d->where[0] == 6 &&
1620 d->where[6] == 0 && ( d->where[5] == 5 || d->where[5] == -5 )
1621 && d->where[3] == 1 && d->where[4] == 1 && ( d->where[2] & TOPBITONLY ) == 0 ) {
1622 x = d->where[1] + ( (LONG)(d->where[2]) << BITSINWORD );
1623 if ( d->where[5] > 0 )
return(x);
1626 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER ) {
1630 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1631 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1635 else if ( d->type == DOLZERO )
return(0);
1636 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1637 && d->where[1] == -SNUMBER && d->where[3] == 0 ) {
1641 else if ( d->type == DOLINDEX && d->index >= 0 && d->index < AM.OffsetIndex ) {
1645 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1646 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1650 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1651 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0
1652 && d->where[2] < AM.OffsetIndex ) {
1656 AN.ErrorInDollar = 1;
1665int ExecInside(UBYTE *s)
1672 if ( AC.insidelevel >= MAXNEST ) {
1673 MLOCK(ErrorMessageLock);
1674 MesPrint(
"@Nesting of inside statements more than %d levels",(WORD)MAXNEST);
1675 MUNLOCK(ErrorMessageLock);
1678 AC.insidesumcheck[AC.insidelevel] = NestingChecksum();
1679 AC.insidestack[AC.insidelevel] = cbuf[AC.cbufnum].Pointer
1680 - cbuf[AC.cbufnum].Buffer + 2;
1685 while ( *s ==
',' ) s++;
1686 if ( *s == 0 )
break;
1689 if ( FG.cTable[*s] != 0 ) {
1690 MLOCK(ErrorMessageLock);
1691 MesPrint(
"Illegal name for $ variable: %s",s-1);
1692 MUNLOCK(ErrorMessageLock);
1695 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
1697 if ( ( number = GetDollar(t) ) < 0 ) {
1698 number = AddDollar(t,0,0,0);
1705 MLOCK(ErrorMessageLock);
1706 MesPrint(
"&Illegal object in Inside statement");
1707 MUNLOCK(ErrorMessageLock);
1709 while ( *s && *s !=
',' && s[1] !=
'$' ) s++;
1710 if ( *s == 0 )
break;
1713 AT.WorkPointer[1] = w - AT.WorkPointer;
1714 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
1730int InsideDollar(PHEAD WORD *ll, WORD level)
1733 int numvar = (int)(ll[1]-3), j, error = 0;
1734 WORD numdol, *oldcterm, *oldwork = AT.WorkPointer, olddefer, *r, *m;
1735 WORD oldnumlhs, *dbuffer;
1737 oldcterm = AN.cTerm; AN.cTerm = 0;
1738 oldnumlhs = AR.Cnumlhs; AR.Cnumlhs = ll[2];
1740 olddefer = AR.DeferFlag;
1742 while ( --numvar >= 0 ) {
1744 d = Dollars + numdol;
1747 int nummodopt, dtype = -1;
1748 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1749 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1750 if ( numdol == ModOptdollars[nummodopt].number )
break;
1752 if ( nummodopt < NumModOptdollars ) {
1753 dtype = ModOptdollars[nummodopt].type;
1754 if ( dtype == MODLOCAL ) {
1755 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1758 LOCK(d->pthreadslock);
1763 newd = DolToTerms(BHEAD numdol);
1767 if ( newd->where[0] == 0 ) {
1770 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1771 M_free(newd,
"Copy of dollar variable");
1779 while ( --j >= 0 ) *m++ = *r++;
1786 error = -1;
goto idcall;
1788 AT.WorkPointer = oldwork;
1791 if (
EndSort(BHEAD (WORD *)((
void *)(&dbuffer)),2) < 0 ) { error = 1;
break; }
1792 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"old buffer of dollar");
1794 if ( dbuffer == 0 || *dbuffer == 0 ) {
1796 if ( dbuffer ) M_free(dbuffer,
"buffer of dollar");
1797 d->where = &(AM.dollarzero); d->size = 0;
1801 r = d->where;
while ( *r ) r += *r;
1802 d->size = (r-d->where)+1;
1805 cbuf[AM.dbufnum].rhs[numdol] = (WORD *)(1);
1810 if ( dtype > 0 && dtype != MODLOCAL ) {
1811 UNLOCK(d->pthreadslock);
1814 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1815 M_free(newd,
"Copy of dollar variable");
1819 AR.Cnumlhs = oldnumlhs;
1820 AR.DeferFlag = olddefer;
1821 AN.cTerm = oldcterm;
1822 AT.WorkPointer = oldwork;
1831void ExchangeDollars(
int num1,
int num2)
1836 d1 = Dollars + num1; node1 = d1->node;
1837 d2 = Dollars + num2; node2 = d2->node;
1838 nam = d1->name; d1->name = d2->name; d2->name = nam;
1839 d1->node = node2; d2->node = node1;
1840 AC.dollarnames->namenode[node1].number = num2;
1841 AC.dollarnames->namenode[node2].number = num1;
1849LONG TermsInDollar(WORD num)
1856 int nummodopt, dtype = -1;
1857 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1858 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1859 if ( num == ModOptdollars[nummodopt].number )
break;
1861 if ( nummodopt < NumModOptdollars ) {
1862 dtype = ModOptdollars[nummodopt].type;
1863 if ( dtype == MODLOCAL ) {
1864 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1867 LOCK(d->pthreadslock);
1872 if ( d->type == DOLTERMS ) {
1875 while ( *t ) { t += *t; n++; }
1877 else if ( d->type == DOLWILDARGS ) {
1879 if ( d->where[0] == 0 ) {
1881 while ( *t != 0 ) { NEXTARG(t); n++; }
1883 else if ( d->where[0] == 1 ) n = 1;
1885 else if ( d->type == DOLZERO ) n = 0;
1888 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1898LONG SizeOfDollar(WORD num)
1905 int nummodopt, dtype = -1;
1906 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1907 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1908 if ( num == ModOptdollars[nummodopt].number )
break;
1910 if ( nummodopt < NumModOptdollars ) {
1911 dtype = ModOptdollars[nummodopt].type;
1912 if ( dtype == MODLOCAL ) {
1913 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1916 LOCK(d->pthreadslock);
1921 if ( d->type == DOLTERMS ) {
1923 while ( *t ) t += *t;
1925 n = (LONG)(t - d->where);
1927 else if ( d->type == DOLWILDARGS ) {
1929 if ( d->where[0] == 0 ) {
1931 while ( *t != 0 ) { NEXTARG(t); n++; }
1933 n = (LONG)(t - d->where);
1935 else if ( d->where[0] == 1 ) n = 1;
1937 else if ( d->type == DOLZERO ) n = 0;
1940 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1960UBYTE *PreIfDollarEval(UBYTE *s,
int *value)
1963 UBYTE *s1,*s2,*s3,*s4,*s5,*t,c,c1,c2,c3;
1965 WORD *buf1 = 0, *buf2 = 0, numset, *oldwork = AT.WorkPointer;
1970 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
1972 while ( *t !=
'=' && *t !=
'!' && *t !=
'>' && *t !=
'<' ) {
1973 if ( *t ==
'[' ) { SKIPBRA1(t) }
1974 else if ( *t ==
'{' ) { SKIPBRA2(t) }
1975 else if ( *t ==
'(' ) { SKIPBRA3(t) }
1976 else if ( *t ==
']' || *t ==
'}' || *t ==
')' ) {
1977 MLOCK(ErrorMessageLock);
1978 MesPrint(
"@Improper bracketting in #if");
1979 MUNLOCK(ErrorMessageLock);
1985 while ( *t ==
'=' || *t ==
'!' || *t ==
'>' || *t ==
'<' ) t++;
1987 while ( *t && *t !=
')' ) {
1988 if ( *t ==
'[' ) { SKIPBRA1(t) }
1989 else if ( *t ==
'{' ) { SKIPBRA2(t) }
1990 else if ( *t ==
'(' ) { SKIPBRA3(t) }
1991 else if ( *t ==
']' || *t ==
'}' ) {
1992 MLOCK(ErrorMessageLock);
1993 MesPrint(
"@Improper brackets in #if");
1994 MUNLOCK(ErrorMessageLock);
2000 MLOCK(ErrorMessageLock);
2001 MesPrint(
"@Missing ) to match $( in #if");
2002 MUNLOCK(ErrorMessageLock);
2005 s4 = t; c2 = *s4; *s4 = 0;
2006 if ( s2+2 < s3 || s2 == s3 ) {
2008 MLOCK(ErrorMessageLock);
2009 MesPrint(
"@Illegal operator in $( option of #if");
2010 MUNLOCK(ErrorMessageLock);
2014 if ( *s2 ==
'=' ) oprtr = EQUAL;
2015 else if ( *s2 ==
'>' ) oprtr = GREATER;
2016 else if ( *s2 ==
'<' ) oprtr = LESS;
2019 else if ( *s2 ==
'!' && s2[1] ==
'=' ) oprtr = NOTEQUAL;
2020 else if ( *s2 ==
'=' && s2[1] ==
'=' ) oprtr = EQUAL;
2021 else if ( *s2 ==
'<' && s2[1] ==
'=' ) oprtr = LESSEQUAL;
2022 else if ( *s2 ==
'>' && s2[1] ==
'=' ) oprtr = GREATEREQUAL;
2029 while ( *s3 ==
' ' || *s3 ==
'\t' || *s3 ==
'\n' || *s3 ==
'\r' ) s3++;
2031 while ( chartype[*t] == 0 ) t++;
2033 t++; c = *t; *t = 0;
2034 if ( StrICmp(s3,(UBYTE *)
"set_") == 0 ) {
2035 if ( oprtr != EQUAL && oprtr != NOTEQUAL ) {
2037 MLOCK(ErrorMessageLock);
2038 MesPrint(
"@Improper operator for special keyword in $( ) option");
2039 MUNLOCK(ErrorMessageLock);
2044 else if ( StrICmp(s3,(UBYTE *)
"multipleof_") == 0 ) {
2045 if ( oprtr != EQUAL && oprtr != NOTEQUAL )
goto ImpOp;
2056 else { type = 0; c = *t; }
2058 *t++ = c; s3 = t; s5 = s4-1;
2059 while ( *s5 !=
')' ) {
2060 if ( *s5 ==
' ' || *s5 ==
'\t' || *s5 ==
'\n' || *s5 ==
'\r' ) s5--;
2062 MLOCK(ErrorMessageLock);
2063 MesPrint(
"@Improper use of special keyword in $( ) option");
2064 MUNLOCK(ErrorMessageLock);
2070 else { c3 = c2; s5 = s4; }
2074 if ( ( buf1 = TranslateExpression(s1) ) == 0 ) {
2075 AT.WorkPointer = oldwork;
2082 numset = DoTempSet(t,s3);
2086 MLOCK(ErrorMessageLock);
2087 MesPrint(
"@Argument of set_ is not a valid set");
2088 MUNLOCK(ErrorMessageLock);
2094 while ( FG.cTable[*s3] == 0 || FG.cTable[*s3] == 1
2095 || *s3 ==
'_' ) s3++;
2097 if ( GetName(AC.varnames,t,&numset,NOAUTO) != CSET ) {
2098 *s3 = c;
goto noset;
2102 while ( *s3 ==
' ' || *s3 ==
'\t' || *s3 ==
'\n' || *s3 ==
'\r' ) s3++;
2103 if ( s3 != s5 )
goto noset;
2104 *value = IsSetMember(buf1,numset);
2105 if ( oprtr == NOTEQUAL ) *value ^= 1;
2108 if ( ( buf2 = TranslateExpression(s3) ) == 0 )
goto onerror;
2111 *value = TwoExprCompare(buf1,buf2,oprtr);
2113 else if ( type == 2 ) {
2114 *value = IsMultipleOf(buf1,buf2);
2115 if ( oprtr == NOTEQUAL ) *value ^= 1;
2123 if ( buf1 ) M_free(buf1,
"Buffer in $()");
2124 if ( buf2 ) M_free(buf2,
"Buffer in $()");
2125 *s5 = c3; *s4++ = c2; *s2 = c1;
2126 AT.WorkPointer = oldwork;
2130 if ( buf1 ) M_free(buf1,
"Buffer in $()");
2131 if ( buf2 ) M_free(buf2,
"Buffer in $()");
2132 AT.WorkPointer = oldwork;
2142WORD *TranslateExpression(UBYTE *s)
2145 CBUF *C = cbuf+AC.cbufnum;
2146 WORD oldnumrhs = C->numrhs;
2147 LONG oldcpointer = C->Pointer - C->Buffer;
2148 WORD *w = AT.WorkPointer;
2149 WORD retcode, oldEside;
2151 *w++ = SUBEXPSIZE + 4;
2153 *w++ = SUBEXPRESSION;
2159 *w++ = 1; *w++ = 1; *w++ = 3; *w++ = 0;
2161 if ( ( retcode = CompileAlgebra(s,RHSIDE,AC.ProtoType) ) < 0 ) {
2162 MLOCK(ErrorMessageLock);
2163 MesPrint(
"@Error translating first expression in $( ) option");
2164 MUNLOCK(ErrorMessageLock);
2167 else { AC.ProtoType[2] = retcode; }
2172 AN.RepPoint = AT.RepCount + 1;
2173 oldEside = AR.Eside; AR.Eside = RHSIDE;
2174 AR.Cnumlhs = C->numlhs;
2175 if (
Generator(BHEAD AC.ProtoType-1,C->numlhs) ) {
2176 AR.Eside = oldEside;
2179 AR.Eside = oldEside;
2184 C->Pointer = C->Buffer + oldcpointer;
2185 C->numrhs = oldnumrhs;
2186 AT.WorkPointer = AC.ProtoType - 1;
2199int IsSetMember(WORD *buffer, WORD numset)
2201 WORD *t = buffer, *tt, num, csize, num1;
2204 if ( numset < AM.NumFixedSets ) {
2205 if ( t[*t] != 0 )
return(0);
2207 if ( numset == POS0_ || numset == NEG0_ || numset == EVEN_
2208 || numset == Z_ || numset == Q_ )
return(1);
2211 if ( numset == SYMBOL_ ) {
2212 if ( *t == 8 && t[1] == SYMBOL && t[7] == 3 && t[6] == 1
2213 && t[5] == 1 && t[4] == 1 )
return(1);
2216 if ( numset == INDEX_ ) {
2217 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2218 && t[4] == 1 && t[3] > 0 )
return(1);
2219 if ( *t == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex)
2223 if ( numset == FIXED_ ) {
2224 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2225 && t[4] == 1 && t[3] > 0 && t[3] < AM.OffsetIndex )
return(1);
2226 if ( *t == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex)
2230 if ( numset == DUMMYINDEX_ ) {
2231 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2232 && t[4] == 1 && t[3] >= AM.IndDum && t[3] < AM.IndDum+MAXDUMMIES )
return(1);
2233 if ( *t == 4 && t[3] == 3 && t[2] == 1
2234 && t[1] >= AM.IndDum && t[1] < AM.IndDum+MAXDUMMIES )
return(1);
2237 if ( numset == VECTOR_ ) {
2238 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2239 && t[4] == 1 && t[3] < (AM.OffsetVector+WILDOFFSET) && t[3] >= AM.OffsetVector )
return(1);
2243 if ( ABS(tt[0]) != *t-1 )
return(0);
2244 if ( numset == Q_ )
return(1);
2245 if ( numset == POS_ || numset == POS0_ )
return(tt[0]>0);
2246 else if ( numset == NEG_ || numset == NEG0_ )
return(tt[0]<0);
2247 i = (ABS(tt[0])-1)/2;
2249 if ( tt[0] != 1 )
return(0);
2250 for ( j = 1; j < i; j++ ) {
if ( tt[j] != 0 )
return(0); }
2251 if ( numset == Z_ )
return(1);
2252 if ( numset == ODD_ )
return(t[1]&1);
2253 if ( numset == EVEN_ )
return(1-(t[1]&1));
2256 if ( t[*t] != 0 )
return(0);
2257 type = Sets[numset].type;
2260 if ( t[0] == 8 && t[1] == SYMBOL && t[7] == 3 && t[6] == 1
2261 && t[5] == 1 && t[4] == 1 ) {
2264 else if ( t[0] == 4 && t[2] == 1 && t[1] <= MAXPOWER ) {
2266 if ( t[3] < 0 ) num = -num;
2272 if ( t[0] == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2273 && t[4] == 1 && t[3] < 0 ) {
2279 if ( t[0] == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2280 && t[4] == 1 && t[3] > 0 ) {
2283 else if ( t[0] == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex ) {
2289 if ( t[0] == 4+FUNHEAD && t[3+FUNHEAD] == 3 && t[2+FUNHEAD] == 1
2290 && t[1+FUNHEAD] == 1 && t[1] >= FUNCTION ) {
2296 if ( t[0] == 4 && t[2] == 1 && t[1] <= AM.OffsetIndex && t[3] == 3 ) {
2304 if ( csize != t[0]-1 )
return(0);
2305 if ( Sets[numset].first < 3*MAXPOWER ) {
2306 num1 = num = Sets[numset].first;
2307 if ( num >= MAXPOWER ) num -= 2*MAXPOWER;
2309 if ( num1 < MAXPOWER ) {
2310 if ( t[t[0]-1] >= 0 )
return(0);
2312 else if ( t[t[0]-1] > 0 )
return(0);
2315 bufterm[0] = 4; bufterm[1] = ABS(num);
2317 if ( num < 0 ) bufterm[3] = -3;
2318 else bufterm[3] = 3;
2320 if ( num1 < MAXPOWER ) {
2321 if ( num >= 0 )
return(0);
2323 else if ( num > 0 )
return(0);
2326 if ( Sets[numset].last > -3*MAXPOWER ) {
2327 num1 = num = Sets[numset].last;
2328 if ( num <= -MAXPOWER ) num += 2*MAXPOWER;
2330 if ( num1 > -MAXPOWER ) {
2331 if ( t[t[0]-1] <= 0 )
return(0);
2333 else if ( t[t[0]-1] < 0 )
return(0);
2336 bufterm[0] = 4; bufterm[1] = ABS(num);
2338 if ( num < 0 ) bufterm[3] = -3;
2339 else bufterm[3] = 3;
2341 if ( num1 > -MAXPOWER ) {
2342 if ( num <= 0 )
return(0);
2344 else if ( num < 0 )
return(0);
2351 t = SetElements + Sets[numset].first;
2352 tt = SetElements + Sets[numset].last;
2354 if ( num == *t )
return(1);
2380int IsMultipleOf(WORD *buf1, WORD *buf2)
2384 WORD *t1, *t2, *m1, *m2, *r1, *r2, nc1, nc2, ni1, ni2;
2385 UWORD *IfScrat1, *IfScrat2;
2387 if ( *buf1 == 0 && *buf2 == 0 )
return(1);
2391 t1 = buf1; t2 = buf2; num1 = 0; num2 = 0;
2392 while ( *t1 ) { t1 += *t1; num1++; }
2393 while ( *t2 ) { t2 += *t2; num2++; }
2394 if ( num1 != num2 )
return(0);
2398 t1 = buf1; t2 = buf2;
2400 m1 = t1+1; m2 = t2+1; t1 += *t1; t2 += *t2;
2401 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2402 if ( r1-m1 != r2-m2 )
return(0);
2404 if ( *m1 != *m2 )
return(0);
2411 IfScrat1 = (UWORD *)(TermMalloc(
"IsMultipleOf")); IfScrat2 = (UWORD *)(TermMalloc(
"IsMultipleOf"));
2412 t1 = buf1; t2 = buf2;
2413 t1 += *t1; t2 += *t2;
2414 if ( *t1 == 0 && *t2 == 0 )
return(1);
2415 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2416 nc1 = REDLENG(t1[-1]); nc2 = REDLENG(t2[-1]);
2417 if ( DivRat(BHEAD (UWORD *)r1,nc1,(UWORD *)r2,nc2,IfScrat1,&ni1) ) {
2418 MLOCK(ErrorMessageLock);
2419 MesPrint(
"@Called from MultipleOf in $( )");
2420 MUNLOCK(ErrorMessageLock);
2421 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2425 t1 += *t1; t2 += *t2;
2426 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2427 nc1 = REDLENG(t1[-1]); nc2 = REDLENG(t2[-1]);
2428 if ( DivRat(BHEAD (UWORD *)r1,nc1,(UWORD *)r2,nc2,IfScrat2,&ni2) ) {
2429 MLOCK(ErrorMessageLock);
2430 MesPrint(
"@Called from MultipleOf in $( )");
2431 MUNLOCK(ErrorMessageLock);
2432 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2435 if ( ni1 != ni2 )
return(0);
2437 for ( j = 0; j < i; j++ ) {
2438 if ( IfScrat1[j] != IfScrat2[j] ) {
2439 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2444 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2455int TwoExprCompare(WORD *buf1, WORD *buf2,
int oprtr)
2458 WORD *t1, *t2, cond;
2459 t1 = buf1; t2 = buf2;
2460 while ( *t1 && *t2 ) {
2461 cond = CompareTerms(BHEAD t1,t2,1);
2465 case EQUAL:
return(0);
2466 case NOTEQUAL:
return(1);
2467 case GREATEREQUAL:
return(0);
2468 case GREATER:
return(0);
2469 case LESS:
return(1);
2470 case LESSEQUAL:
return(1);
2475 case EQUAL:
return(0);
2476 case NOTEQUAL:
return(1);
2477 case GREATEREQUAL:
return(1);
2478 case GREATER:
return(1);
2479 case LESS:
return(0);
2480 case LESSEQUAL:
return(0);
2484 t1 += *t1; t2 += *t2;
2488 case EQUAL:
return(1);
2489 case NOTEQUAL:
return(0);
2490 case GREATEREQUAL:
return(1);
2491 case GREATER:
return(0);
2492 case LESS:
return(0);
2493 case LESSEQUAL:
return(1);
2498 case EQUAL:
return(0);
2499 case NOTEQUAL:
return(1);
2500 case GREATEREQUAL:
return(1);
2501 case GREATER:
return(1);
2502 case LESS:
return(0);
2503 case LESSEQUAL:
return(0);
2508 case EQUAL:
return(0);
2509 case NOTEQUAL:
return(1);
2510 case GREATEREQUAL:
return(0);
2511 case GREATER:
return(0);
2512 case LESS:
return(1);
2513 case LESSEQUAL:
return(1);
2516 MLOCK(ErrorMessageLock);
2517 MesPrint(
"@Internal problems with operator in $( )");
2518 MUNLOCK(ErrorMessageLock);
2531static UWORD *dscrat = 0;
2534int DollarRaiseLow(UBYTE *name, LONG value)
2540 WORD lnum[4], nnum, *t1, *t2, i;
2542 s = name;
while ( *s ) s++;
2543 if ( s[-1] ==
'-' && s[-2] ==
'-' && s > name+2 ) s -= 2;
2544 else if ( s[-1] ==
'+' && s[-2] ==
'+' && s > name+2 ) s -= 2;
2546 num = GetDollar(name);
2549 if ( value < 0 ) { value = -value; sgn = -1; }
2550 if ( d->type == DOLZERO ) {
2551 if ( d->where ) M_free(d->where,
"DollarRaiseLow");
2553 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2554 if ( ( value & AWORDMASK ) != 0 ) {
2555 d->where[0] = 6; d->where[1] = value >> BITSINWORD;
2556 d->where[2] = (WORD)value; d->where[3] = 1; d->where[4] = 0;
2557 d->where[5] = 5*sgn; d->where[6] = 0;
2561 d->where[0] = 4; d->where[1] = (WORD)value; d->where[2] = 1;
2562 d->where[3] = 3*sgn; d->where[4] = 0;
2563 d->type = DOLNUMBER;
2566 else if ( d->type == DOLNUMBER || ( d->type == DOLTERMS
2567 && d->where[d->where[0]] == 0
2568 && d->where[0] == ABS(d->where[d->where[0]-1])+1 ) ) {
2569 if ( ( value & AWORDMASK ) != 0 ) {
2570 lnum[0] = value >> BITSINWORD;
2571 lnum[1] = (WORD)value; lnum[2] = 1; lnum[3] = 0;
2575 lnum[0] = (WORD)value; lnum[1] = 1; nnum = sgn;
2577 i = d->where[d->where[0]-1];
2579 if ( dscrat == 0 ) {
2580 dscrat = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"DollarRaiseLow");
2582 if ( AddRat(BHEAD (UWORD *)(d->where+1),i,
2583 (UWORD *)lnum,nnum,dscrat,&ndscrat) ) {
2584 MLOCK(ErrorMessageLock);
2585 MesCall(
"DollarRaiseLow");
2586 MUNLOCK(ErrorMessageLock);
2589 ndscrat = INCLENG(ndscrat);
2592 M_free(d->where,
"DollarRaiseLow");
2598 if ( i+2 > d->size ) {
2599 M_free(d->where,
"DollarRaiseLow");
2601 if ( d->size < MINALLOC ) d->size = MINALLOC;
2602 d->size = ((d->size+7)/8)*8;
2603 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2605 t1 = d->where; *t1++ = i+1; t2 = (WORD *)dscrat;
2606 while ( --i > 0 ) *t1++ = *t2++;
2607 *t1++ = ndscrat; *t1 = 0;
2635 WORD num, type, *td;
2637 if ( *arg == SNUMBER )
return(arg[1]);
2638 if ( *arg == DOLLAREXPR2 && arg[1] < 0 )
return(-arg[1]-1);
2639 d = Dollars + arg[1];
2642 int nummodopt, dtype = -1;
2643 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2644 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2645 if ( arg[1] == ModOptdollars[nummodopt].number )
break;
2647 if ( nummodopt < NumModOptdollars ) {
2648 dtype = ModOptdollars[nummodopt].type;
2649 if ( dtype == MODLOCAL ) {
2650 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2656 if ( *arg == DOLLAREXPRESSION ) {
2657 if ( arg[2] != DOLLAREXPR2 ) {
2660 if ( type == DOLZERO ) {}
2661 else if ( type == DOLNUMBER ) {
2663 if ( ( td[0] != 4 ) || ( (td[1]&SPECMASK) != 0 ) || ( td[2] != 1 ) ) {
2664 MLOCK(ErrorMessageLock);
2666 MesPrint(
"$-variable is not a short number in print statement");
2669 MesPrint(
"$-variable is not a short number in do loop");
2671 MUNLOCK(ErrorMessageLock);
2674 return( td[3] > 0 ? td[1]: -td[1] );
2677 MLOCK(ErrorMessageLock);
2679 MesPrint(
"$-variable is not a number in print statement");
2682 MesPrint(
"$-variable is not a number in do loop");
2684 MUNLOCK(ErrorMessageLock);
2691 else if ( *arg == DOLLAREXPR2 ) {
2692 if ( arg[1] < 0 ) { num = -arg[1]-1; }
2693 else if ( arg[2] != DOLLAREXPR2 && par == -1 ) {
2699 MLOCK(ErrorMessageLock);
2701 MesPrint(
"Invalid $-variable in print statement");
2704 MesPrint(
"Invalid $-variable in do loop");
2706 MUNLOCK(ErrorMessageLock);
2710 if ( num == 0 )
return(d->nfactors);
2711 if ( num > d->nfactors || num < 1 ) {
2712 MLOCK(ErrorMessageLock);
2714 MesPrint(
"Not a valid factor number for $-variable in print statement");
2717 MesPrint(
"Not a valid factor number for $-variable in do loop");
2719 MUNLOCK(ErrorMessageLock);
2723 if ( d->factors[num].type == DOLNUMBER )
2724 return(d->factors[num].value);
2726 MLOCK(ErrorMessageLock);
2728 MesPrint(
"$-variable in print statement is not a number");
2731 MesPrint(
"$-variable in do loop is not a number");
2733 MUNLOCK(ErrorMessageLock);
2744WORD TestDoLoop(PHEAD WORD *lhsbuf, WORD level)
2747 WORD start,finish,incr;
2752 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2753 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2756 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2757 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2761 if ( ( finish == start ) || ( finish > start && incr > 0 )
2762 || ( finish < start && incr < 0 ) ) {}
2763 else { level = lhsbuf[3]; }
2767 d = Dollars + lhsbuf[2];
2770 int nummodopt, dtype = -1;
2771 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2772 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2773 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2775 if ( nummodopt < NumModOptdollars ) {
2776 dtype = ModOptdollars[nummodopt].type;
2777 if ( dtype == MODLOCAL ) {
2778 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2785 if ( d->size < MINALLOC ) {
2786 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2788 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2792 d->where[1] = start;
2796 d->type = DOLNUMBER;
2798 else if ( start < 0 ) {
2800 d->where[1] = -start;
2804 d->type = DOLNUMBER;
2809 if ( d == Dollars + lhsbuf[2] ) {
2810 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2811 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2812 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2822WORD TestEndDoLoop(PHEAD WORD *lhsbuf, WORD level)
2825 WORD start,finish,incr,value;
2830 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2831 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2834 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2835 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2839 if ( ( finish == start ) || ( finish > start && incr > 0 )
2840 || ( finish < start && incr < 0 ) ) {}
2841 else { level = lhsbuf[3]; }
2845 d = Dollars + lhsbuf[2];
2848 int nummodopt, dtype = -1;
2849 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2850 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2851 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2853 if ( nummodopt < NumModOptdollars ) {
2854 dtype = ModOptdollars[nummodopt].type;
2855 if ( dtype == MODLOCAL ) {
2856 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2865 if ( d->type == DOLZERO ) {
2868 else if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2869 && ( d->where[4] == 0 ) && ( d->where[0] == 4 )
2870 && ( d->where[1] > 0 ) && ( d->where[2] == 1 ) ) {
2871 value = ( d->where[3] < 0 ) ? -d->where[1]: d->where[1];
2874 MLOCK(ErrorMessageLock);
2875 MesPrint(
"Wrong type of object in do loop parameter");
2876 MUNLOCK(ErrorMessageLock);
2881 if ( ( finish > start && value <= finish ) ||
2882 ( finish < start && value >= finish ) ||
2883 ( finish == start && value == finish ) ) {}
2884 else level = lhsbuf[3];
2886 if ( d->size < MINALLOC ) {
2887 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2889 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2893 d->where[1] = value;
2897 d->type = DOLNUMBER;
2899 else if ( start < 0 ) {
2901 d->where[1] = -value;
2905 d->type = DOLNUMBER;
2910 if ( d == Dollars + lhsbuf[2] ) {
2911 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2912 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2913 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2937int DollarFactorize(PHEAD WORD numdollar)
2940 DOLLARS d = Dollars + numdollar;
2942 WORD *oldworkpointer;
2943 WORD *buf1, *t, *term, *buf1content, *buf2, *termextra;
2944 WORD *buf3, *argextra;
2946 WORD *tstop, pow, *r;
2948 int i, j, jj, action = 0, sign = 1;
2950 WORD startebuf = cbuf[AT.ebufnum].numrhs;
2951 WORD nfactors, factorsincontent, extrafactor = 0;
2952 WORD oldsorttype = AR.SortType;
2955 int nummodopt, dtype;
2957 if ( AS.MultiThreaded ) {
2958 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2959 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2961 if ( nummodopt < NumModOptdollars ) {
2962 dtype = ModOptdollars[nummodopt].type;
2963 if ( dtype == MODLOCAL ) {
2964 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2967 LOCK(d->pthreadslock);
2972 CleanDollarFactors(d);
2974 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
2976 if ( d->type != DOLTERMS ) {
2977 if ( d->type != DOLZERO ) d->nfactors = 1;
2980 if ( d->where[d->where[0]] == 0 ) {
2993 AR.SortType = SORTHIGHFIRST;
2994 if ( oldsorttype != AR.SortType ) {
2998 if ( AN.ncmod != 0 ) {
2999 if ( AN.ncmod != 1 || ( (WORD)AN.cmod[0] < 0 ) ) {
3000 AR.SortType = oldsorttype;
3001 MLOCK(ErrorMessageLock);
3002 MesPrint(
"Factorization modulus a number, greater than a WORD not implemented.");
3003 MUNLOCK(ErrorMessageLock);
3006 if ( Modulus(term) ) {
3007 AR.SortType = oldsorttype;
3008 MLOCK(ErrorMessageLock);
3009 MesCall(
"DollarFactorize");
3010 MUNLOCK(ErrorMessageLock);
3013 if ( !*term) { term = t;
continue; }
3019 EndSort(BHEAD (WORD *)((
void *)(&buf1)),2);
3020 t = buf1;
while ( *t ) t += *t;
3024 t = term;
while ( *t ) t += *t;
3025 ii = insize = t - term;
3026 buf1 = (WORD *)Malloc1((insize+1)*
sizeof(WORD),
"DollarFactorize-1");
3036 buf1content = TermMalloc(
"DollarContent");
3038 if ( ( buf2 =
TakeContent(BHEAD buf1,buf1content) ) == 0 ) {
3040 TermFree(buf1content,
"DollarContent");
3041 M_free(buf1,
"DollarFactorize-1");
3042 AR.SortType = oldsorttype;
3043 MLOCK(ErrorMessageLock);
3044 MesCall(
"DollarFactorize");
3045 MUNLOCK(ErrorMessageLock);
3049 else if ( ( buf1content[0] == 4 ) && ( buf1content[1] == 1 ) &&
3050 ( buf1content[2] == 1 ) && ( buf1content[3] == 3 ) ) {
3052 if ( buf2 != buf1 ) {
3053 M_free(buf2,
"DollarFactorize-2");
3056 factorsincontent = 0;
3063 if ( buf2 != buf1 ) M_free(buf1,
"DollarFactorize-1");
3065 t = buf1;
while ( *t ) t += *t;
3070 factorsincontent = 0;
3072 tstop = term + *term;
3073 if ( tstop[-1] < 0 ) factorsincontent++;
3074 if ( ABS(tstop[-1]) == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {
3075 tstop -= ABS(tstop[-1]);
3079 tstop -= ABS(tstop[-1]);
3082 while ( term < tstop ) {
3085 t = term+2; i = (term[1]-2)/2;
3087 factorsincontent += ABS(t[1]);
3092 t = term+2; i = (term[1]-2)/3;
3094 factorsincontent += ABS(t[2]);
3100 factorsincontent += (term[1]-2)/2;
3103 factorsincontent += term[1]-2;
3106 if ( *term >= FUNCTION ) factorsincontent++;
3113 factorsincontent = 0;
3125 if ( ( t[1] != SYMBOL ) && ( *t != (ABS(t[*t-1])+1) ) ) {
3130 if ( DetCommu(buf1) > 1 ) {
3131 MesPrint(
"Cannot factorize a $-expression with more than one noncommuting object");
3132 AR.SortType = oldsorttype;
3133 M_free(buf1,
"DollarFactorize-2");
3134 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3135 MesCall(
"DollarFactorize");
3141 termextra = AT.WorkPointer;
3147 AR.SortType = oldsorttype;
3148 M_free(buf1,
"DollarFactorize-2");
3149 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3150 MesCall(
"DollarFactorize");
3158 if (
EndSort(BHEAD (WORD *)((
void *)(&buf2)),2) < 0 ) {
goto getout; }
3160 t = buf2;
while ( *t > 0 ) t += *t;
3170 MesCall(
"DollarFactorize");
3171 AR.SortType = oldsorttype;
3172 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-3");
3173 M_free(buf1,
"DollarFactorize-3");
3174 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3178 if ( buf2 != buf1 && buf2 ) {
3179 M_free(buf2,
"DollarFactorize-3");
3183 AR.SortType = oldsorttype;
3190 if ( *term == 4 && term[4] == 0 && term[3] == -3 && term[2] == 1
3192 WORD *tt1, *tt2, *ttstop;
3194 tt1 = term; tt2 = term + *term + 1;
3197 while ( *ttstop ) ttstop += *ttstop;
3200 while ( tt2 < ttstop ) *tt1++ = *tt2++;
3209 while ( *term ) { term += *term; }
3224 if ( dtype > 0 && dtype != MODLOCAL ) { LOCK(d->pthreadslock); }
3226 if ( nfactors == 1 && extrafactor == 0 ) {
3227 if ( factorsincontent == 0 ) {
3230 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
3239 term = buf1;
while ( *term ) term += *term;
3240 d->factors[0].size = i = term - buf1;
3241 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3242 term = buf1; NCOPY(t,term,i); *t = 0;
3243 AR.SortType = oldsorttype;
3244 M_free(buf3,
"DollarFactorize-4");
3245 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3246 M_free(buf1,
"DollarFactorize-4");
3247 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3251 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3252 term = buf1;
while ( *term ) term += *term;
3253 d->factors[0].size = i = term - buf1;
3254 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3255 term = buf1; NCOPY(t,term,i); *t = 0;
3256 M_free(buf3,
"DollarFactorize-4");
3258 if ( buf2 != buf1 && buf2 ) {
3259 M_free(buf2,
"DollarFactorize-4");
3264 else if ( action ) {
3265 C = cbuf+AC.cbufnum;
3266 CC = cbuf+AT.ebufnum;
3267 oldworkpointer = AT.WorkPointer;
3268 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3270 for ( i = 0; i < nfactors; i++ ) {
3271 argextra = AT.WorkPointer;
3275 if ( ConvertFromPoly(BHEAD term,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol
3276 ,startebuf-numxsymbol,1) <= 0 ) {
3278getout2: AR.SortType = oldsorttype;
3279 M_free(d->factors,
"factors in dollar");
3282 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
3284 M_free(buf3,
"DollarFactorize-4");
3285 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3286 M_free(buf1,
"DollarFactorize-4");
3287 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3290 AT.WorkPointer = argextra + *argextra;
3294 if (
Generator(BHEAD argextra,C->numlhs+1) ) {
3300 AT.WorkPointer = oldworkpointer;
3302 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3304 d->factors[i].type = DOLTERMS;
3305 t = d->factors[i].where;
3306 while ( *t ) t += *t;
3307 d->factors[i].size = t - d->factors[i].where;
3309 CC->numrhs = startebuf;
3312 C = cbuf+AC.cbufnum;
3313 oldworkpointer = AT.WorkPointer;
3314 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3316 for ( i = 0; i < nfactors; i++ ) {
3319 argextra = oldworkpointer;
3321 NCOPY(argextra,term,j)
3322 AT.WorkPointer = argextra;
3323 if (
Generator(BHEAD oldworkpointer,C->numlhs+1) ) {
3328 AT.WorkPointer = oldworkpointer;
3330 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3331 d->factors[i].type = DOLTERMS;
3332 t = d->factors[i].where;
3333 while ( *t ) t += *t;
3334 d->factors[i].size = t - d->factors[i].where;
3337 d->nfactors = nfactors + factorsincontent;
3342 if ( buf3 ) M_free(buf3,
"DollarFactorize-5");
3343 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-5");
3344 M_free(buf1,
"DollarFactorize-5");
3348 tstop = term + *term;
3349 if ( tstop[-1] < 0 ) { tstop[-1] = -tstop[-1]; sign = -sign; }
3352 while ( term < tstop ) {
3355 t = term+2; i = (term[1]-2)/2;
3357 if ( t[1] < 0 ) { t[1] = -t[1]; pow = -1; }
3359 for ( jj = 0; jj < t[1]; jj++ ) {
3360 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3361 r[0] = 8; r[1] = SYMBOL; r[2] = 4; r[3] = *t; r[4] = pow;
3362 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3363 d->factors[j].type = DOLTERMS;
3364 d->factors[j].size = 8;
3371 t = term+2; i = (term[1]-2)/3;
3373 if ( t[2] < 0 ) { t[2] = -t[2]; pow = -1; }
3375 for ( jj = 0; jj < t[2]; jj++ ) {
3376 r = d->factors[j].where = (WORD *)Malloc1(10*
sizeof(WORD),
"factor");
3377 r[0] = 9; r[1] = DOTPRODUCT; r[2] = 5; r[3] = t[0]; r[4] = t[1];
3378 r[5] = pow; r[6] = 1; r[7] = 1; r[8] = 3; r[9] = 0;
3379 d->factors[j].type = DOLTERMS;
3380 d->factors[j].size = 9;
3388 t = term+2; i = (term[1]-2)/2;
3390 for ( jj = 0; jj < t[1]; jj++ ) {
3391 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3392 r[0] = 8; r[1] = *term; r[2] = 4; r[3] = *t; r[4] = t[1];
3393 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3394 d->factors[j].type = DOLTERMS;
3395 d->factors[j].size = 8;
3402 t = term+2; i = term[1]-2;
3404 for ( jj = 0; jj < t[1]; jj++ ) {
3405 r = d->factors[j].where = (WORD *)Malloc1(8*
sizeof(WORD),
"factor");
3406 r[0] = 7; r[1] = *term; r[2] = 3; r[3] = *t;
3407 r[4] = 1; r[5] = 1; r[6] = 3; r[7] = 0;
3408 d->factors[j].type = DOLTERMS;
3409 d->factors[j].size = 7;
3416 if ( *term >= FUNCTION ) {
3417 r = d->factors[j].where = (WORD *)Malloc1((term[1]+5)*
sizeof(WORD),
"factor");
3418 *r++ = d->factors[j].size = term[1]+4;
3419 for ( jj = 0; jj < t[1]; jj++ ) *r++ = term[jj];
3420 *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3434 tstop = term + *term;
3435 if ( tstop[-1] == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {}
3436 else if ( tstop[-1] == 3 && tstop[-2] == 1 && (UWORD)(tstop[-3]) <= MAXPOSITIVE ) {
3437 d->factors[j].where = 0;
3438 d->factors[j].size = 0;
3439 d->factors[j].type = DOLNUMBER;
3440 d->factors[j].value = sign*tstop[-3];
3445 d->factors[j].where = r = (WORD *)Malloc1((tstop[-1]+2)*
sizeof(WORD),
"numfactor");
3446 d->factors[j].size = tstop[-1]+1;
3447 d->factors[j].type = DOLTERMS;
3448 d->factors[j].value = 0;
3455 r = d->factors[j].where;
3457 r += *r; r[-1] = -r[-1];
3465 for ( jj = j; jj > 0; jj-- ) {
3466 d->factors[jj] = d->factors[jj-1];
3468 d->factors[0].where = 0;
3469 d->factors[0].size = 0;
3470 d->factors[0].type = DOLNUMBER;
3471 d->factors[0].value = -1;
3475 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3483 if ( d->nfactors > 1 ) {
3484 WORD ***fac, j1, j2, k, ret, *s1, *s2, *s3;
3486 facsize = (LONG **)Malloc1((
sizeof(WORD **)+
sizeof(LONG *))*d->nfactors,
"SortDollarFactors");
3487 fac = (WORD ***)(facsize+d->nfactors);
3489 for ( j = 0; j < d->nfactors; j++ ) {
3490 if ( d->factors[j].where ) {
3491 fac[k] = &(d->factors[j].where);
3492 facsize[k] = &(d->factors[j].size);
3497 for ( j = 1; j < k; j++ ) {
3500 s1 = *(fac[j1]); s2 = *(fac[j2]);
3501 while ( *s1 && *s2 ) {
3502 if ( ( ret = CompareTerms(BHEAD s2, s1, (WORD)2) ) == 0 ) {
3503 s1 += *s1; s2 += *s2;
3505 else if ( ret > 0 )
goto nextj;
3508 s3 = *(fac[j1]); *(fac[j1]) = *(fac[j2]); *(fac[j2]) = s3;
3509 x = *(facsize[j1]); *(facsize[j1]) = *(facsize[j2]); *(facsize[j2]) = x;
3511 if ( j1 > 0 )
goto nextj1;
3515 if ( *s1 )
goto nextj;
3516 if ( *s2 )
goto exch;
3520 M_free(facsize,
"SortDollarFactors");
3526 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
3536void CleanDollarFactors(
DOLLARS d)
3539 if ( d->nfactors >= 1 ) {
3540 for ( i = 0; i < d->nfactors; i++ ) {
3542 if ( d->factors[i].where )
3543 M_free(d->factors[i].where,
"dollar factors");
3547 M_free(d->factors,
"dollar factors");
3558WORD *TakeDollarContent(PHEAD WORD *dollarbuffer, WORD **factor)
3565 t = dollarbuffer; pow = 1;
3571 t += *t; t[-1] = -t[-1];
3577 if ( AN.cmod != 0 ) {
3578 if ( ( *factor =
MakeDollarMod(BHEAD dollarbuffer,&remain) ) == 0 ) {
3582 (*factor)[**factor-1] = -(*factor)[**factor-1];
3583 (*factor)[**factor-1] += AN.cmod[0];
3591 (*factor)[**factor-1] = -(*factor)[**factor-1];
3613 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMb, *LCMc;
3614 WORD *r, *r1, *r2, *r3, *rnext, i, k, j, *oldworkpointer, *factor;
3615 WORD kGCD, kLCM, kGCD2, kkLCM, jLCM, jGCD;
3616 CBUF *C = cbuf+AC.cbufnum;
3618 GCDbuffer = NumberMalloc(
"MakeDollarInteger");
3619 GCDbuffer2 = NumberMalloc(
"MakeDollarInteger");
3620 LCMbuffer = NumberMalloc(
"MakeDollarInteger");
3621 LCMb = NumberMalloc(
"MakeDollarInteger");
3622 LCMc = NumberMalloc(
"MakeDollarInteger");
3631 if ( k < 0 ) k = -k;
3632 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3633 for ( kGCD = 0; kGCD < k; kGCD++ ) GCDbuffer[kGCD] = r3[kGCD];
3635 if ( k < 0 ) k = -k;
3637 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3638 for ( kLCM = 0; kLCM < k; kLCM++ ) LCMbuffer[kLCM] = r3[kLCM];
3648 if ( k < 0 ) k = -k;
3649 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3650 if ( ( ( GCDbuffer[0] == 1 ) && ( kGCD == 1 ) ) ) {
3655 else if ( ( ( k != 1 ) || ( r3[0] != 1 ) ) ) {
3656 if ( GcdLong(BHEAD GCDbuffer,kGCD,(UWORD *)r3,k,GCDbuffer2,&kGCD2) ) {
3657 goto MakeDollarIntegerErr;
3660 for ( i = 0; i < kGCD; i++ ) GCDbuffer[i] = GCDbuffer2[i];
3663 kGCD = 1; GCDbuffer[0] = 1;
3666 if ( k < 0 ) k = -k;
3668 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3669 if ( ( ( LCMbuffer[0] == 1 ) && ( kLCM == 1 ) ) ) {
3670 for ( kLCM = 0; kLCM < k; kLCM++ )
3671 LCMbuffer[kLCM] = r3[kLCM];
3673 else if ( ( k != 1 ) || ( r3[0] != 1 ) ) {
3674 if ( GcdLong(BHEAD LCMbuffer,kLCM,(UWORD *)r3,k,LCMb,&kkLCM) ) {
3675 goto MakeDollarIntegerErr;
3677 DivLong((UWORD *)r3,k,LCMb,kkLCM,LCMb,&kkLCM,LCMc,&jLCM);
3678 MulLong(LCMbuffer,kLCM,LCMb,kkLCM,LCMc,&jLCM);
3679 for ( kLCM = 0; kLCM < jLCM; kLCM++ )
3680 LCMbuffer[kLCM] = LCMc[kLCM];
3688 r3 = (WORD *)(GCDbuffer);
3689 if ( kGCD == kLCM ) {
3690 for ( jGCD = 0; jGCD < kGCD; jGCD++ )
3691 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3694 else if ( kGCD > kLCM ) {
3695 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3696 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3697 for ( jGCD = kLCM; jGCD < kGCD; jGCD++ )
3702 for ( jGCD = kGCD; jGCD < kLCM; jGCD++ )
3704 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3705 r3[jGCD+kLCM] = LCMbuffer[jGCD];
3712 factor = r1 = (WORD *)Malloc1((j+2)*
sizeof(WORD),
"MakeDollarInteger");
3713 *r1++ = j+1; r2 = r3;
3714 for ( i = 0; i < k; i++ ) { *r1++ = *r2++; *r1++ = *r2++; }
3727 oldworkpointer = AT.WorkPointer;
3732 r2 = oldworkpointer;
3733 while ( r < r3 ) *r2++ = *r++;
3735 if ( DivRat(BHEAD (UWORD *)r3,j,GCDbuffer,k,(UWORD *)r2,&i) ) {
3736 goto MakeDollarIntegerErr;
3740 if ( rnext[-1] < 0 ) r2[-1] = -i;
3742 *oldworkpointer = r2-oldworkpointer;
3743 AT.WorkPointer = r2;
3744 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3745 goto MakeDollarIntegerErr;
3749 AT.WorkPointer = oldworkpointer;
3751 EndSort(BHEAD (WORD *)bufout,2);
3755 NumberFree(LCMc,
"MakeDollarInteger");
3756 NumberFree(LCMb,
"MakeDollarInteger");
3757 NumberFree(LCMbuffer,
"MakeDollarInteger");
3758 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3759 NumberFree(GCDbuffer,
"MakeDollarInteger");
3762MakeDollarIntegerErr:
3763 NumberFree(LCMc,
"MakeDollarInteger");
3764 NumberFree(LCMb,
"MakeDollarInteger");
3765 NumberFree(LCMbuffer,
"MakeDollarInteger");
3766 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3767 NumberFree(GCDbuffer,
"MakeDollarInteger");
3768 MesCall(
"MakeDollarInteger");
3787 WORD *r, *r1, x, xx, ix, ip;
3788 WORD *factor, *oldworkpointer;
3790 CBUF *C = cbuf+AC.cbufnum;
3793 if ( r[*r-1] < 0 ) x += AN.cmod[0];
3797 factor = (WORD *)Malloc1(5*
sizeof(WORD),
"MakeDollarMod");
3798 factor[0] = 4; factor[1] = x; factor[2] = 1; factor[3] = 3; factor[4] = 0;
3806 oldworkpointer = AT.WorkPointer;
3808 r1 = oldworkpointer; i = *r;
3810 xx = r1[-3];
if ( r1[-1] < 0 ) xx += AN.cmod[0];
3811 r1[-1] = (WORD)((((LONG)xx)*ix) % AN.cmod[0]);
3812 *r1 = 0; AT.WorkPointer = r1;
3813 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3817 AT.WorkPointer = oldworkpointer;
3819 EndSort(BHEAD (WORD *)bufout,2);
3829int GetDolNum(PHEAD WORD *t, WORD *tstop)
3833 if ( t+3 < tstop && t[3] == DOLLAREXPR2 ) {
3837 int nummodopt, dtype;
3839 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3840 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3841 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3843 if ( nummodopt < NumModOptdollars ) {
3844 dtype = ModOptdollars[nummodopt].type;
3845 if ( dtype == MODLOCAL ) {
3846 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3849 MLOCK(ErrorMessageLock);
3850 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3851 DOLLARNAME(Dollars,t[2]),AC.CModule);
3852 MUNLOCK(ErrorMessageLock);
3859 if ( d->factors == 0 ) {
3860 MLOCK(ErrorMessageLock);
3861 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
3862 MUNLOCK(ErrorMessageLock);
3865 num = GetDolNum(BHEAD t+t[1],tstop);
3866 if ( num == 0 )
return(d->nfactors);
3867 if ( num > d->nfactors ) {
3868 MLOCK(ErrorMessageLock);
3869 MesPrint(
"Attempt to use an nonexisting factor %d of a $-variable",num);
3870 MUNLOCK(ErrorMessageLock);
3873 w = d->factors[num-1].where;
3874 if ( w == 0 )
return(d->factors[num-1].value);
3875 if ( w[0] == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1 && w[1] > 0
3876 && w[1] < MAXPOSITIVE )
return(w[1]);
3878 MLOCK(ErrorMessageLock);
3879 MesPrint(
"Illegal type of factor number of a $-variable");
3880 MUNLOCK(ErrorMessageLock);
3884 else if ( t[2] < 0 ) {
3891 int nummodopt, dtype;
3893 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3894 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3895 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3897 if ( nummodopt < NumModOptdollars ) {
3898 dtype = ModOptdollars[nummodopt].type;
3899 if ( dtype == MODLOCAL ) {
3900 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3903 MLOCK(ErrorMessageLock);
3904 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3905 DOLLARNAME(Dollars,t[2]),AC.CModule);
3906 MUNLOCK(ErrorMessageLock);
3913 if ( d->type == DOLZERO )
return(0);
3914 if ( d->type == DOLTERMS || d->type == DOLNUMBER ) {
3915 if ( d->where[0] == 4 && d->where[4] == 0 && d->where[3] == 3
3916 && d->where[2] == 1 && d->where[1] > 0
3917 && d->where[1] < MAXPOSITIVE )
return(d->where[1]);
3918 MLOCK(ErrorMessageLock);
3919 MesPrint(
"Attempt to use an nonexisting factor of a $-variable");
3920 MUNLOCK(ErrorMessageLock);
3923 MLOCK(ErrorMessageLock);
3924 MesPrint(
"Illegal type of factor number of a $-variable");
3925 MUNLOCK(ErrorMessageLock);
3944 int i, n = NumPotModdollars;
3945 for ( i = 0; i < n; i++ ) {
3946 if ( numdollar == PotModdollars[i] )
break;
3949 *(WORD *)FromList(&AC.PotModDolList) = numdollar;
int LocalConvertToPoly(PHEAD WORD *, WORD *, WORD, WORD)
WORD * poly_factorize_dollar(PHEAD WORD *)
WORD CompCoef(WORD *, WORD *)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
WORD * TakeContent(PHEAD WORD *, WORD *)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)
int GetModInverses(WORD, WORD, WORD *, WORD *)
WORD * MakeDollarInteger(PHEAD WORD *bufin, WORD **bufout)
void AddPotModdollar(WORD numdollar)
WORD EvalDoLoopArg(PHEAD WORD *arg, WORD par)
WORD * MakeDollarMod(PHEAD WORD *buffer, WORD **bufout)
int PF_BroadcastPreDollar(WORD **dbuffer, LONG *newsize, int *numterms)