40 static UBYTE underscore[2] = {
'_',0};
54 int CatchDollar(
int par)
57 CBUF *C = cbuf + AC.cbufnum;
58 int error = 0, numterms = 0, numdollar, resetmods = 0;
60 WORD *w, *t, n, nsize, *oldwork = AT.WorkPointer, *dbuffer;
61 WORD oldncmod = AN.ncmod;
63 if ( AN.ncmod && ( ( AC.modmode & ALSODOLLARS ) == 0 ) ) AN.ncmod = 0;
64 if ( AN.ncmod && AN.cmod == 0 ) { SetMods(); resetmods = 1; }
66 numdollar = C->lhs[C->numlhs][2];
68 d = Dollars+numdollar;
70 d->type = DOLUNDEFINED;
71 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
72 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
73 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"$-buffer old");
74 d->size = 0; d->where = &(AM.dollarzero);
75 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
77 if ( resetmods ) UnSetMods();
94 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag ) {
99 if (
NewSort(BHEAD0) ) {
if ( !error ) error = 1;
goto onerror; }
102 if ( !error ) error = 1;
105 AN.RepPoint = AT.RepCount + 1;
106 w = C->rhs[C->lhs[C->numlhs][5]];
111 AR.Cnumlhs = C->numlhs;
112 if (
Generator(BHEAD oldwork,C->numlhs) ) { error = 1;
break; }
114 AT.WorkPointer = oldwork;
115 if (
EndSort(BHEAD (WORD *)((VOID *)(&dbuffer)),2) < 0 ) { error = 1; }
119 while ( *w ) { w += *w; numterms++; }
122 newsize = w - dbuffer+1;
125 if ( AC.RhsExprInModuleFlag )
130 if ( numterms == 0 ) {
134 else if ( numterms == 1 ) {
138 if ( nsize < 0 ) { nsize = -nsize; }
139 if ( nsize == (n-1) ) {
142 if ( *w != 1 )
goto doterms;
143 w++;
while ( w < ( t + n - 1 ) ) {
if ( *w )
break; w++; }
144 if ( w < ( t + n - 1 ) )
goto doterms;
148 else if ( n == 7 && t[6] == 3 && t[5] == 1 && t[4] == 1
149 && t[1] == INDEX && t[2] == 3 ) {
159 cbuf[AM.dbufnum].CanCommu[numdollar] = numcommute(dbuffer,
160 &(cbuf[AM.dbufnum].NumTerms[numdollar]));
162 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"$-buffer old");
163 d->size = newsize; d->where = dbuffer;
164 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
166 if ( C->Pointer > C->rhs[C->numrhs] ) C->Pointer = C->rhs[C->numrhs];
167 C->numlhs--; C->numrhs--;
170 if ( PF.me == MASTER || !AC.RhsExprInModuleFlag )
174 if ( resetmods ) UnSetMods();
196 int AssignDollar(
PHEAD WORD *term, WORD level)
199 CBUF *C = cbuf+AM.rbufnum;
200 int numterms = 0, numdollar = C->lhs[level][2];
202 DOLLARS d = Dollars + numdollar;
203 WORD *w, *t, n, nsize, *rh = cbuf[C->lhs[level][7]].rhs[C->lhs[level][5]];
205 WORD olddefer, oldcompress, oldncmod = AN.ncmod;
207 int nummodopt, dtype = -1, dw;
209 if ( AN.ncmod && ( ( AC.modmode & ALSODOLLARS ) == 0 ) ) AN.ncmod = 0;
210 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
216 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
217 if ( numdollar == ModOptdollars[nummodopt].number )
break;
219 if ( nummodopt >= NumModOptdollars ) {
220 MLOCK(ErrorMessageLock);
221 MesPrint(
"Illegal attempt to change $-variable in multi-threaded module %l",AC.CModule);
222 MUNLOCK(ErrorMessageLock);
225 dtype = ModOptdollars[nummodopt].type;
226 if ( dtype == MODLOCAL ) {
227 d = ModOptdollars[nummodopt].dstruct+AT.identity;
243 LOCK(d->pthreadslockread);
246 case DOLZERO:
goto NoChangeZero;
249 if ( ( dw = d->where[0] ) > 0 && d->where[dw] != 0 ) {
252 if ( dtype == MODMAX && d->where[dw-1] >= 0 )
goto NoChangeZero;
253 if ( dtype == MODMIN && d->where[dw-1] <= 0 )
goto NoChangeZero;
256 numvalue = DolToNumber(BHEAD numdollar);
257 if ( AN.ErrorInDollar != 0 )
break;
258 if ( dtype == MODMAX && numvalue >= 0 )
goto NoChangeZero;
259 if ( dtype == MODMIN && numvalue <= 0 )
goto NoChangeZero;
264 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
265 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
267 CleanDollarFactors(d);
269 UNLOCK(d->pthreadslockread);
279 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
280 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
281 CleanDollarFactors(d);
285 else if ( *w == 4 && w[4] == 0 && w[2] == 1 ) {
292 LOCK(d->pthreadslockread);
294 WORD oldsize, *oldwhere, i;
295 oldsize = d->size; oldwhere = d->where;
297 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
298 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
299 for ( i = 0; i < oldsize; i++ ) d->where[i] = oldwhere[i];
300 if ( oldwhere && oldwhere != &(AM.dollarzero) ) M_free(oldwhere,
"dollar contents");
305 if ( dtype == MODMAX && w[3] <= 0 )
goto NoChangeOne;
306 if ( dtype == MODMIN && w[3] >= 0 )
goto NoChangeOne;
310 if ( ( dw = d->where[0] ) > 0 && d->where[dw] != 0 ) {
313 if ( dtype == MODMAX &&
CompCoef(d->where,w) >= 0 )
goto NoChangeOne;
314 if ( dtype == MODMIN &&
CompCoef(d->where,w) <= 0 )
goto NoChangeOne;
322 numvalue = DolToNumber(BHEAD numdollar);
323 if ( AN.ErrorInDollar != 0 )
break;
324 if ( numvalue == 0 ) {
327 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
328 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
331 d->where[0] = extraterm[0] = 4;
332 d->where[1] = extraterm[1] = ABS(numvalue);
333 d->where[2] = extraterm[2] = 1;
334 d->where[3] = extraterm[3] = numvalue > 0 ? 3 : -3;
337 if ( dtype == MODMAX &&
CompCoef(extraterm,w) >= 0 )
goto NoChangeOne;
338 if ( dtype == MODMIN &&
CompCoef(extraterm,w) <= 0 )
goto NoChangeOne;
348 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
349 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
351 CleanDollarFactors(d);
353 UNLOCK(d->pthreadslockread);
362 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
364 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
365 cbuf[AM.dbufnum].rhs[numdollar] = d->where;
373 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
374 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
375 CleanDollarFactors(d);
385 if ( dtype == MODSUM ) {
387 LOCK(d->pthreadslockread);
390 CleanDollarFactors(d);
410 olddefer = AR.DeferFlag; AR.DeferFlag = 0;
411 oldcompress = AR.NoCompress; AR.NoCompress = 1;
413 n = *w; t = ww = AT.WorkPointer;
419 AR.DeferFlag = olddefer;
425 if ( ( newsize =
EndSort(BHEAD (WORD *)((VOID *)(&ss)),2) ) < 0 ) {
429 numterms = 0; t = ss;
while ( *t ) { numterms++; t += *t; }
432 if ( dtype != MODSUM ) {
434 LOCK(d->pthreadslockread);
437 if ( numterms == 0 ) {
442 if ( dtype == MODMAX || dtype == MODMIN ) {
443 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
444 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
450 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
451 d->where = &(AM.dollarzero);
453 cbuf[AM.dbufnum].rhs[numdollar] = 0;
454 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
455 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
458 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
465 if ( dtype == MODMAX || dtype == MODMIN ) {
466 if ( numterms == 1 && ( *ss-1 == ABS(ss[*ss-1]) ) ) {
470 if ( dtype == MODMAX && ss[*ss-1] > 0 )
break;
471 if ( dtype == MODMIN && ss[*ss-1] < 0 )
break;
472 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
473 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
477 if ( ( dw = d->where[0] ) > 0 && d->where[dw] != 0 )
break;
478 if ( dtype == MODMAX &&
CompCoef(ss,d->where) > 0 )
break;
479 if ( dtype == MODMIN &&
CompCoef(ss,d->where) < 0 )
break;
480 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
481 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
485 numvalue = DolToNumber(BHEAD numdollar);
486 if ( AN.ErrorInDollar != 0 )
break;
487 if ( numvalue == 0 ) {
490 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
491 cbuf[AM.dbufnum].NumTerms[numdollar] = 0;
494 d->where[0] = extraterm[0] = 4;
495 d->where[1] = extraterm[1] = ABS(numvalue);
496 d->where[2] = extraterm[2] = 1;
497 d->where[3] = extraterm[3] = numvalue > 0 ? 3 : -3;
500 if ( dtype == MODMAX &&
CompCoef(ss,extraterm) > 0 )
break;
501 if ( dtype == MODMIN &&
CompCoef(ss,extraterm) < 0 )
break;
502 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
503 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
509 if ( ss ) { M_free(ss,
"Sort of $"); ss = 0; }
510 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
519 if ( d->where && d->where != &(AM.dollarzero) ) { M_free(d->where,
"dollar contents"); d->where = 0; }
520 d->size = newsize + 1;
522 cbuf[AM.dbufnum].rhs[numdollar] = w = d->where;
524 AR.DeferFlag = olddefer; AR.NoCompress = oldcompress;
528 if ( numterms == 0 ) {
531 else if ( numterms == 1 ) {
535 if ( nsize < 0 ) { nsize = -nsize; }
536 if ( nsize == (n-1) ) {
540 w++;
while ( w < ( t + n - 1 ) ) {
if ( *w )
break; w++; }
541 if ( w >= ( t + n - 1 ) ) d->type = DOLNUMBER;
544 else if ( n == 7 && t[6] == 3 && t[5] == 1 && t[4] == 1
545 && t[1] == INDEX && t[2] == 3 ) {
550 if ( d->type == DOLTERMS ) {
551 cbuf[AM.dbufnum].CanCommu[numdollar] = numcommute(d->where,
552 &(cbuf[AM.dbufnum].NumTerms[numdollar]));
555 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
556 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
561 UNLOCK(d->pthreadslockread);
579 UBYTE *WriteDollarToBuffer(WORD numdollar, WORD par)
582 UBYTE *s, *oldcurbufwrt = AO.CurBufWrt;
583 WORD *t, lbrac = 0, first = 0, arg[2], oldOutputMode = AC.OutputMode;
584 WORD oldinfbrack = AO.InFbrack;
587 AO.DollarOutSizeBuffer = 32;
588 AO.DollarOutBuffer = (UBYTE *)Malloc1(AO.DollarOutSizeBuffer,
"DollarOutBuffer");
589 AO.DollarInOutBuffer = 1;
592 s = AO.DollarOutBuffer;
594 if ( par > 0 ) { AC.OutputMode = NORMALFORMAT; }
596 AO.CurBufWrt = (UBYTE *)underscore;
601 WriteArgument(d->where);
604 WriteSubTerm(d->where,1);
610 if ( WriteTerm(t,&lbrac,first,PRINTON,0) ) {
621 if ( *t ) TokenToLine((UBYTE *)(","));
625 arg[0] = -INDEX; arg[1] = d->index;
630 AO.DollarInOutBuffer = 1;
634 AO.DollarInOutBuffer = 1;
637 AC.OutputMode = oldOutputMode;
639 AO.InFbrack = oldinfbrack;
640 AO.CurBufWrt = oldcurbufwrt;
642 MLOCK(ErrorMessageLock);
643 MesPrint(
"&Illegal dollar object for writing");
644 MUNLOCK(ErrorMessageLock);
645 M_free(AO.DollarOutBuffer,
"DollarOutBuffer");
646 AO.DollarOutBuffer = 0;
647 AO.DollarOutSizeBuffer = 0;
650 return(AO.DollarOutBuffer);
665 UBYTE *WriteDollarFactorToBuffer(WORD numdollar, WORD numfac, WORD par)
668 UBYTE *s, *oldcurbufwrt = AO.CurBufWrt;
669 WORD *t, lbrac = 0, first = 0, n[5], oldOutputMode = AC.OutputMode;
670 WORD oldinfbrack = AO.InFbrack;
673 if ( numfac > d->nfactors || numfac < 0 ) {
674 MLOCK(ErrorMessageLock);
675 MesPrint(
"&Illegal factor number for this dollar variable: %d",numfac);
676 MesPrint(
"&There are %d factors",d->nfactors);
677 MUNLOCK(ErrorMessageLock);
681 AO.DollarOutSizeBuffer = 32;
682 AO.DollarOutBuffer = (UBYTE *)Malloc1(AO.DollarOutSizeBuffer,
"DollarOutBuffer");
683 AO.DollarInOutBuffer = 1;
686 s = AO.DollarOutBuffer;
688 if ( par > 0 ) { AC.OutputMode = NORMALFORMAT; }
690 AO.CurBufWrt = (UBYTE *)underscore;
694 n[0] = 4; n[1] = d->nfactors; n[2] = 1; n[3] = 3; n[4] = 0; t = n;
696 else if ( d->factors[numfac-1].where == 0 ) {
697 if ( d->factors[numfac-1].value < 0 ) {
698 n[0] = 4; n[1] = -d->factors[numfac-1].value; n[2] = 1; n[3] = -3; n[4] = 0; t = n;
701 n[0] = 4; n[1] = d->factors[numfac-1].value; n[2] = 1; n[3] = 3; n[4] = 0; t = n;
704 else { t = d->factors[numfac-1].where; }
706 if ( WriteTerm(t,&lbrac,first,PRINTON,0) ) {
711 AC.OutputMode = oldOutputMode;
713 AO.InFbrack = oldinfbrack;
714 AO.CurBufWrt = oldcurbufwrt;
716 MLOCK(ErrorMessageLock);
717 MesPrint(
"&Illegal dollar object for writing");
718 MUNLOCK(ErrorMessageLock);
719 M_free(AO.DollarOutBuffer,
"DollarOutBuffer");
720 AO.DollarOutBuffer = 0;
721 AO.DollarOutSizeBuffer = 0;
724 return(AO.DollarOutBuffer);
732 void AddToDollarBuffer(UBYTE *s)
735 UBYTE *t = s, *u, *newdob;
737 while ( *t ) { t++; }
739 while ( i + AO.DollarInOutBuffer >= AO.DollarOutSizeBuffer ) {
740 j = AO.DollarInOutBuffer;
741 AO.DollarOutSizeBuffer *= 2;
742 t = AO.DollarOutBuffer;
743 newdob = (UBYTE *)Malloc1(AO.DollarOutSizeBuffer,
"DollarOutBuffer");
745 while ( --j >= 0 ) *u++ = *t++;
746 M_free(AO.DollarOutBuffer,
"DollarOutBuffer");
747 AO.DollarOutBuffer = newdob;
749 t = AO.DollarOutBuffer + AO.DollarInOutBuffer-1;
750 while ( t == AO.DollarOutBuffer && ( *s ==
'+' || *s ==
' ' ) ) s++;
753 if ( *s ==
' ' ) { s++;
continue; }
757 AO.DollarInOutBuffer += i;
768 void TermAssign(WORD *term)
771 WORD *t, *tstop, *astop, *w, *m;
774 astop = term + *term;
775 tstop = astop - ABS(astop[-1]);
777 while ( t < tstop ) {
778 if ( *t == AM.termfunnum && t[1] == FUNHEAD+2
779 && t[FUNHEAD] == -DOLLAREXPRESSION ) {
780 d = Dollars + t[FUNHEAD+1];
781 newsize = *term - FUNHEAD - 1;
782 if ( d->size > 2*newsize && d->size > 1000 ) {
783 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
785 d->where = &(AM.dollarzero);
787 if ( d->size < newsize ) {
788 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
790 d->where = (WORD *)Malloc1(newsize*
sizeof(WORD),
"dollar contents");
792 cbuf[AM.dbufnum].rhs[t[FUNHEAD+1]] = w = d->where;
794 while ( m < t ) *w++ = *m++;
796 while ( m < tstop ) {
797 if ( *m == AM.termfunnum && m[1] == FUNHEAD+2
798 && m[FUNHEAD] == -DOLLAREXPRESSION ) { m += m[1]; }
801 while ( --i >= 0 ) *w++ = *m++;
804 while ( m < astop ) *w++ = *m++;
805 *(d->where) = w - d->where;
809 while ( m < astop ) *w++ = *m++;
815 if ( t >= tstop )
return;
826 void WildDollars(PHEAD0)
830 WORD *m, *t, *w, *ww, *orig = 0;
837 while ( m < AN.WildStop ) {
838 if ( *m != LOADDOLLAR ) { m += m[1];
continue; }
840 while ( *t == LOADDOLLAR || *t == FROMSET || *t == SETTONUM ) t -= 4;
841 if ( t < AN.WildValue ) {
842 MLOCK(ErrorMessageLock);
843 MesPrint(
"&Serious bug in wildcard prototype. Found in WildDollars");
844 MUNLOCK(ErrorMessageLock);
848 d = Dollars + numdollar;
853 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
854 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
855 if ( numdollar == ModOptdollars[nummodopt].number )
break;
857 if ( nummodopt < NumModOptdollars ) {
858 dtype = ModOptdollars[nummodopt].type;
859 if ( dtype == MODLOCAL ) {
860 d = ModOptdollars[nummodopt].dstruct+AT.identity;
863 MLOCK(ErrorMessageLock);
864 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
865 DOLLARNAME(Dollars,numdollar),AC.CModule);
866 MUNLOCK(ErrorMessageLock);
887 orig = cbuf[AT.ebufnum].rhs[t[3]];
888 w = orig;
while ( *w ) w += *w;
889 weneed = w - orig + 1;
900 orig = cbuf[AT.ebufnum].rhs[t[3]];
901 if ( *orig > 0 ) weneed = *orig+2;
903 w = orig+1;
while ( *w ) { NEXTARG(w) }
904 weneed = w - orig + 1;
911 if ( d->size > 2*weneed && d->size > 1000 ) {
912 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollarspace");
913 d->where = &(AM.dollarzero);
916 if ( d->size < weneed ) {
917 if ( weneed < 20 ) weneed = 20;
918 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollarspace");
919 d->where = (WORD *)Malloc1(weneed*
sizeof(WORD),
"dollarspace");
927 cbuf[AM.dbufnum].CanCommu[numdollar] = 0;
928 cbuf[AM.dbufnum].NumTerms[numdollar] = 1;
930 cbuf[AM.dbufnum].rhs[numdollar] = (WORD *)(1);
939 d->where[0] = 4; d->where[2] = 1;
940 if ( t[3] >= 0 ) { d->where[1] = t[3]; d->where[3] = 3; }
941 else { d->where[1] = -t[3]; d->where[3] = -3; }
942 if ( t[3] == 0 ) { d->type = DOLZERO; d->where[0] = 0; }
943 else { d->type = DOLNUMBER; d->where[4] = 0; }
946 *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = t[3]; *w++ = 1;
947 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
953 i = *orig;
while ( --i >= 0 ) *w++ = *orig++;
961 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[3];
962 *w++ = 1; *w++ = 1; *w++ = -3; *w = 0;
965 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[3];
966 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
969 d->type = DOLINDEX; d->index = t[3]; *w = 0;
972 *w++ = FUNHEAD+4; *w++ = t[3]; *w++ = FUNHEAD;
974 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
977 if ( *orig > 0 ) ww = orig + *orig + 1;
979 ww = orig+1;
while ( *ww ) { NEXTARG(ww) }
981 while ( orig < ww ) *w++ = *orig++;
983 d->type = DOLWILDARGS;
986 d->type = DOLUNDEFINED;
998 WORD DolToTensor(
PHEAD WORD numdollar)
1001 DOLLARS d = Dollars + numdollar;
1004 int nummodopt, dtype = -1;
1005 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1006 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1007 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1009 if ( nummodopt < NumModOptdollars ) {
1010 dtype = ModOptdollars[nummodopt].type;
1011 if ( dtype == MODLOCAL ) {
1012 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1015 LOCK(d->pthreadslockread);
1020 AN.ErrorInDollar = 0;
1021 if ( d->type == DOLTERMS && d->where[0] == FUNHEAD+4 &&
1022 d->where[FUNHEAD+4] == 0 && d->where[FUNHEAD+3] == 3 &&
1023 d->where[FUNHEAD+2] == 1 && d->where[FUNHEAD+1] == 1 &&
1024 d->where[1] >= FUNCTION && d->where[1] < FUNCTION+WILDOFFSET
1025 && functions[d->where[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1026 retval = d->where[1];
1028 else if ( d->type == DOLARGUMENT &&
1029 d->where[0] <= -FUNCTION && d->where[0] > -FUNCTION-WILDOFFSET
1030 && functions[-d->where[0]-FUNCTION].spec >= TENSORFUNCTION ) {
1031 retval = -d->where[0];
1033 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1034 && d->where[1] <= -FUNCTION && d->where[1] > -FUNCTION-WILDOFFSET
1036 && functions[-d->where[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1037 retval = -d->where[1];
1039 else if ( d->type == DOLSUBTERM &&
1040 d->where[0] >= FUNCTION && d->where[0] < FUNCTION+WILDOFFSET
1041 && functions[d->where[0]-FUNCTION].spec >= TENSORFUNCTION ) {
1042 retval = d->where[0];
1045 AN.ErrorInDollar = 1;
1049 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1059 WORD DolToFunction(
PHEAD WORD numdollar)
1062 DOLLARS d = Dollars + numdollar;
1065 int nummodopt, dtype = -1;
1066 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1067 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1068 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1070 if ( nummodopt < NumModOptdollars ) {
1071 dtype = ModOptdollars[nummodopt].type;
1072 if ( dtype == MODLOCAL ) {
1073 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1076 LOCK(d->pthreadslockread);
1081 AN.ErrorInDollar = 0;
1082 if ( d->type == DOLTERMS && d->where[0] == FUNHEAD+4 &&
1083 d->where[FUNHEAD+4] == 0 && d->where[FUNHEAD+3] == 3 &&
1084 d->where[FUNHEAD+2] == 1 && d->where[FUNHEAD+1] == 1 &&
1085 d->where[1] >= FUNCTION && d->where[1] < FUNCTION+WILDOFFSET ) {
1086 retval = d->where[1];
1088 else if ( d->type == DOLARGUMENT &&
1089 d->where[0] <= -FUNCTION && d->where[0] > -FUNCTION-WILDOFFSET ) {
1090 retval = -d->where[0];
1092 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1093 && d->where[1] <= -FUNCTION && d->where[1] > -FUNCTION-WILDOFFSET
1094 && d->where[2] == 0 ) {
1095 retval = -d->where[1];
1097 else if ( d->type == DOLSUBTERM &&
1098 d->where[0] >= FUNCTION && d->where[0] < FUNCTION+WILDOFFSET ) {
1099 retval = d->where[0];
1102 AN.ErrorInDollar = 1;
1106 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1116 WORD DolToVector(
PHEAD WORD numdollar)
1119 DOLLARS d = Dollars + numdollar;
1122 int nummodopt, dtype = -1;
1123 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1124 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1125 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1127 if ( nummodopt < NumModOptdollars ) {
1128 dtype = ModOptdollars[nummodopt].type;
1129 if ( dtype == MODLOCAL ) {
1130 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1133 LOCK(d->pthreadslockread);
1138 AN.ErrorInDollar = 0;
1139 if ( d->type == DOLINDEX && d->index < 0 ) {
1142 else if ( d->type == DOLARGUMENT && ( d->where[0] == -VECTOR
1143 || d->where[0] == -MINVECTOR ) ) {
1144 retval = d->where[1];
1146 else if ( d->type == DOLSUBTERM && d->where[0] == INDEX
1147 && d->where[1] == 3 && d->where[2] < 0 ) {
1148 retval = d->where[2];
1150 else if ( d->type == DOLTERMS && d->where[0] == 7 &&
1151 d->where[7] == 0 && d->where[6] == 3 &&
1152 d->where[5] == 1 && d->where[4] == 1 &&
1153 d->where[1] >= INDEX && d->where[3] < 0 ) {
1154 retval = d->where[3];
1156 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1157 && ( d->where[1] == -VECTOR || d->where[1] == -MINVECTOR )
1158 && d->where[3] == 0 ) {
1159 retval = d->where[2];
1161 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1162 && d->where[1] < 0 ) {
1163 retval = d->where[1];
1166 AN.ErrorInDollar = 1;
1170 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1180 WORD DolToNumber(
PHEAD WORD numdollar)
1183 DOLLARS d = Dollars + numdollar;
1185 int nummodopt, dtype = -1;
1186 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1187 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1188 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1190 if ( nummodopt < NumModOptdollars ) {
1191 dtype = ModOptdollars[nummodopt].type;
1192 if ( dtype == MODLOCAL ) {
1193 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1198 AN.ErrorInDollar = 0;
1199 if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1200 && d->where[0] == 4 &&
1201 d->where[4] == 0 && ( d->where[3] == 3 || d->where[3] == -3 )
1202 && d->where[2] == 1 && ( d->where[1] & TOPBITONLY ) == 0 ) {
1203 if ( d->where[3] > 0 )
return(d->where[1]);
1204 else return(-d->where[1]);
1206 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER ) {
1207 return(d->where[1]);
1209 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1210 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1211 return(d->where[1]);
1213 else if ( d->type == DOLZERO )
return(0);
1214 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1215 && d->where[1] == -SNUMBER && d->where[3] == 0 ) {
1216 return(d->where[2]);
1218 else if ( d->type == DOLINDEX && d->index >= 0 && d->index < AM.OffsetIndex ) {
1221 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1222 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1223 return(d->where[1]);
1225 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1226 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0
1227 && d->where[2] < AM.OffsetIndex ) {
1228 return(d->where[2]);
1230 AN.ErrorInDollar = 1;
1239 WORD DolToSymbol(
PHEAD WORD numdollar)
1242 DOLLARS d = Dollars + numdollar;
1245 int nummodopt, dtype = -1;
1246 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1247 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1248 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1250 if ( nummodopt < NumModOptdollars ) {
1251 dtype = ModOptdollars[nummodopt].type;
1252 if ( dtype == MODLOCAL ) {
1253 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1256 LOCK(d->pthreadslockread);
1261 AN.ErrorInDollar = 0;
1262 if ( d->type == DOLTERMS && d->where[0] == 8 &&
1263 d->where[8] == 0 && d->where[7] == 3 && d->where[6] == 1
1264 && d->where[5] == 1 && d->where[4] == 1 && d->where[1] == SYMBOL ) {
1265 retval = d->where[2];
1267 else if ( d->type == DOLARGUMENT && d->where[0] == -SYMBOL ) {
1268 retval = d->where[1];
1270 else if ( d->type == DOLSUBTERM && d->where[0] == SYMBOL
1271 && d->where[1] == 4 && d->where[3] == 1 ) {
1272 retval = d->where[2];
1274 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1275 && d->where[1] == -SYMBOL && d->where[3] == 0 ) {
1276 retval = d->where[2];
1279 AN.ErrorInDollar = 1;
1283 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1293 WORD DolToIndex(
PHEAD WORD numdollar)
1296 DOLLARS d = Dollars + numdollar;
1299 int nummodopt, dtype = -1;
1300 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1301 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1302 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1304 if ( nummodopt < NumModOptdollars ) {
1305 dtype = ModOptdollars[nummodopt].type;
1306 if ( dtype == MODLOCAL ) {
1307 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1310 LOCK(d->pthreadslockread);
1315 AN.ErrorInDollar = 0;
1316 if ( d->type == DOLTERMS && d->where[0] == 7 &&
1317 d->where[7] == 0 && d->where[6] == 3 && d->where[5] == 1
1318 && d->where[4] == 1 && d->where[1] == INDEX && d->where[3] >= 0 ) {
1319 retval = d->where[3];
1321 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER
1322 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1323 retval = d->where[1];
1325 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1326 && d->where[1] >= 0 ) {
1327 retval = d->where[1];
1329 else if ( d->type == DOLZERO )
return(0);
1330 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1331 && d->where[1] == -SNUMBER && d->where[3] == 0 && d->where[2] >= 0
1332 && d->where[2] < AM.OffsetIndex ) {
1333 retval = d->where[2];
1335 else if ( d->type == DOLINDEX && d->index >= 0 ) {
1338 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1339 && d->where[1] >= 0 ) {
1340 retval = d->where[1];
1342 else if ( d->type == DOLSUBTERM && d->where[0] == INDEX
1343 && d->where[1] == 3 && d->where[2] >= 0 ) {
1344 retval = d->where[2];
1346 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1347 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0 ) {
1348 retval = d->where[2];
1351 AN.ErrorInDollar = 1;
1355 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1374 DOLLARS d = Dollars + numdollar, newd;
1377 int nummodopt, dtype = -1;
1378 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1379 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1380 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1382 if ( nummodopt < NumModOptdollars ) {
1383 dtype = ModOptdollars[nummodopt].type;
1384 if ( dtype == MODLOCAL ) {
1385 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1390 AN.ErrorInDollar = 0;
1391 switch ( d->type ) {
1397 if ( t[0] <= -FUNCTION ) {
1398 *w++ = FUNHEAD+4; *w++ = -t[0];
1399 *w++ = FUNHEAD; FILLFUN(w)
1400 *w++ = 1; *w++ = 1; *w++ = 3;
1402 else if ( t[0] == -SYMBOL ) {
1403 *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = t[1];
1404 *w++ = 1; *w++ = 1; *w++ = 1; *w++ = 3;
1406 else if ( t[0] == -VECTOR || t[0] == -INDEX ) {
1407 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[1];
1408 *w++ = 1; *w++ = 1; *w++ = 3;
1410 else if ( t[0] == -MINVECTOR ) {
1411 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = t[1];
1412 *w++ = 1; *w++ = 1; *w++ = -3;
1414 else if ( t[0] == -SNUMBER ) {
1417 *w++ = -t[1]; *w++ = 1; *w++ = -3;
1420 *w++ = t[1]; *w++ = 1; *w++ = 3;
1423 *w = 0; size = w - AT.WorkPointer;
1430 while ( *t ) t += *t;
1431 size = t - d->where;
1437 *w++ = size+4; t = d->where; NCOPY(w,t,size)
1438 *w++ = 1; *w++ = 1; *w++ = 3;
1439 w = AT.WorkPointer; size = d->where[1]+4;
1443 *w++ = 7; *w++ = INDEX; *w++ = 3; *w++ = d->index;
1444 *w++ = 1; *w++ = 1; *w++ = 3; *w = 0;
1445 w = AT.WorkPointer; size = 7;
1452 if ( *t == 0 )
return(0);
1455 MLOCK(ErrorMessageLock);
1456 MesPrint(
"Trying to convert a $ with an argument field into an expression");
1457 MUNLOCK(ErrorMessageLock);
1464 if ( *t < 0 )
goto ShortArgument;
1465 size = *t - ARGHEAD;
1469 MLOCK(ErrorMessageLock);
1470 MesPrint(
"Trying to use an undefined $ in an expression");
1471 MUNLOCK(ErrorMessageLock);
1474 if ( d->where ) { d->where[0] = 0; }
1475 else d->where = &(AM.dollarzero);
1482 newd = (
DOLLARS)Malloc1(
sizeof(
struct DoLlArS)+(size+1)*
sizeof(WORD),
1483 "Copy of dollar variable");
1484 t = (WORD *)(newd+1);
1486 newd->name = d->name;
1487 newd->node = d->node;
1488 newd->type = DOLTERMS;
1490 newd->numdummies = d->numdummies;
1492 newd->pthreadslockread = dummylock;
1493 newd->pthreadslockwrite = dummylock;
1497 newd->nfactors = d->nfactors;
1498 if ( d->nfactors > 1 ) {
1499 newd->factors = (
FACDOLLAR *)Malloc1(d->nfactors*
sizeof(
FACDOLLAR),
"Dollar factors");
1500 for ( i = 0; i < d->nfactors; i++ ) {
1501 newd->factors[i].where = 0;
1502 newd->factors[i].size = 0;
1503 newd->factors[i].type = DOLUNDEFINED;
1504 newd->factors[i].value = d->factors[i].value;
1507 else { newd->factors = 0; }
1516 LONG DolToLong(
PHEAD WORD numdollar)
1519 DOLLARS d = Dollars + numdollar;
1522 int nummodopt, dtype = -1;
1523 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1524 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1525 if ( numdollar == ModOptdollars[nummodopt].number )
break;
1527 if ( nummodopt < NumModOptdollars ) {
1528 dtype = ModOptdollars[nummodopt].type;
1529 if ( dtype == MODLOCAL ) {
1530 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1535 AN.ErrorInDollar = 0;
1536 if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1537 && d->where[0] == 4 &&
1538 d->where[4] == 0 && ( d->where[3] == 3 || d->where[3] == -3 )
1539 && d->where[2] == 1 && ( d->where[1] & TOPBITONLY ) == 0 ) {
1541 if ( d->where[3] > 0 )
return(x);
1544 else if ( ( d->type == DOLTERMS || d->type == DOLNUMBER )
1545 && d->where[0] == 6 &&
1546 d->where[6] == 0 && ( d->where[5] == 5 || d->where[5] == -5 )
1547 && d->where[3] == 1 && d->where[4] == 1 && ( d->where[2] & TOPBITONLY ) == 0 ) {
1548 x = d->where[1] + ( (LONG)(d->where[2]) << BITSINWORD );
1549 if ( d->where[5] > 0 )
return(x);
1552 else if ( d->type == DOLARGUMENT && d->where[0] == -SNUMBER ) {
1556 else if ( d->type == DOLARGUMENT && d->where[0] == -INDEX
1557 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1561 else if ( d->type == DOLZERO )
return(0);
1562 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1563 && d->where[1] == -SNUMBER && d->where[3] == 0 ) {
1567 else if ( d->type == DOLINDEX && d->index >= 0 && d->index < AM.OffsetIndex ) {
1571 else if ( d->type == DOLWILDARGS && d->where[0] == 1
1572 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
1576 else if ( d->type == DOLWILDARGS && d->where[0] == 0
1577 && d->where[1] == -INDEX && d->where[3] == 0 && d->where[2] >= 0
1578 && d->where[2] < AM.OffsetIndex ) {
1582 AN.ErrorInDollar = 1;
1591 int ExecInside(UBYTE *s)
1598 if ( AC.insidelevel >= MAXNEST ) {
1599 MLOCK(ErrorMessageLock);
1600 MesPrint(
"@Nesting of inside statements more than %d levels",(WORD)MAXNEST);
1601 MUNLOCK(ErrorMessageLock);
1604 AC.insidesumcheck[AC.insidelevel] = NestingChecksum();
1605 AC.insidestack[AC.insidelevel] = cbuf[AC.cbufnum].Pointer
1606 - cbuf[AC.cbufnum].Buffer + 2;
1611 while ( *s ==
',' ) s++;
1612 if ( *s == 0 )
break;
1615 if ( FG.cTable[*s] != 0 ) {
1616 MLOCK(ErrorMessageLock);
1617 MesPrint(
"Illegal name for $ variable: %s",s-1);
1618 MUNLOCK(ErrorMessageLock);
1621 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
1623 if ( ( number = GetDollar(t) ) < 0 ) {
1624 number = AddDollar(t,0,0,0);
1631 MLOCK(ErrorMessageLock);
1632 MesPrint(
"&Illegal object in Inside statement");
1633 MUNLOCK(ErrorMessageLock);
1635 while ( *s && *s !=
',' && s[1] !=
'$' ) s++;
1636 if ( *s == 0 )
break;
1639 AT.WorkPointer[1] = w - AT.WorkPointer;
1640 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
1656 int InsideDollar(
PHEAD WORD *ll, WORD level)
1659 int numvar = (int)(ll[1]-3), j, error = 0;
1660 WORD numdol, *oldcterm, *oldwork = AT.WorkPointer, olddefer, *r, *m;
1661 WORD oldnumlhs, *dbuffer;
1663 oldcterm = AN.cTerm; AN.cTerm = 0;
1664 oldnumlhs = AR.Cnumlhs; AR.Cnumlhs = ll[2];
1666 olddefer = AR.DeferFlag;
1668 while ( --numvar >= 0 ) {
1670 d = Dollars + numdol;
1673 int nummodopt, dtype = -1;
1674 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1675 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1676 if ( numdol == ModOptdollars[nummodopt].number )
break;
1678 if ( nummodopt < NumModOptdollars ) {
1679 dtype = ModOptdollars[nummodopt].type;
1680 if ( dtype == MODLOCAL ) {
1681 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1685 LOCK(d->pthreadslockread);
1690 newd = DolToTerms(BHEAD numdol);
1691 if ( newd == 0 || newd->where[0] == 0 )
continue;
1697 while ( --j >= 0 ) *m++ = *r++;
1704 error = -1;
goto idcall;
1706 AT.WorkPointer = oldwork;
1708 if (
EndSort(BHEAD (WORD *)((VOID *)(&dbuffer)),2) < 0 ) { error = 1;
break; }
1709 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"old buffer of dollar");
1711 if ( dbuffer == 0 || *dbuffer == 0 ) {
1713 if ( dbuffer ) M_free(dbuffer,
"buffer of dollar");
1714 d->where = &(AM.dollarzero); d->size = 0;
1718 r = d->where;
while ( *r ) r += *r;
1719 d->size = r-d->where;
1722 cbuf[AM.dbufnum].rhs[numdol] = (WORD *)(1);
1727 if ( dtype > 0 && dtype != MODLOCAL ) {
1729 UNLOCK(d->pthreadslockread);
1732 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1733 M_free(newd,
"Copy of dollar variable");
1737 AR.Cnumlhs = oldnumlhs;
1738 AR.DeferFlag = olddefer;
1739 AN.cTerm = oldcterm;
1740 AT.WorkPointer = oldwork;
1749 void ExchangeDollars(
int num1,
int num2)
1754 d1 = Dollars + num1; node1 = d1->node;
1755 d2 = Dollars + num2; node2 = d2->node;
1756 nam = d1->name; d1->name = d2->name; d2->name = nam;
1757 d1->node = node2; d2->node = node1;
1758 AC.dollarnames->namenode[node1].number = num2;
1759 AC.dollarnames->namenode[node2].number = num1;
1767 LONG TermsInDollar(WORD num)
1774 int nummodopt, dtype = -1;
1775 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1776 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1777 if ( num == ModOptdollars[nummodopt].number )
break;
1779 if ( nummodopt < NumModOptdollars ) {
1780 dtype = ModOptdollars[nummodopt].type;
1781 if ( dtype == MODLOCAL ) {
1782 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1785 LOCK(d->pthreadslockread);
1790 if ( d->type == DOLTERMS ) {
1793 while ( *t ) { t += *t; n++; }
1795 else if ( d->type == DOLWILDARGS ) {
1797 if ( d->where[0] == 0 ) {
1799 while ( *t != 0 ) { NEXTARG(t); n++; }
1801 else if ( d->where[0] == 1 ) n = 1;
1803 else if ( d->type == DOLZERO ) n = 0;
1806 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1826 UBYTE *PreIfDollarEval(UBYTE *s,
int *value)
1829 UBYTE *s1,*s2,*s3,*s4,*s5,*t,c,c1,c2,c3;
1831 WORD *buf1 = 0, *buf2 = 0, numset, *oldwork = AT.WorkPointer;
1836 while ( *s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r' ) s++;
1838 while ( *t !=
'=' && *t !=
'!' && *t !=
'>' && *t !=
'<' ) {
1839 if ( *t ==
'[' ) { SKIPBRA1(t) }
1840 else if ( *t ==
'{' ) { SKIPBRA2(t) }
1841 else if ( *t ==
'(' ) { SKIPBRA3(t) }
1842 else if ( *t ==
']' || *t ==
'}' || *t ==
')' ) {
1843 MLOCK(ErrorMessageLock);
1844 MesPrint(
"@Improper bracketting in #if");
1845 MUNLOCK(ErrorMessageLock);
1851 while ( *t ==
'=' || *t ==
'!' || *t ==
'>' || *t ==
'<' ) t++;
1853 while ( *t && *t !=
')' ) {
1854 if ( *t ==
'[' ) { SKIPBRA1(t) }
1855 else if ( *t ==
'{' ) { SKIPBRA2(t) }
1856 else if ( *t ==
'(' ) { SKIPBRA3(t) }
1857 else if ( *t ==
']' || *t ==
'}' ) {
1858 MLOCK(ErrorMessageLock);
1859 MesPrint(
"@Improper brackets in #if");
1860 MUNLOCK(ErrorMessageLock);
1866 MLOCK(ErrorMessageLock);
1867 MesPrint(
"@Missing ) to match $( in #if");
1868 MUNLOCK(ErrorMessageLock);
1871 s4 = t; c2 = *s4; *s4 = 0;
1872 if ( s2+2 < s3 || s2 == s3 ) {
1874 MLOCK(ErrorMessageLock);
1875 MesPrint(
"@Illegal operator in $( option of #if");
1876 MUNLOCK(ErrorMessageLock);
1880 if ( *s2 ==
'=' ) oprtr = EQUAL;
1881 else if ( *s2 ==
'>' ) oprtr = GREATER;
1882 else if ( *s2 ==
'<' ) oprtr = LESS;
1885 else if ( *s2 ==
'!' && s2[1] ==
'=' ) oprtr = NOTEQUAL;
1886 else if ( *s2 ==
'=' && s2[1] ==
'=' ) oprtr = EQUAL;
1887 else if ( *s2 ==
'<' && s2[1] ==
'=' ) oprtr = LESSEQUAL;
1888 else if ( *s2 ==
'>' && s2[1] ==
'=' ) oprtr = GREATEREQUAL;
1895 while ( *s3 ==
' ' || *s3 ==
'\t' || *s3 ==
'\n' || *s3 ==
'\r' ) s3++;
1897 while ( chartype[*t] == 0 ) t++;
1899 t++; c = *t; *t = 0;
1900 if ( StrICmp(s3,(UBYTE *)
"set_") == 0 ) {
1901 if ( oprtr != EQUAL && oprtr != NOTEQUAL ) {
1903 MLOCK(ErrorMessageLock);
1904 MesPrint(
"@Improper operator for special keyword in $( ) option");
1905 MUNLOCK(ErrorMessageLock);
1910 else if ( StrICmp(s3,(UBYTE *)
"multipleof_") == 0 ) {
1911 if ( oprtr != EQUAL && oprtr != NOTEQUAL )
goto ImpOp;
1922 else { type = 0; c = *t; }
1924 *t++ = c; s3 = t; s5 = s4-1;
1925 while ( *s5 !=
')' ) {
1926 if ( *s5 ==
' ' || *s5 ==
'\t' || *s5 ==
'\n' || *s5 ==
'\r' ) s5--;
1928 MLOCK(ErrorMessageLock);
1929 MesPrint(
"@Improper use of special keyword in $( ) option");
1930 MUNLOCK(ErrorMessageLock);
1936 else { c3 = c2; s5 = s4; }
1940 if ( ( buf1 = TranslateExpression(s1) ) == 0 ) {
1941 AT.WorkPointer = oldwork;
1948 numset = DoTempSet(t,s3);
1952 MLOCK(ErrorMessageLock);
1953 MesPrint(
"@Argument of set_ is not a valid set");
1954 MUNLOCK(ErrorMessageLock);
1960 while ( FG.cTable[*s3] == 0 || FG.cTable[*s3] == 1
1961 || *s3 ==
'_' ) s3++;
1963 if ( GetName(AC.varnames,t,&numset,NOAUTO) != CSET ) {
1964 *s3 = c;
goto noset;
1968 while ( *s3 ==
' ' || *s3 ==
'\t' || *s3 ==
'\n' || *s3 ==
'\r' ) s3++;
1969 if ( s3 != s5 )
goto noset;
1970 *value = IsSetMember(buf1,numset);
1971 if ( oprtr == NOTEQUAL ) *value ^= 1;
1974 if ( ( buf2 = TranslateExpression(s3) ) == 0 )
goto onerror;
1977 *value = TwoExprCompare(buf1,buf2,oprtr);
1979 else if ( type == 2 ) {
1980 *value = IsMultipleOf(buf1,buf2);
1981 if ( oprtr == NOTEQUAL ) *value ^= 1;
1989 if ( buf1 ) M_free(buf1,
"Buffer in $()");
1990 if ( buf2 ) M_free(buf2,
"Buffer in $()");
1991 *s5 = c3; *s4++ = c2; *s2 = c1;
1992 AT.WorkPointer = oldwork;
1996 if ( buf1 ) M_free(buf1,
"Buffer in $()");
1997 if ( buf2 ) M_free(buf2,
"Buffer in $()");
1998 AT.WorkPointer = oldwork;
2008 WORD *TranslateExpression(UBYTE *s)
2011 CBUF *C = cbuf+AC.cbufnum;
2012 WORD oldnumrhs = C->numrhs;
2013 LONG oldcpointer = C->Pointer - C->Buffer;
2014 WORD *w = AT.WorkPointer;
2015 WORD retcode, oldEside;
2017 *w++ = SUBEXPSIZE + 4;
2019 *w++ = SUBEXPRESSION;
2025 *w++ = 1; *w++ = 1; *w++ = 3; *w++ = 0;
2027 if ( ( retcode = CompileAlgebra(s,RHSIDE,AC.ProtoType) ) < 0 ) {
2028 MLOCK(ErrorMessageLock);
2029 MesPrint(
"@Error translating first expression in $( ) option");
2030 MUNLOCK(ErrorMessageLock);
2033 else { AC.ProtoType[2] = retcode; }
2038 AN.RepPoint = AT.RepCount + 1;
2039 oldEside = AR.Eside; AR.Eside = RHSIDE;
2040 AR.Cnumlhs = C->numlhs;
2041 if (
Generator(BHEAD AC.ProtoType-1,C->numlhs) ) {
2042 AR.Eside = oldEside;
2045 AR.Eside = oldEside;
2049 C->Pointer = C->Buffer + oldcpointer;
2050 C->numrhs = oldnumrhs;
2051 AT.WorkPointer = AC.ProtoType - 1;
2064 int IsSetMember(WORD *buffer, WORD numset)
2066 WORD *t = buffer, *tt, num, csize, num1;
2069 if ( numset < AM.NumFixedSets ) {
2070 if ( t[*t] != 0 )
return(0);
2072 if ( numset == POS0_ || numset == NEG0_ || numset == EVEN_
2073 || numset == Z_ || numset == Q_ )
return(1);
2076 if ( numset == SYMBOL_ ) {
2077 if ( *t == 8 && t[1] == SYMBOL && t[7] == 3 && t[6] == 1
2078 && t[5] == 1 && t[4] == 1 )
return(1);
2081 if ( numset == INDEX_ ) {
2082 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2083 && t[4] == 1 && t[3] > 0 )
return(1);
2084 if ( *t == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex)
2088 if ( numset == FIXED_ ) {
2089 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2090 && t[4] == 1 && t[3] > 0 && t[3] < AM.OffsetIndex )
return(1);
2091 if ( *t == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex)
2095 if ( numset == DUMMYINDEX_ ) {
2096 if ( *t == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2097 && t[4] == 1 && t[3] >= AM.IndDum && t[3] < AM.IndDum+MAXDUMMIES )
return(1);
2098 if ( *t == 4 && t[3] == 3 && t[2] == 1
2099 && t[1] >= AM.IndDum && t[1] < AM.IndDum+MAXDUMMIES )
return(1);
2103 if ( ABS(tt[0]) != *t-1 )
return(0);
2104 if ( numset == Q_ )
return(1);
2105 if ( numset == POS_ || numset == POS0_ )
return(tt[0]>0);
2106 else if ( numset == NEG_ || numset == NEG0_ )
return(tt[0]<0);
2107 i = (ABS(tt[0])-1)/2;
2109 if ( tt[0] != 1 )
return(0);
2110 for ( j = 1; j < i; j++ ) {
if ( tt[j] != 0 )
return(0); }
2111 if ( numset == Z_ )
return(1);
2112 if ( numset == ODD_ )
return(t[1]&1);
2113 if ( numset == EVEN_ )
return(1-(t[1]&1));
2116 if ( t[*t] != 0 )
return(0);
2117 type = Sets[numset].type;
2120 if ( t[0] == 8 && t[1] == SYMBOL && t[7] == 3 && t[6] == 1
2121 && t[5] == 1 && t[4] == 1 ) {
2124 else if ( t[0] == 4 && t[2] == 1 && t[1] <= MAXPOWER ) {
2126 if ( t[3] < 0 ) num = -num;
2132 if ( t[0] == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2133 && t[4] == 1 && t[3] < 0 ) {
2139 if ( t[0] == 7 && t[1] == INDEX && t[6] == 3 && t[5] == 1
2140 && t[4] == 1 && t[3] > 0 ) {
2143 else if ( t[0] == 4 && t[3] == 3 && t[2] == 1 && t[1] < AM.OffsetIndex ) {
2149 if ( t[0] == 4+FUNHEAD && t[3+FUNHEAD] == 3 && t[2+FUNHEAD] == 1
2150 && t[1+FUNHEAD] == 1 && t[1] >= FUNCTION ) {
2156 if ( t[0] == 4 && t[2] == 1 && t[1] <= AM.OffsetIndex && t[3] == 3 ) {
2164 if ( csize != t[0]-1 )
return(0);
2165 if ( Sets[numset].first < 3*MAXPOWER ) {
2166 num1 = num = Sets[numset].first;
2167 if ( num >= MAXPOWER ) num -= 2*MAXPOWER;
2169 if ( num1 < MAXPOWER ) {
2170 if ( t[t[0]-1] >= 0 )
return(0);
2172 else if ( t[t[0]-1] > 0 )
return(0);
2175 bufterm[0] = 4; bufterm[1] = ABS(num);
2177 if ( num < 0 ) bufterm[3] = -3;
2178 else bufterm[3] = 3;
2180 if ( num1 < MAXPOWER ) {
2181 if ( num >= 0 )
return(0);
2183 else if ( num > 0 )
return(0);
2186 if ( Sets[numset].last > -3*MAXPOWER ) {
2187 num1 = num = Sets[numset].last;
2188 if ( num <= -MAXPOWER ) num += 2*MAXPOWER;
2190 if ( num1 > -MAXPOWER ) {
2191 if ( t[t[0]-1] <= 0 )
return(0);
2193 else if ( t[t[0]-1] < 0 )
return(0);
2196 bufterm[0] = 4; bufterm[1] = ABS(num);
2198 if ( num < 0 ) bufterm[3] = -3;
2199 else bufterm[3] = 3;
2201 if ( num1 > -MAXPOWER ) {
2202 if ( num <= 0 )
return(0);
2204 else if ( num < 0 )
return(0);
2211 t = SetElements + Sets[numset].first;
2212 tt = SetElements + Sets[numset].last;
2214 if ( num == *t )
return(1);
2240 int IsMultipleOf(WORD *buf1, WORD *buf2)
2244 WORD *t1, *t2, *m1, *m2, *r1, *r2, nc1, nc2, ni1, ni2;
2245 UWORD *IfScrat1, *IfScrat2;
2247 if ( *buf1 == 0 && *buf2 == 0 )
return(1);
2251 t1 = buf1; t2 = buf2; num1 = 0; num2 = 0;
2252 while ( *t1 ) { t1 += *t1; num1++; }
2253 while ( *t2 ) { t2 += *t2; num2++; }
2254 if ( num1 != num2 )
return(0);
2258 t1 = buf1; t2 = buf2;
2260 m1 = t1+1; m2 = t2+1; t1 += *t1; t2 += *t2;
2261 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2262 if ( r1-m1 != r2-m2 )
return(0);
2264 if ( *m1 != *m2 )
return(0);
2271 IfScrat1 = (UWORD *)(TermMalloc(
"IsMultipleOf")); IfScrat2 = (UWORD *)(TermMalloc(
"IsMultipleOf"));
2272 t1 = buf1; t2 = buf2;
2273 t1 += *t1; t2 += *t2;
2274 if ( *t1 == 0 && *t2 == 0 )
return(1);
2275 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2276 nc1 = REDLENG(t1[-1]); nc2 = REDLENG(t2[-1]);
2277 if ( DivRat(BHEAD (UWORD *)r1,nc1,(UWORD *)r2,nc2,IfScrat1,&ni1) ) {
2278 MLOCK(ErrorMessageLock);
2279 MesPrint(
"@Called from MultipleOf in $( )");
2280 MUNLOCK(ErrorMessageLock);
2281 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2285 t1 += *t1; t2 += *t2;
2286 r1 = t1 - ABS(t1[-1]); r2 = t2 - ABS(t2[-1]);
2287 nc1 = REDLENG(t1[-1]); nc2 = REDLENG(t2[-1]);
2288 if ( DivRat(BHEAD (UWORD *)r1,nc1,(UWORD *)r2,nc2,IfScrat2,&ni2) ) {
2289 MLOCK(ErrorMessageLock);
2290 MesPrint(
"@Called from MultipleOf in $( )");
2291 MUNLOCK(ErrorMessageLock);
2292 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2295 if ( ni1 != ni2 )
return(0);
2297 for ( j = 0; j < i; j++ ) {
2298 if ( IfScrat1[j] != IfScrat2[j] ) {
2299 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2304 TermFree(IfScrat1,
"IsMultipleOf"); TermFree(IfScrat2,
"IsMultipleOf");
2315 int TwoExprCompare(WORD *buf1, WORD *buf2,
int oprtr)
2318 WORD *t1, *t2, cond;
2319 t1 = buf1; t2 = buf2;
2320 while ( *t1 && *t2 ) {
2321 cond = CompareTerms(BHEAD t1,t2,1);
2325 case EQUAL:
return(0);
2326 case NOTEQUAL:
return(1);
2327 case GREATEREQUAL:
return(0);
2328 case GREATER:
return(0);
2329 case LESS:
return(1);
2330 case LESSEQUAL:
return(1);
2335 case EQUAL:
return(0);
2336 case NOTEQUAL:
return(1);
2337 case GREATEREQUAL:
return(1);
2338 case GREATER:
return(1);
2339 case LESS:
return(0);
2340 case LESSEQUAL:
return(0);
2344 t1 += *t1; t2 += *t2;
2348 case EQUAL:
return(1);
2349 case NOTEQUAL:
return(0);
2350 case GREATEREQUAL:
return(1);
2351 case GREATER:
return(0);
2352 case LESS:
return(0);
2353 case LESSEQUAL:
return(1);
2358 case EQUAL:
return(0);
2359 case NOTEQUAL:
return(1);
2360 case GREATEREQUAL:
return(1);
2361 case GREATER:
return(1);
2362 case LESS:
return(0);
2363 case LESSEQUAL:
return(0);
2368 case EQUAL:
return(0);
2369 case NOTEQUAL:
return(1);
2370 case GREATEREQUAL:
return(0);
2371 case GREATER:
return(0);
2372 case LESS:
return(1);
2373 case LESSEQUAL:
return(1);
2376 MLOCK(ErrorMessageLock);
2377 MesPrint(
"@Internal problems with operator in $( )");
2378 MUNLOCK(ErrorMessageLock);
2391 static UWORD *dscrat = 0;
2392 static WORD ndscrat;
2394 int DollarRaiseLow(UBYTE *name, LONG value)
2400 WORD lnum[4], nnum, *t1, *t2, i;
2402 s = name;
while ( *s ) s++;
2403 if ( s[-1] ==
'-' && s[-2] ==
'-' && s > name+2 ) s -= 2;
2404 else if ( s[-1] ==
'+' && s[-2] ==
'+' && s > name+2 ) s -= 2;
2406 num = GetDollar(name);
2409 if ( value < 0 ) { value = -value; sgn = -1; }
2410 if ( d->type == DOLZERO ) {
2411 if ( d->where ) M_free(d->where,
"DollarRaiseLow");
2413 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2414 if ( ( value & AWORDMASK ) != 0 ) {
2415 d->where[0] = 6; d->where[1] = value >> BITSINWORD;
2416 d->where[2] = (WORD)value; d->where[3] = 1; d->where[4] = 0;
2417 d->where[5] = 5*sgn; d->where[6] = 0;
2421 d->where[0] = 4; d->where[1] = (WORD)value; d->where[2] = 1;
2422 d->where[3] = 3*sgn; d->where[4] = 0;
2423 d->type = DOLNUMBER;
2426 else if ( d->type == DOLNUMBER || ( d->type == DOLTERMS
2427 && d->where[d->where[0]] == 0
2428 && d->where[0] == ABS(d->where[d->where[0]-1])+1 ) ) {
2429 if ( ( value & AWORDMASK ) != 0 ) {
2430 lnum[0] = value >> BITSINWORD;
2431 lnum[1] = (WORD)value; lnum[2] = 1; lnum[3] = 0;
2435 lnum[0] = (WORD)value; lnum[1] = 1; nnum = sgn;
2437 i = d->where[d->where[0]-1];
2439 if ( dscrat == 0 ) {
2440 dscrat = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"DollarRaiseLow");
2442 if ( AddRat(BHEAD (UWORD *)(d->where+1),i,
2443 (UWORD *)lnum,nnum,dscrat,&ndscrat) ) {
2444 MLOCK(ErrorMessageLock);
2445 MesCall(
"DollarRaiseLow");
2446 MUNLOCK(ErrorMessageLock);
2449 ndscrat = INCLENG(ndscrat);
2452 M_free(d->where,
"DollarRaiseLow");
2458 if ( i+2 > d->size ) {
2459 M_free(d->where,
"DollarRaiseLow");
2461 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"DollarRaiseLow");
2463 t1 = d->where; *t1++ = i+1; t2 = (WORD *)dscrat;
2464 while ( --i > 0 ) *t1++ = *t2++;
2465 *t1++ = ndscrat; *t1 = 0;
2493 WORD num, type, *td;
2495 if ( *arg == SNUMBER )
return(arg[1]);
2496 if ( *arg == DOLLAREXPR2 && arg[1] < 0 )
return(-arg[1]-1);
2497 d = Dollars + arg[1];
2500 int nummodopt, dtype = -1;
2501 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2502 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2503 if ( arg[1] == ModOptdollars[nummodopt].number )
break;
2505 if ( nummodopt < NumModOptdollars ) {
2506 dtype = ModOptdollars[nummodopt].type;
2507 if ( dtype == MODLOCAL ) {
2508 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2514 if ( *arg == DOLLAREXPRESSION ) {
2515 if ( arg[2] != DOLLAREXPR2 ) {
2518 if ( type == DOLZERO ) {}
2519 else if ( type == DOLNUMBER ) {
2521 if ( ( td[0] != 4 ) || ( (td[1]&SPECMASK) != 0 ) || ( td[2] != 1 ) ) {
2522 MLOCK(ErrorMessageLock);
2524 MesPrint(
"$-variable is not a short number in print statement");
2527 MesPrint(
"$-variable is not a short number in do loop");
2529 MUNLOCK(ErrorMessageLock);
2532 return( td[3] > 0 ? td[1]: -td[1] );
2535 MLOCK(ErrorMessageLock);
2537 MesPrint(
"$-variable is not a number in print statement");
2540 MesPrint(
"$-variable is not a number in do loop");
2542 MUNLOCK(ErrorMessageLock);
2549 else if ( *arg == DOLLAREXPR2 ) {
2550 if ( arg[1] < 0 ) { num = -arg[1]-1; }
2551 else if ( arg[2] != DOLLAREXPR2 && par == -1 ) {
2557 MLOCK(ErrorMessageLock);
2559 MesPrint(
"Invalid $-variable in print statement");
2562 MesPrint(
"Invalid $-variable in do loop");
2564 MUNLOCK(ErrorMessageLock);
2568 if ( num == 0 )
return(d->nfactors);
2569 if ( num > d->nfactors || num < 1 ) {
2570 MLOCK(ErrorMessageLock);
2572 MesPrint(
"Not a valid factor number for $-variable in print statement");
2575 MesPrint(
"Not a valid factor number for $-variable in do loop");
2577 MUNLOCK(ErrorMessageLock);
2581 if ( d->factors[num].type == DOLNUMBER )
2582 return(d->factors[num].value);
2584 MLOCK(ErrorMessageLock);
2586 MesPrint(
"$-variable in print statement is not a number");
2589 MesPrint(
"$-variable in do loop is not a number");
2591 MUNLOCK(ErrorMessageLock);
2602 WORD TestDoLoop(
PHEAD WORD *lhsbuf, WORD level)
2605 WORD start,finish,incr;
2610 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2611 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2614 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2615 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2619 if ( ( finish == start ) || ( finish > start && incr > 0 )
2620 || ( finish < start && incr < 0 ) ) {}
2621 else { level = lhsbuf[3]; }
2625 d = Dollars + lhsbuf[2];
2628 int nummodopt, dtype = -1;
2629 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2630 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2631 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2633 if ( nummodopt < NumModOptdollars ) {
2634 dtype = ModOptdollars[nummodopt].type;
2635 if ( dtype == MODLOCAL ) {
2636 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2643 if ( d->size < 5 ) {
2644 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2646 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2650 d->where[1] = start;
2654 d->type = DOLNUMBER;
2656 else if ( start < 0 ) {
2658 d->where[1] = -start;
2662 d->type = DOLNUMBER;
2667 if ( d == Dollars + lhsbuf[2] ) {
2668 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2669 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2670 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2680 WORD TestEndDoLoop(
PHEAD WORD *lhsbuf, WORD level)
2683 WORD start,finish,incr,value;
2688 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2689 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2692 while ( ( *h == DOLLAREXPRESSION || *h == DOLLAREXPR2 )
2693 && ( h[2] == DOLLAREXPR2 ) ) h += 2;
2697 if ( ( finish == start ) || ( finish > start && incr > 0 )
2698 || ( finish < start && incr < 0 ) ) {}
2699 else { level = lhsbuf[3]; }
2703 d = Dollars + lhsbuf[2];
2706 int nummodopt, dtype = -1;
2707 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2708 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2709 if ( lhsbuf[2] == ModOptdollars[nummodopt].number )
break;
2711 if ( nummodopt < NumModOptdollars ) {
2712 dtype = ModOptdollars[nummodopt].type;
2713 if ( dtype == MODLOCAL ) {
2714 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2723 if ( d->type == DOLZERO ) {
2726 else if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2727 && ( d->where[4] == 0 ) && ( d->where[0] == 4 )
2728 && ( d->where[1] > 0 ) && ( d->where[2] == 1 ) ) {
2729 value = ( d->where[3] < 0 ) ? -d->where[1]: d->where[1];
2732 MLOCK(ErrorMessageLock);
2733 MesPrint(
"Wrong type of object in do loop parameter");
2734 MUNLOCK(ErrorMessageLock);
2739 if ( ( finish > start && value <= finish ) ||
2740 ( finish < start && value >= finish ) ||
2741 ( finish == start && value == finish ) ) {}
2742 else level = lhsbuf[3];
2744 if ( d->size < 5 ) {
2745 if ( d->where && d->where != &(AM.dollarzero) ) M_free(d->where,
"dollar contents");
2747 d->where = (WORD *)Malloc1(d->size*
sizeof(WORD),
"dollar contents");
2751 d->where[1] = value;
2755 d->type = DOLNUMBER;
2757 else if ( start < 0 ) {
2759 d->where[1] = -value;
2763 d->type = DOLNUMBER;
2768 if ( d == Dollars + lhsbuf[2] ) {
2769 cbuf[AM.dbufnum].CanCommu[lhsbuf[2]] = 0;
2770 cbuf[AM.dbufnum].NumTerms[lhsbuf[2]] = 1;
2771 cbuf[AM.dbufnum].rhs[lhsbuf[2]] = d->where;
2797 DOLLARS d = Dollars + numdollar;
2799 WORD *oldworkpointer;
2800 WORD *buf1, *t, *term, *buf1content, *buf2, *termextra;
2801 WORD *buf3, *argextra;
2803 WORD *tstop, pow, *r;
2805 int i, j, jj, action = 0, sign = 1;
2807 WORD startebuf = cbuf[AT.ebufnum].numrhs;
2808 WORD nfactors, factorsincontent;
2809 WORD oldsorttype = AR.SortType;
2812 int nummodopt, dtype;
2814 if ( AS.MultiThreaded ) {
2815 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2816 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2818 if ( nummodopt < NumModOptdollars ) {
2819 dtype = ModOptdollars[nummodopt].type;
2820 if ( dtype == MODLOCAL ) {
2821 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2824 LOCK(d->pthreadslockread);
2829 CleanDollarFactors(d);
2831 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2833 if ( d->type != DOLTERMS ) {
2834 if ( d->type != DOLZERO ) d->nfactors = 1;
2837 if ( d->where[d->where[0]] == 0 ) {
2850 AR.SortType = SORTHIGHFIRST;
2851 if ( oldsorttype != AR.SortType ) {
2855 if ( AN.ncmod != 0 ) {
2856 if ( AN.ncmod != 1 || ( (WORD)AN.cmod[0] < 0 ) ) {
2857 AR.SortType = oldsorttype;
2858 MLOCK(ErrorMessageLock);
2859 MesPrint(
"Factorization modulus a number, greater than a WORD not implemented.");
2860 MUNLOCK(ErrorMessageLock);
2863 if ( Modulus(term) ) {
2864 AR.SortType = oldsorttype;
2865 MLOCK(ErrorMessageLock);
2866 MesCall(
"DollarFactorize");
2867 MUNLOCK(ErrorMessageLock);
2870 if ( !*term) { term = t;
continue; }
2875 EndSort(BHEAD (WORD *)((
void *)(&buf1)),2);
2876 t = buf1;
while ( *t ) t += *t;
2880 t = term;
while ( *t ) t += *t;
2881 ii = insize = t - term;
2882 buf1 = (WORD *)Malloc1((insize+1)*
sizeof(WORD),
"DollarFactorize-1");
2892 if ( ( buf2 = TakeDollarContent(BHEAD buf1,&buf1content) ) == 0 ) {
2893 M_free(buf1,
"DollarFactorize-1");
2894 AR.SortType = oldsorttype;
2895 MLOCK(ErrorMessageLock);
2896 MesCall(
"DollarFactorize");
2897 MUNLOCK(ErrorMessageLock);
2901 else if ( ( buf1content[0] == 4 ) && ( buf1content[1] == 1 ) &&
2902 ( buf1content[2] == 1 ) && ( buf1content[3] == 3 ) &&
2903 ( buf1content[4] == 0 ) ) {
2904 M_free(buf2,
"DollarFactorize-2");
2905 factorsincontent = 0;
2911 M_free(buf1,
"DollarFactorize-1");
2913 t = buf1;
while ( *t ) t += *t;
2918 factorsincontent = 0;
2920 tstop = term + *term;
2921 if ( tstop[-1] < 0 ) factorsincontent++;
2922 if ( ABS(tstop[-1]) == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {
2923 tstop -= ABS(tstop[-1]);
2927 tstop -= ABS(tstop[-1]);
2930 while ( term < tstop ) {
2933 t = term+2; i = (term[1]-2)/2;
2935 factorsincontent += ABS(t[1]);
2940 t = term+2; i = (term[1]-2)/3;
2942 factorsincontent += ABS(t[2]);
2948 factorsincontent += (term[1]-2)/2;
2951 factorsincontent += term[1]-2;
2954 if ( *term >= FUNCTION ) factorsincontent++;
2961 factorsincontent = 0;
2973 if ( ( t[1] != SYMBOL ) && ( *t != (ABS(t[*t-1])+1) ) ) {
2978 if ( DetCommu(buf1) > 1 ) {
2979 MesPrint(
"Cannot factorize a $-expression with more than one noncommuting object");
2980 AR.SortType = oldsorttype;
2981 M_free(buf1,
"DollarFactorize-2");
2982 if ( buf1content ) M_free(buf1content,
"DollarFactorize-4");
2983 MesCall(
"DollarFactorize");
2989 termextra = AT.WorkPointer;
2995 AR.SortType = oldsorttype;
2996 M_free(buf1,
"DollarFactorize-2");
2997 if ( buf1content ) M_free(buf1content,
"DollarFactorize-4");
2998 MesCall(
"DollarFactorize");
3005 if (
EndSort(BHEAD (WORD *)((
void *)(&buf2)),2) < 0 ) {
goto getout; }
3007 t = buf2;
while ( *t > 0 ) t += *t;
3016 if ( ( buf3 = poly_factorize_dollar(BHEAD buf2) ) == 0 ) {
3017 MesCall(
"DollarFactorize");
3018 AR.SortType = oldsorttype;
3019 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-3");
3020 M_free(buf1,
"DollarFactorize-3");
3021 if ( buf1content ) M_free(buf1content,
"DollarFactorize-4");
3025 if ( buf2 != buf1 && buf2 ) {
3026 M_free(buf2,
"DollarFactorize-3");
3030 AR.SortType = oldsorttype;
3037 if ( *term == 4 && term[4] == 0 && term[3] == -3 && term[2] == 1
3039 WORD *tt1, *tt2, *ttstop;
3041 tt1 = term; tt2 = term + *term + 1;
3044 while ( *ttstop ) ttstop += *ttstop;
3047 while ( tt2 < ttstop ) *tt1++ = *tt2++;
3055 if ( *term == 0 ) { nfactors++; term++; }
3069 if ( dtype > 0 && dtype != MODLOCAL ) { LOCK(d->pthreadslockread); }
3071 if ( nfactors == 1 ) {
3072 if ( factorsincontent == 0 ) {
3075 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3077 AR.SortType = oldsorttype;
3078 M_free(buf3,
"DollarFactorize-4");
3079 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3080 M_free(buf1,
"DollarFactorize-4");
3081 if ( buf1content ) M_free(buf1content,
"DollarFactorize-4");
3085 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3086 term = buf1;
while ( *term ) term += *term;
3087 d->factors[0].size = i = term - buf1;
3088 d->factors[0].where = t = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"DollarFactorize-5");
3089 term = buf1; NCOPY(t,term,i); *t = 0;
3090 M_free(buf3,
"DollarFactorize-4");
3092 if ( buf2 != buf1 && buf2 ) {
3093 M_free(buf2,
"DollarFactorize-4");
3098 else if ( action ) {
3099 C = cbuf+AC.cbufnum;
3100 CC = cbuf+AT.ebufnum;
3101 oldworkpointer = AT.WorkPointer;
3102 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3104 for ( i = 0; i < nfactors; i++ ) {
3105 argextra = AT.WorkPointer;
3109 if ( ConvertFromPoly(BHEAD term,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol
3110 ,startebuf-numxsymbol,1) <= 0 ) {
3112 getout2: AR.SortType = oldsorttype;
3113 M_free(d->factors,
"factors in dollar");
3116 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3118 M_free(buf3,
"DollarFactorize-4");
3119 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-4");
3120 M_free(buf1,
"DollarFactorize-4");
3121 if ( buf1content ) M_free(buf1content,
"DollarFactorize-4");
3124 AT.WorkPointer = argextra + *argextra;
3128 if (
Generator(BHEAD argextra,C->numlhs+1) ) {
3134 AT.WorkPointer = oldworkpointer;
3135 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3137 d->factors[i].type = DOLTERMS;
3138 t = d->factors[i].where;
3139 while ( *t ) t += *t;
3140 d->factors[i].size = t - d->factors[i].where;
3142 CC->numrhs = startebuf;
3145 C = cbuf+AC.cbufnum;
3146 oldworkpointer = AT.WorkPointer;
3147 d->factors = (
FACDOLLAR *)Malloc1(
sizeof(
FACDOLLAR)*(nfactors+factorsincontent),
"factors in dollar");
3149 for ( i = 0; i < nfactors; i++ ) {
3152 argextra = oldworkpointer;
3154 NCOPY(argextra,term,j)
3155 AT.WorkPointer = argextra;
3156 if (
Generator(BHEAD oldworkpointer,C->numlhs+1) ) {
3161 AT.WorkPointer = oldworkpointer;
3162 EndSort(BHEAD (WORD *)((
void *)(&(d->factors[i].where))),2);
3163 d->factors[i].type = DOLTERMS;
3164 t = d->factors[i].where;
3165 while ( *t ) t += *t;
3166 d->factors[i].size = t - d->factors[i].where;
3169 d->nfactors = nfactors + factorsincontent;
3174 if ( buf3 ) M_free(buf3,
"DollarFactorize-5");
3175 if ( buf2 != buf1 && buf2 ) M_free(buf2,
"DollarFactorize-5");
3176 M_free(buf1,
"DollarFactorize-5");
3180 tstop = term + *term;
3181 if ( tstop[-1] < 0 ) { tstop[-1] = -tstop[-1]; sign = -sign; }
3184 while ( term < tstop ) {
3187 t = term+2; i = (term[1]-2)/2;
3189 if ( t[1] < 0 ) { t[1] = -t[1]; pow = -1; }
3191 for ( jj = 0; jj < t[1]; jj++ ) {
3192 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3193 r[0] = 8; r[1] = SYMBOL; r[2] = 4; r[3] = *t; r[4] = pow;
3194 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3195 d->factors[j].type = DOLTERMS;
3196 d->factors[j].size = 8;
3203 t = term+2; i = (term[1]-2)/3;
3205 if ( t[2] < 0 ) { t[2] = -t[2]; pow = -1; }
3207 for ( jj = 0; jj < t[2]; jj++ ) {
3208 r = d->factors[j].where = (WORD *)Malloc1(10*
sizeof(WORD),
"factor");
3209 r[0] = 9; r[1] = DOTPRODUCT; r[2] = 5; r[3] = t[0]; r[4] = t[1];
3210 r[5] = pow; r[6] = 1; r[7] = 1; r[8] = 3; r[9] = 0;
3211 d->factors[j].type = DOLTERMS;
3212 d->factors[j].size = 9;
3220 t = term+2; i = (term[1]-2)/2;
3222 for ( jj = 0; jj < t[1]; jj++ ) {
3223 r = d->factors[j].where = (WORD *)Malloc1(9*
sizeof(WORD),
"factor");
3224 r[0] = 8; r[1] = *term; r[2] = 4; r[3] = *t; r[4] = t[1];
3225 r[5] = 1; r[6] = 1; r[7] = 3; r[8] = 0;
3226 d->factors[j].type = DOLTERMS;
3227 d->factors[j].size = 8;
3234 t = term+2; i = term[1]-2;
3236 for ( jj = 0; jj < t[1]; jj++ ) {
3237 r = d->factors[j].where = (WORD *)Malloc1(8*
sizeof(WORD),
"factor");
3238 r[0] = 7; r[1] = *term; r[2] = 3; r[3] = *t;
3239 r[4] = 1; r[5] = 1; r[6] = 3; r[7] = 0;
3240 d->factors[j].type = DOLTERMS;
3241 d->factors[j].size = 7;
3248 if ( *term >= FUNCTION ) {
3249 r = d->factors[j].where = (WORD *)Malloc1((term[1]+5)*
sizeof(WORD),
"factor");
3250 *r++ = d->factors[j].size = term[1]+4;
3251 for ( jj = 0; jj < t[1]; jj++ ) *r++ = term[jj];
3252 *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3266 tstop = term + *term;
3267 if ( tstop[-1] == 3 && tstop[-2] == 1 && tstop[-3] == 1 ) {}
3268 else if ( tstop[-1] == 3 && tstop[-2] == 1 && (UWORD)(tstop[-3]) <= MAXPOSITIVE ) {
3269 d->factors[j].where = 0;
3270 d->factors[j].size = 0;
3271 d->factors[j].type = DOLNUMBER;
3272 d->factors[j].value = sign*tstop[-3];
3277 d->factors[j].where = r = (WORD *)Malloc1((tstop[-1]+2)*
sizeof(WORD),
"numfactor");
3278 d->factors[j].size = tstop[-1]+1;
3279 d->factors[j].type = DOLTERMS;
3280 d->factors[j].value = 0;
3287 r = d->factors[j].where;
3289 r += *r; r[-1] = -r[-1];
3297 for ( jj = j; jj > 0; jj-- ) {
3298 d->factors[jj] = d->factors[jj-1];
3300 d->factors[0].where = 0;
3301 d->factors[0].size = 0;
3302 d->factors[0].type = DOLNUMBER;
3303 d->factors[0].value = -1;
3307 if ( buf1content ) M_free(buf1content,
"DollarFactorize-5");
3315 if ( d->nfactors > 1 ) {
3316 WORD ***fac, j1, j2, k, ret, *s1, *s2, *s3;
3318 facsize = (LONG **)Malloc1((
sizeof(WORD **)+
sizeof(LONG *))*d->nfactors,
"SortDollarFactors");
3319 fac = (WORD ***)(facsize+d->nfactors);
3321 for ( j = 0; j < d->nfactors; j++ ) {
3322 if ( d->factors[j].where ) {
3323 fac[k] = &(d->factors[j].where);
3324 facsize[k] = &(d->factors[j].size);
3329 for ( j = 1; j < k; j++ ) {
3332 s1 = *(fac[j1]); s2 = *(fac[j2]);
3333 while ( *s1 && *s2 ) {
3334 if ( ( ret = CompareTerms(BHEAD s2, s1, (WORD)2) ) == 0 ) {
3335 s1 += *s1; s2 += *s2;
3337 else if ( ret > 0 )
goto nextj;
3340 s3 = *(fac[j1]); *(fac[j1]) = *(fac[j2]); *(fac[j2]) = s3;
3341 x = *(facsize[j1]); *(facsize[j1]) = *(facsize[j2]); *(facsize[j2]) = x;
3343 if ( j1 > 0 )
goto nextj1;
3347 if ( *s1 )
goto nextj;
3348 if ( *s2 )
goto exch;
3352 M_free(facsize,
"SortDollarFactors");
3358 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3368 void CleanDollarFactors(
DOLLARS d)
3371 if ( d->nfactors > 1 ) {
3372 for ( i = 0; i < d->nfactors; i++ ) {
3373 if ( d->factors[i].where )
3374 M_free(d->factors[i].where,
"dollar factors");
3378 M_free(d->factors,
"dollar factors");
3389 WORD *TakeDollarContent(
PHEAD WORD *dollarbuffer, WORD **factor)
3396 t = dollarbuffer; pow = 1;
3402 t += *t; t[-1] = -t[-1];
3408 if ( AN.cmod != 0 ) {
3409 if ( ( *factor =
MakeDollarMod(BHEAD dollarbuffer,&remain) ) == 0 ) {
3413 (*factor)[**factor-1] = -(*factor)[**factor-1];
3414 (*factor)[**factor-1] += AN.cmod[0];
3422 (*factor)[**factor-1] = -(*factor)[**factor-1];
3444 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMb, *LCMc;
3445 WORD *r, *r1, *r2, *r3, *rnext, i, k, j, *oldworkpointer, *factor;
3446 WORD kGCD, kLCM, kGCD2, kkLCM, jLCM, jGCD;
3447 CBUF *C = cbuf+AC.cbufnum;
3449 GCDbuffer = NumberMalloc(
"MakeDollarInteger");
3450 GCDbuffer2 = NumberMalloc(
"MakeDollarInteger");
3451 LCMbuffer = NumberMalloc(
"MakeDollarInteger");
3452 LCMb = NumberMalloc(
"MakeDollarInteger");
3453 LCMc = NumberMalloc(
"MakeDollarInteger");
3462 if ( k < 0 ) k = -k;
3463 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3464 for ( kGCD = 0; kGCD < k; kGCD++ ) GCDbuffer[kGCD] = r3[kGCD];
3466 if ( k < 0 ) k = -k;
3468 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3469 for ( kLCM = 0; kLCM < k; kLCM++ ) LCMbuffer[kLCM] = r3[kLCM];
3479 if ( k < 0 ) k = -k;
3480 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3481 if ( ( ( GCDbuffer[0] == 1 ) && ( kGCD == 1 ) ) ) {
3486 else if ( ( ( k != 1 ) || ( r3[0] != 1 ) ) ) {
3487 if ( GcdLong(BHEAD GCDbuffer,kGCD,(UWORD *)r3,k,GCDbuffer2,&kGCD2) ) {
3488 goto MakeDollarIntegerErr;
3491 for ( i = 0; i < kGCD; i++ ) GCDbuffer[i] = GCDbuffer2[i];
3494 kGCD = 1; GCDbuffer[0] = 1;
3497 if ( k < 0 ) k = -k;
3499 while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
3500 if ( ( ( LCMbuffer[0] == 1 ) && ( kLCM == 1 ) ) ) {
3501 for ( kLCM = 0; kLCM < k; kLCM++ )
3502 LCMbuffer[kLCM] = r3[kLCM];
3504 else if ( ( k != 1 ) || ( r3[0] != 1 ) ) {
3505 if ( GcdLong(BHEAD LCMbuffer,kLCM,(UWORD *)r3,k,LCMb,&kkLCM) ) {
3506 goto MakeDollarIntegerErr;
3508 DivLong((UWORD *)r3,k,LCMb,kkLCM,LCMb,&kkLCM,LCMc,&jLCM);
3509 MulLong(LCMbuffer,kLCM,LCMb,kkLCM,LCMc,&jLCM);
3510 for ( kLCM = 0; kLCM < jLCM; kLCM++ )
3511 LCMbuffer[kLCM] = LCMc[kLCM];
3519 r3 = (WORD *)(GCDbuffer);
3520 if ( kGCD == kLCM ) {
3521 for ( jGCD = 0; jGCD < kGCD; jGCD++ )
3522 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3525 else if ( kGCD > kLCM ) {
3526 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3527 r3[jGCD+kGCD] = LCMbuffer[jGCD];
3528 for ( jGCD = kLCM; jGCD < kGCD; jGCD++ )
3533 for ( jGCD = kGCD; jGCD < kLCM; jGCD++ )
3535 for ( jGCD = 0; jGCD < kLCM; jGCD++ )
3536 r3[jGCD+kLCM] = LCMbuffer[jGCD];
3543 factor = r1 = (WORD *)Malloc1((j+2)*
sizeof(WORD),
"MakeDollarInteger");
3544 *r1++ = j+1; r2 = r3;
3545 for ( i = 0; i < k; i++ ) { *r1++ = *r2++; *r1++ = *r2++; }
3558 oldworkpointer = AT.WorkPointer;
3563 r2 = oldworkpointer;
3564 while ( r < r3 ) *r2++ = *r++;
3566 if ( DivRat(BHEAD (UWORD *)r3,j,GCDbuffer,k,(UWORD *)r2,&i) ) {
3567 goto MakeDollarIntegerErr;
3571 if ( rnext[-1] < 0 ) r2[-1] = -i;
3573 *oldworkpointer = r2-oldworkpointer;
3574 AT.WorkPointer = r2;
3575 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3576 goto MakeDollarIntegerErr;
3580 AT.WorkPointer = oldworkpointer;
3581 EndSort(BHEAD (WORD *)bufout,2);
3585 NumberFree(LCMc,
"MakeDollarInteger");
3586 NumberFree(LCMb,
"MakeDollarInteger");
3587 NumberFree(LCMbuffer,
"MakeDollarInteger");
3588 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3589 NumberFree(GCDbuffer,
"MakeDollarInteger");
3592 MakeDollarIntegerErr:
3593 NumberFree(LCMc,
"MakeDollarInteger");
3594 NumberFree(LCMb,
"MakeDollarInteger");
3595 NumberFree(LCMbuffer,
"MakeDollarInteger");
3596 NumberFree(GCDbuffer2,
"MakeDollarInteger");
3597 NumberFree(GCDbuffer,
"MakeDollarInteger");
3598 MesCall(
"MakeDollarInteger");
3617 WORD *r, *r1, x, xx, ix, ip;
3618 WORD *factor, *oldworkpointer;
3620 CBUF *C = cbuf+AC.cbufnum;
3623 if ( r[*r-1] < 0 ) x += AN.cmod[0];
3627 factor = (WORD *)Malloc1(5*
sizeof(WORD),
"MakeDollarMod");
3628 factor[0] = 4; factor[1] = x; factor[2] = 1; factor[3] = 3; factor[4] = 0;
3636 oldworkpointer = AT.WorkPointer;
3638 r1 = oldworkpointer; i = *r;
3640 xx = r1[-3];
if ( r1[-1] < 0 ) xx += AN.cmod[0];
3641 r1[-1] = (WORD)((((LONG)xx)*ix) % AN.cmod[0]);
3642 *r1 = 0; AT.WorkPointer = r1;
3643 if (
Generator(BHEAD oldworkpointer,C->numlhs) ) {
3647 AT.WorkPointer = oldworkpointer;
3648 EndSort(BHEAD (WORD *)bufout,2);
3658 int GetDolNum(
PHEAD WORD *t, WORD *tstop)
3662 if ( t+3 < tstop && t[3] == DOLLAREXPR2 ) {
3666 int nummodopt, dtype;
3668 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3669 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3670 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3672 if ( nummodopt < NumModOptdollars ) {
3673 dtype = ModOptdollars[nummodopt].type;
3674 if ( dtype == MODLOCAL ) {
3675 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3678 MLOCK(ErrorMessageLock);
3679 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3680 DOLLARNAME(Dollars,t[2]),AC.CModule);
3681 MUNLOCK(ErrorMessageLock);
3688 if ( d->factors == 0 ) {
3689 MLOCK(ErrorMessageLock);
3690 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
3691 MUNLOCK(ErrorMessageLock);
3694 num = GetDolNum(BHEAD t+t[1],tstop);
3695 if ( num == 0 )
return(d->nfactors);
3696 if ( num > d->nfactors ) {
3697 MLOCK(ErrorMessageLock);
3698 MesPrint(
"Attempt to use an nonexisting factor %d of a $-variable",num);
3699 MUNLOCK(ErrorMessageLock);
3702 w = d->factors[num-1].where;
3703 if ( w == 0 )
return(d->factors[num-1].value);
3704 if ( w[0] == 4 && w[4] == 0 && w[3] == 3 && w[2] == 1 && w[1] > 0
3705 && w[1] < MAXPOSITIVE )
return(w[1]);
3707 MLOCK(ErrorMessageLock);
3708 MesPrint(
"Illegal type of factor number of a $-variable");
3709 MUNLOCK(ErrorMessageLock);
3713 else if ( t[2] < 0 ) {
3720 int nummodopt, dtype;
3722 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
3723 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3724 if ( t[2] == ModOptdollars[nummodopt].number )
break;
3726 if ( nummodopt < NumModOptdollars ) {
3727 dtype = ModOptdollars[nummodopt].type;
3728 if ( dtype == MODLOCAL ) {
3729 d = ModOptdollars[nummodopt].dstruct+AT.identity;
3732 MLOCK(ErrorMessageLock);
3733 MesPrint(
"&Illegal attempt to use $-variable %s in module %l",
3734 DOLLARNAME(Dollars,t[2]),AC.CModule);
3735 MUNLOCK(ErrorMessageLock);
3742 if ( d->type == DOLZERO )
return(0);
3743 if ( d->type == DOLTERMS || d->type == DOLNUMBER ) {
3744 if ( d->where[0] == 4 && d->where[4] == 0 && d->where[3] == 3
3745 && d->where[2] == 1 && d->where[1] > 0
3746 && d->where[1] < MAXPOSITIVE )
return(d->where[1]);
3747 MLOCK(ErrorMessageLock);
3748 MesPrint(
"Attempt to use an nonexisting factor of a $-variable");
3749 MUNLOCK(ErrorMessageLock);
3752 MLOCK(ErrorMessageLock);
3753 MesPrint(
"Illegal type of factor number of a $-variable");
3754 MUNLOCK(ErrorMessageLock);
3773 int i, n = NumPotModdollars;
3774 for ( i = 0; i < n; i++ ) {
3775 if ( numdollar == PotModdollars[i] )
break;
3778 *(WORD *)FromList(&AC.PotModDolList) = numdollar;
WORD * MakeDollarMod(PHEAD WORD *buffer, WORD **bufout)
int DollarFactorize(PHEAD WORD numdollar)
WORD EvalDoLoopArg(PHEAD WORD *arg, WORD par)
int LocalConvertToPoly(PHEAD WORD *, WORD *, WORD, WORD)
int GetModInverses(WORD, WORD, WORD *, WORD *)
WORD StoreTerm(PHEAD WORD *)
void AddPotModdollar(WORD numdollar)
WORD * MakeDollarInteger(PHEAD WORD *bufin, WORD **bufout)
int PF_BroadcastPreDollar(WORD **dbuffer, LONG *newsize, int *numterms)
WORD Generator(PHEAD WORD *, WORD)
WORD CompCoef(WORD *, WORD *)
LONG EndSort(PHEAD WORD *, int)