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 ) {
904 MLOCK(ErrorMessageLock);
905 MesPrint(
"!>Serious bug in wildcard prototype. Found in WildDollars");
906 MUNLOCK(ErrorMessageLock);
911 d = Dollars + numdollar;
916 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
917 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
918 if ( numdollar == ModOptdollars[nummodopt].number )
break;
920 if ( nummodopt < NumModOptdollars ) {
921 dtype = ModOptdollars[nummodopt].type;
922 if ( DollarLocalCopy(dtype) ) {
923 d = ModOptdollars[nummodopt].dstruct+AT.identity;
926 MLOCK(ErrorMessageLock);
927 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
928 DOLLARNAME(Dollars,numdollar),AC.CModule);
929 MUNLOCK(ErrorMessageLock);
950 orig = cbuf[AT.ebufnum].rhs[t[3]];
951 w = orig;
while ( *w ) w += *w;
952 weneed = w - orig + 1;
963 orig = cbuf[AT.ebufnum].rhs[t[3]];
964 if ( *orig > 0 ) weneed = *orig+2;
966 w = orig+1;
while ( *w ) { NEXTARG(w) }
967 weneed = w - orig + 1;
974 if ( weneed < MINALLOC ) weneed = MINALLOC;
975 weneed = ((weneed+7)/8)*8;
976 if ( d->size > 2*weneed && d->size > 1000 ) {
977 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollarspace");
978 d->where = &(AM.dollarzero);
981 if ( d->size < weneed ) {
982 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollarspace");
983 d->where = (WORD *)Malloc1(weneed*
sizeof(WORD),
"dollarspace");
991 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
992 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
994 cbuf[AM.dbufnum].rhs[numdollar] = (WORD *)(1);
1003 d->where[0] = 4; d->where[2] = 1;
1004 if ( t[3] >= 0 ) { d->where[1] = t[3]; d->where[3] = 3; }
1005 else { d->where[1] = -t[3]; d->where[3] = -3; }
1006 if ( t[3] == 0 ) { d->type = DOLZERO; d->where[0] = 0; }
1007 else { d->type = DOLNUMBER; d->where[4] = 0; }
1024 i = *orig;
while ( --i >= 0 ) *w++ = *orig++;
1032 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[3];
1033 *w++ = 1; *w++ = 1; *w++ = -3; *w = 0;
1036 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[3];
1037 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1040 d->type = DOLINDEX; d->index = t[3]; *w = 0;
1043 *w++ = FUNHEAD+4; *w++ = t[3]; *w++ = FUNHEAD;
1045 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1048 if ( *orig > 0 ) ww = orig + *orig + 1;
1050 ww = orig+1;
while ( *ww ) { NEXTARG(ww) }
1052 while ( orig < ww ) *w++ = *orig++;
1054 d->type = DOLWILDARGS;
1057 d->type = DOLUNDEFINED;
1069WORD DolToTensor(PHEAD WORD numdollar)
1072 DOLLARS d = Dollars + numdollar;
1075 int nummodopt, dtype = -1;
1076 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1077 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1078 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1080 if ( nummodopt < NumModOptdollars ) {
1081 dtype = ModOptdollars[nummodopt].type;
1082 if ( DollarLocalCopy(dtype) ) {
1083 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1086 LOCK(d->pthreadslock);
1091 AN.ErrorInDollar = 0;
1092 if ( d->type == DOLTERMS && d->where[0] == FUNHEAD+4 &&
1093 d->where[FUNHEAD+4] == 0 && d->where[FUNHEAD+3] == 3 &&
1094 d->where[FUNHEAD+2] == 1 && d->where[FUNHEAD+1] == 1 &&
1095 d->where[1] >= FUNCTION && d->where[1] < FUNCTION+WILDOFFSET
1096 && functions[d->where[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1097 retval = d->where[1];
1099 else if ( d->type == DOLARGUMENT &&
1100 d->where[0] <= -FUNCTION && d->where[0] > -FUNCTION-WILDOFFSET
1101 && functions[-d->where[0]-FUNCTION].spec >= TENSORFUNCTION ) {
1102 retval = -d->where[0];
1104 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1105 && d->where[1] <= -FUNCTION && d->where[1] > -FUNCTION-WILDOFFSET
1107 && functions[-d->where[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1108 retval = -d->where[1];
1110 else if ( d->type == DOLSUBTERM &&
1111 d->where[0] >= FUNCTION && d->where[0] < FUNCTION+WILDOFFSET
1112 && functions[d->where[0]-FUNCTION].spec >= TENSORFUNCTION ) {
1113 retval = d->where[0];
1116 AN.ErrorInDollar = 1;
1120 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1130WORD DolToFunction(PHEAD WORD numdollar)
1133 DOLLARS d = Dollars + numdollar;
1136 int nummodopt, dtype = -1;
1137 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1138 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1139 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1141 if ( nummodopt < NumModOptdollars ) {
1142 dtype = ModOptdollars[nummodopt].type;
1143 if ( DollarLocalCopy(dtype) ) {
1144 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1147 LOCK(d->pthreadslock);
1152 AN.ErrorInDollar = 0;
1153 if ( d->type == DOLTERMS && d->where[0] == FUNHEAD+4 &&
1154 d->where[FUNHEAD+4] == 0 && d->where[FUNHEAD+3] == 3 &&
1155 d->where[FUNHEAD+2] == 1 && d->where[FUNHEAD+1] == 1 &&
1156 d->where[1] >= FUNCTION && d->where[1] < FUNCTION+WILDOFFSET ) {
1157 retval = d->where[1];
1159 else if ( d->type == DOLARGUMENT &&
1160 d->where[0] <= -FUNCTION && d->where[0] > -FUNCTION-WILDOFFSET ) {
1161 retval = -d->where[0];
1163 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1164 && d->where[1] <= -FUNCTION && d->where[1] > -FUNCTION-WILDOFFSET
1165 && d->where[2] == 0 ) {
1166 retval = -d->where[1];
1168 else if ( d->type == DOLSUBTERM &&
1169 d->where[0] >= FUNCTION && d->where[0] < FUNCTION+WILDOFFSET ) {
1170 retval = d->where[0];
1173 AN.ErrorInDollar = 1;
1177 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1187WORD DolToVector(PHEAD WORD numdollar)
1190 DOLLARS d = Dollars + numdollar;
1193 int nummodopt, dtype = -1;
1194 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1195 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1196 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1198 if ( nummodopt < NumModOptdollars ) {
1199 dtype = ModOptdollars[nummodopt].type;
1200 if ( DollarLocalCopy(dtype) ) {
1201 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1204 LOCK(d->pthreadslock);
1209 AN.ErrorInDollar = 0;
1210 if ( d->type == DOLINDEX && d->index < 0 ) {
1213 else if ( d->type == DOLARGUMENT && ( d->where[0] == -VECTOR
1214 || d->where[0] == -MINVECTOR ) ) {
1215 retval = d->where[1];
1217 else if ( d->type == DOLSUBTERM && d->where[0] == INDEX
1218 && d->where[1] == 3 && d->where[2] < 0 ) {
1219 retval = d->where[2];
1221 else if ( d->type == DOLTERMS && d->where[0] == 7 &&
1222 d->where[7] == 0 && d->where[6] == 3 &&
1223 d->where[5] == 1 && d->where[4] == 1 &&
1224 d->where[1] >= INDEX && d->where[3] < 0 ) {
1225 retval = d->where[3];
1227 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1228 && ( d->where[1] == -VECTOR || d->where[1] == -MINVECTOR )
1229 && d->where[3] == 0 ) {
1230 retval = d->where[2];
1232 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1233 && d->where[1] < 0 ) {
1234 retval = d->where[1];
1237 AN.ErrorInDollar = 1;
1241 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1251WORD DolToNumber(PHEAD WORD numdollar)
1254 DOLLARS d = Dollars + numdollar;
1256 int nummodopt, dtype = -1;
1257 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1258 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1259 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1261 if ( nummodopt < NumModOptdollars ) {
1262 dtype = ModOptdollars[nummodopt].type;
1263 if ( DollarLocalCopy(dtype) ) {
1264 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1269 AN.ErrorInDollar = 0;
1270 if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1271 && d->where[0] == 4 &&
1272 d->where[4] == 0 && ( d->where[3] == 3 || d->where[3] == -3 )
1273 && d->where[2] == 1 && ( d->where[1] & TOPBITONLY ) == 0 ) {
1274 if ( d->where[3] > 0 )
return(d->where[1]);
1275 else return(-d->where[1]);
1277 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER ) {
1278 return(d->where[1]);
1280 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1281 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1282 return(d->where[1]);
1284 else if ( d->type == DOLZERO )
return(0);
1285 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1286 && d->where[1] == -SNUMBER && d->where[3] == 0 ) {
1287 return(d->where[2]);
1289 else if ( d->type == DOLINDEX && d->index >= 0 && d->index < AM.OffsetIndex ) {
1292 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1293 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1294 return(d->where[1]);
1296 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1297 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0
1298 && d->where[2] < AM.OffsetIndex ) {
1299 return(d->where[2]);
1301 AN.ErrorInDollar = 1;
1310WORD DolToSymbol(PHEAD WORD numdollar)
1313 DOLLARS d = Dollars + numdollar;
1316 int nummodopt, dtype = -1;
1317 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1318 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1319 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1321 if ( nummodopt < NumModOptdollars ) {
1322 dtype = ModOptdollars[nummodopt].type;
1323 if ( DollarLocalCopy(dtype) ) {
1324 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1327 LOCK(d->pthreadslock);
1332 AN.ErrorInDollar = 0;
1333 if ( d->type == DOLTERMS && d->where[0] == 8 &&
1334 d->where[8] == 0 && d->where[7] == 3 && d->where[6] == 1
1335 && d->where[5] == 1 && d->where[4] == 1 && d->where[1] == SYMBOL ) {
1336 retval = d->where[3];
1338 else if ( d->type == DOLARGUMENT && d->where[0] == -SYMBOL ) {
1339 retval = d->where[1];
1341 else if ( d->type == DOLSUBTERM && d->where[0] == SYMBOL
1342 && d->where[1] == 4 && d->where[3] == 1 ) {
1343 retval = d->where[2];
1345 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1346 && d->where[1] == -SYMBOL && d->where[3] == 0 ) {
1347 retval = d->where[2];
1350 AN.ErrorInDollar = 1;
1354 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1364WORD DolToIndex(PHEAD WORD numdollar)
1367 DOLLARS d = Dollars + numdollar;
1370 int nummodopt, dtype = -1;
1371 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1372 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1373 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1375 if ( nummodopt < NumModOptdollars ) {
1376 dtype = ModOptdollars[nummodopt].type;
1377 if ( DollarLocalCopy(dtype) ) {
1378 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1381 LOCK(d->pthreadslock);
1386 AN.ErrorInDollar = 0;
1387 if ( d->type == DOLTERMS && d->where[0] == 7 &&
1388 d->where[7] == 0 && d->where[6] == 3 && d->where[5] == 1
1389 && d->where[4] == 1 && d->where[1] == INDEX && d->where[3] >= 0 ) {
1390 retval = d->where[3];
1392 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER
1393 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1394 retval = d->where[1];
1396 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1397 && d->where[1] >= 0 ) {
1398 retval = d->where[1];
1400 else if ( d->type == DOLZERO )
return(0);
1401 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1402 && d->where[1] == -SNUMBER && d->where[3] == 0 && d->where[2] >= 0
1403 && d->where[2] < AM.OffsetIndex ) {
1404 retval = d->where[2];
1406 else if ( d->type == DOLINDEX && d->index >= 0 ) {
1409 else if ( d->type == DOLNUMBER && d->where[0] == 4 && d->where[2] == 1
1410 && d->where[3] == 3 && d->where[4] == 0 && d->where[1] < AM.OffsetIndex ) {
1411 retval = d->where[1];
1413 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1414 && d->where[1] >= 0 ) {
1415 retval = d->where[1];
1417 else if ( d->type == DOLSUBTERM && d->where[0] == INDEX
1418 && d->where[1] == 3 && d->where[2] >= 0 ) {
1419 retval = d->where[2];
1421 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1422 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0 ) {
1423 retval = d->where[2];
1426 AN.ErrorInDollar = 1;
1430 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
1445DOLLARS DolToTerms(PHEAD WORD numdollar)
1449 DOLLARS d = Dollars + numdollar, newd;
1452 int nummodopt, dtype = -1;
1453 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1454 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1455 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1457 if ( nummodopt < NumModOptdollars ) {
1458 dtype = ModOptdollars[nummodopt].type;
1459 if ( DollarLocalCopy(dtype) ) {
1460 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1465 AN.ErrorInDollar = 0;
1466 switch ( d->type ) {
1472 if ( t[0] <= -FUNCTION ) {
1473 *w++ = FUNHEAD+4; *w++ = -t[0];
1474 *w++ = FUNHEAD; FILLFUN(w)
1475 *w++ = 1; *w++ = 1; *w++ = 3;
1477 else if ( t[0] == -SYMBOL ) {
1478 *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = t[1];
1479 *w++ = 1; *w++ = 1; *w++ = 1; *w++ = 3;
1481 else if ( t[0] == -VECTOR || t[0] == -INDEX ) {
1482 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[1];
1483 *w++ = 1; *w++ = 1; *w++ = 3;
1485 else if ( t[0] == -MINVECTOR ) {
1486 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[1];
1487 *w++ = 1; *w++ = 1; *w++ = -3;
1489 else if ( t[0] == -SNUMBER ) {
1492 *w++ = -t[1]; *w++ = 1; *w++ = -3;
1495 *w++ = t[1]; *w++ = 1; *w++ = 3;
1498 *w = 0; size = w - AT.WorkPointer;
1506 while ( *t ) t += *t;
1507 size = t - d->where;
1513 *w++ = size+4; t = d->where; NCOPY(w,t,size)
1514 *w++ = 1; *w++ = 1; *w++ = 3;
1515 w = AT.WorkPointer; size = d->where[1]+4;
1519 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = d->index;
1520 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1521 w = AT.WorkPointer; size = 7;
1528 if ( *t == 0 )
return(0);
1531 MLOCK(ErrorMessageLock);
1532 MesPrint(
"Trying to convert a $ with an argument field into an expression");
1533 MUNLOCK(ErrorMessageLock);
1540 if ( *t < 0 )
goto ShortArgument;
1541 size = *t - ARGHEAD;
1545 MLOCK(ErrorMessageLock);
1546 MesPrint(
"Trying to use an undefined $ in an expression");
1547 MUNLOCK(ErrorMessageLock);
1551 if ( d->where ) { d->where[0] = 0; }
1552 else d->where = &(AM.dollarzero);
1559 newd = (
DOLLARS)Malloc1(
sizeof(
struct DoLlArS)+(size+1)*
sizeof(WORD),
1560 "Copy of dollar variable");
1561 t = (WORD *)(newd+1);
1563 newd->name = d->name;
1564 newd->node = d->node;
1565 newd->type = DOLTERMS;
1567 newd->numdummies = d->numdummies;
1569 INIRECLOCK(newd->pthreadslock);
1573 newd->nfactors = d->nfactors;
1574 if ( d->nfactors > 1 ) {
1575 newd->factors = (
FACDOLLAR *)Malloc1(d->nfactors*
sizeof(
FACDOLLAR),
"Dollar factors");
1576 for ( i = 0; i < d->nfactors; i++ ) {
1577 newd->factors[i].where = 0;
1578 newd->factors[i].size = 0;
1579 newd->factors[i].type = DOLUNDEFINED;
1580 newd->factors[i].value = d->factors[i].value;
1583 else { newd->factors = 0; }
1592LONG DolToLong(PHEAD WORD numdollar)
1595 DOLLARS d = Dollars + numdollar;
1598 int nummodopt, dtype = -1;
1599 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1600 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1601 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1603 if ( nummodopt < NumModOptdollars ) {
1604 dtype = ModOptdollars[nummodopt].type;
1605 if ( DollarLocalCopy(dtype) ) {
1606 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1611 AN.ErrorInDollar = 0;
1612 if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1613 && d->where[0] == 4 &&
1614 d->where[4] == 0 && ( d->where[3] == 3 || d->where[3] == -3 )
1615 && d->where[2] == 1 && ( d->where[1] & TOPBITONLY ) == 0 ) {
1617 if ( d->where[3] > 0 )
return(x);
1620 else if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1621 && d->where[0] == 6 &&
1622 d->where[6] == 0 && ( d->where[5] == 5 || d->where[5] == -5 )
1623 && d->where[3] == 1 && d->where[4] == 1 && ( d->where[2] & TOPBITONLY ) == 0 ) {
1624 x = d->where[1] + ( (LONG)(d->where[2]) << BITSINWORD );
1625 if ( d->where[5] > 0 )
return(x);
1628 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER ) {
1632 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1633 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1637 else if ( d->type == DOLZERO )
return(0);
1638 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1639 && d->where[1] == -SNUMBER && d->where[3] == 0 ) {
1643 else if ( d->type == DOLINDEX && d->index >= 0 && d->index < AM.OffsetIndex ) {
1647 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1648 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1652 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1653 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0
1654 && d->where[2] < AM.OffsetIndex ) {
1658 AN.ErrorInDollar = 1;
1667int ExecInside(UBYTE *s)
1674 if ( AC.insidelevel >= MAXNEST ) {
1675 MLOCK(ErrorMessageLock);
1676 MesPrint(
"@Nesting of inside statements more than %d levels",(WORD)MAXNEST);
1677 MUNLOCK(ErrorMessageLock);
1680 AC.insidesumcheck[AC.insidelevel] = NestingChecksum();
1681 AC.insidestack[AC.insidelevel] = cbuf[AC.cbufnum].Pointer
1682 - cbuf[AC.cbufnum].Buffer + 2;
1687 while ( *s ==
',' ) s++;
1688 if ( *s == 0 )
break;
1691 if ( FG.cTable[*s] != 0 ) {
1692 MLOCK(ErrorMessageLock);
1693 MesPrint(
"Illegal name for $ variable: %s",s-1);
1694 MUNLOCK(ErrorMessageLock);
1697 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
1699 if ( ( number = GetDollar(t) ) < 0 ) {
1700 number = AddDollar(t,0,0,0);
1707 MLOCK(ErrorMessageLock);
1708 MesPrint(
"&Illegal object in Inside statement");
1709 MUNLOCK(ErrorMessageLock);
1711 while ( *s && *s !=
',' && s[1] !=
'$' ) s++;
1712 if ( *s == 0 )
break;
1715 AT.WorkPointer[1] = w - AT.WorkPointer;
1716 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
1732int InsideDollar(PHEAD WORD *ll, WORD level)
1735 int numvar = (int)(ll[1]-3), j, error = 0;
1736 WORD numdol, *oldcterm, *oldwork = AT.WorkPointer, olddefer, *r, *m;
1737 WORD oldnumlhs, *dbuffer;
1739 oldcterm = AN.cTerm; AN.cTerm = 0;
1740 oldnumlhs = AR.Cnumlhs; AR.Cnumlhs = ll[2];
1742 olddefer = AR.DeferFlag;
1744 while ( --numvar >= 0 ) {
1746 d = Dollars + numdol;
1749 int nummodopt, dtype = -1;
1750 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1751 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1752 if ( numdol == ModOptdollars[nummodopt].number )
break;
1754 if ( nummodopt < NumModOptdollars ) {
1755 dtype = ModOptdollars[nummodopt].type;
1756 if ( DollarLocalCopy(dtype) ) {
1757 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1760 LOCK(d->pthreadslock);
1765 newd = DolToTerms(BHEAD numdol);
1769 if ( newd->where[0] == 0 ) {
1772 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1773 M_free(newd,
"Copy of dollar variable");
1781 while ( --j >= 0 ) *m++ = *r++;
1788 error = -1;
goto idcall;
1790 AT.WorkPointer = oldwork;
1793 if (
EndSort(BHEAD (WORD *)((
void *)(&dbuffer)),2) < 0 ) { error = 1;
break; }
1794 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"old buffer of dollar");
1796 if ( dbuffer == 0 || *dbuffer == 0 ) {
1798 if ( dbuffer ) M_free(dbuffer,
"buffer of dollar");
1799 d->where = &(AM.dollarzero); d->size = 0;
1803 r = d->where;
while ( *r ) r += *r;
1804 d->size = (r-d->where)+1;
1807 cbuf[AM.dbufnum].rhs[numdol] = (WORD *)(1);
1812 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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);
2517 MLOCK(ErrorMessageLock);
2518 MesPrint(
"!>Internal problems with operator in $( )");
2519 MUNLOCK(ErrorMessageLock);
2533static UWORD *dscrat = 0;
2536int DollarRaiseLow(UBYTE *name, LONG value)
2542 WORD lnum[4], nnum, *t1, *t2, i;
2544 s = name;
while ( *s ) s++;
2545 if ( s[-1] ==
'-' && s[-2] ==
'-' && s > name+2 ) s -= 2;
2546 else if ( s[-1] ==
'+' && s[-2] ==
'+' && s > name+2 ) s -= 2;
2548 num = GetDollar(name);
2551 if ( value < 0 ) { value = -value; sgn = -1; }
2552 if ( d->type == DOLZERO ) {
2553 if ( d->where ) M_free(d->where,
"DollarRaiseLow");
2555 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2556 if ( ( value & AWORDMASK ) != 0 ) {
2557 d->where[0] = 6; d->where[1] = value >> BITSINWORD;
2558 d->where[2] = (WORD)value; d->where[3] = 1; d->where[4] = 0;
2559 d->where[5] = 5*sgn; d->where[6] = 0;
2563 d->where[0] = 4; d->where[1] = (WORD)value; d->where[2] = 1;
2564 d->where[3] = 3*sgn; d->where[4] = 0;
2565 d->type = DOLNUMBER;
2568 else if ( d->type == DOLNUMBER || ( d->type == DOLTERMS
2569 && d->where[d->where[0]] == 0
2570 && d->where[0] == ABS(d->where[d->where[0]-1])+1 ) ) {
2571 if ( ( value & AWORDMASK ) != 0 ) {
2572 lnum[0] = value >> BITSINWORD;
2573 lnum[1] = (WORD)value; lnum[2] = 1; lnum[3] = 0;
2577 lnum[0] = (WORD)value; lnum[1] = 1; nnum = sgn;
2579 i = d->where[d->where[0]-1];
2581 if ( dscrat == 0 ) {
2582 dscrat = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"DollarRaiseLow");
2584 if ( AddRat(BHEAD (UWORD *)(d->where+1),i,
2585 (UWORD *)lnum,nnum,dscrat,&ndscrat) ) {
2586 MLOCK(ErrorMessageLock);
2587 MesCall(
"DollarRaiseLow");
2588 MUNLOCK(ErrorMessageLock);
2591 ndscrat = INCLENG(ndscrat);
2594 M_free(d->where,
"DollarRaiseLow");
2600 if ( i+2 > d->size ) {
2601 M_free(d->where,
"DollarRaiseLow");
2603 if ( d->size < MINALLOC ) d->size = MINALLOC;
2604 d->size = ((d->size+7)/8)*8;
2605 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2607 t1 = d->where; *t1++ = i+1; t2 = (WORD *)dscrat;
2608 while ( --i > 0 ) *t1++ = *t2++;
2609 *t1++ = ndscrat; *t1 = 0;
2637 WORD num, type, *td;
2639 if ( *arg == SNUMBER )
return(arg[1]);
2640 if ( *arg == DOLLAREXPR2 && arg[1] < 0 )
return(-arg[1]-1);
2641 d = Dollars + arg[1];
2644 int nummodopt, dtype = -1;
2645 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2646 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2647 if ( arg[1] == ModOptdollars[nummodopt].number )
break;
2649 if ( nummodopt < NumModOptdollars ) {
2650 dtype = ModOptdollars[nummodopt].type;
2651 if ( DollarLocalCopy(dtype) ) {
2652 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2658 if ( *arg == DOLLAREXPRESSION ) {
2659 if ( arg[2] != DOLLAREXPR2 ) {
2662 if ( type == DOLZERO ) {}
2663 else if ( type == DOLNUMBER ) {
2665 if ( ( td[0] != 4 ) || ( (td[1]&SPECMASK) != 0 ) || ( td[2] != 1 ) ) {
2666 MLOCK(ErrorMessageLock);
2668 MesPrint(
"$-variable is not a short number in print statement");
2671 MesPrint(
"$-variable is not a short number in do loop");
2673 MUNLOCK(ErrorMessageLock);
2676 return( td[3] > 0 ? td[1]: -td[1] );
2679 MLOCK(ErrorMessageLock);
2681 MesPrint(
"$-variable is not a number in print statement");
2684 MesPrint(
"$-variable is not a number in do loop");
2686 MUNLOCK(ErrorMessageLock);
2693 else if ( *arg == DOLLAREXPR2 ) {
2694 if ( arg[1] < 0 ) { num = -arg[1]-1; }
2695 else if ( arg[2] != DOLLAREXPR2 && par == -1 ) {
2701 MLOCK(ErrorMessageLock);
2703 MesPrint(
"Invalid $-variable in print statement");
2706 MesPrint(
"Invalid $-variable in do loop");
2708 MUNLOCK(ErrorMessageLock);
2712 if ( num == 0 )
return(d->nfactors);
2713 if ( num > d->nfactors || num < 1 ) {
2714 MLOCK(ErrorMessageLock);
2716 MesPrint(
"Not a valid factor number for $-variable in print statement");
2719 MesPrint(
"Not a valid factor number for $-variable in do loop");
2721 MUNLOCK(ErrorMessageLock);
2725 if ( d->factors[num].type == DOLNUMBER )
2726 return(d->factors[num].value);
2728 MLOCK(ErrorMessageLock);
2730 MesPrint(
"$-variable in print statement is not a number");
2733 MesPrint(
"$-variable in do loop is not a number");
2735 MUNLOCK(ErrorMessageLock);
2746WORD TestDoLoop(PHEAD WORD *lhsbuf, WORD level)
2749 WORD start,finish,incr;
2754 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2755 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2758 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2759 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2763 if ( ( finish == start ) || ( finish > start && incr > 0 )
2764 || ( finish < start && incr < 0 ) ) {}
2765 else { level = lhsbuf[3]; }
2769 d = Dollars + lhsbuf[2];
2772 int nummodopt, dtype = -1;
2773 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2774 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2775 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2777 if ( nummodopt < NumModOptdollars ) {
2778 dtype = ModOptdollars[nummodopt].type;
2779 if ( DollarLocalCopy(dtype) ) {
2780 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2787 if ( d->size < MINALLOC ) {
2788 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2790 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2794 d->where[1] = start;
2798 d->type = DOLNUMBER;
2800 else if ( start < 0 ) {
2802 d->where[1] = -start;
2806 d->type = DOLNUMBER;
2811 if ( d == Dollars + lhsbuf[2] ) {
2812 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2813 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2814 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2824WORD TestEndDoLoop(PHEAD WORD *lhsbuf, WORD level)
2827 WORD start,finish,incr,value;
2832 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2833 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2836 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2837 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2841 if ( ( finish == start ) || ( finish > start && incr > 0 )
2842 || ( finish < start && incr < 0 ) ) {}
2843 else { level = lhsbuf[3]; }
2847 d = Dollars + lhsbuf[2];
2850 int nummodopt, dtype = -1;
2851 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2852 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2853 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2855 if ( nummodopt < NumModOptdollars ) {
2856 dtype = ModOptdollars[nummodopt].type;
2857 if ( DollarLocalCopy(dtype) ) {
2858 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2867 if ( d->type == DOLZERO ) {
2870 else if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2871 && ( d->where[4] == 0 ) && ( d->where[0] == 4 )
2872 && ( d->where[1] > 0 ) && ( d->where[2] == 1 ) ) {
2873 value = ( d->where[3] < 0 ) ? -d->where[1]: d->where[1];
2876 MLOCK(ErrorMessageLock);
2877 MesPrint(
"Wrong type of object in do loop parameter");
2878 MUNLOCK(ErrorMessageLock);
2883 if ( ( finish > start && value <= finish ) ||
2884 ( finish < start && value >= finish ) ||
2885 ( finish == start && value == finish ) ) {}
2886 else level = lhsbuf[3];
2888 if ( d->size < MINALLOC ) {
2889 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2891 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2895 d->where[1] = value;
2899 d->type = DOLNUMBER;
2901 else if ( start < 0 ) {
2903 d->where[1] = -value;
2907 d->type = DOLNUMBER;
2912 if ( d == Dollars + lhsbuf[2] ) {
2913 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2914 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2915 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2939int DollarFactorize(PHEAD WORD numdollar)
2942 DOLLARS d = Dollars + numdollar;
2944 WORD *oldworkpointer;
2945 WORD *buf1, *t, *term, *buf1content, *buf2, *termextra;
2946 WORD *buf3, *argextra;
2948 WORD *tstop, pow, *r;
2950 int i, j, jj, action = 0, sign = 1;
2952 WORD startebuf = cbuf[AT.ebufnum].numrhs;
2953 WORD nfactors, factorsincontent, extrafactor = 0;
2954 WORD oldsorttype = AR.SortType;
2957 int nummodopt, dtype;
2959 if ( AS.MultiThreaded ) {
2960 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2961 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2963 if ( nummodopt < NumModOptdollars ) {
2964 dtype = ModOptdollars[nummodopt].type;
2965 if ( DollarLocalCopy(dtype) ) {
2966 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2969 LOCK(d->pthreadslock);
2974 CleanDollarFactors(d);
2976 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
2978 if ( d->type != DOLTERMS ) {
2979 if ( d->type != DOLZERO ) d->nfactors = 1;
2982 if ( d->where[d->where[0]] == 0 ) {
2995 AR.SortType = SORTHIGHFIRST;
2996 if ( oldsorttype != AR.SortType ) {
3000 if ( AN.ncmod != 0 ) {
3001 if ( AN.ncmod != 1 || ( (WORD)AN.cmod[0] < 0 ) ) {
3002 AR.SortType = oldsorttype;
3003 MLOCK(ErrorMessageLock);
3004 MesPrint(
"Factorization modulus a number, greater than a WORD not implemented.");
3005 MUNLOCK(ErrorMessageLock);
3008 if ( Modulus(term) ) {
3009 AR.SortType = oldsorttype;
3010 MLOCK(ErrorMessageLock);
3011 MesCall(
"DollarFactorize");
3012 MUNLOCK(ErrorMessageLock);
3015 if ( !*term) { term = t;
continue; }
3021 EndSort(BHEAD (WORD *)((
void *)(&buf1)),2);
3022 t = buf1;
while ( *t ) t += *t;
3026 t = term;
while ( *t ) t += *t;
3027 ii = insize = t - term;
3028 buf1 = (WORD *)Malloc1((insize+1)*
sizeof(WORD),
"DollarFactorize-1");
3038 buf1content = TermMalloc(
"DollarContent");
3040 if ( ( buf2 =
TakeContent(BHEAD buf1,buf1content) ) == 0 ) {
3042 TermFree(buf1content,
"DollarContent");
3043 M_free(buf1,
"DollarFactorize-1");
3044 AR.SortType = oldsorttype;
3045 MLOCK(ErrorMessageLock);
3046 MesCall(
"DollarFactorize");
3047 MUNLOCK(ErrorMessageLock);
3051 else if ( ( buf1content[0] == 4 ) && ( buf1content[1] == 1 ) &&
3052 ( buf1content[2] == 1 ) && ( buf1content[3] == 3 ) ) {
3054 if ( buf2 != buf1 ) {
3055 M_free(buf2,
"DollarFactorize-2");
3058 factorsincontent = 0;
3065 if ( buf2 != buf1 ) M_free(buf1,
"DollarFactorize-1");
3067 t = buf1;
while ( *t ) t += *t;
3072 factorsincontent = 0;
3074 tstop = term + *term;
3075 if ( tstop[-1] < 0 ) factorsincontent++;
3076 if ( ABS(tstop[-1]) == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {
3077 tstop -= ABS(tstop[-1]);
3081 tstop -= ABS(tstop[-1]);
3084 while ( term < tstop ) {
3087 t = term+2; i = (term[1]-2)/2;
3089 factorsincontent += ABS(t[1]);
3094 t = term+2; i = (term[1]-2)/3;
3096 factorsincontent += ABS(t[2]);
3102 factorsincontent += (term[1]-2)/2;
3105 factorsincontent += term[1]-2;
3108 if ( *term >= FUNCTION ) factorsincontent++;
3115 factorsincontent = 0;
3127 if ( ( t[1] != SYMBOL ) && ( *t != (ABS(t[*t-1])+1) ) ) {
3132 if ( DetCommu(buf1) > 1 ) {
3133 MesPrint(
"Cannot factorize a $-expression with more than one noncommuting object");
3134 AR.SortType = oldsorttype;
3135 M_free(buf1,
"DollarFactorize-2");
3136 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3137 MesCall(
"DollarFactorize");
3143 termextra = AT.WorkPointer;
3149 AR.SortType = oldsorttype;
3150 M_free(buf1,
"DollarFactorize-2");
3151 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3152 MesCall(
"DollarFactorize");
3160 if (
EndSort(BHEAD (WORD *)((
void *)(&buf2)),2) < 0 ) {
goto getout; }
3162 t = buf2;
while ( *t > 0 ) t += *t;
3172 MesCall(
"DollarFactorize");
3173 AR.SortType = oldsorttype;
3174 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-3");
3175 M_free(buf1,
"DollarFactorize-3");
3176 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3180 if ( buf2 != buf1 && buf2 ) {
3181 M_free(buf2,
"DollarFactorize-3");
3185 AR.SortType = oldsorttype;
3192 if ( *term == 4 && term[4] == 0 && term[3] == -3 && term[2] == 1
3194 WORD *tt1, *tt2, *ttstop;
3196 tt1 = term; tt2 = term + *term + 1;
3199 while ( *ttstop ) ttstop += *ttstop;
3202 while ( tt2 < ttstop ) *tt1++ = *tt2++;
3211 while ( *term ) { term += *term; }
3226 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslock); }
3228 if ( nfactors == 1 && extrafactor == 0 ) {
3229 if ( factorsincontent == 0 ) {
3232 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
3241 term = buf1;
while ( *term ) term += *term;
3242 d->factors[0].size = i = term - buf1;
3243 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3244 term = buf1; NCOPY(t,term,i); *t = 0;
3245 AR.SortType = oldsorttype;
3246 M_free(buf3,
"DollarFactorize-4");
3247 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3248 M_free(buf1,
"DollarFactorize-4");
3249 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3253 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3254 term = buf1;
while ( *term ) term += *term;
3255 d->factors[0].size = i = term - buf1;
3256 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3257 term = buf1; NCOPY(t,term,i); *t = 0;
3258 M_free(buf3,
"DollarFactorize-4");
3260 if ( buf2 != buf1 && buf2 ) {
3261 M_free(buf2,
"DollarFactorize-4");
3266 else if ( action ) {
3267 C = cbuf+AC.cbufnum;
3268 CC = cbuf+AT.ebufnum;
3269 oldworkpointer = AT.WorkPointer;
3270 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3272 for ( i = 0; i < nfactors; i++ ) {
3273 argextra = AT.WorkPointer;
3277 if ( ConvertFromPoly(BHEAD term,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol
3278 ,startebuf-numxsymbol,1) <= 0 ) {
3280getout2: AR.SortType = oldsorttype;
3281 M_free(d->factors,
"factors in dollar");
3284 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
3286 M_free(buf3,
"DollarFactorize-4");
3287 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3288 M_free(buf1,
"DollarFactorize-4");
3289 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3292 AT.WorkPointer = argextra + *argextra;
3296 if (
Generator(BHEAD argextra,C->numlhs+1) ) {
3302 AT.WorkPointer = oldworkpointer;
3304 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3306 d->factors[i].type = DOLTERMS;
3307 t = d->factors[i].where;
3308 while ( *t ) t += *t;
3309 d->factors[i].size = t - d->factors[i].where;
3311 CC->numrhs = startebuf;
3314 C = cbuf+AC.cbufnum;
3315 oldworkpointer = AT.WorkPointer;
3316 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3318 for ( i = 0; i < nfactors; i++ ) {
3321 argextra = oldworkpointer;
3323 NCOPY(argextra,term,j)
3324 AT.WorkPointer = argextra;
3325 if (
Generator(BHEAD oldworkpointer,C->numlhs+1) ) {
3330 AT.WorkPointer = oldworkpointer;
3332 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3333 d->factors[i].type = DOLTERMS;
3334 t = d->factors[i].where;
3335 while ( *t ) t += *t;
3336 d->factors[i].size = t - d->factors[i].where;
3339 d->nfactors = nfactors + factorsincontent;
3344 if ( buf3 ) M_free(buf3,
"DollarFactorize-5");
3345 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-5");
3346 M_free(buf1,
"DollarFactorize-5");
3350 tstop = term + *term;
3351 if ( tstop[-1] < 0 ) { tstop[-1] = -tstop[-1]; sign = -sign; }
3354 while ( term < tstop ) {
3357 t = term+2; i = (term[1]-2)/2;
3359 if ( t[1] < 0 ) { t[1] = -t[1]; pow = -1; }
3361 for ( jj = 0; jj < t[1]; jj++ ) {
3362 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3363 r[0] = 8; r[1] = SYMBOL; r[2] = 4; r[3] = *t; r[4] = pow;
3364 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3365 d->factors[j].type = DOLTERMS;
3366 d->factors[j].size = 8;
3373 t = term+2; i = (term[1]-2)/3;
3375 if ( t[2] < 0 ) { t[2] = -t[2]; pow = -1; }
3377 for ( jj = 0; jj < t[2]; jj++ ) {
3378 r = d->factors[j].where = (WORD *)Malloc1(10*
sizeof(WORD),
"factor");
3379 r[0] = 9; r[1] = DOTPRODUCT; r[2] = 5; r[3] = t[0]; r[4] = t[1];
3380 r[5] = pow; r[6] = 1; r[7] = 1; r[8] = 3; r[9] = 0;
3381 d->factors[j].type = DOLTERMS;
3382 d->factors[j].size = 9;
3390 t = term+2; i = (term[1]-2)/2;
3392 for ( jj = 0; jj < t[1]; jj++ ) {
3393 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3394 r[0] = 8; r[1] = *term; r[2] = 4; r[3] = *t; r[4] = t[1];
3395 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3396 d->factors[j].type = DOLTERMS;
3397 d->factors[j].size = 8;
3404 t = term+2; i = term[1]-2;
3406 for ( jj = 0; jj < t[1]; jj++ ) {
3407 r = d->factors[j].where = (WORD *)Malloc1(8*
sizeof(WORD),
"factor");
3408 r[0] = 7; r[1] = *term; r[2] = 3; r[3] = *t;
3409 r[4] = 1; r[5] = 1; r[6] = 3; r[7] = 0;
3410 d->factors[j].type = DOLTERMS;
3411 d->factors[j].size = 7;
3418 if ( *term >= FUNCTION ) {
3419 r = d->factors[j].where = (WORD *)Malloc1((term[1]+5)*
sizeof(WORD),
"factor");
3420 *r++ = d->factors[j].size = term[1]+4;
3421 for ( jj = 0; jj < t[1]; jj++ ) *r++ = term[jj];
3422 *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3436 tstop = term + *term;
3437 if ( tstop[-1] == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {}
3438 else if ( tstop[-1] == 3 && tstop[-2] == 1 && (UWORD)(tstop[-3]) <= MAXPOSITIVE ) {
3439 d->factors[j].where = 0;
3440 d->factors[j].size = 0;
3441 d->factors[j].type = DOLNUMBER;
3442 d->factors[j].value = sign*tstop[-3];
3447 d->factors[j].where = r = (WORD *)Malloc1((tstop[-1]+2)*
sizeof(WORD),
"numfactor");
3448 d->factors[j].size = tstop[-1]+1;
3449 d->factors[j].type = DOLTERMS;
3450 d->factors[j].value = 0;
3457 r = d->factors[j].where;
3459 r += *r; r[-1] = -r[-1];
3467 for ( jj = j; jj > 0; jj-- ) {
3468 d->factors[jj] = d->factors[jj-1];
3470 d->factors[0].where = 0;
3471 d->factors[0].size = 0;
3472 d->factors[0].type = DOLNUMBER;
3473 d->factors[0].value = -1;
3477 if ( buf1content ) TermFree(buf1content,
"DollarContent");
3485 if ( d->nfactors > 1 ) {
3486 WORD ***fac, j1, j2, k, ret, *s1, *s2, *s3;
3488 facsize = (LONG **)Malloc1((
sizeof(WORD **)+
sizeof(LONG *))*d->nfactors,
"SortDollarFactors");
3489 fac = (WORD ***)(facsize+d->nfactors);
3491 for ( j = 0; j < d->nfactors; j++ ) {
3492 if ( d->factors[j].where ) {
3493 fac[k] = &(d->factors[j].where);
3494 facsize[k] = &(d->factors[j].size);
3499 for ( j = 1; j < k; j++ ) {
3502 s1 = *(fac[j1]); s2 = *(fac[j2]);
3503 while ( *s1 && *s2 ) {
3504 if ( ( ret = CompareTerms(BHEAD s2, s1, (WORD)2) ) == 0 ) {
3505 s1 += *s1; s2 += *s2;
3507 else if ( ret > 0 )
goto nextj;
3510 s3 = *(fac[j1]); *(fac[j1]) = *(fac[j2]); *(fac[j2]) = s3;
3511 x = *(facsize[j1]); *(facsize[j1]) = *(facsize[j2]); *(facsize[j2]) = x;
3513 if ( j1 > 0 )
goto nextj1;
3517 if ( *s1 )
goto nextj;
3518 if ( *s2 )
goto exch;
3522 M_free(facsize,
"SortDollarFactors");
3528 if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); }
3538void CleanDollarFactors(
DOLLARS d)
3541 if ( d->nfactors >= 1 ) {
3542 for ( i = 0; i < d->nfactors; i++ ) {
3544 if ( d->factors[i].where )
3545 M_free(d->factors[i].where,
"dollar factors");
3549 M_free(d->factors,
"dollar factors");
3560WORD *TakeDollarContent(PHEAD WORD *dollarbuffer, WORD **factor)
3567 t = dollarbuffer; pow = 1;
3573 t += *t; t[-1] = -t[-1];
3579 if ( AN.cmod != 0 ) {
3580 if ( ( *factor =
MakeDollarMod(BHEAD dollarbuffer,&remain) ) == 0 ) {
3584 (*factor)[**factor-1] = -(*factor)[**factor-1];
3585 (*factor)[**factor-1] += AN.cmod[0];
3593 (*factor)[**factor-1] = -(*factor)[**factor-1];
3615 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMb, *LCMc;
3616 WORD *r, *r1, *r2, *r3, *rnext, i, k, j, *oldworkpointer, *factor;
3617 WORD kGCD, kLCM, kGCD2, kkLCM, jLCM, jGCD;
3618 CBUF *C = cbuf+AC.cbufnum;
3620 GCDbuffer = NumberMalloc(
"MakeDollarInteger");
3621 GCDbuffer2 = NumberMalloc(
"MakeDollarInteger");
3622 LCMbuffer = NumberMalloc(
"MakeDollarInteger");
3623 LCMb = NumberMalloc(
"MakeDollarInteger");
3624 LCMc = NumberMalloc(
"MakeDollarInteger");
3633 if ( k < 0 ) k = -k;
3634 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3635 for ( kGCD = 0; kGCD < k; kGCD++ ) GCDbuffer[kGCD] = r3[kGCD];
3637 if ( k < 0 ) k = -k;
3639 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3640 for ( kLCM = 0; kLCM < k; kLCM++ ) LCMbuffer[kLCM] = r3[kLCM];
3650 if ( k < 0 ) k = -k;
3651 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3652 if ( ( ( GCDbuffer[0] == 1 ) && ( kGCD == 1 ) ) ) {
3657 else if ( ( ( k != 1 ) || ( r3[0] != 1 ) ) ) {
3658 if ( GcdLong(BHEAD GCDbuffer,kGCD,(UWORD *)r3,k,GCDbuffer2,&kGCD2) ) {
3659 goto MakeDollarIntegerErr;
3662 for ( i = 0; i < kGCD; i++ ) GCDbuffer[i] = GCDbuffer2[i];
3665 kGCD = 1; GCDbuffer[0] = 1;
3668 if ( k < 0 ) k = -k;
3670 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3671 if ( ( ( LCMbuffer[0] == 1 ) && ( kLCM == 1 ) ) ) {
3672 for ( kLCM = 0; kLCM < k; kLCM++ )
3673 LCMbuffer[kLCM] = r3[kLCM];
3675 else if ( ( k != 1 ) || ( r3[0] != 1 ) ) {
3676 if ( GcdLong(BHEAD LCMbuffer,kLCM,(UWORD *)r3,k,LCMb,&kkLCM) ) {
3677 goto MakeDollarIntegerErr;
3679 DivLong((UWORD *)r3,k,LCMb,kkLCM,LCMb,&kkLCM,LCMc,&jLCM);
3680 MulLong(LCMbuffer,kLCM,LCMb,kkLCM,LCMc,&jLCM);
3681 for ( kLCM = 0; kLCM < jLCM; kLCM++ )
3682 LCMbuffer[kLCM] = LCMc[kLCM];
3690 r3 = (WORD *)(GCDbuffer);
3691 if ( kGCD == kLCM ) {
3692 for ( jGCD = 0; jGCD < kGCD; jGCD++ )
3693 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3696 else if ( kGCD > kLCM ) {
3697 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3698 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3699 for ( jGCD = kLCM; jGCD < kGCD; jGCD++ )
3704 for ( jGCD = kGCD; jGCD < kLCM; jGCD++ )
3706 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3707 r3[jGCD+kLCM] = LCMbuffer[jGCD];
3714 factor = r1 = (WORD *)Malloc1((j+2)*
sizeof(WORD),
"MakeDollarInteger");
3715 *r1++ = j+1; r2 = r3;
3716 for ( i = 0; i < k; i++ ) { *r1++ = *r2++; *r1++ = *r2++; }
3729 oldworkpointer = AT.WorkPointer;
3734 r2 = oldworkpointer;
3735 while ( r < r3 ) *r2++ = *r++;
3737 if ( DivRat(BHEAD (UWORD *)r3,j,GCDbuffer,k,(UWORD *)r2,&i) ) {
3738 goto MakeDollarIntegerErr;
3742 if ( rnext[-1] < 0 ) r2[-1] = -i;
3744 *oldworkpointer = r2-oldworkpointer;
3745 AT.WorkPointer = r2;
3746 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3747 goto MakeDollarIntegerErr;
3751 AT.WorkPointer = oldworkpointer;
3753 EndSort(BHEAD (WORD *)bufout,2);
3757 NumberFree(LCMc,
"MakeDollarInteger");
3758 NumberFree(LCMb,
"MakeDollarInteger");
3759 NumberFree(LCMbuffer,
"MakeDollarInteger");
3760 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3761 NumberFree(GCDbuffer,
"MakeDollarInteger");
3764MakeDollarIntegerErr:
3765 NumberFree(LCMc,
"MakeDollarInteger");
3766 NumberFree(LCMb,
"MakeDollarInteger");
3767 NumberFree(LCMbuffer,
"MakeDollarInteger");
3768 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3769 NumberFree(GCDbuffer,
"MakeDollarInteger");
3770 MesCall(
"MakeDollarInteger");
3789 WORD *r, *r1, x, xx, ix, ip;
3790 WORD *factor, *oldworkpointer;
3792 CBUF *C = cbuf+AC.cbufnum;
3795 if ( r[*r-1] < 0 ) x += AN.cmod[0];
3799 factor = (WORD *)Malloc1(5*
sizeof(WORD),
"MakeDollarMod");
3800 factor[0] = 4; factor[1] = x; factor[2] = 1; factor[3] = 3; factor[4] = 0;
3808 oldworkpointer = AT.WorkPointer;
3810 r1 = oldworkpointer; i = *r;
3812 xx = r1[-3];
if ( r1[-1] < 0 ) xx += AN.cmod[0];
3813 r1[-1] = (WORD)((((LONG)xx)*ix) % AN.cmod[0]);
3814 *r1 = 0; AT.WorkPointer = r1;
3815 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3819 AT.WorkPointer = oldworkpointer;
3821 EndSort(BHEAD (WORD *)bufout,2);
3831int GetDolNum(PHEAD WORD *t, WORD *tstop)
3835 if ( t+3 < tstop && t[3] == DOLLAREXPR2 ) {
3839 int nummodopt, dtype;
3841 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3842 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3843 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3845 if ( nummodopt < NumModOptdollars ) {
3846 dtype = ModOptdollars[nummodopt].type;
3847 if ( DollarLocalCopy(dtype) ) {
3848 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3851 MLOCK(ErrorMessageLock);
3852 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3853 DOLLARNAME(Dollars,t[2]),AC.CModule);
3854 MUNLOCK(ErrorMessageLock);
3861 if ( d->factors == 0 ) {
3862 MLOCK(ErrorMessageLock);
3863 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
3864 MUNLOCK(ErrorMessageLock);
3867 num = GetDolNum(BHEAD t+t[1],tstop);
3868 if ( num == 0 )
return(d->nfactors);
3869 if ( num > d->nfactors ) {
3870 MLOCK(ErrorMessageLock);
3871 MesPrint(
"Attempt to use an nonexisting factor %d of a $-variable",num);
3872 MUNLOCK(ErrorMessageLock);
3875 w = d->factors[num-1].where;
3876 if ( w == 0 )
return(d->factors[num-1].value);
3877 if ( w[0] == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1 && w[1] > 0
3878 && w[1] < MAXPOSITIVE )
return(w[1]);
3880 MLOCK(ErrorMessageLock);
3881 MesPrint(
"Illegal type of factor number of a $-variable");
3882 MUNLOCK(ErrorMessageLock);
3886 else if ( t[2] < 0 ) {
3893 int nummodopt, dtype;
3895 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3896 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3897 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3899 if ( nummodopt < NumModOptdollars ) {
3900 dtype = ModOptdollars[nummodopt].type;
3901 if ( DollarLocalCopy(dtype) ) {
3902 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3905 MLOCK(ErrorMessageLock);
3906 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3907 DOLLARNAME(Dollars,t[2]),AC.CModule);
3908 MUNLOCK(ErrorMessageLock);
3915 if ( d->type == DOLZERO )
return(0);
3916 if ( d->type == DOLTERMS || d->type == DOLNUMBER ) {
3917 if ( d->where[0] == 4 && d->where[4] == 0 && d->where[3] == 3
3918 && d->where[2] == 1 && d->where[1] > 0
3919 && d->where[1] < MAXPOSITIVE )
return(d->where[1]);
3920 MLOCK(ErrorMessageLock);
3921 MesPrint(
"Attempt to use an nonexisting factor of a $-variable");
3922 MUNLOCK(ErrorMessageLock);
3925 MLOCK(ErrorMessageLock);
3926 MesPrint(
"Illegal type of factor number of a $-variable");
3927 MUNLOCK(ErrorMessageLock);
3946 int i, n = NumPotModdollars;
3947 for ( i = 0; i < n; i++ ) {
3948 if ( numdollar == PotModdollars[i] )
break;
3951 *(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)