106 WORD GetIfDollarNum(WORD *ifp, WORD *ifstop)
110 if ( ifp[2] < 0 ) {
return(-ifp[2]-1); }
112 if ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) {
113 if ( d->nfactors == 0 ) {
114 MLOCK(ErrorMessageLock);
115 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
116 MUNLOCK(ErrorMessageLock);
119 num = GetIfDollarNum(ifp+3,ifstop);
120 if ( num > d->nfactors ) {
121 MLOCK(ErrorMessageLock);
122 MesPrint(
"Dollar factor number %s out of range",num);
123 MUNLOCK(ErrorMessageLock);
129 w = d->factors[num-1].where;
130 if ( w == 0 )
return(d->factors[num].value);
132 if ( *w == 0 )
return(0);
133 if ( *w == 4 && w[3] == 3 && w[2] == 1 && w[1] < MAXPOSITIVE && w[4] == 0 ) {
136 if ( ( w[w[0]] != 0 ) || ( ABS(w[w[0]-1]) != w[0]-1 ) ) {
137 MLOCK(ErrorMessageLock);
138 MesPrint(
"Dollar factor number expected but found expression");
139 MUNLOCK(ErrorMessageLock);
143 MLOCK(ErrorMessageLock);
144 MesPrint(
"Dollar factor number out of range");
145 MUNLOCK(ErrorMessageLock);
153 if ( d->type == DOLZERO ) {
156 else if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
157 w = d->where;
goto getnumber;
160 MLOCK(ErrorMessageLock);
161 MesPrint(
"Dollar factor number is wrong type");
162 MUNLOCK(ErrorMessageLock);
180 WORD DoIfStatement(
PHEAD WORD *ifcode, WORD *term)
184 UWORD *coef1 = 0, *coef2, *coef3, *cc;
185 WORD ncoef1, ncoef2, ncoef3, i = 0, first, *r, acoef, ismul1, ismul2, j;
186 UWORD *Spac1, *Spac2;
187 ifstop = ifcode + ifcode[1];
189 if ( ifp >= ifstop )
return(1);
190 if ( ( ifp + ifp[1] ) >= ifstop ) {
193 if ( ifp[2] )
return(1);
197 if ( HowMany(BHEAD ifp,term) )
return(1);
200 if ( Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]) )
return(1);
203 if ( CountDo(term,ifp) )
return(1);
212 int nummodopt, dtype = -1;
213 if ( AS.MultiThreaded ) {
214 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
215 if ( ifp[2] == ModOptdollars[nummodopt].number )
break;
217 if ( nummodopt < NumModOptdollars ) {
218 dtype = ModOptdollars[nummodopt].type;
219 if ( dtype == MODLOCAL ) {
220 d = ModOptdollars[nummodopt].dstruct+AT.identity;
228 if ( dtype == DOLZERO )
return(0);
229 if ( dtype == DOLUNDEFINED ) {
230 if ( AC.UnsureDollarMode == 0 ) {
231 MesPrint(
"$%s is undefined",AC.dollarnames->namebuffer+d->name);
238 r = ifp+2; j = ifp[1] - 2;
240 if ( *r == AR.CurExpr )
return(1);
245 r = ifp+2; j = ifp[1] - 2;
247 if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 )
253 if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 )
return(0);
261 if ( ifp[3] == ( ifp[1] + 3 ) )
return(DoIfStatement(BHEAD ifp,term));
262 ifstop = ifp + ifp[1];
270 coef3 = NumberMalloc(
"DoIfStatement");
271 Spac1 = NumberMalloc(
"DoIfStatement");
272 Spac2 = (UWORD *)(TermMalloc(
"DoIfStatement"));
273 ncoef1 = 0; first = 1; ismul1 = 0;
277 if ( ifp[-2] == ORCOND && ncoef1 ) {
279 ncoef1 = 1; coef1[0] = coef1[1] = 1;
282 if ( ifp[-2] == ANDCOND && !ncoef1 )
goto SkipCond;
291 cc = (UWORD *)(ifp + 3);
292 for ( i = 0; i < j; i++ ) coef2[i] = cc[i];
296 coef2[0] = HowMany(BHEAD ifp,term);
298 if ( coef2[0] == 0 ) ncoef2 = 0;
301 acoef = CountDo(term,ifp);
302 coef2[0] = ABS(acoef);
304 if ( acoef == 0 ) ncoef2 = 0;
305 else if ( acoef < 0 ) ncoef2 = -1;
308 acoef = Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]);
309 coef2[0] = ABS(acoef);
311 if ( acoef == 0 ) ncoef2 = 0;
312 else if ( acoef < 0 ) ncoef2 = -1;
318 cc = (UWORD *)(r - i);
319 if ( ncoef2 < 0 ) ncoef2 = (ncoef2+1)>>1;
320 else ncoef2 = (ncoef2-1)>>1;
321 i--;
for ( j = 0; j < i; j++ ) coef2[j] = cc[j];
324 ncoef2 = coef2[0] = DoIfStatement(BHEAD ifp,term);
343 int nummodopt, dtype = -1;
344 if ( AS.MultiThreaded ) {
345 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
346 if ( ifp[2] == ModOptdollars[nummodopt].number )
break;
348 if ( nummodopt < NumModOptdollars ) {
349 dtype = ModOptdollars[nummodopt].type;
350 if ( dtype == MODLOCAL ) {
351 d = ModOptdollars[nummodopt].dstruct+AT.identity;
354 LOCK(d->pthreadslockread);
362 if ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) {
363 if ( d->nfactors == 0 ) {
364 MLOCK(ErrorMessageLock);
365 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
366 MUNLOCK(ErrorMessageLock);
369 WORD num = GetIfDollarNum(ifp+3,ifstop);
371 while ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) ifp += 3;
372 if ( num > d->nfactors ) {
373 MLOCK(ErrorMessageLock);
374 MesPrint(
"Dollar factor number %s out of range",num);
375 MUNLOCK(ErrorMessageLock);
379 ncoef2 = 1; coef2[0] = d->nfactors; coef2[1] = 1;
382 w = d->factors[num-1].where;
384 if ( d->factors[num-1].value < 0 ) {
385 ncoef2 = -1; coef2[0] = -d->factors[num-1].value; coef2[1] = 1;
388 ncoef2 = 1; coef2[0] = d->factors[num-1].value; coef2[1] = 1;
395 if ( i == ( *w-1 ) ) {
397 if ( *r < 0 ) ncoef2 = -ncoef2;
398 i--; cc = coef2; r = w + 1;
399 while ( --i >= 0 ) *cc++ = (UWORD)(*r++);
409 if ( AC.UnsureDollarMode == 0 ) {
411 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
413 MLOCK(ErrorMessageLock);
414 MesPrint(
"$%s is undefined",AC.dollarnames->namebuffer+d->name);
415 MUNLOCK(ErrorMessageLock);
418 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
421 ncoef2 = coef2[0] = 0; coef2[1] = 1;
424 if ( d->where[0] != INDEX || d->where[1] != 3
425 || d->where[2] < 0 || d->where[2] >= AM.OffsetIndex ) {
426 if ( AC.UnsureDollarMode == 0 ) {
428 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
430 MLOCK(ErrorMessageLock);
431 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
432 MUNLOCK(ErrorMessageLock);
435 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
438 d->index = d->where[2];
440 if ( d->index == 0 ) {
441 ncoef2 = coef2[0] = 0; coef2[1] = 1;
443 else if ( d->index > 0 && d->index < AM.OffsetIndex ) {
444 ncoef2 = 1; coef2[0] = d->index; coef2[1] = 1;
446 else if ( AC.UnsureDollarMode == 0 ) {
448 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
450 MLOCK(ErrorMessageLock);
451 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
452 MUNLOCK(ErrorMessageLock);
455 ncoef2 = coef2[0] = 0; coef2[1] = 1;
458 if ( d->where[0] <= -FUNCTION ||
459 ( d->where[0] < 0 && d->where[2] != 0 )
460 || ( d->where[0] > 0 && d->where[d->where[0]] != 0 )
462 if ( AC.UnsureDollarMode == 0 ) {
464 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
466 MLOCK(ErrorMessageLock);
467 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
468 MUNLOCK(ErrorMessageLock);
471 ncoef2 = coef2[0] = 0; coef2[1] = 1;
475 if ( d->where[0] == -SNUMBER ) {
476 if ( d->where[1] == 0 ) {
477 ncoef2 = coef2[0] = 0;
479 else if ( d->where[1] < 0 ) {
481 coef2[0] = -d->where[1];
485 coef2[0] = d->where[1];
489 else if ( d->where[0] == -INDEX
490 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
491 if ( d->where[1] == 0 ) {
492 ncoef2 = coef2[0] = 0; coef2[1] = 1;
495 ncoef2 = 1; coef2[0] = d->where[1];
499 else if ( d->where[0] > 0
500 && d->where[ARGHEAD] == (d->where[0]-ARGHEAD)
501 && ABS(d->where[d->where[0]-1]) ==
502 (d->where[0] - ARGHEAD-1) ) {
503 i = d->where[d->where[0]-1];
504 ncoef2 = (ABS(i)-1)/2;
505 if ( i < 0 ) { ncoef2 = -ncoef2; i = -i; }
506 i--; cc = coef2; r = d->where + ARGHEAD+1;
507 while ( --i >= 0 ) *cc++ = (UWORD)(*r++);
510 if ( AC.UnsureDollarMode == 0 ) {
512 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
514 MLOCK(ErrorMessageLock);
515 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
516 MUNLOCK(ErrorMessageLock);
519 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
524 if ( d->where[d->where[0]] == 0 ) {
525 r = d->where + d->where[0]-1;
527 if ( i == ( d->where[0]-1 ) ) {
529 if ( *r < 0 ) ncoef2 = -ncoef2;
530 i--; cc = coef2; r = d->where + 1;
531 while ( --i >= 0 ) *cc++ = (UWORD)(*r++);
536 if ( AC.UnsureDollarMode == 0 ) {
538 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
540 MLOCK(ErrorMessageLock);
541 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
542 MUNLOCK(ErrorMessageLock);
545 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
550 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
555 r = ifp+2; j = ifp[1] - 2; ncoef2 = 0;
557 if ( *r == AR.CurExpr ) { ncoef2 = 1;
break; }
564 r = ifp+2; j = ifp[1] - 2;
567 if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 ) {
574 if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 ) {
588 if ( ifp[-2] != ORCOND && ifp[-2] != ANDCOND ) {
589 if ( ( ifp[-2] == EQUAL || ifp[-2] == NOTEQUAL ) &&
590 ( ismul2 || ismul1 ) ) {
591 if ( ismul1 && ismul2 ) {
592 if ( coef1[0] == coef2[0] ) i = 1;
598 Divvy(BHEAD coef2,&ncoef2,coef1,ncoef1);
599 cc = coef2; ncoef3 = ncoef2;
603 Divvy(BHEAD coef1,&ncoef1,coef2,ncoef2);
604 cc = coef1; ncoef3 = ncoef1;
606 if ( ncoef3 < 0 ) ncoef3 = -ncoef3;
608 if ( ifp[-2] == EQUAL ) i = 1;
611 else if ( cc[ncoef3] != 1 ) {
612 if ( ifp[-2] == EQUAL ) i = 0;
616 for ( j = 1; j < ncoef3; j++ ) {
617 if ( cc[ncoef3+j] != 0 )
break;
620 if ( ifp[-2] == EQUAL ) i = 0;
623 else if ( ifp[-2] == EQUAL ) i = 1;
629 else if ( AddRat(BHEAD coef1,ncoef1,coef2,-ncoef2,coef3,&ncoef3) ) {
630 NumberFree(coef3,
"DoIfStatement"); NumberFree(Spac1,
"DoIfStatement"); TermFree(Spac2,
"DoIfStatement");
631 MesCall(
"DoIfStatement");
return(-1);
635 if ( ncoef3 > 0 ) i = 1;
639 if ( ncoef3 >= 0 ) i = 1;
643 if ( ncoef3 < 0 ) i = 1;
647 if ( ncoef3 <= 0 ) i = 1;
651 if ( ncoef3 == 0 ) i = 1;
655 if ( ncoef3 != 0 ) i = 1;
659 donemul:
if ( i ) { ncoef2 = 1; coef2 = Spac2; coef2[0] = coef2[1] = 1; }
669 for ( j = 0; j < i; j++ ) coef1[j] = coef2[j];
673 }
while ( ifp < ifstop );
675 NumberFree(coef3,
"DoIfStatement"); NumberFree(Spac1,
"DoIfStatement"); TermFree(Spac2,
"DoIfStatement");
676 if ( ncoef1 )
return(1);
690 WORD HowMany(
PHEAD WORD *ifcode, WORD *term)
693 WORD *m, *t, *r, *w, power, RetVal, i, topje, *newterm;
694 WORD *OldWork, *ww, *mm;
699 AN.WildValue = w = m + SUBEXPSIZE;
702 OldWork = AT.WorkPointer;
703 if ( ( ifcode[4] & 1 ) != 0 ) {
705 ww = AT.WorkPointer; i = m[0]; mm = m;
708 *ww++ = 1; *ww++ = 1; *ww++ = 3;
710 RepSto = AN.RepPoint;
713 if (
Generator(BHEAD OldWork,AR.Cnumlhs) ) {
716 AN.RepPoint = RepSto;
717 AT.WorkPointer = OldWork;
721 if (
EndSort(BHEAD ww,0) < 0 ) {}
723 AN.RepPoint = RepSto;
724 if ( *ww == 0 || *(ww+*ww) != 0 ) {
725 if ( AP.lhdollarerror == 0 ) {
726 MLOCK(ErrorMessageLock);
727 MesPrint(
"&LHS must be one term");
728 MUNLOCK(ErrorMessageLock);
729 AP.lhdollarerror = 1;
731 AT.WorkPointer = OldWork;
734 m = ww; AT.WorkPointer = ww = m + *m;
735 if ( m[*m-1] < 0 ) { m[*m-1] = -m[*m-1]; }
741 if ( AT.WorkPointer < ww ) AT.WorkPointer = ww;
744 while ( w < AN.WildStop ) {
745 if ( *w == LOADDOLLAR ) numdollars++;
749 AN.RepFunList = AT.WorkPointer;
750 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
751 topje = cbuf[AT.ebufnum].numrhs;
752 if ( AT.WorkPointer >= AT.WorkTop ) {
753 MLOCK(ErrorMessageLock);
755 MUNLOCK(ErrorMessageLock);
758 AN.DisOrderFlag = ifcode[2] & SUBDISORDER;
759 switch ( ifcode[2] & (~SUBDISORDER) ) {
762 AN.UseFindOnly = 1; AN.ForFindOnly = 0;
768 t = term; newterm = r = AT.WorkPointer;
769 NCOPY(r,t,i); AT.WorkPointer = r;
771 if ( FindRest(BHEAD newterm,m) && ( AN.UsedOtherFind ||
772 FindOnly(BHEAD newterm,m) ) ) {
773 Substitute(BHEAD newterm,m,1);
789 t = term; newterm = r = AT.WorkPointer;
790 NCOPY(r,t,i); AT.WorkPointer = r;
793 if ( ( power = FindRest(BHEAD newterm,m) ) > 0 ) {
794 if ( ( power = FindOnce(BHEAD newterm,m) ) > 0 ) {
797 Substitute(BHEAD newterm,m,1);
804 }
while ( FindRest(BHEAD newterm,m) && (
805 AN.UsedOtherFind || FindOnce(BHEAD newterm,m) ) );
807 else if ( power < 0 ) {
809 Substitute(BHEAD newterm,m,1);
816 }
while ( FindRest(BHEAD newterm,m) );
819 else if ( power < 0 ) {
820 if ( FindOnce(BHEAD newterm,m) ) {
822 Substitute(BHEAD newterm,m,1);
828 }
while ( FindOnce(BHEAD newterm,m) );
839 t = term; newterm = r = AT.WorkPointer;
840 NCOPY(r,t,i); AT.WorkPointer = r;
843 if ( FindRest(BHEAD newterm,m) && ( AN.UsedOtherFind || FindOnce(BHEAD newterm,m) ) ) {
844 Substitute(BHEAD newterm,m,1);
855 RetVal = FindMulti(BHEAD term,m);
859 for ( i = 0; i < *term; i++ ) ww[i] = term[i];
860 while ( ( power = FindAll(BHEAD ww,m,AR.Cnumlhs,ifcode) ) != 0 ) { RetVal += power; }
863 ifcode += IDHEAD; ifcode += ifcode[1]; ifcode += *ifcode;
864 AN.UseFindOnly = 1; AN.ForFindOnly = ifcode;
865 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
866 FindOnly(BHEAD term,m) ) ) RetVal = 1;
873 AT.WorkPointer = AN.RepFunList;
874 cbuf[AT.ebufnum].numrhs = topje;
883 VOID DoubleIfBuffers()
887 LONG *newheap, *newifcount;
888 if ( AC.MaxIf == 0 ) newmax = 10;
889 else newmax = 2*AC.MaxIf;
890 newheap = (LONG *)Malloc1(
sizeof(LONG)*(newmax+1),
"IfHeap");
891 newsumcheck = (WORD *)Malloc1(
sizeof(WORD)*(newmax+1),
"IfSumCheck");
892 newifcount = (LONG *)Malloc1(
sizeof(LONG)*(newmax+1),
"IfCount");
894 for ( i = 0; i < AC.MaxIf; i++ ) {
895 newheap[i] = AC.IfHeap[i];
896 newsumcheck[i] = AC.IfSumCheck[i];
897 newifcount[i] = AC.IfCount[i];
899 AC.IfStack = (AC.IfStack-AC.IfHeap) + newheap;
900 M_free(AC.IfHeap,
"AC.IfHeap");
901 M_free(AC.IfCount,
"AC.IfCount");
902 M_free(AC.IfSumCheck,
"AC.IfSumCheck");
905 AC.IfStack = newheap;
908 AC.IfSumCheck = newsumcheck;
909 AC.IfCount = newifcount;
WORD Generator(PHEAD WORD *, WORD)
LONG EndSort(PHEAD WORD *, int)