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 ( DollarLocalCopy(dtype) ) {
238 d = ModOptdollars[nummodopt].dstruct+AT.identity;
253 if ( ! DollarLocalCopy(dtype) ) { 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 if ( ! DollarLocalCopy(dtype) ) { 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 if ( ! DollarLocalCopy(dtype) ) { 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 if ( ! DollarLocalCopy(dtype) ) { 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 if ( ! DollarLocalCopy(dtype) ) { 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 if ( ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 ( DollarLocalCopy(dtype) ) {
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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1812 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1813 M_free(newd,
"Copy of dollar variable");
1817 AR.Cnumlhs = oldnumlhs;
1818 AR.DeferFlag = olddefer;
1819 AN.cTerm = oldcterm;
1820 AT.WorkPointer = oldwork;
1829void ExchangeDollars(
int num1,
int num2)
1834 d1 = Dollars + num1; node1 = d1->node;
1835 d2 = Dollars + num2; node2 = d2->node;
1836 nam = d1->name; d1->name = d2->name; d2->name = nam;
1837 d1->node = node2; d2->node = node1;
1838 AC.dollarnames->namenode[node1].number = num2;
1839 AC.dollarnames->namenode[node2].number = num1;
1847LONG TermsInDollar(WORD num)
1854 int nummodopt, dtype = -1;
1855 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1856 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1857 if ( num == ModOptdollars[nummodopt].number )
break;
1859 if ( nummodopt < NumModOptdollars ) {
1860 dtype = ModOptdollars[nummodopt].type;
1861 if ( DollarLocalCopy(dtype) ) {
1862 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1865 LOCK(d->pthreadslock);
1870 if ( d->type == DOLTERMS ) {
1873 while ( *t ) { t += *t; n++; }
1875 else if ( d->type == DOLWILDARGS ) {
1877 if ( d->where[0] == 0 ) {
1879 while ( *t != 0 ) { NEXTARG(t); n++; }
1881 else if ( d->where[0] == 1 ) n = 1;
1883 else if ( d->type == DOLZERO ) n = 0;
1886 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1896LONG SizeOfDollar(WORD num)
1903 int nummodopt, dtype = -1;
1904 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1905 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1906 if ( num == ModOptdollars[nummodopt].number )
break;
1908 if ( nummodopt < NumModOptdollars ) {
1909 dtype = ModOptdollars[nummodopt].type;
1910 if ( DollarLocalCopy(dtype) ) {
1911 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1914 LOCK(d->pthreadslock);
1919 if ( d->type == DOLTERMS ) {
1921 while ( *t ) t += *t;
1923 n = (LONG)(t - d->where);
1925 else if ( d->type == DOLWILDARGS ) {
1927 if ( d->where[0] == 0 ) {
1929 while ( *t != 0 ) { NEXTARG(t); n++; }
1931 n = (LONG)(t - d->where);
1933 else if ( d->where[0] == 1 ) n = 1;
1935 else if ( d->type == DOLZERO ) n = 0;
1938 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1958UBYTE *PreIfDollarEval(UBYTE *s,
int *value)
1961 UBYTE *s1,*s2,*s3,*s4,*s5,*t,c,c1,c2,c3;
1963 WORD *buf1 = 0, *buf2 = 0, numset, *oldwork = AT.WorkPointer;
1968 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
1970 while ( *t !=
'=' && *t !=
'!' && *t !=
'>' && *t !=
'<' ) {
1971 if ( *t ==
'[' ) { SKIPBRA1(t) }
1972 else if ( *t ==
'{' ) { SKIPBRA2(t) }
1973 else if ( *t ==
'(' ) { SKIPBRA3(t) }
1974 else if ( *t ==
']' || *t ==
'}' || *t ==
')' ) {
1975 MLOCK(ErrorMessageLock);
1976 MesPrint(
"@Improper bracketting in #if");
1977 MUNLOCK(ErrorMessageLock);
1983 while ( *t ==
'=' || *t ==
'!' || *t ==
'>' || *t ==
'<' ) t++;
1985 while ( *t && *t !=
')' ) {
1986 if ( *t ==
'[' ) { SKIPBRA1(t) }
1987 else if ( *t ==
'{' ) { SKIPBRA2(t) }
1988 else if ( *t ==
'(' ) { SKIPBRA3(t) }
1989 else if ( *t ==
']' || *t ==
'}' ) {
1990 MLOCK(ErrorMessageLock);
1991 MesPrint(
"@Improper brackets in #if");
1992 MUNLOCK(ErrorMessageLock);
1998 MLOCK(ErrorMessageLock);
1999 MesPrint(
"@Missing ) to match $( in #if");
2000 MUNLOCK(ErrorMessageLock);
2003 s4 = t; c2 = *s4; *s4 = 0;
2004 if ( s2+2 < s3 || s2 == s3 ) {
2006 MLOCK(ErrorMessageLock);
2007 MesPrint(
"@Illegal operator in $( option of #if");
2008 MUNLOCK(ErrorMessageLock);
2012 if ( *s2 ==
'=' ) oprtr = EQUAL;
2013 else if ( *s2 ==
'>' ) oprtr = GREATER;
2014 else if ( *s2 ==
'<' ) oprtr = LESS;
2017 else if ( *s2 ==
'!' && s2[1] ==
'=' ) oprtr = NOTEQUAL;
2018 else if ( *s2 ==
'=' && s2[1] ==
'=' ) oprtr = EQUAL;
2019 else if ( *s2 ==
'<' && s2[1] ==
'=' ) oprtr = LESSEQUAL;
2020 else if ( *s2 ==
'>' && s2[1] ==
'=' ) oprtr = GREATEREQUAL;
2027 while ( *s3 ==
' ' || *s3 ==
'\t' || *s3 ==
'\n' || *s3 ==
'\r' ) s3++;
2029 while ( chartype[*t] == 0 ) t++;
2031 t++; c = *t; *t = 0;
2032 if ( StrICmp(s3,(UBYTE *)
"set_") == 0 ) {
2033 if ( oprtr != EQUAL && oprtr != NOTEQUAL ) {
2035 MLOCK(ErrorMessageLock);
2036 MesPrint(
"@Improper operator for special keyword in $( ) option");
2037 MUNLOCK(ErrorMessageLock);
2042 else if ( StrICmp(s3,(UBYTE *)
"multipleof_") == 0 ) {
2043 if ( oprtr != EQUAL && oprtr != NOTEQUAL )
goto ImpOp;
2054 else { type = 0; c = *t; }
2056 *t++ = c; s3 = t; s5 = s4-1;
2057 while ( *s5 !=
')' ) {
2058 if ( *s5 ==
' ' || *s5 ==
'\t' || *s5 ==
'\n' || *s5 ==
'\r' ) s5--;
2060 MLOCK(ErrorMessageLock);
2061 MesPrint(
"@Improper use of special keyword in $( ) option");
2062 MUNLOCK(ErrorMessageLock);
2068 else { c3 = c2; s5 = s4; }
2072 if ( ( buf1 = TranslateExpression(s1) ) == 0 ) {
2073 AT.WorkPointer = oldwork;
2080 numset = DoTempSet(t,s3);
2084 MLOCK(ErrorMessageLock);
2085 MesPrint(
"@Argument of set_ is not a valid set");
2086 MUNLOCK(ErrorMessageLock);
2092 while ( FG.cTable[*s3] == 0 || FG.cTable[*s3] == 1
2093 || *s3 ==
'_' ) s3++;
2095 if ( GetName(AC.varnames,t,&numset,NOAUTO) != CSET ) {
2096 *s3 = c;
goto noset;
2100 while ( *s3 ==
' ' || *s3 ==
'\t' || *s3 ==
'\n' || *s3 ==
'\r' ) s3++;
2101 if ( s3 != s5 )
goto noset;
2102 *value = IsSetMember(buf1,numset);
2103 if ( oprtr == NOTEQUAL ) *value ^= 1;
2106 if ( ( buf2 = TranslateExpression(s3) ) == 0 )
goto onerror;
2109 *value = TwoExprCompare(buf1,buf2,oprtr);
2111 else if ( type == 2 ) {
2112 *value = IsMultipleOf(buf1,buf2);
2113 if ( oprtr == NOTEQUAL ) *value ^= 1;
2121 if ( buf1 ) M_free(buf1,
"Buffer in $()");
2122 if ( buf2 ) M_free(buf2,
"Buffer in $()");
2123 *s5 = c3; *s4++ = c2; *s2 = c1;
2124 AT.WorkPointer = oldwork;
2128 if ( buf1 ) M_free(buf1,
"Buffer in $()");
2129 if ( buf2 ) M_free(buf2,
"Buffer in $()");
2130 AT.WorkPointer = oldwork;
2140WORD *TranslateExpression(UBYTE *s)
2143 CBUF *C = cbuf+AC.cbufnum;
2144 WORD oldnumrhs = C->numrhs;
2145 LONG oldcpointer = C->Pointer - C->Buffer;
2146 WORD *w = AT.WorkPointer;
2147 WORD retcode, oldEside;
2149 *w++ = SUBEXPSIZE + 4;
2151 *w++ = SUBEXPRESSION;
2157 *w++ = 1; *w++ = 1; *w++ = 3; *w++ = 0;
2159 if ( ( retcode = CompileAlgebra(s,RHSIDE,AC.ProtoType) ) < 0 ) {
2160 MLOCK(ErrorMessageLock);
2161 MesPrint(
"@Error translating first expression in $( ) option");
2162 MUNLOCK(ErrorMessageLock);
2165 else { AC.ProtoType[2] = retcode; }
2170 AN.RepPoint = AT.RepCount + 1;
2171 oldEside = AR.Eside; AR.Eside = RHSIDE;
2172 AR.Cnumlhs = C->numlhs;
2173 if (
Generator(BHEAD AC.ProtoType-1,C->numlhs) ) {
2174 AR.Eside = oldEside;
2177 AR.Eside = oldEside;
2182 C->Pointer = C->Buffer + oldcpointer;
2183 C->numrhs = oldnumrhs;
2184 AT.WorkPointer = AC.ProtoType - 1;
2197int IsSetMember(WORD *buffer, WORD numset)
2199 WORD *t = buffer, *tt, num, csize, num1;
2202 if ( numset < AM.NumFixedSets ) {
2203 if ( t[*t] != 0 )
return(0);
2205 if ( numset == POS0_ || numset == NEG0_ || numset == EVEN_
2206 || numset == Z_ || numset == Q_ )
return(1);
2209 if ( numset == SYMBOL_ ) {
2210 if ( *t == 8 && t[1] == SYMBOL && t[7] == 3 && t[6] == 1
2211 && t[5] == 1 && t[4] == 1 )
return(1);
2214 if ( numset == INDEX_ ) {
2215 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2216 && t[4] == 1 && t[3] > 0 )
return(1);
2217 if ( *t == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex)
2221 if ( numset == FIXED_ ) {
2222 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2223 && t[4] == 1 && t[3] > 0 && t[3] < AM.OffsetIndex )
return(1);
2224 if ( *t == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex)
2228 if ( numset == DUMMYINDEX_ ) {
2229 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2230 && t[4] == 1 && t[3] >= AM.IndDum && t[3] < AM.IndDum+MAXDUMMIES )
return(1);
2231 if ( *t == 4 && t[3] == 3 && t[2] == 1
2232 && t[1] >= AM.IndDum && t[1] < AM.IndDum+MAXDUMMIES )
return(1);
2235 if ( numset == VECTOR_ ) {
2236 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2237 && t[4] == 1 && t[3] < (AM.OffsetVector+WILDOFFSET) && t[3] >= AM.OffsetVector )
return(1);
2241 if ( ABS(tt[0]) != *t-1 )
return(0);
2242 if ( numset == Q_ )
return(1);
2243 if ( numset == POS_ || numset == POS0_ )
return(tt[0]>0);
2244 else if ( numset == NEG_ || numset == NEG0_ )
return(tt[0]<0);
2245 i = (ABS(tt[0])-1)/2;
2247 if ( tt[0] != 1 )
return(0);
2248 for ( j = 1; j < i; j++ ) {
if ( tt[j] != 0 )
return(0); }
2249 if ( numset == Z_ )
return(1);
2250 if ( numset == ODD_ )
return(t[1]&1);
2251 if ( numset == EVEN_ )
return(1-(t[1]&1));
2254 if ( t[*t] != 0 )
return(0);
2255 type = Sets[numset].type;
2258 if ( t[0] == 8 && t[1] == SYMBOL && t[7] == 3 && t[6] == 1
2259 && t[5] == 1 && t[4] == 1 ) {
2262 else if ( t[0] == 4 && t[2] == 1 && t[1] <= MAXPOWER ) {
2264 if ( t[3] < 0 ) num = -num;
2270 if ( t[0] == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2271 && t[4] == 1 && t[3] < 0 ) {
2277 if ( t[0] == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2278 && t[4] == 1 && t[3] > 0 ) {
2281 else if ( t[0] == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex ) {
2287 if ( t[0] == 4+FUNHEAD && t[3+FUNHEAD] == 3 && t[2+FUNHEAD] == 1
2288 && t[1+FUNHEAD] == 1 && t[1] >= FUNCTION ) {
2294 if ( t[0] == 4 && t[2] == 1 && t[1] <= AM.OffsetIndex && t[3] == 3 ) {
2302 if ( csize != t[0]-1 )
return(0);
2303 if ( Sets[numset].first < 3*MAXPOWER ) {
2304 num1 = num = Sets[numset].first;
2305 if ( num >= MAXPOWER ) num -= 2*MAXPOWER;
2307 if ( num1 < MAXPOWER ) {
2308 if ( t[t[0]-1] >= 0 )
return(0);
2310 else if ( t[t[0]-1] > 0 )
return(0);
2313 bufterm[0] = 4; bufterm[1] = ABS(num);
2315 if ( num < 0 ) bufterm[3] = -3;
2316 else bufterm[3] = 3;
2318 if ( num1 < MAXPOWER ) {
2319 if ( num >= 0 )
return(0);
2321 else if ( num > 0 )
return(0);
2324 if ( Sets[numset].last > -3*MAXPOWER ) {
2325 num1 = num = Sets[numset].last;
2326 if ( num <= -MAXPOWER ) num += 2*MAXPOWER;
2328 if ( num1 > -MAXPOWER ) {
2329 if ( t[t[0]-1] <= 0 )
return(0);
2331 else if ( t[t[0]-1] < 0 )
return(0);
2334 bufterm[0] = 4; bufterm[1] = ABS(num);
2336 if ( num < 0 ) bufterm[3] = -3;
2337 else bufterm[3] = 3;
2339 if ( num1 > -MAXPOWER ) {
2340 if ( num <= 0 )
return(0);
2342 else if ( num < 0 )
return(0);
2349 t = SetElements + Sets[numset].first;
2350 tt = SetElements + Sets[numset].last;
2352 if ( num == *t )
return(1);
2378int IsMultipleOf(WORD *buf1, WORD *buf2)
2382 WORD *t1, *t2, *m1, *m2, *r1, *r2, nc1, nc2, ni1, ni2;
2383 UWORD *IfScrat1, *IfScrat2;
2385 if ( *buf1 == 0 && *buf2 == 0 )
return(1);
2389 t1 = buf1; t2 = buf2; num1 = 0; num2 = 0;
2390 while ( *t1 ) { t1 += *t1; num1++; }
2391 while ( *t2 ) { t2 += *t2; num2++; }
2392 if ( num1 != num2 )
return(0);
2396 t1 = buf1; t2 = buf2;
2398 m1 = t1+1; m2 = t2+1; t1 += *t1; t2 += *t2;
2399 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2400 if ( r1-m1 != r2-m2 )
return(0);
2402 if ( *m1 != *m2 )
return(0);
2409 IfScrat1 = (UWORD *)(TermMalloc(
"IsMultipleOf")); IfScrat2 = (UWORD *)(TermMalloc(
"IsMultipleOf"));
2410 t1 = buf1; t2 = buf2;
2411 t1 += *t1; t2 += *t2;
2412 if ( *t1 == 0 && *t2 == 0 )
return(1);
2413 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2414 nc1 = REDLENG(t1[-1]); nc2 = REDLENG(t2[-1]);
2415 if ( DivRat(BHEAD (UWORD *)r1,nc1,(UWORD *)r2,nc2,IfScrat1,&ni1) ) {
2416 MLOCK(ErrorMessageLock);
2417 MesPrint(
"@Called from MultipleOf in $( )");
2418 MUNLOCK(ErrorMessageLock);
2419 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2423 t1 += *t1; t2 += *t2;
2424 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2425 nc1 = REDLENG(t1[-1]); nc2 = REDLENG(t2[-1]);
2426 if ( DivRat(BHEAD (UWORD *)r1,nc1,(UWORD *)r2,nc2,IfScrat2,&ni2) ) {
2427 MLOCK(ErrorMessageLock);
2428 MesPrint(
"@Called from MultipleOf in $( )");
2429 MUNLOCK(ErrorMessageLock);
2430 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2433 if ( ni1 != ni2 )
return(0);
2435 for ( j = 0; j < i; j++ ) {
2436 if ( IfScrat1[j] != IfScrat2[j] ) {
2437 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2442 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2453int TwoExprCompare(WORD *buf1, WORD *buf2,
int oprtr)
2456 WORD *t1, *t2, cond;
2457 t1 = buf1; t2 = buf2;
2458 while ( *t1 && *t2 ) {
2459 cond = CompareTerms(BHEAD t1,t2,1);
2463 case EQUAL:
return(0);
2464 case NOTEQUAL:
return(1);
2465 case GREATEREQUAL:
return(0);
2466 case GREATER:
return(0);
2467 case LESS:
return(1);
2468 case LESSEQUAL:
return(1);
2473 case EQUAL:
return(0);
2474 case NOTEQUAL:
return(1);
2475 case GREATEREQUAL:
return(1);
2476 case GREATER:
return(1);
2477 case LESS:
return(0);
2478 case LESSEQUAL:
return(0);
2482 t1 += *t1; t2 += *t2;
2486 case EQUAL:
return(1);
2487 case NOTEQUAL:
return(0);
2488 case GREATEREQUAL:
return(1);
2489 case GREATER:
return(0);
2490 case LESS:
return(0);
2491 case LESSEQUAL:
return(1);
2496 case EQUAL:
return(0);
2497 case NOTEQUAL:
return(1);
2498 case GREATEREQUAL:
return(1);
2499 case GREATER:
return(1);
2500 case LESS:
return(0);
2501 case LESSEQUAL:
return(0);
2506 case EQUAL:
return(0);
2507 case NOTEQUAL:
return(1);
2508 case GREATEREQUAL:
return(0);
2509 case GREATER:
return(0);
2510 case LESS:
return(1);
2511 case LESSEQUAL:
return(1);
2514 MLOCK(ErrorMessageLock);
2515 MesPrint(
"@Internal problems with operator in $( )");
2516 MUNLOCK(ErrorMessageLock);
2529static UWORD *dscrat = 0;
2532int DollarRaiseLow(UBYTE *name, LONG value)
2538 WORD lnum[4], nnum, *t1, *t2, i;
2540 s = name;
while ( *s ) s++;
2541 if ( s[-1] ==
'-' && s[-2] ==
'-' && s > name+2 ) s -= 2;
2542 else if ( s[-1] ==
'+' && s[-2] ==
'+' && s > name+2 ) s -= 2;
2544 num = GetDollar(name);
2547 if ( value < 0 ) { value = -value; sgn = -1; }
2548 if ( d->type == DOLZERO ) {
2549 if ( d->where ) M_free(d->where,
"DollarRaiseLow");
2551 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2552 if ( ( value & AWORDMASK ) != 0 ) {
2553 d->where[0] = 6; d->where[1] = value >> BITSINWORD;
2554 d->where[2] = (WORD)value; d->where[3] = 1; d->where[4] = 0;
2555 d->where[5] = 5*sgn; d->where[6] = 0;
2559 d->where[0] = 4; d->where[1] = (WORD)value; d->where[2] = 1;
2560 d->where[3] = 3*sgn; d->where[4] = 0;
2561 d->type = DOLNUMBER;
2564 else if ( d->type == DOLNUMBER || ( d->type == DOLTERMS
2565 && d->where[d->where[0]] == 0
2566 && d->where[0] == ABS(d->where[d->where[0]-1])+1 ) ) {
2567 if ( ( value & AWORDMASK ) != 0 ) {
2568 lnum[0] = value >> BITSINWORD;
2569 lnum[1] = (WORD)value; lnum[2] = 1; lnum[3] = 0;
2573 lnum[0] = (WORD)value; lnum[1] = 1; nnum = sgn;
2575 i = d->where[d->where[0]-1];
2577 if ( dscrat == 0 ) {
2578 dscrat = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"DollarRaiseLow");
2580 if ( AddRat(BHEAD (UWORD *)(d->where+1),i,
2581 (UWORD *)lnum,nnum,dscrat,&ndscrat) ) {
2582 MLOCK(ErrorMessageLock);
2583 MesCall(
"DollarRaiseLow");
2584 MUNLOCK(ErrorMessageLock);
2587 ndscrat = INCLENG(ndscrat);
2590 M_free(d->where,
"DollarRaiseLow");
2596 if ( i+2 > d->size ) {
2597 M_free(d->where,
"DollarRaiseLow");
2599 if ( d->size < MINALLOC ) d->size = MINALLOC;
2600 d->size = ((d->size+7)/8)*8;
2601 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2603 t1 = d->where; *t1++ = i+1; t2 = (WORD *)dscrat;
2604 while ( --i > 0 ) *t1++ = *t2++;
2605 *t1++ = ndscrat; *t1 = 0;
2633 WORD num, type, *td;
2635 if ( *arg == SNUMBER )
return(arg[1]);
2636 if ( *arg == DOLLAREXPR2 && arg[1] < 0 )
return(-arg[1]-1);
2637 d = Dollars + arg[1];
2640 int nummodopt, dtype = -1;
2641 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2642 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2643 if ( arg[1] == ModOptdollars[nummodopt].number )
break;
2645 if ( nummodopt < NumModOptdollars ) {
2646 dtype = ModOptdollars[nummodopt].type;
2647 if ( DollarLocalCopy(dtype) ) {
2648 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2654 if ( *arg == DOLLAREXPRESSION ) {
2655 if ( arg[2] != DOLLAREXPR2 ) {
2658 if ( type == DOLZERO ) {}
2659 else if ( type == DOLNUMBER ) {
2661 if ( ( td[0] != 4 ) || ( (td[1]&SPECMASK) != 0 ) || ( td[2] != 1 ) ) {
2662 MLOCK(ErrorMessageLock);
2664 MesPrint(
"$-variable is not a short number in print statement");
2667 MesPrint(
"$-variable is not a short number in do loop");
2669 MUNLOCK(ErrorMessageLock);
2672 return( td[3] > 0 ? td[1]: -td[1] );
2675 MLOCK(ErrorMessageLock);
2677 MesPrint(
"$-variable is not a number in print statement");
2680 MesPrint(
"$-variable is not a number in do loop");
2682 MUNLOCK(ErrorMessageLock);
2689 else if ( *arg == DOLLAREXPR2 ) {
2690 if ( arg[1] < 0 ) { num = -arg[1]-1; }
2691 else if ( arg[2] != DOLLAREXPR2 && par == -1 ) {
2697 MLOCK(ErrorMessageLock);
2699 MesPrint(
"Invalid $-variable in print statement");
2702 MesPrint(
"Invalid $-variable in do loop");
2704 MUNLOCK(ErrorMessageLock);
2708 if ( num == 0 )
return(d->nfactors);
2709 if ( num > d->nfactors || num < 1 ) {
2710 MLOCK(ErrorMessageLock);
2712 MesPrint(
"Not a valid factor number for $-variable in print statement");
2715 MesPrint(
"Not a valid factor number for $-variable in do loop");
2717 MUNLOCK(ErrorMessageLock);
2721 if ( d->factors[num].type == DOLNUMBER )
2722 return(d->factors[num].value);
2724 MLOCK(ErrorMessageLock);
2726 MesPrint(
"$-variable in print statement is not a number");
2729 MesPrint(
"$-variable in do loop is not a number");
2731 MUNLOCK(ErrorMessageLock);
2742WORD TestDoLoop(PHEAD WORD *lhsbuf, WORD level)
2745 WORD start,finish,incr;
2750 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2751 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2754 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2755 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2759 if ( ( finish == start ) || ( finish > start && incr > 0 )
2760 || ( finish < start && incr < 0 ) ) {}
2761 else { level = lhsbuf[3]; }
2765 d = Dollars + lhsbuf[2];
2768 int nummodopt, dtype = -1;
2769 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2770 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2771 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2773 if ( nummodopt < NumModOptdollars ) {
2774 dtype = ModOptdollars[nummodopt].type;
2775 if ( DollarLocalCopy(dtype) ) {
2776 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2783 if ( d->size < MINALLOC ) {
2784 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2786 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2790 d->where[1] = start;
2794 d->type = DOLNUMBER;
2796 else if ( start < 0 ) {
2798 d->where[1] = -start;
2802 d->type = DOLNUMBER;
2807 if ( d == Dollars + lhsbuf[2] ) {
2808 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2809 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2810 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2820WORD TestEndDoLoop(PHEAD WORD *lhsbuf, WORD level)
2823 WORD start,finish,incr,value;
2828 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2829 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2832 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2833 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2837 if ( ( finish == start ) || ( finish > start && incr > 0 )
2838 || ( finish < start && incr < 0 ) ) {}
2839 else { level = lhsbuf[3]; }
2843 d = Dollars + lhsbuf[2];
2846 int nummodopt, dtype = -1;
2847 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2848 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2849 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2851 if ( nummodopt < NumModOptdollars ) {
2852 dtype = ModOptdollars[nummodopt].type;
2853 if ( DollarLocalCopy(dtype) ) {
2854 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2863 if ( d->type == DOLZERO ) {
2866 else if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2867 && ( d->where[4] == 0 ) && ( d->where[0] == 4 )
2868 && ( d->where[1] > 0 ) && ( d->where[2] == 1 ) ) {
2869 value = ( d->where[3] < 0 ) ? -d->where[1]: d->where[1];
2872 MLOCK(ErrorMessageLock);
2873 MesPrint(
"Wrong type of object in do loop parameter");
2874 MUNLOCK(ErrorMessageLock);
2879 if ( ( finish > start && value <= finish ) ||
2880 ( finish < start && value >= finish ) ||
2881 ( finish == start && value == finish ) ) {}
2882 else level = lhsbuf[3];
2884 if ( d->size < MINALLOC ) {
2885 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2887 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2891 d->where[1] = value;
2895 d->type = DOLNUMBER;
2897 else if ( start < 0 ) {
2899 d->where[1] = -value;
2903 d->type = DOLNUMBER;
2908 if ( d == Dollars + lhsbuf[2] ) {
2909 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2910 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2911 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2935int DollarFactorize(PHEAD WORD numdollar)
2938 DOLLARS d = Dollars + numdollar;
2940 WORD *oldworkpointer;
2941 WORD *buf1, *t, *term, *buf1content, *buf2, *termextra;
2942 WORD *buf3, *argextra;
2944 WORD *tstop, pow, *r;
2946 int i, j, jj, action = 0, sign = 1;
2948 WORD startebuf = cbuf[AT.ebufnum].numrhs;
2949 WORD nfactors, factorsincontent, extrafactor = 0;
2950 WORD oldsorttype = AR.SortType;
2953 int nummodopt, dtype;
2955 if ( AS.MultiThreaded ) {
2956 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2957 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2959 if ( nummodopt < NumModOptdollars ) {
2960 dtype = ModOptdollars[nummodopt].type;
2961 if ( DollarLocalCopy(dtype) ) {
2962 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2965 LOCK(d->pthreadslock);
2970 CleanDollarFactors(d);
2972 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
2974 if ( d->type != DOLTERMS ) {
2975 if ( d->type != DOLZERO ) d->nfactors = 1;
2978 if ( d->where[d->where[0]] == 0 ) {
2991 AR.SortType = SORTHIGHFIRST;
2992 if ( oldsorttype != AR.SortType ) {
2996 if ( AN.ncmod != 0 ) {
2997 if ( AN.ncmod != 1 || ( (WORD)AN.cmod[0] < 0 ) ) {
2998 AR.SortType = oldsorttype;
2999 MLOCK(ErrorMessageLock);
3000 MesPrint(
"Factorization modulus a number, greater than a WORD not implemented.");
3001 MUNLOCK(ErrorMessageLock);
3004 if ( Modulus(term) ) {
3005 AR.SortType = oldsorttype;
3006 MLOCK(ErrorMessageLock);
3007 MesCall(
"DollarFactorize");
3008 MUNLOCK(ErrorMessageLock);
3011 if ( !*term) { term = t;
continue; }
3017 EndSort(BHEAD (WORD *)((
void *)(&buf1)),2);
3018 t = buf1;
while ( *t ) t += *t;
3022 t = term;
while ( *t ) t += *t;
3023 ii = insize = t - term;
3024 buf1 = (WORD *)Malloc1((insize+1)*
sizeof(WORD),
"DollarFactorize-1");
3034 buf1content = TermMalloc(
"DollarContent");
3036 if ( ( buf2 =
TakeContent(BHEAD buf1,buf1content) ) == 0 ) {
3038 TermFree(buf1content,
"DollarContent");
3039 M_free(buf1,
"DollarFactorize-1");
3040 AR.SortType = oldsorttype;
3041 MLOCK(ErrorMessageLock);
3042 MesCall(
"DollarFactorize");
3043 MUNLOCK(ErrorMessageLock);
3047 else if ( ( buf1content[0] == 4 ) && ( buf1content[1] == 1 ) &&
3048 ( buf1content[2] == 1 ) && ( buf1content[3] == 3 ) ) {
3050 if ( buf2 != buf1 ) {
3051 M_free(buf2,
"DollarFactorize-2");
3054 factorsincontent = 0;
3061 if ( buf2 != buf1 ) M_free(buf1,
"DollarFactorize-1");
3063 t = buf1;
while ( *t ) t += *t;
3068 factorsincontent = 0;
3070 tstop = term + *term;
3071 if ( tstop[-1] < 0 ) factorsincontent++;
3072 if ( ABS(tstop[-1]) == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {
3073 tstop -= ABS(tstop[-1]);
3077 tstop -= ABS(tstop[-1]);
3080 while ( term < tstop ) {
3083 t = term+2; i = (term[1]-2)/2;
3085 factorsincontent += ABS(t[1]);
3090 t = term+2; i = (term[1]-2)/3;
3092 factorsincontent += ABS(t[2]);
3098 factorsincontent += (term[1]-2)/2;
3101 factorsincontent += term[1]-2;
3104 if ( *term >= FUNCTION ) factorsincontent++;
3111 factorsincontent = 0;
3123 if ( ( t[1] != SYMBOL ) && ( *t != (ABS(t[*t-1])+1) ) ) {
3128 if ( DetCommu(buf1) > 1 ) {
3129 MesPrint(
"Cannot factorize a $-expression with more than one noncommuting object");
3130 AR.SortType = oldsorttype;
3131 M_free(buf1,
"DollarFactorize-2");
3132 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3133 MesCall(
"DollarFactorize");
3139 termextra = AT.WorkPointer;
3145 AR.SortType = oldsorttype;
3146 M_free(buf1,
"DollarFactorize-2");
3147 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3148 MesCall(
"DollarFactorize");
3156 if (
EndSort(BHEAD (WORD *)((
void *)(&buf2)),2) < 0 ) {
goto getout; }
3158 t = buf2;
while ( *t > 0 ) t += *t;
3168 MesCall(
"DollarFactorize");
3169 AR.SortType = oldsorttype;
3170 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-3");
3171 M_free(buf1,
"DollarFactorize-3");
3172 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3176 if ( buf2 != buf1 && buf2 ) {
3177 M_free(buf2,
"DollarFactorize-3");
3181 AR.SortType = oldsorttype;
3188 if ( *term == 4 && term[4] == 0 && term[3] == -3 && term[2] == 1
3190 WORD *tt1, *tt2, *ttstop;
3192 tt1 = term; tt2 = term + *term + 1;
3195 while ( *ttstop ) ttstop += *ttstop;
3198 while ( tt2 < ttstop ) *tt1++ = *tt2++;
3207 while ( *term ) { term += *term; }
3222 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslock); }
3224 if ( nfactors == 1 && extrafactor == 0 ) {
3225 if ( factorsincontent == 0 ) {
3228 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
3237 term = buf1;
while ( *term ) term += *term;
3238 d->factors[0].size = i = term - buf1;
3239 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3240 term = buf1; NCOPY(t,term,i); *t = 0;
3241 AR.SortType = oldsorttype;
3242 M_free(buf3,
"DollarFactorize-4");
3243 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3244 M_free(buf1,
"DollarFactorize-4");
3245 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3249 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3250 term = buf1;
while ( *term ) term += *term;
3251 d->factors[0].size = i = term - buf1;
3252 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3253 term = buf1; NCOPY(t,term,i); *t = 0;
3254 M_free(buf3,
"DollarFactorize-4");
3256 if ( buf2 != buf1 && buf2 ) {
3257 M_free(buf2,
"DollarFactorize-4");
3262 else if ( action ) {
3263 C = cbuf+AC.cbufnum;
3264 CC = cbuf+AT.ebufnum;
3265 oldworkpointer = AT.WorkPointer;
3266 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3268 for ( i = 0; i < nfactors; i++ ) {
3269 argextra = AT.WorkPointer;
3273 if ( ConvertFromPoly(BHEAD term,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol
3274 ,startebuf-numxsymbol,1) <= 0 ) {
3276getout2: AR.SortType = oldsorttype;
3277 M_free(d->factors,
"factors in dollar");
3280 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
3282 M_free(buf3,
"DollarFactorize-4");
3283 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3284 M_free(buf1,
"DollarFactorize-4");
3285 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3288 AT.WorkPointer = argextra + *argextra;
3292 if (
Generator(BHEAD argextra,C->numlhs+1) ) {
3298 AT.WorkPointer = oldworkpointer;
3300 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3302 d->factors[i].type = DOLTERMS;
3303 t = d->factors[i].where;
3304 while ( *t ) t += *t;
3305 d->factors[i].size = t - d->factors[i].where;
3307 CC->numrhs = startebuf;
3310 C = cbuf+AC.cbufnum;
3311 oldworkpointer = AT.WorkPointer;
3312 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3314 for ( i = 0; i < nfactors; i++ ) {
3317 argextra = oldworkpointer;
3319 NCOPY(argextra,term,j)
3320 AT.WorkPointer = argextra;
3321 if (
Generator(BHEAD oldworkpointer,C->numlhs+1) ) {
3326 AT.WorkPointer = oldworkpointer;
3328 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3329 d->factors[i].type = DOLTERMS;
3330 t = d->factors[i].where;
3331 while ( *t ) t += *t;
3332 d->factors[i].size = t - d->factors[i].where;
3335 d->nfactors = nfactors + factorsincontent;
3340 if ( buf3 ) M_free(buf3,
"DollarFactorize-5");
3341 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-5");
3342 M_free(buf1,
"DollarFactorize-5");
3346 tstop = term + *term;
3347 if ( tstop[-1] < 0 ) { tstop[-1] = -tstop[-1]; sign = -sign; }
3350 while ( term < tstop ) {
3353 t = term+2; i = (term[1]-2)/2;
3355 if ( t[1] < 0 ) { t[1] = -t[1]; pow = -1; }
3357 for ( jj = 0; jj < t[1]; jj++ ) {
3358 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3359 r[0] = 8; r[1] = SYMBOL; r[2] = 4; r[3] = *t; r[4] = pow;
3360 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3361 d->factors[j].type = DOLTERMS;
3362 d->factors[j].size = 8;
3369 t = term+2; i = (term[1]-2)/3;
3371 if ( t[2] < 0 ) { t[2] = -t[2]; pow = -1; }
3373 for ( jj = 0; jj < t[2]; jj++ ) {
3374 r = d->factors[j].where = (WORD *)Malloc1(10*
sizeof(WORD),
"factor");
3375 r[0] = 9; r[1] = DOTPRODUCT; r[2] = 5; r[3] = t[0]; r[4] = t[1];
3376 r[5] = pow; r[6] = 1; r[7] = 1; r[8] = 3; r[9] = 0;
3377 d->factors[j].type = DOLTERMS;
3378 d->factors[j].size = 9;
3386 t = term+2; i = (term[1]-2)/2;
3388 for ( jj = 0; jj < t[1]; jj++ ) {
3389 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3390 r[0] = 8; r[1] = *term; r[2] = 4; r[3] = *t; r[4] = t[1];
3391 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3392 d->factors[j].type = DOLTERMS;
3393 d->factors[j].size = 8;
3400 t = term+2; i = term[1]-2;
3402 for ( jj = 0; jj < t[1]; jj++ ) {
3403 r = d->factors[j].where = (WORD *)Malloc1(8*
sizeof(WORD),
"factor");
3404 r[0] = 7; r[1] = *term; r[2] = 3; r[3] = *t;
3405 r[4] = 1; r[5] = 1; r[6] = 3; r[7] = 0;
3406 d->factors[j].type = DOLTERMS;
3407 d->factors[j].size = 7;
3414 if ( *term >= FUNCTION ) {
3415 r = d->factors[j].where = (WORD *)Malloc1((term[1]+5)*
sizeof(WORD),
"factor");
3416 *r++ = d->factors[j].size = term[1]+4;
3417 for ( jj = 0; jj < t[1]; jj++ ) *r++ = term[jj];
3418 *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3432 tstop = term + *term;
3433 if ( tstop[-1] == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {}
3434 else if ( tstop[-1] == 3 && tstop[-2] == 1 && (UWORD)(tstop[-3]) <= MAXPOSITIVE ) {
3435 d->factors[j].where = 0;
3436 d->factors[j].size = 0;
3437 d->factors[j].type = DOLNUMBER;
3438 d->factors[j].value = sign*tstop[-3];
3443 d->factors[j].where = r = (WORD *)Malloc1((tstop[-1]+2)*
sizeof(WORD),
"numfactor");
3444 d->factors[j].size = tstop[-1]+1;
3445 d->factors[j].type = DOLTERMS;
3446 d->factors[j].value = 0;
3453 r = d->factors[j].where;
3455 r += *r; r[-1] = -r[-1];
3463 for ( jj = j; jj > 0; jj-- ) {
3464 d->factors[jj] = d->factors[jj-1];
3466 d->factors[0].where = 0;
3467 d->factors[0].size = 0;
3468 d->factors[0].type = DOLNUMBER;
3469 d->factors[0].value = -1;
3473 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3481 if ( d->nfactors > 1 ) {
3482 WORD ***fac, j1, j2, k, ret, *s1, *s2, *s3;
3484 facsize = (LONG **)Malloc1((
sizeof(WORD **)+
sizeof(LONG *))*d->nfactors,
"SortDollarFactors");
3485 fac = (WORD ***)(facsize+d->nfactors);
3487 for ( j = 0; j < d->nfactors; j++ ) {
3488 if ( d->factors[j].where ) {
3489 fac[k] = &(d->factors[j].where);
3490 facsize[k] = &(d->factors[j].size);
3495 for ( j = 1; j < k; j++ ) {
3498 s1 = *(fac[j1]); s2 = *(fac[j2]);
3499 while ( *s1 && *s2 ) {
3500 if ( ( ret = CompareTerms(BHEAD s2, s1, (WORD)2) ) == 0 ) {
3501 s1 += *s1; s2 += *s2;
3503 else if ( ret > 0 )
goto nextj;
3506 s3 = *(fac[j1]); *(fac[j1]) = *(fac[j2]); *(fac[j2]) = s3;
3507 x = *(facsize[j1]); *(facsize[j1]) = *(facsize[j2]); *(facsize[j2]) = x;
3509 if ( j1 > 0 )
goto nextj1;
3513 if ( *s1 )
goto nextj;
3514 if ( *s2 )
goto exch;
3518 M_free(facsize,
"SortDollarFactors");
3524 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
3534void CleanDollarFactors(
DOLLARS d)
3537 if ( d->nfactors >= 1 ) {
3538 for ( i = 0; i < d->nfactors; i++ ) {
3540 if ( d->factors[i].where )
3541 M_free(d->factors[i].where,
"dollar factors");
3545 M_free(d->factors,
"dollar factors");
3556WORD *TakeDollarContent(PHEAD WORD *dollarbuffer, WORD **factor)
3563 t = dollarbuffer; pow = 1;
3569 t += *t; t[-1] = -t[-1];
3575 if ( AN.cmod != 0 ) {
3576 if ( ( *factor =
MakeDollarMod(BHEAD dollarbuffer,&remain) ) == 0 ) {
3580 (*factor)[**factor-1] = -(*factor)[**factor-1];
3581 (*factor)[**factor-1] += AN.cmod[0];
3589 (*factor)[**factor-1] = -(*factor)[**factor-1];
3611 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMb, *LCMc;
3612 WORD *r, *r1, *r2, *r3, *rnext, i, k, j, *oldworkpointer, *factor;
3613 WORD kGCD, kLCM, kGCD2, kkLCM, jLCM, jGCD;
3614 CBUF *C = cbuf+AC.cbufnum;
3616 GCDbuffer = NumberMalloc(
"MakeDollarInteger");
3617 GCDbuffer2 = NumberMalloc(
"MakeDollarInteger");
3618 LCMbuffer = NumberMalloc(
"MakeDollarInteger");
3619 LCMb = NumberMalloc(
"MakeDollarInteger");
3620 LCMc = NumberMalloc(
"MakeDollarInteger");
3629 if ( k < 0 ) k = -k;
3630 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3631 for ( kGCD = 0; kGCD < k; kGCD++ ) GCDbuffer[kGCD] = r3[kGCD];
3633 if ( k < 0 ) k = -k;
3635 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3636 for ( kLCM = 0; kLCM < k; kLCM++ ) LCMbuffer[kLCM] = r3[kLCM];
3646 if ( k < 0 ) k = -k;
3647 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3648 if ( ( ( GCDbuffer[0] == 1 ) && ( kGCD == 1 ) ) ) {
3653 else if ( ( ( k != 1 ) || ( r3[0] != 1 ) ) ) {
3654 if ( GcdLong(BHEAD GCDbuffer,kGCD,(UWORD *)r3,k,GCDbuffer2,&kGCD2) ) {
3655 goto MakeDollarIntegerErr;
3658 for ( i = 0; i < kGCD; i++ ) GCDbuffer[i] = GCDbuffer2[i];
3661 kGCD = 1; GCDbuffer[0] = 1;
3664 if ( k < 0 ) k = -k;
3666 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3667 if ( ( ( LCMbuffer[0] == 1 ) && ( kLCM == 1 ) ) ) {
3668 for ( kLCM = 0; kLCM < k; kLCM++ )
3669 LCMbuffer[kLCM] = r3[kLCM];
3671 else if ( ( k != 1 ) || ( r3[0] != 1 ) ) {
3672 if ( GcdLong(BHEAD LCMbuffer,kLCM,(UWORD *)r3,k,LCMb,&kkLCM) ) {
3673 goto MakeDollarIntegerErr;
3675 DivLong((UWORD *)r3,k,LCMb,kkLCM,LCMb,&kkLCM,LCMc,&jLCM);
3676 MulLong(LCMbuffer,kLCM,LCMb,kkLCM,LCMc,&jLCM);
3677 for ( kLCM = 0; kLCM < jLCM; kLCM++ )
3678 LCMbuffer[kLCM] = LCMc[kLCM];
3686 r3 = (WORD *)(GCDbuffer);
3687 if ( kGCD == kLCM ) {
3688 for ( jGCD = 0; jGCD < kGCD; jGCD++ )
3689 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3692 else if ( kGCD > kLCM ) {
3693 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3694 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3695 for ( jGCD = kLCM; jGCD < kGCD; jGCD++ )
3700 for ( jGCD = kGCD; jGCD < kLCM; jGCD++ )
3702 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3703 r3[jGCD+kLCM] = LCMbuffer[jGCD];
3710 factor = r1 = (WORD *)Malloc1((j+2)*
sizeof(WORD),
"MakeDollarInteger");
3711 *r1++ = j+1; r2 = r3;
3712 for ( i = 0; i < k; i++ ) { *r1++ = *r2++; *r1++ = *r2++; }
3725 oldworkpointer = AT.WorkPointer;
3730 r2 = oldworkpointer;
3731 while ( r < r3 ) *r2++ = *r++;
3733 if ( DivRat(BHEAD (UWORD *)r3,j,GCDbuffer,k,(UWORD *)r2,&i) ) {
3734 goto MakeDollarIntegerErr;
3738 if ( rnext[-1] < 0 ) r2[-1] = -i;
3740 *oldworkpointer = r2-oldworkpointer;
3741 AT.WorkPointer = r2;
3742 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3743 goto MakeDollarIntegerErr;
3747 AT.WorkPointer = oldworkpointer;
3749 EndSort(BHEAD (WORD *)bufout,2);
3753 NumberFree(LCMc,
"MakeDollarInteger");
3754 NumberFree(LCMb,
"MakeDollarInteger");
3755 NumberFree(LCMbuffer,
"MakeDollarInteger");
3756 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3757 NumberFree(GCDbuffer,
"MakeDollarInteger");
3760MakeDollarIntegerErr:
3761 NumberFree(LCMc,
"MakeDollarInteger");
3762 NumberFree(LCMb,
"MakeDollarInteger");
3763 NumberFree(LCMbuffer,
"MakeDollarInteger");
3764 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3765 NumberFree(GCDbuffer,
"MakeDollarInteger");
3766 MesCall(
"MakeDollarInteger");
3785 WORD *r, *r1, x, xx, ix, ip;
3786 WORD *factor, *oldworkpointer;
3788 CBUF *C = cbuf+AC.cbufnum;
3791 if ( r[*r-1] < 0 ) x += AN.cmod[0];
3795 factor = (WORD *)Malloc1(5*
sizeof(WORD),
"MakeDollarMod");
3796 factor[0] = 4; factor[1] = x; factor[2] = 1; factor[3] = 3; factor[4] = 0;
3804 oldworkpointer = AT.WorkPointer;
3806 r1 = oldworkpointer; i = *r;
3808 xx = r1[-3];
if ( r1[-1] < 0 ) xx += AN.cmod[0];
3809 r1[-1] = (WORD)((((LONG)xx)*ix) % AN.cmod[0]);
3810 *r1 = 0; AT.WorkPointer = r1;
3811 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3815 AT.WorkPointer = oldworkpointer;
3817 EndSort(BHEAD (WORD *)bufout,2);
3827int GetDolNum(PHEAD WORD *t, WORD *tstop)
3831 if ( t+3 < tstop && t[3] == DOLLAREXPR2 ) {
3835 int nummodopt, dtype;
3837 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3838 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3839 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3841 if ( nummodopt < NumModOptdollars ) {
3842 dtype = ModOptdollars[nummodopt].type;
3843 if ( DollarLocalCopy(dtype) ) {
3844 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3847 MLOCK(ErrorMessageLock);
3848 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3849 DOLLARNAME(Dollars,t[2]),AC.CModule);
3850 MUNLOCK(ErrorMessageLock);
3857 if ( d->factors == 0 ) {
3858 MLOCK(ErrorMessageLock);
3859 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
3860 MUNLOCK(ErrorMessageLock);
3863 num = GetDolNum(BHEAD t+t[1],tstop);
3864 if ( num == 0 )
return(d->nfactors);
3865 if ( num > d->nfactors ) {
3866 MLOCK(ErrorMessageLock);
3867 MesPrint(
"Attempt to use an nonexisting factor %d of a $-variable",num);
3868 MUNLOCK(ErrorMessageLock);
3871 w = d->factors[num-1].where;
3872 if ( w == 0 )
return(d->factors[num-1].value);
3873 if ( w[0] == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1 && w[1] > 0
3874 && w[1] < MAXPOSITIVE )
return(w[1]);
3876 MLOCK(ErrorMessageLock);
3877 MesPrint(
"Illegal type of factor number of a $-variable");
3878 MUNLOCK(ErrorMessageLock);
3882 else if ( t[2] < 0 ) {
3889 int nummodopt, dtype;
3891 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3892 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3893 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3895 if ( nummodopt < NumModOptdollars ) {
3896 dtype = ModOptdollars[nummodopt].type;
3897 if ( DollarLocalCopy(dtype) ) {
3898 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3901 MLOCK(ErrorMessageLock);
3902 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3903 DOLLARNAME(Dollars,t[2]),AC.CModule);
3904 MUNLOCK(ErrorMessageLock);
3911 if ( d->type == DOLZERO )
return(0);
3912 if ( d->type == DOLTERMS || d->type == DOLNUMBER ) {
3913 if ( d->where[0] == 4 && d->where[4] == 0 && d->where[3] == 3
3914 && d->where[2] == 1 && d->where[1] > 0
3915 && d->where[1] < MAXPOSITIVE )
return(d->where[1]);
3916 MLOCK(ErrorMessageLock);
3917 MesPrint(
"Attempt to use an nonexisting factor of a $-variable");
3918 MUNLOCK(ErrorMessageLock);
3921 MLOCK(ErrorMessageLock);
3922 MesPrint(
"Illegal type of factor number of a $-variable");
3923 MUNLOCK(ErrorMessageLock);
3942 int i, n = NumPotModdollars;
3943 for ( i = 0; i < n; i++ ) {
3944 if ( numdollar == PotModdollars[i] )
break;
3947 *(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)