85static WORD tranarray[10] = { SUBEXPRESSION, SUBEXPSIZE, 0, 1, 0, 0, 0, 0, 0, 0 };
87int CoTransform(UBYTE *in)
90 UBYTE *s = in, c, *ss, *Tempbuf;
91 WORD number, type, i, *work = AT.WorkPointer+2, *wp, range[2], one = 1;
95 while ( *in ==
',' ) in++;
106 number = DoTempSet(s,in);
109 c = in[1]; in[1] = 0;
110 MesPrint(
"& %s: A set in a transform statement should be followed by a comma",s);
112 if ( error == 0 ) error = 1;
115 else if ( *in ==
'[' || FG.cTable[*in] == 0 ) {
118 if ( *in !=
',' )
break;
120 type = GetName(AC.varnames,s,&number,NOAUTO);
121 if ( type == CFUNCTION ) {
123 if ( (number+FUNCTION) == FLOATFUN ) {
124 MesPrint(
"&Illegal use of a transform statement and float_");
125 if ( error == 0 ) error = 1;
128 number += MAXVARIABLES + FUNCTION; }
129 else if ( type != CSET ) {
130 MesPrint(
"& %s: A transform statement starts with sets of functions",s);
131 if ( error == 0 ) error = 1;
136 MesPrint(
"&Illegal syntax in Transform statement",s);
137 if ( error == 0 ) error = 1;
141 if ( number < MAXVARIABLES ) {
145 if ( Sets[number].type != CFUNCTION ) {
146 MesPrint(
"&A set in a transform statement should be a set of functions");
147 if ( error == 0 ) error = 1;
151 r1 = SetElements + Sets[number].first;
152 r2 = SetElements + Sets[number].last;
154 if ( *r1++ == FLOATFUN ) {
155 MesPrint(
"&Illegal use of a transform statement and float_");
156 if ( error == 0 ) error = 1;
162 else if ( error == 0 ) error = 1;
167 while ( *in ==
',' ) in++;
178 if ( FG.cTable[*in] != 0 ) {
179 MesPrint(
"&Illegal character in Transform statement");
180 if ( error == 0 ) error = 1;
184 if ( *in ==
'>' || *in ==
'<' || *in ==
'+' || *in ==
'-' ) in++;
188 MesPrint(
"&Illegal syntax in specifying a transformation inside a Transform statement");
189 if ( error == 0 ) error = 1;
195 if ( StrICmp(s,(UBYTE *)
"replace") == 0 ) {
208 if ( ( in = ReadRange(in,range,0) ) == 0 ) {
209 if ( error == 0 ) error = 1;
220 if ( error == 0 ) error = 1;
226 if ( error == 0 ) error = 1;
230 if ( *in !=
',' && *in !=
'\0' ) {
232 if ( error == 0 ) error = 1;
236 ss = Tempbuf = (UBYTE *)Malloc1(i+5,
"CoTransform/replace");
237 *ss++ =
'd'; *ss++ =
'u'; *ss++ =
'm'; *ss++ =
'_';
240 AC.ProtoType = tranarray;
241 tranarray[4] = AC.cbufnum;
242 irhs = CompileAlgebra(Tempbuf,RHSIDE,AC.ProtoType);
243 M_free(Tempbuf,
"CoTransform/replace");
245 if ( error == 0 ) error = 1;
258 *wp++ = SUBEXPSIZE+4;
259 for ( i = 0; i < SUBEXPSIZE; i++ ) *wp++ = tranarray[i];
264 work = wp; *wp++ = 0;
271 else if ( StrICmp(s,(UBYTE *)
"decode" ) == 0 ) {
275 else if ( StrICmp(s,(UBYTE *)
"encode" ) == 0 ) {
278 if ( ( in = ReadRange(in,range,2) ) == 0 ) {
279 if ( error == 0 ) error = 1;
283 s = in;
while ( FG.cTable[*in] == 0 ) in++;
288 if ( StrICmp(s,(UBYTE *)
"base") == 0 ) {
291 MesPrint(
"&Illegal base specification in encode/decode transformation");
292 if ( error == 0 ) error = 1;
300 if ( GetName(AC.dollarnames,ss,&numdol,NOAUTO) != CDOLLAR ) {
301 MesPrint(
"&%s is undefined",ss-1);
302 numdol = AddDollar(ss,DOLINDEX,&one,1);
310 while ( FG.cTable[*in] == 1 ) {
311 x = 10*x + *in++ -
'0';
312 if ( x > MAXPOSITIVE4 ) {
313illsize: MesPrint(
"&Illegal value for base in encode/decode transformation");
314 if ( error == 0 ) error = 1;
318 if ( x <= 1 )
goto illsize;
320 if ( *in !=
',' && *in !=
'\0' ) {
321 MesPrint(
"&Illegal termination of transformation");
322 if ( error == 0 ) error = 1;
327 MesPrint(
"&Illegal option in encode/decode transformation");
328 if ( error == 0 ) error = 1;
344 work = wp; *wp++ = 0;
351 else if ( StrICmp(s,(UBYTE *)
"implode") == 0
352 || StrICmp(s,(UBYTE *)
"tosumnotation") == 0 ) {
358 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
359 if ( error == 0 ) error = 1;
367 work = wp; *wp++ = 0;
374 else if ( StrICmp(s,(UBYTE *)
"explode") == 0
375 || StrICmp(s,(UBYTE *)
"tointegralnotation") == 0 ) {
381 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
382 if ( error == 0 ) error = 1;
390 work = wp; *wp++ = 0;
397 else if ( StrICmp(s,(UBYTE *)
"permute") == 0 ) {
402 *wp++ = MAXPOSITIVE4;
412 WORD number; UBYTE *t;
414 while ( FG.cTable[*in] < 2 ) in++;
416 if ( ( number = GetDollar(t) ) < 0 ) {
417 MesPrint(
"&Undefined variable $%s",t);
418 if ( !error ) error = 1;
419 number = AddDollar(t,0,0,0);
426 while ( FG.cTable[*in] == 1 ) {
427 x = 10*x + *in++ -
'0';
428 if ( x > MAXPOSITIVE4 ) {
429 MesPrint(
"&value in permute transformation too large");
430 if ( error == 0 ) error = 1;
435 MesPrint(
"&value 0 in permute transformation not allowed");
436 if ( error == 0 ) error = 1;
441 }
while ( *in ==
',' );
443 MesPrint(
"&Illegal syntax in permute transformation");
444 if ( error == 0 ) error = 1;
448 if ( *in !=
',' && *in !=
'(' && *in !=
'\0' ) {
449 MesPrint(
"&Illegal ending in permute transformation");
450 if ( error == 0 ) error = 1;
454 if ( *wstart == 1 ) wstart--;
455 }
while ( *in ==
'(' );
457 work = wp; *wp++ = 0;
464 else if ( StrICmp(s,(UBYTE *)
"reverse") == 0 ) {
467 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
468 if ( error == 0 ) error = 1;
476 work = wp; *wp++ = 0;
483 else if ( StrICmp(s,(UBYTE *)
"dedup") == 0 ) {
486 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
487 if ( error == 0 ) error = 1;
495 work = wp; *wp++ = 0;
502 else if ( StrICmp(s,(UBYTE *)
"cycle") == 0 ) {
505 if ( ( in = ReadRange(in,range,0) ) == 0 ) {
506 if ( error == 0 ) error = 1;
519 else if ( *in ==
'-' ) {
523 MesPrint(
"&Cycle in a Transform statement should be followed by =+/-number/$");
524 if ( error == 0 ) error = 1;
531 while ( FG.cTable[*in] == 0 || FG.cTable[*in] == 1 ) in++;
533 if ( ( x = GetDollar(si) ) < 0 ) {
534 MesPrint(
"&Undefined $-variable in transform,cycle statement.");
538 if ( one < 0 ) x += MAXPOSITIVE4;
543 while ( FG.cTable[*in] == 1 ) {
544 x = 10*x + *in++ -
'0';
545 if ( x > MAXPOSITIVE4 ) {
546 MesPrint(
"&Number in cycle in a Transform statement too big");
547 if ( error == 0 ) error = 1;
554 work = wp; *wp++ = 0;
561 else if ( StrICmp(s,(UBYTE *)
"islyndon" ) == 0 ) {
565 else if ( StrICmp(s,(UBYTE *)
"islyndon<" ) == 0 ) {
569 else if ( StrICmp(s,(UBYTE *)
"islyndon-" ) == 0 ) {
573 else if ( StrICmp(s,(UBYTE *)
"islyndon>" ) == 0 ) {
577 else if ( StrICmp(s,(UBYTE *)
"islyndon+" ) == 0 ) {
581 else if ( StrICmp(s,(UBYTE *)
"tolyndon" ) == 0 ) {
585 else if ( StrICmp(s,(UBYTE *)
"tolyndon<" ) == 0 ) {
589 else if ( StrICmp(s,(UBYTE *)
"tolyndon-" ) == 0 ) {
593 else if ( StrICmp(s,(UBYTE *)
"tolyndon>" ) == 0 ) {
597 else if ( StrICmp(s,(UBYTE *)
"tolyndon+" ) == 0 ) {
605 else if ( StrICmp(s,(UBYTE *)
"addargs" ) == 0 ) {
608 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
609 if ( error == 0 ) error = 1;
617 work = wp; *wp++ = 0;
624 else if ( ( StrICmp(s,(UBYTE *)
"mulargs" ) == 0 )
625 || ( StrICmp(s,(UBYTE *)
"multiplyargs" ) == 0 ) ) {
628 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
629 if ( error == 0 ) error = 1;
637 work = wp; *wp++ = 0;
644 else if ( StrICmp(s,(UBYTE *)
"dropargs" ) == 0 ) {
647 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
648 if ( error == 0 ) error = 1;
656 work = wp; *wp++ = 0;
663 else if ( StrICmp(s,(UBYTE *)
"selectargs" ) == 0 ) {
666 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
667 if ( error == 0 ) error = 1;
675 work = wp; *wp++ = 0;
682 else if ( StrICmp(s,(UBYTE *)
"ztoh") == 0 ) {
688 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
689 if ( error == 0 ) error = 1;
697 work = wp; *wp++ = 0;
704 else if ( StrICmp(s,(UBYTE *)
"htoz") == 0 ) {
710 if ( ( in = ReadRange(in,range,1) ) == 0 ) {
711 if ( error == 0 ) error = 1;
719 work = wp; *wp++ = 0;
726 MesPrint(
"&Unknown transformation inside a Transform statement: %s",s);
728 if ( error == 0 ) error = 1;
731 while ( *s ==
',') s++;
733 AT.WorkPointer[0] = TYPETRANSFORM;
734 AT.WorkPointer[1] = i = wp - AT.WorkPointer;
750int RunTransform(PHEAD WORD *term, WORD *params)
752 WORD *t, *tstop, *w, *m, *out, *in, *tt, retval;
753 WORD *fun, *args, *info, *infoend, *onetransform, *funs, *endfun;
754 WORD *thearg = 0, *iterm, *newterm, *nt, *oldwork = AT.WorkPointer, sign = 1;
756 out = tstop = term + *term;
757 tstop -= ABS(tstop[-1]);
760 while ( t < tstop ) {
761 endfun = onetransform = params + *params;
763 if ( *t < FUNCTION ) {}
764 else if ( funs == endfun ) {
767 if ( *t == FLOATFUN )
goto next;
769 while ( in < t ) *out++ = *in++;
770 tt = t + t[1]; fun = out;
771 while ( in < tt ) *out++ = *in++;
773 args = onetransform + 1;
774 info = args;
while ( *info <= MAXRANGEINDICATOR ) {
775 if ( *info == ALLARGS ) info++;
776 else if ( *info == NUMARG ) info += 2;
777 else if ( *info == ARGRANGE ) info += 3;
778 else if ( *info == MAKEARGS ) info += 3;
782 if ( RunReplace(BHEAD fun,args,info) )
goto abo;
786 if ( RunEncode(BHEAD fun,args,info) )
goto abo;
790 if ( RunDecode(BHEAD fun,args,info) )
goto abo;
794 if ( RunImplode(fun,args) )
goto abo;
798 if ( RunExplode(BHEAD fun,args) )
goto abo;
802 if ( RunPermute(BHEAD fun,args,info) )
goto abo;
806 if ( RunReverse(BHEAD fun,args) )
goto abo;
810 if ( RunDedup(BHEAD fun,args) )
goto abo;
814 if ( RunCycle(BHEAD fun,args,info) )
goto abo;
818 if ( RunAddArg(BHEAD fun,args) )
goto abo;
822 if ( RunMulArg(BHEAD fun,args) )
goto abo;
826 if ( ( retval = RunIsLyndon(BHEAD fun,args,1) ) < -1 )
goto abo;
830 if ( ( retval = RunIsLyndon(BHEAD fun,args,-1) ) < -1 )
goto abo;
834 if ( ( retval = RunToLyndon(BHEAD fun,args,1) ) < -1 )
goto abo;
838 if ( ( retval = RunToLyndon(BHEAD fun,args,-1) ) < -1 )
goto abo;
841 if ( retval == -1 )
break;
845 AT.WorkPointer += 2*AM.MaxTer;
846 if ( AT.WorkPointer > AT.WorkTop ) {
847 MLOCK(ErrorMessageLock);
849 MUNLOCK(ErrorMessageLock);
852 iterm = AT.WorkPointer;
854 for ( i = 0; i < *info; i++ ) iterm[i] = info[i];
855 AT.WorkPointer = iterm + *iterm;
858 if (
Generator(BHEAD iterm,AR.Cnumlhs) ) {
860 AT.WorkPointer = oldwork;
863 newterm = AT.WorkPointer;
864 if (
EndSort(BHEAD newterm,1) < 0 ) {}
865 if ( ( *newterm && *(newterm+*newterm) != 0 ) || *newterm == 0 ) {
866 MLOCK(ErrorMessageLock);
867 MesPrint(
"&yes/no information in islyndon/tolyndon does not evaluate into a single term");
868 MUNLOCK(ErrorMessageLock);
872 i = *newterm; tt = iterm; nt = newterm;
874 AT.WorkPointer = iterm + *iterm;
876 infoend = info+info[1];
883 if ( info >= infoend ) {
885 MLOCK(ErrorMessageLock);
886 MesPrint(
"There should be a yes and a no argument in islyndon/tolyndon");
887 MUNLOCK(ErrorMessageLock);
891 if ( info >= infoend )
goto abortlyndon;
894 else if ( retval == 1 ) {
898 if ( info >= infoend )
goto abortlyndon;
901 if ( info >= infoend )
goto abortlyndon;
904 if ( info < infoend )
goto abortlyndon;
913 if ( *thearg == -SNUMBER && thearg[1] == 0 ) {
914 *term = 0;
return(0);
916 if ( *thearg == -SNUMBER && thearg[1] == 1 ) { }
919 *out++ = EXPONENT; out++; *out++ = 1; FILLFUN3(out);
920 COPY1ARG(out,thearg);
921 *out++ = -SNUMBER; *out++ = 1;
926 if ( RunDropArg(BHEAD fun,args) )
goto abo;
930 if ( RunSelectArg(BHEAD fun,args) )
goto abo;
935 WORD s = RunZtoHArg(BHEAD fun,args);
936 if ( s < 0 )
goto abo;
937 if ( s == 1 ) sign = -sign;
943 WORD s = RunHtoZArg(BHEAD fun,args);
944 if ( s < 0 )
goto abo;
945 if ( s == 1 ) sign = -sign;
951 MLOCK(ErrorMessageLock);
952 MesPrint(
"!>Irregular code in execution of transform statement");
953 MUNLOCK(ErrorMessageLock);
957 onetransform += *onetransform;
958 }
while ( *onetransform );
961 while ( funs < endfun ) {
962 if ( *funs > MAXVARIABLES ) {
963 if ( *t == *funs-MAXVARIABLES )
goto hit;
966 w = SetElements + Sets[*funs].first;
967 m = SetElements + Sets[*funs].last;
969 if ( *w == *t )
goto hit;
981 tt = term + *term;
while ( in < tt ) *out++ = *in++;
982 if ( sign == -1 ) out[-1] = -out[-1];
990 MLOCK(ErrorMessageLock);
991 MesCall(
"RunTransform");
992 MUNLOCK(ErrorMessageLock);
1008int RunEncode(PHEAD WORD *fun, WORD *args, WORD *info)
1010 WORD base, *f, *funstop, *fun1, *t, size1, size2, size3, *arg;
1011 int num, num1, num2, n, i, i1, i2;
1012 UWORD *scrat1, *scrat2, *scrat3;
1013 WORD *tt, *tstop, totarg, arg1, arg2;
1014 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1015 if ( *args != ARGRANGE ) {
1016 MLOCK(ErrorMessageLock);
1017 MesPrint(
"Illegal range encountered in RunEncode");
1018 MUNLOCK(ErrorMessageLock);
1021 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1022 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1023 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1024 if ( arg1 > totarg || arg2 > totarg )
return(0);
1026 if ( info[2] == BASECODE ) {
1030 base = DolToNumber(BHEAD i1);
1031 if ( AN.ErrorInDollar || base < 2 ) {
1032 MLOCK(ErrorMessageLock);
1033 MesPrint(
"$%s does not have a number value > 1 in base/encode/transform statement in module %l",
1034 DOLLARNAME(Dollars,i1),AC.CModule);
1035 MUNLOCK(ErrorMessageLock);
1042 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1043 else { num1 = arg1; num2 = arg2; }
1045 WantAddPointers(num);
1049 n = 1; funstop = fun+fun[1]; f = fun+FUNHEAD;
1050 while ( n < num1 ) {
1051 if ( f >= funstop )
return(0);
1056 while ( n <= num2 ) {
1057 if ( f >= funstop )
return(0);
1058 if ( *f != -SNUMBER ) {
1059 if ( *f < 0 )
return(0);
1062 if ( (*f-i1) != (ARGHEAD+1) )
return(0);
1066 if ( *t != 0 )
return(0);
1070 AT.pWorkSpace[AT.pWorkPointer+i] = f;
1079 if ( arg1 > arg2 ) {
1082 t = AT.pWorkSpace[AT.pWorkPointer+i1];
1083 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
1084 AT.pWorkSpace[AT.pWorkPointer+i2] = t;
1096 scrat1 = NumberMalloc(
"RunEncode");
1097 scrat2 = NumberMalloc(
"RunEncode");
1098 scrat3 = NumberMalloc(
"RunEncode");
1099 arg = AT.pWorkSpace[AT.pWorkPointer];
1100 size1 = PutArgInScratch(arg,scrat1);
1103 if ( MulLong(scrat1,size1,(UWORD *)(&base),1,scrat2,&size2) ) {
1104 NumberFree(scrat3,
"RunEncode");
1105 NumberFree(scrat2,
"RunEncode");
1106 NumberFree(scrat1,
"RunEncode");
1110 size3 = PutArgInScratch(arg,scrat3);
1111 if ( AddLong(scrat2,size2,scrat3,size3,scrat1,&size1) ) {
1112 NumberFree(scrat3,
"RunEncode");
1113 NumberFree(scrat2,
"RunEncode");
1114 NumberFree(scrat1,
"RunEncode");
1127 *fun1++ = -SNUMBER; *fun1++ = 0;
1128 while ( f < funstop ) *fun1++ = *f++;
1129 fun[1] = funstop-fun;
1131 else if ( size1 == 1 && scrat1[0] <= MAXPOSITIVE ) {
1132 *fun1++ = -SNUMBER; *fun1++ = scrat1[0];
1133 while ( f < funstop ) *fun1++ = *f++;
1136 else if ( size1 == -1 && scrat1[0] <= MAXPOSITIVE+1 ) {
1138 if ( scrat1[0] < MAXPOSITIVE ) *fun1++ = scrat1[0];
1139 else *fun1++ = (WORD)(MAXPOSITIVE+1);
1140 while ( f < funstop ) *fun1++ = *f++;
1143 else if ( ABS(size1)*2+2+ARGHEAD <= f-fun1 ) {
1144 if ( size1 < 0 ) { size2 = size1*2-1; size1 = -size1; size3 = -size2; }
1145 else { size2 = 2*size1+1; size3 = size2; }
1146 *fun1++ = size3+ARGHEAD+1;
1147 *fun1++ = 0; FILLARG(fun1);
1149 for ( i = 0; i < size1; i++ ) *fun1++ = scrat1[i];
1151 for ( i = 1; i < size1; i++ ) *fun1++ = 0;
1153 while ( f < funstop ) *fun1++ = *f++;
1158 if ( size1 < 0 ) { size2 = size1*2-1; size1 = -size1; size3 = -size2; }
1159 else { size2 = 2*size1+1; size3 = size2; }
1160 *t++ = size3+ARGHEAD+1;
1161 *t++ = 0; FILLARG(t);
1163 for ( i = 0; i < size1; i++ ) *t++ = scrat1[i];
1165 for ( i = 1; i < size1; i++ ) *t++ = 0;
1167 while ( f < funstop ) *t++ = *f++;
1169 while ( f < t ) *fun1++ = *f++;
1172 NumberFree(scrat3,
"RunEncode");
1173 NumberFree(scrat2,
"RunEncode");
1174 NumberFree(scrat1,
"RunEncode");
1178 MLOCK(ErrorMessageLock);
1179 MesPrint(
"!>Unimplemented type of encoding encountered in RunEncode");
1180 MUNLOCK(ErrorMessageLock);
1186 MLOCK(ErrorMessageLock);
1187 MesCall(
"RunEncode");
1188 MUNLOCK(ErrorMessageLock);
1197int RunDecode(PHEAD WORD *fun, WORD *args, WORD *info)
1199 WORD base, num, num1, num2, n, *f, *funstop, *fun1, size1, size2, size3, *t;
1200 WORD i1, i2, i, sig;
1201 UWORD *scrat1, *scrat2, *scrat3;
1202 WORD *tt, *tstop, totarg, arg1, arg2;
1203 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1204 if ( *args != ARGRANGE ) {
1205 MLOCK(ErrorMessageLock);
1206 MesPrint(
"Illegal range encountered in RunDecode");
1207 MUNLOCK(ErrorMessageLock);
1210 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1211 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1212 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1213 if ( arg1 > totarg && arg2 > totarg )
return(0);
1214 if ( info[2] == BASECODE ) {
1218 base = DolToNumber(BHEAD i1);
1219 if ( AN.ErrorInDollar || base < 2 ) {
1220 MLOCK(ErrorMessageLock);
1221 MesPrint(
"$%s does not have a number value > 1 in base/decode/transform statement in module %l",
1222 DOLLARNAME(Dollars,i1),AC.CModule);
1223 MUNLOCK(ErrorMessageLock);
1230 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1231 else { num1 = arg1; num2 = arg2; }
1233 if ( num <= 1 )
return(0);
1237 funstop = fun + fun[1];
1238 f = fun + FUNHEAD; n = 1;
1239 while ( f < funstop ) {
1240 if ( n == num1 )
break;
1243 if ( f >= funstop )
return(0);
1247 if ( *f == -SNUMBER ) {}
1248 else if ( *f < 0 )
return(0);
1252 if ( (*f-i1) != (ARGHEAD+1) )
return(0);
1256 if ( *t != 0 )
return(0);
1265 scrat1 = NumberMalloc(
"RunEncode");
1266 scrat2 = NumberMalloc(
"RunEncode");
1267 scrat3 = NumberMalloc(
"RunEncode");
1268 size1 = PutArgInScratch(fun1,scrat1);
1269 if ( size1 < 0 ) { sig = -1; size1 = -size1; }
1274 scrat2[0] = base; size2 = 1;
1275 if ( RaisPow(BHEAD scrat2,&size2,num) ) {
1276 NumberFree(scrat3,
"RunEncode");
1277 NumberFree(scrat2,
"RunEncode");
1278 NumberFree(scrat1,
"RunEncode");
1281 if ( BigLong(scrat1,size1,scrat2,size2) >= 0 ) {
1282 NumberFree(scrat3,
"RunEncode");
1283 NumberFree(scrat2,
"RunEncode");
1284 NumberFree(scrat1,
"RunEncode");
1290 if ( *fun1 > num*2 ) {
1291 t = fun1 + 2*num; f = fun1 + *fun1;
1292 while ( f < funstop ) *t++ = *f++;
1295 else if ( *fun1 < num*2 ) {
1297 fun[1] += (num-1)*2;
1298 t = funstop + (num-1)*2;
1301 fun[1] += 2*num - *fun1;
1302 t = funstop +2*num - *fun1;
1305 while ( f > fun1 ) *--t = *--f;
1310 for ( i = num-1; i >= 0; i-- ) {
1311 DivLong(scrat1,size1,(UWORD *)(&base),1,scrat2,&size2,scrat3,&size3);
1312 fun1[2*i] = -SNUMBER;
1313 if ( size3 == 0 ) fun1[2*i+1] = 0;
1314 else fun1[2*i+1] = (WORD)(scrat3[0])*sig;
1315 for ( i1 = 0; i1 < size2; i1++ ) scrat1[i1] = scrat2[i1];
1319 MLOCK(ErrorMessageLock);
1320 MesPrint(
"RunDecode: number to be decoded is too big");
1321 MUNLOCK(ErrorMessageLock);
1322 NumberFree(scrat3,
"RunEncode");
1323 NumberFree(scrat2,
"RunEncode");
1324 NumberFree(scrat1,
"RunEncode");
1330 if ( arg1 > arg2 ) {
1331 i1 = 1; i2 = 2*num-1;
1333 i = fun1[i1]; fun1[i1] = fun1[i2]; fun1[i2] = i;
1337 NumberFree(scrat3,
"RunEncode");
1338 NumberFree(scrat2,
"RunEncode");
1339 NumberFree(scrat1,
"RunEncode");
1343 MLOCK(ErrorMessageLock);
1344 MesPrint(
"!>Unimplemented type of encoding encountered in RunDecode");
1345 MUNLOCK(ErrorMessageLock);
1351 MLOCK(ErrorMessageLock);
1352 MesCall(
"RunDecode");
1353 MUNLOCK(ErrorMessageLock);
1369int RunReplace(PHEAD WORD *fun, WORD *args, WORD *info)
1371 int n = 0, i, dirty = 0, totarg, nfix, nwild, ngeneral;
1372 WORD *t, *tt, *u, *tstop, *info1, *infoend, *oldwork = AT.WorkPointer;
1373 WORD *term, *newterm, *nt, *term1, *term2;
1374 WORD wild[4], mask, *term3, *term4, *oldmask = AT.WildMask;
1375 WORD n1, n2, doanyway;
1377 t = fun; tstop = fun + fun[1]; u = tstop;
1378 for ( i = 0; i < FUNHEAD; i++ ) *u++ = *t++;
1380 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1382 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1385 totarg = tstop - tt;
1394 AT.WorkPointer += 2*AM.MaxTer;
1395 if ( AT.WorkPointer > AT.WorkTop ) {
1396 MLOCK(ErrorMessageLock);
1398 MUNLOCK(ErrorMessageLock);
1401 term = AT.WorkPointer;
1402 for ( i = 0; i < *info; i++ ) term[i] = info[i];
1403 AT.WorkPointer = term + *term;
1406 if (
Generator(BHEAD term,AR.Cnumlhs) ) {
1408 AT.WorkPointer = oldwork;
1411 newterm = AT.WorkPointer;
1412 if (
EndSort(BHEAD newterm,1) < 0 ) {}
1413 if ( ( *newterm && *(newterm+*newterm) != 0 ) || *newterm == 0 ) {
1414 MLOCK(ErrorMessageLock);
1415 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1416 MUNLOCK(ErrorMessageLock);
1420 i = *newterm; tt = term; nt = newterm;
1422 AT.WorkPointer = term + *term;
1425 term1 = term + *term;
1427 *term2++ = REPLACEMENT;
1428 term2++; FILLFUN(term2)
1432 infoend = info + info[1];
1433 info1 = info + FUNHEAD;
1434 nfix = nwild = ngeneral = 0;
1435 while ( info1 < infoend ) {
1436 if ( *info1 == -SNUMBER ) {
1438 info1 += 2; NEXTARG(info1)
1440 else if ( *info1 <= -FUNCTION ) {
1441 if ( *info1 == -WILDARGFUN ) {
1443 info1++; NEXTARG(info1)
1446 *term2++ = *info1++; COPY1ARG(term2,info1)
1450 else if ( *info1 == -INDEX ) {
1451 if ( info1[1] == WILDARGINDEX + AM.OffsetIndex ) {
1453 info1 += 2; NEXTARG(info1)
1456 *term2++ = *info1++; *term2++ = *info1++; COPY1ARG(term2,info1)
1460 else if ( *info1 == -SYMBOL ) {
1461 if ( info1[1] == WILDARGSYMBOL ) {
1463 info1 += 2; NEXTARG(info1)
1466 *term2++ = *info1++; *term2++ = *info1++; COPY1ARG(term2,info1)
1470 else if ( *info1 == -MINVECTOR || *info1 == -VECTOR ) {
1471 if ( info1[1] == WILDARGVECTOR + AM.OffsetVector ) {
1473 info1 += 2; NEXTARG(info1)
1476 *term2++ = *info1++; *term2++ = *info1++; COPY1ARG(term2,info1)
1482 MLOCK(ErrorMessageLock);
1483 MesPrint(
"!>irregular code found in replace transformation (RunReplace)");
1484 MUNLOCK(ErrorMessageLock);
1489 AT.WorkPointer = term2;
1490 *term1 = term2 - term1;
1491 term1[2] = *term1 - 1;
1495 while ( t < tstop ) {
1497 if ( TestArgNum(n,totarg,args) == 0 ) {
1498 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1499 if ( *t <= -FUNCTION ) { *u++ = *t++; }
1500 else if ( *t < 0 ) { *u++ = *t++; *u++ = *t++; }
1501 else { i = *t; NCOPY(u,t,i) }
1517 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1518 if ( *t == -SNUMBER ) {
1519 info1 = info + FUNHEAD;
1520 while ( info1 < infoend ) {
1521 if ( *info1 == -SNUMBER ) {
1522 if ( info1[1] == t[1] ) {
1523 if ( info1[2] == -SNUMBER ) {
1524 *u++ = -SNUMBER; *u++ = info1[3];
1529 if ( info1[0] <= -FUNCTION ) i = 1;
1530 else if ( info1[0] < 0 ) i = 2;
1548 doanyway = 1; n2 = t[1];
1552 if ( *t < AM.OffsetIndex && *t >= 0 ) {
1553 info1 = info + FUNHEAD;
1554 while ( info1 < infoend ) {
1555 if ( ( *info1 == -SNUMBER ) && ( info1[1] == *t )
1556 && ( ( ( info1[2] == -SNUMBER ) && ( info1[3] >= 0 )
1557 && ( info1[3] < AM.OffsetIndex ) )
1558 || ( info1[2] == -INDEX || info1[2] == -VECTOR
1559 || info1[2] == -MINVECTOR ) ) ) {
1572 else if ( *t == -SNUMBER ) {
1573 doanyway = 1; n2 = t[1];
1581 if ( ngeneral > 0 ) {
1582 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1584 term3 = term1 + *term1;
1585 term4 = term1 + FUNHEAD;
1586 while ( term4 < term3 ) {
1587 if ( *term4 == *t && ( *t <= -FUNCTION ||
1588 ( t[1] == term4[1] ) ) )
break;
1591 if ( term4 < term3 )
goto dothisnow;
1595 term3 = term1 + *term1;
1596 term4 = term1 + FUNHEAD;
1597 while ( term4 < term3 ) {
1598 if ( ( term4[1] == *t ) &&
1599 ( ( *term4 == -INDEX || *term4 == -VECTOR ||
1600 ( *term4 == -SYMBOL && term4[1] < AM.OffsetIndex
1601 && term4[1] >= 0 ) ) ) )
break;
1604 if ( term4 < term3 )
goto dothisnow;
1621 info1 = info + FUNHEAD;
1622 while ( info1 < infoend ) {
1623 if ( *info1 == -SYMBOL && info1[1] == WILDARGSYMBOL
1624 && ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) ) {
1626 wild[2] = WILDARGSYMBOL;
1628 AN.WildValue = wild;
1629 AN.WildStop = wild + wild[1];
1630 AT.WildMask = &mask;
1633 if ( *t == -SYMBOL || ( *t > 0 && CheckWild(BHEAD WILDARGSYMBOL,SYMTOSUB,1,t) == 0 )
1639 n1 = SYMBOL; n2 = WILDARGSYMBOL;
1643 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1644 *term3++ = DUMFUN; term3++; FILLFUN(term3)
1645 COPY1ARG(term3,info1)
1648 *term3++ = fun[0]; term3++; FILLFUN(term3)
1651 term2[2] = term3 - term2 - 1;
1653 *term3++ = REPLACEMENT;
1654 term3++; FILLFUN(term3)
1656 if ( n1 < FUNCTION ) *term3++ = n2;
1657 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1659 COPY1ARG(term3,term4)
1665 *term3++ = 1; *term3++ = 1; *term3++ = 3;
1666 *term2 = term3 - term2;
1668 AT.WorkPointer = term3;
1670 if (
Generator(BHEAD term2,AR.Cnumlhs) ) {
1672 AT.WorkPointer = oldwork;
1673 AT.WildMask = oldmask;
1676 term4 = AT.WorkPointer;
1677 if (
EndSort(BHEAD term4,1) < 0 ) {}
1678 if ( ( *term4 && *(term4+*term4) != 0 ) || *term4 == 0 ) {
1679 MLOCK(ErrorMessageLock);
1680 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1681 MUNLOCK(ErrorMessageLock);
1687 i = term4[2]-FUNHEAD;
1688 term3 = term4+FUNHEAD+1;
1690 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1694 AT.WorkPointer = term2;
1698 info1 += 2; NEXTARG(info1)
1700 else if ( ( *info1 == -INDEX )
1701 && ( info[1] == WILDARGINDEX + AM.OffsetIndex ) ) {
1703 wild[2] = WILDARGINDEX+AM.OffsetIndex;
1705 AN.WildValue = wild;
1706 AN.WildStop = wild + wild[1];
1707 AT.WildMask = &mask;
1710 if ( ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION )
1711 || ( *t == -INDEX || ( *t > 0 && CheckWild(BHEAD WILDARGINDEX,INDTOSUB,1,t) == 0 ) ) ) {
1716 n1 = INDEX; n2 = WILDARGINDEX+AM.OffsetIndex;
1720 info1 += 2; NEXTARG(info1)
1722 else if ( ( *info1 == -VECTOR )
1723 && ( info1[1] == WILDARGVECTOR + AM.OffsetVector ) ) {
1725 wild[2] = WILDARGVECTOR+AM.OffsetVector;
1727 AN.WildValue = wild;
1728 AN.WildStop = wild + wild[1];
1729 AT.WildMask = &mask;
1732 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
1733 if ( *t < MINSPEC ) {
1734 n1 = VECTOR; n2 = WILDARGVECTOR+AM.OffsetVector;
1739 else if ( *t == -VECTOR || *t == -MINVECTOR ||
1740 ( *t > 0 && CheckWild(BHEAD WILDARGVECTOR,VECTOSUB,1,t) == 0 ) ) {
1745 n1 = VECTOR; n2 = WILDARGVECTOR+AM.OffsetVector;
1749 info1 += 2; NEXTARG(info1)
1751 else if ( *info1 == -WILDARGFUN ) {
1753 wild[2] = WILDARGFUN;
1755 AN.WildValue = wild;
1756 AN.WildStop = wild + wild[1];
1757 AT.WildMask = &mask;
1760 if ( *t <= -FUNCTION || ( *t > 0 && CheckWild(BHEAD WILDARGFUN,FUNTOFUN,1,t) == 0 ) ) {
1765 n2 = n1 = -WILDARGFUN;
1769 info1++; NEXTARG(info1)
1772 NEXTARG(info1) NEXTARG(info1)
1776 if ( ngeneral > 0 ) {
1784 term3 = term2; term4 = term1; i = *term1;
1785 NCOPY(term3,term4,i)
1787 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1788 *term3++ = DUMFUN; term3++; FILLFUN(term3);
1793 *term3++ = fun[0]; term3++; FILLFUN(term3); *term3++ = *t;
1795 term4[1] = term3-term4;
1796 *term3++ = 1; *term3++ = 1; *term3++ = 3;
1797 *term2 = term3-term2;
1798 AT.WorkPointer = term3;
1800 if (
Generator(BHEAD term2,AR.Cnumlhs) ) {
1802 AT.WorkPointer = oldwork;
1803 AT.WildMask = oldmask;
1806 term4 = AT.WorkPointer;
1807 if (
EndSort(BHEAD term4,1) < 0 ) {}
1808 if ( ( *term4 && *(term4+*term4) != 0 ) || *term4 == 0 ) {
1809 MLOCK(ErrorMessageLock);
1810 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1811 MUNLOCK(ErrorMessageLock);
1817 i = term4[2]-FUNHEAD;
1818 term3 = term4+FUNHEAD+1;
1821 AT.WorkPointer = term2;
1829 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1830 if ( *t <= -FUNCTION ) { *u++ = *t++; }
1831 else if ( *t < 0 ) { *u++ = *t++; *u++ = *t++; }
1832 else { i = *t; NCOPY(u,t,i) }
1839 i = u - tstop; tstop[1] = i; tstop[2] = dirty;
1840 t = fun; u = tstop; NCOPY(t,u,i)
1841 AT.WorkPointer = oldwork;
1842 AT.WildMask = oldmask;
1853int RunImplode(WORD *fun, WORD *args)
1856 WORD *tt, *tstop, totarg, arg1, arg2, num1, num2, i1, n;
1857 WORD *f, *t, *ttt, *t4, *ff, *fff;
1858 WORD moveup, numzero, outspace;
1859 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1860 if ( *args != ARGRANGE ) {
1861 MLOCK(ErrorMessageLock);
1862 MesPrint(
"Illegal range encountered in RunImplode");
1863 MUNLOCK(ErrorMessageLock);
1866 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1867 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1868 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1872 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1873 else { num1 = arg1; num2 = arg2; }
1874 if ( num1 > totarg || num2 > totarg )
return(0);
1880 n = 1; f = fun+FUNHEAD;
1881 while ( n < num1 ) {
1882 if ( f >= tstop )
return(0);
1898 while ( n <= num2 ) {
1899 if ( f >= tstop )
return(0);
1900 if ( *f == -SNUMBER ) { *tt++ = -1; *tt++ = 0;
1901 if ( f[1] < 0 ) { *tt++ = -f[1]; *tt++ = -1; }
1902 else { *tt++ = f[1]; *tt++ = 1; }
1905 else if ( *f == -SYMBOL ) { *tt++ = f[1]; *tt++ = 1; *tt++ = 1; *tt++ = 1; f += 2; }
1906 else if ( *f < 0 )
return(0);
1908 if ( *f != ( f[ARGHEAD]+ARGHEAD ) )
return(0);
1911 if ( ( i1 > 3 ) || ( t[-1] != 1 ) )
return(0);
1912 if ( (UWORD)(t[-2]) > MAXPOSITIVE4 )
return(0);
1913 if ( f[ARGHEAD] == i1+1 ) {
1914 *tt++ = -1; *tt++ = 0; *tt++ = t[-2];
1915 if ( *t < 0 ) { *tt++ = -1; }
1918 else if ( ( f[ARGHEAD+1] != SYMBOL )
1919 || ( f[ARGHEAD+2] != 4 )
1920 || ( ( f+ARGHEAD+1+f[ARGHEAD+2] ) < ( t-i1 ) ) )
return(0);
1923 *tt++ = f[ARGHEAD+3];
1924 *tt++ = f[ARGHEAD+4];
1926 if ( *t < 0 ) { *tt++ = -1; }
1939 if ( arg1 > arg2 ) {
1943 t = tt - 4; numzero = 0;
1944 while ( t >= tstop ) {
1945 if ( t[2] == 0 ) numzero++;
1947 if ( numzero > 0 ) {
1950 ttt = t4 + 4*numzero;
1951 while ( ttt < tt ) *t4++ = *ttt++;
1961 numzero = 0; ttt = t;
1963 if ( t[2] == 0 ) numzero++;
1965 if ( numzero > 0 ) {
1968 while ( t4 < tt ) *ttt++ = *t4++;
1988 t = tstop; outspace = 0;
1991 if ( t[2] > MAXPOSITIVE4 ) {
return(0); }
1994 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) { outspace += 2; }
1995 else { outspace += 8 + ARGHEAD; }
1998 if ( outspace < (fff-ff) ) {
2001 if ( t[0] == -1 ) { *ff++ = -SNUMBER; *ff++ = t[2]*t[3]; }
2002 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) {
2003 *ff++ = -SYMBOL; *ff++ = t[0];
2006 *ff++ = 8+ARGHEAD; *ff++ = 0; FILLARG(ff);
2007 *ff++ = 8; *ff++ = SYMBOL; *ff++ = 4; *ff++ = t[0]; *ff++ = t[1];
2008 *ff++ = t[2]; *ff++ = 1; *ff++ = t[3] > 0 ? 3: -3;
2012 while ( fff < tstop ) *ff++ = *fff++;
2015 else if ( outspace > (fff-ff) ) {
2021 moveup = outspace-(fff-ff);
2024 while ( t > fff ) *--ttt = *--t;
2025 tt += moveup; tstop += moveup;
2034 if ( t[0] == -1 ) { *ff++ = -SNUMBER; *ff++ = t[2]*t[3]; }
2035 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) {
2036 *ff++ = -SYMBOL; *ff++ = t[0];
2039 *ff++ = 8+ARGHEAD; *ff++ = 0; FILLARG(ff);
2040 *ff++ = 8; *ff++ = SYMBOL; *ff++ = 4; *ff++ = t[0]; *ff++ = t[1];
2041 *ff++ = t[2]; *ff++ = 1; *ff++ = t[3] > 0 ? 3: -3;
2054int RunExplode(PHEAD WORD *fun, WORD *args)
2056 WORD arg1, arg2, num1, num2, *tt, *tstop, totarg, *tonew, *newfun;
2058 int reverse = 0, iarg, i, numzero;
2059 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
2060 if ( *args != ARGRANGE ) {
2061 MLOCK(ErrorMessageLock);
2062 MesPrint(
"Illegal range encountered in RunExplode");
2063 MUNLOCK(ErrorMessageLock);
2066 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2067 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2068 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2072 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; reverse = 1; }
2073 else { num1 = arg1; num2 = arg2; }
2074 if ( num1 > totarg || num2 > totarg )
return(0);
2075 if ( tstop + AM.MaxTer > AT.WorkTop )
goto OverWork;
2080 tonew = newfun = tstop;
2081 ff = fun + FUNHEAD; iarg = 0;
2082 while ( ff < tstop ) {
2084 if ( iarg == num1 ) {
2085 i = ff - fun; f = fun;
2094 while ( iarg <= num2 ) {
2095 if ( *ff == -SYMBOL || ( *ff == -SNUMBER && ff[1] == 0 ) )
2096 { *tonew++ = *ff++; *tonew++ = *ff++; }
2097 else if ( *ff == -SNUMBER ) {
2098 numzero = ABS(ff[1])-1;
2100 *tonew++ = -SNUMBER; *tonew++ = ff[1] < 0 ? -1: 1;
2101 while ( numzero > 0 ) {
2102 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2106 while ( numzero > 0 ) {
2107 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2109 *tonew++ = -SNUMBER; *tonew++ = ff[1] < 0 ? -1: 1;
2113 else if ( *ff < 0 ) {
return(0); }
2115 if ( *ff != ARGHEAD+8 || ff[ARGHEAD] != 8
2116 || ff[ARGHEAD+1] != SYMBOL || ABS(ff[ARGHEAD+7]) != 3
2117 || ff[ARGHEAD+6] != 1 )
return(0);
2118 numzero = ff[ARGHEAD+5];
2119 if ( numzero >= MAXPOSITIVE4 )
return(0);
2122 if ( ff[ARGHEAD+7] > 0 ) { *tonew++ = -SNUMBER; *tonew++ = 1; }
2124 *tonew++ = ARGHEAD+8; *tonew++ = 0; FILLARG(tonew)
2125 *tonew++ = 8; *tonew++ = SYMBOL; *tonew++ = ff[ARGHEAD+3];
2126 *tonew++ = ff[ARGHEAD+4]; *tonew++ = 1; *tonew++ = 1;
2129 while ( numzero > 0 ) {
2130 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2134 while ( numzero > 0 ) {
2135 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2137 *tonew++ = ARGHEAD+8; *tonew++ = 0; FILLARG(tonew)
2138 *tonew++ = 8; *tonew++ = SYMBOL; *tonew++ = 4;
2139 *tonew++ = ff[ARGHEAD+3]; *tonew++ = ff[ARGHEAD+4];
2140 *tonew++ = 1; *tonew++ = 1;
2141 if ( ff[ARGHEAD+7] > 0 ) *tonew++ = 3;
2146 if ( tonew > AT.WorkTop )
goto OverWork;
2152 while ( ff < tstop ) *tonew++ = *ff++;
2153 i = newfun[1] = tonew-newfun;
2157 MLOCK(ErrorMessageLock);
2159 MUNLOCK(ErrorMessageLock);
2168int RunPermute(PHEAD WORD *fun, WORD *args, WORD *info)
2170 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, *f, *f1, *f2, *infostop;
2171 WORD *in, *iw, withdollar;
2173 if ( *args != ARGRANGE ) {
2174 MLOCK(ErrorMessageLock);
2175 MesPrint(
"Illegal range encountered in RunPermute");
2176 MUNLOCK(ErrorMessageLock);
2179 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2180 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2181 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2182 arg1 = 1; arg2 = totarg;
2191 WantAddPointers(num);
2192 f = fun+FUNHEAD; n = 1; i = 0;
2193 while ( n < arg1 ) { n++; NEXTARG(f) }
2195 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2201 infostop = info + *info;
2203 if ( *info > totarg )
return(0);
2208 withdollar = 0; in = info;
2209 while ( in < infostop ) {
2211 d = Dollars - *in - 1;
2214 int nummodopt, dtype = -1, numdollar = -*in-1;
2215 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2216 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2217 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2219 if ( nummodopt < NumModOptdollars ) {
2220 dtype = ModOptdollars[nummodopt].type;
2221 if ( DollarLocalCopy(dtype) ) {
2222 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2225 LOCK(d->pthreadslock);
2231 if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2232 && d->where[0] == 4 && d->where[4] == 0 ) {
2233 if ( d->where[3] < 0 || d->where[2] != 1 || d->where[1] > totarg )
return(0);
2235 else if ( d->type == DOLWILDARGS ) {
2238 if ( *iw == -SNUMBER ) {
2239 if ( iw[1] <= 0 || iw[1] > totarg )
return(0);
2247 MLOCK(ErrorMessageLock);
2248 MesPrint(
"Illegal type of $-variable in RunPermute");
2249 MUNLOCK(ErrorMessageLock);
2254 else if ( *in > totarg )
return(0);
2258 WORD *incopy, *tocopy;
2259 incopy = TermMalloc(
"RunPermute");
2260 tocopy = incopy+1; in = info;
2261 while ( in < infostop ) {
2263 d = Dollars - *in - 1;
2266 int nummodopt, dtype = -1, numdollar = -*in-1;
2267 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2268 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2269 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2271 if ( nummodopt < NumModOptdollars ) {
2272 dtype = ModOptdollars[nummodopt].type;
2273 if ( DollarLocalCopy(dtype) ) {
2274 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2277 LOCK(d->pthreadslock);
2283 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
2284 *tocopy++ = d->where[1] - 1;
2286 else if ( d->type == DOLWILDARGS ) {
2289 *tocopy++ = iw[1] - 1;
2295 else *tocopy++ = *in++;
2298 *incopy = tocopy - incopy;
2300 tt = AT.pWorkSpace[AT.pWorkPointer+*in];
2302 while ( in < tocopy ) {
2303 if ( *in > totarg )
return(0);
2304 AT.pWorkSpace[AT.pWorkPointer+in[-1]] = AT.pWorkSpace[AT.pWorkPointer+*in];
2307 AT.pWorkSpace[AT.pWorkPointer+in[-1]] = tt;
2308 TermFree(incopy,
"RunPermute");
2312 tt = AT.pWorkSpace[AT.pWorkPointer+*info];
2314 while ( info < infostop ) {
2315 if ( *info > totarg )
return(0);
2316 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = AT.pWorkSpace[AT.pWorkPointer+*info];
2319 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = tt;
2341 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2343 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2348 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop-tt;
2349 arg1 = 1; arg2 = totarg;
2351 WantAddPointers(num);
2352 f = fun+FUNHEAD; n = 1; i = 0;
2353 while ( n < arg1 ) { n++; f++; }
2355 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2361 infostop = info + *info;
2363 if ( *info > totarg )
return(0);
2364 tt = AT.pWorkSpace[AT.pWorkPointer+*info];
2366 while ( info < infostop ) {
2367 if ( *info > totarg )
return(0);
2368 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = AT.pWorkSpace[AT.pWorkPointer+*info];
2371 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = tt;
2376 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2378 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++= *f++; }
2384 MLOCK(ErrorMessageLock);
2386 MUNLOCK(ErrorMessageLock);
2395int RunReverse(PHEAD WORD *fun, WORD *args)
2397 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, *f, *f1, *f2, i1, i2;
2398 if ( *args != ARGRANGE ) {
2399 MLOCK(ErrorMessageLock);
2400 MesPrint(
"Illegal range encountered in RunReverse");
2401 MUNLOCK(ErrorMessageLock);
2404 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2405 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2406 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2407 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2415 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2416 if ( arg2 > totarg )
return(0);
2419 WantAddPointers(num);
2420 f = fun+FUNHEAD; n = 1; i = 0;
2421 while ( n < arg1 ) { n++; NEXTARG(f) }
2423 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2426 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2427 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2428 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2431 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2433 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2438 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2439 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2447 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2448 if ( arg2 > totarg )
return(0);
2451 WantAddPointers(num);
2452 f = fun+FUNHEAD; n = 1; i = 0;
2453 while ( n < arg1 ) { n++; f++; }
2455 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2458 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2459 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2460 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2463 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2465 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++ = *f++; }
2471 MLOCK(ErrorMessageLock);
2473 MUNLOCK(ErrorMessageLock);
2482int RunDedup(PHEAD WORD *fun, WORD *args)
2484 WORD *tt, totarg, *tstop, arg1, arg2, n, i, j,k, *f, *f1, *f2, *fd, *fstart;
2485 if ( *args != ARGRANGE ) {
2486 MLOCK(ErrorMessageLock);
2487 MesPrint(
"Illegal range encountered in RunDedup");
2488 MUNLOCK(ErrorMessageLock);
2491 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2492 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2493 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2494 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2496 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2497 if ( arg2 > totarg )
return(0);
2499 f = fun+FUNHEAD; n = 1;
2500 while ( n < arg1 ) { n++; NEXTARG(f) }
2505 for (; n <= arg2; n++ ) {
2507 for ( j = 0; j < i; j++ ) {
2510 for ( k = 0; k < fd-f2; k++ )
2511 if ( f2[k] != f[k] )
break;
2513 if ( k == fd-f2 )
break;
2527 for (j = n; j <= totarg; j++) {
2534 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2535 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2537 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2538 if ( arg2 > totarg )
return(0);
2544 for (; n <= arg2; n++ ) {
2545 for ( j = arg1; j < i; j++ ) {
2546 if ( f[n-1] == f[j-1] )
break;
2557 for (j = n; j <= totarg; j++, i++) {
2561 fun[1] = f + i - 1 - fun;
2571int RunCycle(PHEAD WORD *fun, WORD *args, WORD *info)
2573 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, j, *f, *f1, *f2, x, ncyc, cc;
2574 if ( *args != ARGRANGE ) {
2575 MLOCK(ErrorMessageLock);
2576 MesPrint(
"Illegal range encountered in RunCycle");
2577 MUNLOCK(ErrorMessageLock);
2581 if ( ncyc >= MAXPOSITIVE2 ) {
2582 ncyc -= MAXPOSITIVE2;
2583 if ( ncyc >= MAXPOSITIVE4 ) {
2584 ncyc -= MAXPOSITIVE4;
2588 ncyc = DolToNumber(BHEAD ncyc);
2589 if ( AN.ErrorInDollar ) {
2590 MesPrint(
" Error in Dollar variable in transform,cycle()=$");
2593 if ( ncyc >= MAXPOSITIVE4 || ncyc <= -MAXPOSITIVE4 ) {
2594 MesPrint(
" Illegal value from Dollar variable in transform,cycle()=$");
2599 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2600 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2601 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2602 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2603 if ( arg1 > arg2 ) { n = arg1; arg1 = arg2; arg2 = n; }
2604 if ( arg2 > totarg )
return(0);
2613 WantAddPointers(num);
2614 f = fun+FUNHEAD; n = 1; i = 0;
2615 while ( n < arg1 ) { n++; NEXTARG(f) }
2617 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2624 if ( x > i/2 ) x -= i;
2626 else if ( x <= -i ) {
2628 if ( x <= -i/2 ) x += i;
2632 tt = AT.pWorkSpace[AT.pWorkPointer+i-1];
2633 for ( j = i-1; j > 0; j-- )
2634 AT.pWorkSpace[AT.pWorkPointer+j] = AT.pWorkSpace[AT.pWorkPointer+j-1];
2635 AT.pWorkSpace[AT.pWorkPointer] = tt;
2639 tt = AT.pWorkSpace[AT.pWorkPointer];
2640 for ( j = 1; j < i; j++ )
2641 AT.pWorkSpace[AT.pWorkPointer+j-1] = AT.pWorkSpace[AT.pWorkPointer+j];
2642 AT.pWorkSpace[AT.pWorkPointer+j-1] = tt;
2649 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2651 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2656 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2657 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2658 if ( arg1 > arg2 ) { n = arg1; arg1 = arg2; arg2 = n; }
2659 if ( arg2 > totarg )
return(0);
2668 WantAddPointers(num);
2669 f = fun+FUNHEAD; n = 1; i = 0;
2670 while ( n < arg1 ) { n++; f++; }
2672 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2679 if ( x > i/2 ) x -= i;
2681 else if ( x <= -i ) {
2683 if ( x <= -i/2 ) x += i;
2687 tt = AT.pWorkSpace[AT.pWorkPointer+i-1];
2688 for ( j = i-1; j > 0; j-- )
2689 AT.pWorkSpace[AT.pWorkPointer+j] = AT.pWorkSpace[AT.pWorkPointer+j-1];
2690 AT.pWorkSpace[AT.pWorkPointer] = tt;
2694 tt = AT.pWorkSpace[AT.pWorkPointer];
2695 for ( j = 1; j < i; j++ )
2696 AT.pWorkSpace[AT.pWorkPointer+j-1] = AT.pWorkSpace[AT.pWorkPointer+j];
2697 AT.pWorkSpace[AT.pWorkPointer+j-1] = tt;
2704 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2706 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++ = *f++; }
2712 MLOCK(ErrorMessageLock);
2714 MUNLOCK(ErrorMessageLock);
2723int RunAddArg(PHEAD WORD *fun, WORD *args)
2725 WORD *tt, totarg, *tstop, arg1, arg2, n, num, *f, *f1, *f2;
2726 WORD scribble[10+ARGHEAD];
2728 if ( *args != ARGRANGE ) {
2729 MLOCK(ErrorMessageLock);
2730 MesPrint(
"Illegal range encountered in RunAddArg");
2731 MUNLOCK(ErrorMessageLock);
2734 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
2735 MLOCK(ErrorMessageLock);
2736 MesPrint(
"Illegal attempt to add arguments of a tensor in AddArg");
2737 MUNLOCK(ErrorMessageLock);
2740 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2741 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2743 if ( totarg == 0 )
return(0);
2744 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2755 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2756 if ( arg2 > totarg )
return(0);
2758 if ( num == 1 )
return(0);
2759 f = fun+FUNHEAD; n = 1;
2760 while ( n < arg1 ) { n++; NEXTARG(f) }
2763 while ( n <= arg2 ) {
2765 f2 = f + *f; f += ARGHEAD;
2766 while ( f < f2 ) {
StoreTerm(BHEAD f); f += *f; }
2768 else if ( *f == -SNUMBER && f[1] == 0 ) {
2772 ToGeneral(f,scribble,1);
2778 if (
EndSort(BHEAD tstop+ARGHEAD,1) < 0 )
return(-1);
2781 while ( *f2 ) { f2 += *f2; num++; }
2783 for ( n = 1; n < ARGHEAD; n++ ) tstop[n] = 0;
2784 if ( num == 1 && ToFast(tstop,tstop) == 1 ) {
2785 f2 = tstop; NEXTARG(f2);
2787 if ( *tstop == ARGHEAD ) {
2788 *tstop = -SNUMBER; tstop[1] = 0;
2794 while ( f < tstop ) *f2++ = *f++;
2795 while ( f < f2 ) *f1++ = *f++;
2797 if ( (space+8)*
sizeof(WORD) > (UWORD)AM.MaxTer ) {
2798 MLOCK(ErrorMessageLock);
2800 MUNLOCK(ErrorMessageLock);
2803 fun[1] = (WORD)space;
2812int RunMulArg(PHEAD WORD *fun, WORD *args)
2814 WORD *t, totarg, *tstop, arg1, arg2, n, *f, nb, *m, i, *w;
2815 WORD *scratch, argbuf[20], argsize, *where, *newterm;
2816 LONG oldcpointer_pos;
2817 CBUF *C = cbuf + AT.ebufnum;
2818 if ( *args != ARGRANGE ) {
2819 MLOCK(ErrorMessageLock);
2820 MesPrint(
"Illegal range encountered in RunMulArg");
2821 MUNLOCK(ErrorMessageLock);
2824 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
2825 MLOCK(ErrorMessageLock);
2826 MesPrint(
"Illegal attempt to multiply arguments of a tensor in MulArg");
2827 MUNLOCK(ErrorMessageLock);
2830 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2831 while ( t < tstop ) { totarg++; NEXTARG(t); }
2833 if ( totarg == 0 )
return(0);
2834 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2835 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2836 if ( arg1 > totarg )
return(0);
2837 if ( arg2 < 1 )
return(0);
2838 if ( arg1 < 1 ) arg1 = 1;
2839 if ( arg2 > totarg ) arg2 = totarg;
2840 if ( arg1 == arg2 )
return(0);
2848 f = fun+FUNHEAD; n = 1;
2849 while ( n < arg1 ) { n++; NEXTARG(f) }
2851 if ( fun >= AT.WorkSpace && fun < AT.WorkTop ) {
2852 if ( AT.WorkPointer < fun+fun[1] ) AT.WorkPointer = fun+fun[1];
2854 scratch = AT.WorkPointer;
2858 while ( n <= arg2 ) {
2860 argsize = *t - ARGHEAD; where = t + ARGHEAD; t += *t;
2862 else if ( *t <= -FUNCTION ) {
2863 argbuf[0] = FUNHEAD+4; argbuf[1] = -*t++; argbuf[2] = FUNHEAD;
2864 for ( i = 2; i < FUNHEAD; i++ ) argbuf[i+1] = 0;
2865 argbuf[FUNHEAD+1] = 1;
2866 argbuf[FUNHEAD+2] = 1;
2867 argbuf[FUNHEAD+3] = 3;
2868 argsize = argbuf[0];
2871 else if ( *t == -SYMBOL ) {
2872 argbuf[0] = 8; argbuf[1] = SYMBOL; argbuf[2] = 4;
2873 argbuf[3] = t[1]; argbuf[4] = 1;
2874 argbuf[5] = 1; argbuf[6] = 1; argbuf[7] = 3;
2875 argsize = 8; t += 2;
2878 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
2879 argbuf[0] = 7; argbuf[1] = INDEX; argbuf[2] = 3;
2881 argbuf[4] = 1; argbuf[5] = 1;
2882 if ( *t == -MINVECTOR ) argbuf[6] = -3;
2884 argsize = 7; t += 2;
2887 else if ( *t == -INDEX ) {
2888 argbuf[0] = 7; argbuf[1] = INDEX; argbuf[2] = 3;
2890 argbuf[4] = 1; argbuf[5] = 1; argbuf[6] = 3;
2891 argsize = 7; t += 2;
2894 else if ( *t == -SNUMBER ) {
2896 argbuf[0] = 4; argbuf[1] = -t[1]; argbuf[2] = 1; argbuf[3] = -3;
2899 argbuf[0] = 4; argbuf[1] = t[1]; argbuf[2] = 1; argbuf[3] = 3;
2901 argsize = 4; t += 2;
2911 m =
AddRHS(AT.ebufnum,1);
2913 for ( i = 0; i < argsize; i++ ) m[i] = where[i];
2917 *w++ = SUBEXPRESSION; *w++ = SUBEXPSIZE; *w++ = C->numrhs; *w++ = 1;
2918 *w++ = AT.ebufnum; FILLSUB(w);
2920 *w++ = 1; *w++ = 1; *w++ = 3;
2921 *scratch = w-scratch;
2925 newterm = AT.WorkPointer;
2926 EndSort(BHEAD newterm+ARGHEAD,1);
2929 w = newterm+ARGHEAD;
while ( *w ) w += *w;
2930 *newterm = w-newterm; newterm[1] = 0;
2931 if ( ToFast(newterm,newterm) ) {
2932 if ( *newterm <= -FUNCTION ) w = newterm+1;
2935 while ( t < tstop ) *w++ = *t++;
2937 t = newterm; NCOPY(f,t,i);
2939 AT.WorkPointer = scratch;
2940 if ( AT.WorkPointer > AT.WorkSpace && AT.WorkPointer < f ) AT.WorkPointer = f;
2953int RunIsLyndon(PHEAD WORD *fun, WORD *args,
int par)
2955 WORD *tt, totarg, *tstop, arg1, arg2, arg, num, *f, n, i;
2957 WORD sign, i1, i2, retval;
2958 if ( fun[0] <= GAMMASEVEN && fun[0] >= GAMMA )
return(0);
2959 if ( *args != ARGRANGE ) {
2960 MLOCK(ErrorMessageLock);
2961 MesPrint(
"Illegal range encountered in RunIsLyndon");
2962 MUNLOCK(ErrorMessageLock);
2965 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2966 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2967 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2968 if ( arg1 > totarg || arg2 > totarg )
return(-1);
2972 if ( arg1 == arg2 )
return(1);
2973 if ( arg2 < arg1 ) {
2974 arg = arg1; arg1 = arg2; arg2 = arg; sign = 1;
2979 WantAddPointers(num);
2980 f = fun+FUNHEAD; n = 1; i = 0;
2981 while ( n < arg1 ) { n++; NEXTARG(f) }
2983 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2990 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2991 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2992 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3000 for ( i1 = 1; i1 < num; i1++ ) {
3001 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+i1],
3002 AT.pWorkSpace[AT.pWorkPointer]);
3003 if ( retval > 0 )
continue;
3004 if ( retval < 0 )
return(0);
3005 for ( i2 = 1; i2 < num; i2++ ) {
3006 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num],
3007 AT.pWorkSpace[AT.pWorkPointer+i2]);
3008 if ( retval < 0 )
return(0);
3009 if ( retval > 0 )
goto nexti1;
3031WORD RunToLyndon(PHEAD WORD *fun, WORD *args,
int par)
3033 WORD *tt, totarg, *tstop, arg1, arg2, arg, num, *f, *f1, *f2, n, i;
3034 WORD sign, i1, i2, retval, unique;
3035 if ( fun[0] <= GAMMASEVEN && fun[0] >= GAMMA )
return(0);
3036 if ( *args != ARGRANGE ) {
3037 MLOCK(ErrorMessageLock);
3038 MesPrint(
"Illegal range encountered in RunToLyndon");
3039 MUNLOCK(ErrorMessageLock);
3042 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3043 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3044 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3045 if ( arg1 > totarg || arg2 > totarg )
return(-1);
3049 if ( arg1 == arg2 )
return(1);
3050 if ( arg2 < arg1 ) {
3051 arg = arg1; arg1 = arg2; arg2 = arg; sign = 1;
3056 WantAddPointers((2*num));
3057 f = fun+FUNHEAD; n = 1; i = 0;
3058 while ( n < arg1 ) { n++; NEXTARG(f) }
3060 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
3067 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
3068 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
3069 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3078 for ( i1 = 1; i1 < num; i1++ ) {
3079 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+i1],
3080 AT.pWorkSpace[AT.pWorkPointer]);
3081 if ( retval > 0 )
continue;
3087 for ( i2 = 0; i2 < num; i2++ ) {
3088 AT.pWorkSpace[AT.pWorkPointer+num+i2] =
3089 AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num];
3091 for ( i2 = 0; i2 < num; i2++ ) {
3092 AT.pWorkSpace[AT.pWorkPointer+i2] =
3093 AT.pWorkSpace[AT.pWorkPointer+i2+num];
3098 for ( i2 = 1; i2 < num; i2++ ) {
3099 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num],
3100 AT.pWorkSpace[AT.pWorkPointer+i2]);
3101 if ( retval < 0 )
goto Rotate;
3102 if ( retval > 0 )
goto nexti1;
3113 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
3114 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
3115 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3122 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
3124 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
3132 MLOCK(ErrorMessageLock);
3134 MUNLOCK(ErrorMessageLock);
3143int RunDropArg(PHEAD WORD *fun, WORD *args)
3145 WORD *t, *tstop, *f, totarg, arg1, arg2, n;
3147 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3148 while ( t < tstop ) { totarg++; NEXTARG(t); }
3149 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3150 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
3151 if ( arg1 > totarg )
return(0);
3152 if ( arg2 < 1 )
return(0);
3153 if ( arg1 < 1 ) arg1 = 1;
3154 if ( arg2 > totarg ) arg2 = totarg;
3155 f = fun+FUNHEAD; n = 1;
3156 while ( n < arg1 ) { n++; NEXTARG(f) }
3158 while ( n <= arg2 ) { n++; NEXTARG(t) }
3159 while ( t < tstop ) *f++ = *t++;
3169int RunSelectArg(PHEAD WORD *fun, WORD *args)
3171 WORD *t, *tstop, *f, *tt, totarg, arg1, arg2, n;
3173 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3174 while ( t < tstop ) { totarg++; NEXTARG(t); }
3175 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3176 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
3177 if ( arg1 > totarg )
return(0);
3178 if ( arg2 < 1 )
return(0);
3179 if ( arg1 < 1 ) arg1 = 1;
3180 if ( arg2 > totarg ) arg2 = totarg;
3181 f = fun+FUNHEAD; n = 1; t = f;
3182 while ( n < arg1 ) { n++; NEXTARG(t) }
3183 while ( n <= arg2 ) {
3185 while ( t < tt ) *f++ = *t++;
3197int RunZtoHArg(PHEAD WORD *fun, WORD *args)
3199 WORD *tt, totarg, *tstop, arg1, arg2, n, i, *f, *f1;
3201 WORD *t, *t1, *t2, *t3;
3202 if ( *args != ARGRANGE ) {
3203 MLOCK(ErrorMessageLock);
3204 MesPrint(
"Illegal range encountered in RunZtoHArg.");
3205 MUNLOCK(ErrorMessageLock);
3208 if ( functions[fun[0]-FUNCTION].spec != 0 ) {
3209 MLOCK(ErrorMessageLock);
3210 MesPrint(
"The ZtoH transformation can only be executed on regular functions with nonzero integer arguments.");
3211 MUNLOCK(ErrorMessageLock);
3214 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3215 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3216 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3220 f = fun+FUNHEAD; n = 1;
3221 while ( n < arg1 ) { n++; NEXTARG(f) }
3223 for ( i = arg1; i <= arg2; i++, f += 2 ) {
3224 if ( *f != -SNUMBER || f[1] == 0 )
return(-1);
3229 t = f1; t1 = t2 = tt = TermMalloc(
"RunZtoHArg");
3230 while ( t < f ) { *t1++ = *t++; *t1++ = *t++; }
3236 while ( t3 < f ) { t3[1] = -t3[1]; t3 += 2; }
3240 TermFree(tt,
"RunZtoHArg");
3244 while ( f1 < f ) {
if ( f1[1] < 0 ) sign = 1-sign; f1 += 2; }
3253int RunHtoZArg(PHEAD WORD *fun, WORD *args)
3255 WORD *tt, totarg, *tstop, arg1, arg2, n, i, *f, *f1, *f2;
3258 if ( *args != ARGRANGE ) {
3259 MLOCK(ErrorMessageLock);
3260 MesPrint(
"Illegal range encountered in RunZtoHArg.");
3261 MUNLOCK(ErrorMessageLock);
3264 if ( functions[fun[0]-FUNCTION].spec != 0 ) {
3265 MLOCK(ErrorMessageLock);
3266 MesPrint(
"The HtoZ transformation can only be executed on regular functions with nonzero integer arguments.");
3267 MUNLOCK(ErrorMessageLock);
3270 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3271 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3272 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3276 f = fun+FUNHEAD; n = 1;
3277 while ( n < arg1 ) { n++; NEXTARG(f) }
3279 for ( i = arg1; i <= arg2; i++, f += 2 ) {
3280 if ( *f != -SNUMBER || f[1] == 0 )
return(-1);
3285 while ( f2 < f ) {
if ( f2[1] < 0 ) sign = 1-sign; f2 += 2; }
3289 t = f1; t1 = tt = TermMalloc(
"RunHtoZArg");
3290 while ( t < f ) { *t1++ = *t++; *t1++ = *t++; }
3294 t = f1; t2 = tt + 2;
3297 if ( t2[-1] < 0 ) t[1] = -t[1];
3300 TermFree(tt,
"RunHtoZArg");
3319int TestArgNum(
int n,
int totarg, WORD *args)
3328 if ( n == args[1] )
return(1);
3329 if ( args[1] >= MAXPOSITIVE4 ) {
3330 x1 = args[1]-MAXPOSITIVE4;
3331 if ( totarg-x1 == n )
return(1);
3336 if ( args[1] >= MAXPOSITIVE2 ) {
3337 x1 = args[1] - MAXPOSITIVE2;
3338 if ( x1 > MAXPOSITIVE4 ) {
3339 x1 = x1 - MAXPOSITIVE4;
3340 x1 = DolToNumber(BHEAD x1);
3344 x1 = DolToNumber(BHEAD x1);
3347 else if ( args[1] >= MAXPOSITIVE4 ) {
3348 x1 = totarg-(args[1]-MAXPOSITIVE4);
3351 if ( args[2] >= MAXPOSITIVE2 ) {
3352 x2 = args[2] - MAXPOSITIVE2;
3353 if ( x2 > MAXPOSITIVE4 ) {
3354 x2 = x2 - MAXPOSITIVE4;
3355 x2 = DolToNumber(BHEAD x2);
3359 x2 = DolToNumber(BHEAD x2);
3362 else if ( args[2] >= MAXPOSITIVE4 ) {
3363 x2 = totarg-(args[2]-MAXPOSITIVE4);
3367 if ( n >= x2 && n <= x1 )
return(1);
3370 if ( n >= x1 && n <= x2 )
return(1);
3388WORD PutArgInScratch(WORD *arg,UWORD *scrat)
3391 if ( *arg == -SNUMBER ) {
3392 scrat[0] = ABS(arg[1]);
3393 if ( arg[1] < 0 ) size = -1;
3398 if ( *t < 0 ) { i = ((-*t)-1)/2; size = -i; }
3399 else { i = ( *t -1)/2; size = i; }
3424UBYTE *ReadRange(UBYTE *s, WORD *out,
int par)
3426 UBYTE *in = s, *ss, c;
3430 if ( par == 0 && in[1] !=
'=' ) {
3431 MesPrint(
"&A range in this type of transform statement should be followed by an = sign");
3434 else if ( par == 1 && in[1] !=
',' && in[1] !=
'\0' ) {
3435 MesPrint(
"&A range in this type of transform statement should be followed by a comma or end-of-statement");
3438 else if ( par == 2 && in[1] !=
':' ) {
3439 MesPrint(
"&A range in this type of transform statement should be followed by a :");
3443 if ( FG.cTable[*s] == 0 ) {
3444 ss = s;
while ( FG.cTable[*s] == 0 ) s++;
3446 if ( StrICmp(ss,(UBYTE *)
"first") == 0 ) {
3450 else if ( StrICmp(ss,(UBYTE *)
"last") == 0 ) {
3456 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3458 if ( ( x1 = GetDollar(ss) ) < 0 )
goto Error;
3464 while ( *s >=
'0' && *s <=
'9' ) {
3465 x1 = 10*x1 + *s++ -
'0';
3466 if ( x1 >= MAXPOSITIVE4 ) {
3467 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3474 else x1 = MAXPOSITIVE4;
3477 MesPrint(
"&Illegal keyword inside range specification");
3481 else if ( FG.cTable[*s] == 1 ) {
3483 while ( *s >=
'0' && *s <=
'9' ) {
3484 x1 = x1*10 + *s++ -
'0';
3485 if ( x1 >= MAXPOSITIVE4 ) {
3486 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3491 else if ( *s ==
'$' ) {
3493 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3495 if ( ( x1 = GetDollar(ss) ) < 0 )
goto Error;
3500 MesPrint(
"&Illegal character in range specification");
3504 MesPrint(
"&A range is two indicators, separated by a comma or blank");
3508 if ( FG.cTable[*s] == 0 ) {
3509 ss = s;
while ( FG.cTable[*s] == 0 ) s++;
3511 if ( StrICmp(ss,(UBYTE *)
"first") == 0 ) {
3515 else if ( StrICmp(ss,(UBYTE *)
"last") == 0 ) {
3521 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3523 if ( ( x2 = GetDollar(ss) ) < 0 )
goto Error;
3529 while ( *s >=
'0' && *s <=
'9' ) {
3530 x2 = 10*x2 + *s++ -
'0';
3531 if ( x2 >= MAXPOSITIVE4 ) {
3532 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3539 else x2 = MAXPOSITIVE4;
3542 MesPrint(
"&Illegal keyword inside range specification");
3546 else if ( FG.cTable[*s] == 1 ) {
3548 while ( *s >=
'0' && *s <=
'9' ) {
3549 x2 = x2*10 + *s++ -
'0';
3550 if ( x2 >= MAXPOSITIVE4 ) {
3551 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3556 else if ( *s ==
'$' ) {
3558 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3560 if ( ( x2 = GetDollar(ss) ) < 0 )
goto Error;
3565 MesPrint(
"&Illegal character in range specification");
3569 MesPrint(
"&A range is two indicators, separated by a comma or blank between parentheses");
3572 out[0] = x1; out[1] = x2;
3575 MesPrint(
"&Undefined variable $%s in range",ss);
3584int FindRange(PHEAD WORD *args, WORD *arg1, WORD *arg2, WORD totarg)
3586 WORD n[2], fromlast, i;
3587 for ( i = 0; i < 2; i++ ) {
3590 if ( n[i] >= MAXPOSITIVE2 ) {
3591 n[i] -= MAXPOSITIVE2;
3592 if ( n[i] >= MAXPOSITIVE4 ) {
3594 n[i] -= MAXPOSITIVE4;
3596 n[i] = DolToNumber(BHEAD n[i]);
3597 if ( AN.ErrorInDollar ) {
3598 MLOCK(ErrorMessageLock);
3599 MesPrint(
"Illegal $ value in range while executing transform statement.");
3600 MUNLOCK(ErrorMessageLock);
3603 if ( fromlast ) n[i] = totarg-n[i];
3605 else if ( n[i] >= MAXPOSITIVE4 ) { n[i] = totarg-(n[i]-MAXPOSITIVE4); }
3607 MLOCK(ErrorMessageLock);
3608 MesPrint(
"Illegal non-positive value in range (%d) while executing transform statement.", i+1);
3609 MUNLOCK(ErrorMessageLock);
UBYTE * SkipAName(UBYTE *s)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)