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;
950 MLOCK(ErrorMessageLock);
951 MesPrint(
"Irregular code in execution of transform statement");
952 MUNLOCK(ErrorMessageLock);
955 onetransform += *onetransform;
956 }
while ( *onetransform );
959 while ( funs < endfun ) {
960 if ( *funs > MAXVARIABLES ) {
961 if ( *t == *funs-MAXVARIABLES )
goto hit;
964 w = SetElements + Sets[*funs].first;
965 m = SetElements + Sets[*funs].last;
967 if ( *w == *t )
goto hit;
979 tt = term + *term;
while ( in < tt ) *out++ = *in++;
980 if ( sign == -1 ) out[-1] = -out[-1];
988 MLOCK(ErrorMessageLock);
989 MesCall(
"RunTransform");
990 MUNLOCK(ErrorMessageLock);
1006int RunEncode(PHEAD WORD *fun, WORD *args, WORD *info)
1008 WORD base, *f, *funstop, *fun1, *t, size1, size2, size3, *arg;
1009 int num, num1, num2, n, i, i1, i2;
1010 UWORD *scrat1, *scrat2, *scrat3;
1011 WORD *tt, *tstop, totarg, arg1, arg2;
1012 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1013 if ( *args != ARGRANGE ) {
1014 MLOCK(ErrorMessageLock);
1015 MesPrint(
"Illegal range encountered in RunEncode");
1016 MUNLOCK(ErrorMessageLock);
1019 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1020 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1021 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1022 if ( arg1 > totarg || arg2 > totarg )
return(0);
1024 if ( info[2] == BASECODE ) {
1028 base = DolToNumber(BHEAD i1);
1029 if ( AN.ErrorInDollar || base < 2 ) {
1030 MLOCK(ErrorMessageLock);
1031 MesPrint(
"$%s does not have a number value > 1 in base/encode/transform statement in module %l",
1032 DOLLARNAME(Dollars,i1),AC.CModule);
1033 MUNLOCK(ErrorMessageLock);
1040 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1041 else { num1 = arg1; num2 = arg2; }
1043 WantAddPointers(num);
1047 n = 1; funstop = fun+fun[1]; f = fun+FUNHEAD;
1048 while ( n < num1 ) {
1049 if ( f >= funstop )
return(0);
1054 while ( n <= num2 ) {
1055 if ( f >= funstop )
return(0);
1056 if ( *f != -SNUMBER ) {
1057 if ( *f < 0 )
return(0);
1060 if ( (*f-i1) != (ARGHEAD+1) )
return(0);
1064 if ( *t != 0 )
return(0);
1068 AT.pWorkSpace[AT.pWorkPointer+i] = f;
1077 if ( arg1 > arg2 ) {
1080 t = AT.pWorkSpace[AT.pWorkPointer+i1];
1081 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
1082 AT.pWorkSpace[AT.pWorkPointer+i2] = t;
1094 scrat1 = NumberMalloc(
"RunEncode");
1095 scrat2 = NumberMalloc(
"RunEncode");
1096 scrat3 = NumberMalloc(
"RunEncode");
1097 arg = AT.pWorkSpace[AT.pWorkPointer];
1098 size1 = PutArgInScratch(arg,scrat1);
1101 if ( MulLong(scrat1,size1,(UWORD *)(&base),1,scrat2,&size2) ) {
1102 NumberFree(scrat3,
"RunEncode");
1103 NumberFree(scrat2,
"RunEncode");
1104 NumberFree(scrat1,
"RunEncode");
1108 size3 = PutArgInScratch(arg,scrat3);
1109 if ( AddLong(scrat2,size2,scrat3,size3,scrat1,&size1) ) {
1110 NumberFree(scrat3,
"RunEncode");
1111 NumberFree(scrat2,
"RunEncode");
1112 NumberFree(scrat1,
"RunEncode");
1125 *fun1++ = -SNUMBER; *fun1++ = 0;
1126 while ( f < funstop ) *fun1++ = *f++;
1127 fun[1] = funstop-fun;
1129 else if ( size1 == 1 && scrat1[0] <= MAXPOSITIVE ) {
1130 *fun1++ = -SNUMBER; *fun1++ = scrat1[0];
1131 while ( f < funstop ) *fun1++ = *f++;
1134 else if ( size1 == -1 && scrat1[0] <= MAXPOSITIVE+1 ) {
1136 if ( scrat1[0] < MAXPOSITIVE ) *fun1++ = scrat1[0];
1137 else *fun1++ = (WORD)(MAXPOSITIVE+1);
1138 while ( f < funstop ) *fun1++ = *f++;
1141 else if ( ABS(size1)*2+2+ARGHEAD <= f-fun1 ) {
1142 if ( size1 < 0 ) { size2 = size1*2-1; size1 = -size1; size3 = -size2; }
1143 else { size2 = 2*size1+1; size3 = size2; }
1144 *fun1++ = size3+ARGHEAD+1;
1145 *fun1++ = 0; FILLARG(fun1);
1147 for ( i = 0; i < size1; i++ ) *fun1++ = scrat1[i];
1149 for ( i = 1; i < size1; i++ ) *fun1++ = 0;
1151 while ( f < funstop ) *fun1++ = *f++;
1156 if ( size1 < 0 ) { size2 = size1*2-1; size1 = -size1; size3 = -size2; }
1157 else { size2 = 2*size1+1; size3 = size2; }
1158 *t++ = size3+ARGHEAD+1;
1159 *t++ = 0; FILLARG(t);
1161 for ( i = 0; i < size1; i++ ) *t++ = scrat1[i];
1163 for ( i = 1; i < size1; i++ ) *t++ = 0;
1165 while ( f < funstop ) *t++ = *f++;
1167 while ( f < t ) *fun1++ = *f++;
1170 NumberFree(scrat3,
"RunEncode");
1171 NumberFree(scrat2,
"RunEncode");
1172 NumberFree(scrat1,
"RunEncode");
1175 MLOCK(ErrorMessageLock);
1176 MesPrint(
"Unimplemented type of encoding encountered in RunEncode");
1177 MUNLOCK(ErrorMessageLock);
1182 MLOCK(ErrorMessageLock);
1183 MesCall(
"RunEncode");
1184 MUNLOCK(ErrorMessageLock);
1193int RunDecode(PHEAD WORD *fun, WORD *args, WORD *info)
1195 WORD base, num, num1, num2, n, *f, *funstop, *fun1, size1, size2, size3, *t;
1196 WORD i1, i2, i, sig;
1197 UWORD *scrat1, *scrat2, *scrat3;
1198 WORD *tt, *tstop, totarg, arg1, arg2;
1199 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1200 if ( *args != ARGRANGE ) {
1201 MLOCK(ErrorMessageLock);
1202 MesPrint(
"Illegal range encountered in RunDecode");
1203 MUNLOCK(ErrorMessageLock);
1206 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1207 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1208 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1209 if ( arg1 > totarg && arg2 > totarg )
return(0);
1210 if ( info[2] == BASECODE ) {
1214 base = DolToNumber(BHEAD i1);
1215 if ( AN.ErrorInDollar || base < 2 ) {
1216 MLOCK(ErrorMessageLock);
1217 MesPrint(
"$%s does not have a number value > 1 in base/decode/transform statement in module %l",
1218 DOLLARNAME(Dollars,i1),AC.CModule);
1219 MUNLOCK(ErrorMessageLock);
1226 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1227 else { num1 = arg1; num2 = arg2; }
1229 if ( num <= 1 )
return(0);
1233 funstop = fun + fun[1];
1234 f = fun + FUNHEAD; n = 1;
1235 while ( f < funstop ) {
1236 if ( n == num1 )
break;
1239 if ( f >= funstop )
return(0);
1243 if ( *f == -SNUMBER ) {}
1244 else if ( *f < 0 )
return(0);
1248 if ( (*f-i1) != (ARGHEAD+1) )
return(0);
1252 if ( *t != 0 )
return(0);
1261 scrat1 = NumberMalloc(
"RunEncode");
1262 scrat2 = NumberMalloc(
"RunEncode");
1263 scrat3 = NumberMalloc(
"RunEncode");
1264 size1 = PutArgInScratch(fun1,scrat1);
1265 if ( size1 < 0 ) { sig = -1; size1 = -size1; }
1270 scrat2[0] = base; size2 = 1;
1271 if ( RaisPow(BHEAD scrat2,&size2,num) ) {
1272 NumberFree(scrat3,
"RunEncode");
1273 NumberFree(scrat2,
"RunEncode");
1274 NumberFree(scrat1,
"RunEncode");
1277 if ( BigLong(scrat1,size1,scrat2,size2) >= 0 ) {
1278 NumberFree(scrat3,
"RunEncode");
1279 NumberFree(scrat2,
"RunEncode");
1280 NumberFree(scrat1,
"RunEncode");
1286 if ( *fun1 > num*2 ) {
1287 t = fun1 + 2*num; f = fun1 + *fun1;
1288 while ( f < funstop ) *t++ = *f++;
1291 else if ( *fun1 < num*2 ) {
1293 fun[1] += (num-1)*2;
1294 t = funstop + (num-1)*2;
1297 fun[1] += 2*num - *fun1;
1298 t = funstop +2*num - *fun1;
1301 while ( f > fun1 ) *--t = *--f;
1306 for ( i = num-1; i >= 0; i-- ) {
1307 DivLong(scrat1,size1,(UWORD *)(&base),1,scrat2,&size2,scrat3,&size3);
1308 fun1[2*i] = -SNUMBER;
1309 if ( size3 == 0 ) fun1[2*i+1] = 0;
1310 else fun1[2*i+1] = (WORD)(scrat3[0])*sig;
1311 for ( i1 = 0; i1 < size2; i1++ ) scrat1[i1] = scrat2[i1];
1315 MLOCK(ErrorMessageLock);
1316 MesPrint(
"RunDecode: number to be decoded is too big");
1317 MUNLOCK(ErrorMessageLock);
1318 NumberFree(scrat3,
"RunEncode");
1319 NumberFree(scrat2,
"RunEncode");
1320 NumberFree(scrat1,
"RunEncode");
1326 if ( arg1 > arg2 ) {
1327 i1 = 1; i2 = 2*num-1;
1329 i = fun1[i1]; fun1[i1] = fun1[i2]; fun1[i2] = i;
1333 NumberFree(scrat3,
"RunEncode");
1334 NumberFree(scrat2,
"RunEncode");
1335 NumberFree(scrat1,
"RunEncode");
1338 MLOCK(ErrorMessageLock);
1339 MesPrint(
"Unimplemented type of encoding encountered in RunDecode");
1340 MUNLOCK(ErrorMessageLock);
1345 MLOCK(ErrorMessageLock);
1346 MesCall(
"RunDecode");
1347 MUNLOCK(ErrorMessageLock);
1363int RunReplace(PHEAD WORD *fun, WORD *args, WORD *info)
1365 int n = 0, i, dirty = 0, totarg, nfix, nwild, ngeneral;
1366 WORD *t, *tt, *u, *tstop, *info1, *infoend, *oldwork = AT.WorkPointer;
1367 WORD *term, *newterm, *nt, *term1, *term2;
1368 WORD wild[4], mask, *term3, *term4, *oldmask = AT.WildMask;
1369 WORD n1, n2, doanyway;
1371 t = fun; tstop = fun + fun[1]; u = tstop;
1372 for ( i = 0; i < FUNHEAD; i++ ) *u++ = *t++;
1374 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1376 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1379 totarg = tstop - tt;
1388 AT.WorkPointer += 2*AM.MaxTer;
1389 if ( AT.WorkPointer > AT.WorkTop ) {
1390 MLOCK(ErrorMessageLock);
1392 MUNLOCK(ErrorMessageLock);
1395 term = AT.WorkPointer;
1396 for ( i = 0; i < *info; i++ ) term[i] = info[i];
1397 AT.WorkPointer = term + *term;
1400 if (
Generator(BHEAD term,AR.Cnumlhs) ) {
1402 AT.WorkPointer = oldwork;
1405 newterm = AT.WorkPointer;
1406 if (
EndSort(BHEAD newterm,1) < 0 ) {}
1407 if ( ( *newterm && *(newterm+*newterm) != 0 ) || *newterm == 0 ) {
1408 MLOCK(ErrorMessageLock);
1409 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1410 MUNLOCK(ErrorMessageLock);
1414 i = *newterm; tt = term; nt = newterm;
1416 AT.WorkPointer = term + *term;
1419 term1 = term + *term;
1421 *term2++ = REPLACEMENT;
1422 term2++; FILLFUN(term2)
1426 infoend = info + info[1];
1427 info1 = info + FUNHEAD;
1428 nfix = nwild = ngeneral = 0;
1429 while ( info1 < infoend ) {
1430 if ( *info1 == -SNUMBER ) {
1432 info1 += 2; NEXTARG(info1)
1434 else if ( *info1 <= -FUNCTION ) {
1435 if ( *info1 == -WILDARGFUN ) {
1437 info1++; NEXTARG(info1)
1440 *term2++ = *info1++; COPY1ARG(term2,info1)
1444 else if ( *info1 == -INDEX ) {
1445 if ( info1[1] == WILDARGINDEX + AM.OffsetIndex ) {
1447 info1 += 2; NEXTARG(info1)
1450 *term2++ = *info1++; *term2++ = *info1++; COPY1ARG(term2,info1)
1454 else if ( *info1 == -SYMBOL ) {
1455 if ( info1[1] == WILDARGSYMBOL ) {
1457 info1 += 2; NEXTARG(info1)
1460 *term2++ = *info1++; *term2++ = *info1++; COPY1ARG(term2,info1)
1464 else if ( *info1 == -MINVECTOR || *info1 == -VECTOR ) {
1465 if ( info1[1] == WILDARGVECTOR + AM.OffsetVector ) {
1467 info1 += 2; NEXTARG(info1)
1470 *term2++ = *info1++; *term2++ = *info1++; COPY1ARG(term2,info1)
1475 MLOCK(ErrorMessageLock);
1476 MesPrint(
"&irregular code found in replace transformation (RunReplace)");
1477 MUNLOCK(ErrorMessageLock);
1481 AT.WorkPointer = term2;
1482 *term1 = term2 - term1;
1483 term1[2] = *term1 - 1;
1487 while ( t < tstop ) {
1489 if ( TestArgNum(n,totarg,args) == 0 ) {
1490 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1491 if ( *t <= -FUNCTION ) { *u++ = *t++; }
1492 else if ( *t < 0 ) { *u++ = *t++; *u++ = *t++; }
1493 else { i = *t; NCOPY(u,t,i) }
1509 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1510 if ( *t == -SNUMBER ) {
1511 info1 = info + FUNHEAD;
1512 while ( info1 < infoend ) {
1513 if ( *info1 == -SNUMBER ) {
1514 if ( info1[1] == t[1] ) {
1515 if ( info1[2] == -SNUMBER ) {
1516 *u++ = -SNUMBER; *u++ = info1[3];
1521 if ( info1[0] <= -FUNCTION ) i = 1;
1522 else if ( info1[0] < 0 ) i = 2;
1540 doanyway = 1; n2 = t[1];
1544 if ( *t < AM.OffsetIndex && *t >= 0 ) {
1545 info1 = info + FUNHEAD;
1546 while ( info1 < infoend ) {
1547 if ( ( *info1 == -SNUMBER ) && ( info1[1] == *t )
1548 && ( ( ( info1[2] == -SNUMBER ) && ( info1[3] >= 0 )
1549 && ( info1[3] < AM.OffsetIndex ) )
1550 || ( info1[2] == -INDEX || info1[2] == -VECTOR
1551 || info1[2] == -MINVECTOR ) ) ) {
1564 else if ( *t == -SNUMBER ) {
1565 doanyway = 1; n2 = t[1];
1573 if ( ngeneral > 0 ) {
1574 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1576 term3 = term1 + *term1;
1577 term4 = term1 + FUNHEAD;
1578 while ( term4 < term3 ) {
1579 if ( *term4 == *t && ( *t <= -FUNCTION ||
1580 ( t[1] == term4[1] ) ) )
break;
1583 if ( term4 < term3 )
goto dothisnow;
1587 term3 = term1 + *term1;
1588 term4 = term1 + FUNHEAD;
1589 while ( term4 < term3 ) {
1590 if ( ( term4[1] == *t ) &&
1591 ( ( *term4 == -INDEX || *term4 == -VECTOR ||
1592 ( *term4 == -SYMBOL && term4[1] < AM.OffsetIndex
1593 && term4[1] >= 0 ) ) ) )
break;
1596 if ( term4 < term3 )
goto dothisnow;
1613 info1 = info + FUNHEAD;
1614 while ( info1 < infoend ) {
1615 if ( *info1 == -SYMBOL && info1[1] == WILDARGSYMBOL
1616 && ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) ) {
1618 wild[2] = WILDARGSYMBOL;
1620 AN.WildValue = wild;
1621 AT.WildMask = &mask;
1624 if ( *t == -SYMBOL || ( *t > 0 && CheckWild(BHEAD WILDARGSYMBOL,SYMTOSUB,1,t) == 0 )
1630 n1 = SYMBOL; n2 = WILDARGSYMBOL;
1634 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1635 *term3++ = DUMFUN; term3++; FILLFUN(term3)
1636 COPY1ARG(term3,info1)
1639 *term3++ = fun[0]; term3++; FILLFUN(term3)
1642 term2[2] = term3 - term2 - 1;
1644 *term3++ = REPLACEMENT;
1645 term3++; FILLFUN(term3)
1647 if ( n1 < FUNCTION ) *term3++ = n2;
1648 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1650 COPY1ARG(term3,term4)
1656 *term3++ = 1; *term3++ = 1; *term3++ = 3;
1657 *term2 = term3 - term2;
1659 AT.WorkPointer = term3;
1661 if (
Generator(BHEAD term2,AR.Cnumlhs) ) {
1663 AT.WorkPointer = oldwork;
1664 AT.WildMask = oldmask;
1667 term4 = AT.WorkPointer;
1668 if (
EndSort(BHEAD term4,1) < 0 ) {}
1669 if ( ( *term4 && *(term4+*term4) != 0 ) || *term4 == 0 ) {
1670 MLOCK(ErrorMessageLock);
1671 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1672 MUNLOCK(ErrorMessageLock);
1678 i = term4[2]-FUNHEAD;
1679 term3 = term4+FUNHEAD+1;
1681 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1685 AT.WorkPointer = term2;
1689 info1 += 2; NEXTARG(info1)
1691 else if ( ( *info1 == -INDEX )
1692 && ( info[1] == WILDARGINDEX + AM.OffsetIndex ) ) {
1694 wild[2] = WILDARGINDEX+AM.OffsetIndex;
1696 AN.WildValue = wild;
1697 AT.WildMask = &mask;
1700 if ( ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION )
1701 || ( *t == -INDEX || ( *t > 0 && CheckWild(BHEAD WILDARGINDEX,INDTOSUB,1,t) == 0 ) ) ) {
1706 n1 = INDEX; n2 = WILDARGINDEX+AM.OffsetIndex;
1710 info1 += 2; NEXTARG(info1)
1712 else if ( ( *info1 == -VECTOR )
1713 && ( info1[1] == WILDARGVECTOR + AM.OffsetVector ) ) {
1715 wild[2] = WILDARGVECTOR+AM.OffsetVector;
1717 AN.WildValue = wild;
1718 AT.WildMask = &mask;
1721 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
1722 if ( *t < MINSPEC ) {
1723 n1 = VECTOR; n2 = WILDARGVECTOR+AM.OffsetVector;
1728 else if ( *t == -VECTOR || *t == -MINVECTOR ||
1729 ( *t > 0 && CheckWild(BHEAD WILDARGVECTOR,VECTOSUB,1,t) == 0 ) ) {
1734 n1 = VECTOR; n2 = WILDARGVECTOR+AM.OffsetVector;
1738 info1 += 2; NEXTARG(info1)
1740 else if ( *info1 == -WILDARGFUN ) {
1742 wild[2] = WILDARGFUN;
1744 AN.WildValue = wild;
1745 AT.WildMask = &mask;
1748 if ( *t <= -FUNCTION || ( *t > 0 && CheckWild(BHEAD WILDARGFUN,FUNTOFUN,1,t) == 0 ) ) {
1753 n2 = n1 = -WILDARGFUN;
1757 info1++; NEXTARG(info1)
1760 NEXTARG(info1) NEXTARG(info1)
1764 if ( ngeneral > 0 ) {
1772 term3 = term2; term4 = term1; i = *term1;
1773 NCOPY(term3,term4,i)
1775 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1776 *term3++ = DUMFUN; term3++; FILLFUN(term3);
1781 *term3++ = fun[0]; term3++; FILLFUN(term3); *term3++ = *t;
1783 term4[1] = term3-term4;
1784 *term3++ = 1; *term3++ = 1; *term3++ = 3;
1785 *term2 = term3-term2;
1786 AT.WorkPointer = term3;
1788 if (
Generator(BHEAD term2,AR.Cnumlhs) ) {
1790 AT.WorkPointer = oldwork;
1791 AT.WildMask = oldmask;
1794 term4 = AT.WorkPointer;
1795 if (
EndSort(BHEAD term4,1) < 0 ) {}
1796 if ( ( *term4 && *(term4+*term4) != 0 ) || *term4 == 0 ) {
1797 MLOCK(ErrorMessageLock);
1798 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1799 MUNLOCK(ErrorMessageLock);
1805 i = term4[2]-FUNHEAD;
1806 term3 = term4+FUNHEAD+1;
1809 AT.WorkPointer = term2;
1817 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1818 if ( *t <= -FUNCTION ) { *u++ = *t++; }
1819 else if ( *t < 0 ) { *u++ = *t++; *u++ = *t++; }
1820 else { i = *t; NCOPY(u,t,i) }
1827 i = u - tstop; tstop[1] = i; tstop[2] = dirty;
1828 t = fun; u = tstop; NCOPY(t,u,i)
1829 AT.WorkPointer = oldwork;
1830 AT.WildMask = oldmask;
1841int RunImplode(WORD *fun, WORD *args)
1844 WORD *tt, *tstop, totarg, arg1, arg2, num1, num2, i1, n;
1845 WORD *f, *t, *ttt, *t4, *ff, *fff;
1846 WORD moveup, numzero, outspace;
1847 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1848 if ( *args != ARGRANGE ) {
1849 MLOCK(ErrorMessageLock);
1850 MesPrint(
"Illegal range encountered in RunImplode");
1851 MUNLOCK(ErrorMessageLock);
1854 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1855 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1856 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1860 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1861 else { num1 = arg1; num2 = arg2; }
1862 if ( num1 > totarg || num2 > totarg )
return(0);
1868 n = 1; f = fun+FUNHEAD;
1869 while ( n < num1 ) {
1870 if ( f >= tstop )
return(0);
1886 while ( n <= num2 ) {
1887 if ( f >= tstop )
return(0);
1888 if ( *f == -SNUMBER ) { *tt++ = -1; *tt++ = 0;
1889 if ( f[1] < 0 ) { *tt++ = -f[1]; *tt++ = -1; }
1890 else { *tt++ = f[1]; *tt++ = 1; }
1893 else if ( *f == -SYMBOL ) { *tt++ = f[1]; *tt++ = 1; *tt++ = 1; *tt++ = 1; f += 2; }
1894 else if ( *f < 0 )
return(0);
1896 if ( *f != ( f[ARGHEAD]+ARGHEAD ) )
return(0);
1899 if ( ( i1 > 3 ) || ( t[-1] != 1 ) )
return(0);
1900 if ( (UWORD)(t[-2]) > MAXPOSITIVE4 )
return(0);
1901 if ( f[ARGHEAD] == i1+1 ) {
1902 *tt++ = -1; *tt++ = 0; *tt++ = t[-2];
1903 if ( *t < 0 ) { *tt++ = -1; }
1906 else if ( ( f[ARGHEAD+1] != SYMBOL )
1907 || ( f[ARGHEAD+2] != 4 )
1908 || ( ( f+ARGHEAD+1+f[ARGHEAD+2] ) < ( t-i1 ) ) )
return(0);
1911 *tt++ = f[ARGHEAD+3];
1912 *tt++ = f[ARGHEAD+4];
1914 if ( *t < 0 ) { *tt++ = -1; }
1927 if ( arg1 > arg2 ) {
1931 t = tt - 4; numzero = 0;
1932 while ( t >= tstop ) {
1933 if ( t[2] == 0 ) numzero++;
1935 if ( numzero > 0 ) {
1938 ttt = t4 + 4*numzero;
1939 while ( ttt < tt ) *t4++ = *ttt++;
1949 numzero = 0; ttt = t;
1951 if ( t[2] == 0 ) numzero++;
1953 if ( numzero > 0 ) {
1956 while ( t4 < tt ) *ttt++ = *t4++;
1976 t = tstop; outspace = 0;
1979 if ( t[2] > MAXPOSITIVE4 ) {
return(0); }
1982 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) { outspace += 2; }
1983 else { outspace += 8 + ARGHEAD; }
1986 if ( outspace < (fff-ff) ) {
1989 if ( t[0] == -1 ) { *ff++ = -SNUMBER; *ff++ = t[2]*t[3]; }
1990 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) {
1991 *ff++ = -SYMBOL; *ff++ = t[0];
1994 *ff++ = 8+ARGHEAD; *ff++ = 0; FILLARG(ff);
1995 *ff++ = 8; *ff++ = SYMBOL; *ff++ = 4; *ff++ = t[0]; *ff++ = t[1];
1996 *ff++ = t[2]; *ff++ = 1; *ff++ = t[3] > 0 ? 3: -3;
2000 while ( fff < tstop ) *ff++ = *fff++;
2003 else if ( outspace > (fff-ff) ) {
2009 moveup = outspace-(fff-ff);
2012 while ( t > fff ) *--ttt = *--t;
2013 tt += moveup; tstop += moveup;
2022 if ( t[0] == -1 ) { *ff++ = -SNUMBER; *ff++ = t[2]*t[3]; }
2023 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) {
2024 *ff++ = -SYMBOL; *ff++ = t[0];
2027 *ff++ = 8+ARGHEAD; *ff++ = 0; FILLARG(ff);
2028 *ff++ = 8; *ff++ = SYMBOL; *ff++ = 4; *ff++ = t[0]; *ff++ = t[1];
2029 *ff++ = t[2]; *ff++ = 1; *ff++ = t[3] > 0 ? 3: -3;
2042int RunExplode(PHEAD WORD *fun, WORD *args)
2044 WORD arg1, arg2, num1, num2, *tt, *tstop, totarg, *tonew, *newfun;
2046 int reverse = 0, iarg, i, numzero;
2047 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
2048 if ( *args != ARGRANGE ) {
2049 MLOCK(ErrorMessageLock);
2050 MesPrint(
"Illegal range encountered in RunExplode");
2051 MUNLOCK(ErrorMessageLock);
2054 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2055 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2056 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2060 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; reverse = 1; }
2061 else { num1 = arg1; num2 = arg2; }
2062 if ( num1 > totarg || num2 > totarg )
return(0);
2063 if ( tstop + AM.MaxTer > AT.WorkTop )
goto OverWork;
2068 tonew = newfun = tstop;
2069 ff = fun + FUNHEAD; iarg = 0;
2070 while ( ff < tstop ) {
2072 if ( iarg == num1 ) {
2073 i = ff - fun; f = fun;
2082 while ( iarg <= num2 ) {
2083 if ( *ff == -SYMBOL || ( *ff == -SNUMBER && ff[1] == 0 ) )
2084 { *tonew++ = *ff++; *tonew++ = *ff++; }
2085 else if ( *ff == -SNUMBER ) {
2086 numzero = ABS(ff[1])-1;
2088 *tonew++ = -SNUMBER; *tonew++ = ff[1] < 0 ? -1: 1;
2089 while ( numzero > 0 ) {
2090 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2094 while ( numzero > 0 ) {
2095 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2097 *tonew++ = -SNUMBER; *tonew++ = ff[1] < 0 ? -1: 1;
2101 else if ( *ff < 0 ) {
return(0); }
2103 if ( *ff != ARGHEAD+8 || ff[ARGHEAD] != 8
2104 || ff[ARGHEAD+1] != SYMBOL || ABS(ff[ARGHEAD+7]) != 3
2105 || ff[ARGHEAD+6] != 1 )
return(0);
2106 numzero = ff[ARGHEAD+5];
2107 if ( numzero >= MAXPOSITIVE4 )
return(0);
2110 if ( ff[ARGHEAD+7] > 0 ) { *tonew++ = -SNUMBER; *tonew++ = 1; }
2112 *tonew++ = ARGHEAD+8; *tonew++ = 0; FILLARG(tonew)
2113 *tonew++ = 8; *tonew++ = SYMBOL; *tonew++ = ff[ARGHEAD+3];
2114 *tonew++ = ff[ARGHEAD+4]; *tonew++ = 1; *tonew++ = 1;
2117 while ( numzero > 0 ) {
2118 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2122 while ( numzero > 0 ) {
2123 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2125 *tonew++ = ARGHEAD+8; *tonew++ = 0; FILLARG(tonew)
2126 *tonew++ = 8; *tonew++ = SYMBOL; *tonew++ = 4;
2127 *tonew++ = ff[ARGHEAD+3]; *tonew++ = ff[ARGHEAD+4];
2128 *tonew++ = 1; *tonew++ = 1;
2129 if ( ff[ARGHEAD+7] > 0 ) *tonew++ = 3;
2134 if ( tonew > AT.WorkTop )
goto OverWork;
2140 while ( ff < tstop ) *tonew++ = *ff++;
2141 i = newfun[1] = tonew-newfun;
2145 MLOCK(ErrorMessageLock);
2147 MUNLOCK(ErrorMessageLock);
2156int RunPermute(PHEAD WORD *fun, WORD *args, WORD *info)
2158 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, *f, *f1, *f2, *infostop;
2159 WORD *in, *iw, withdollar;
2161 if ( *args != ARGRANGE ) {
2162 MLOCK(ErrorMessageLock);
2163 MesPrint(
"Illegal range encountered in RunPermute");
2164 MUNLOCK(ErrorMessageLock);
2167 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2168 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2169 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2170 arg1 = 1; arg2 = totarg;
2179 WantAddPointers(num);
2180 f = fun+FUNHEAD; n = 1; i = 0;
2181 while ( n < arg1 ) { n++; NEXTARG(f) }
2183 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2189 infostop = info + *info;
2191 if ( *info > totarg )
return(0);
2196 withdollar = 0; in = info;
2197 while ( in < infostop ) {
2199 d = Dollars - *in - 1;
2202 int nummodopt, dtype = -1, numdollar = -*in-1;
2203 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2204 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2205 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2207 if ( nummodopt < NumModOptdollars ) {
2208 dtype = ModOptdollars[nummodopt].type;
2209 if ( dtype == MODLOCAL ) {
2210 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2213 LOCK(d->pthreadslock);
2219 if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2220 && d->where[0] == 4 && d->where[4] == 0 ) {
2221 if ( d->where[3] < 0 || d->where[2] != 1 || d->where[1] > totarg )
return(0);
2223 else if ( d->type == DOLWILDARGS ) {
2226 if ( *iw == -SNUMBER ) {
2227 if ( iw[1] <= 0 || iw[1] > totarg )
return(0);
2235 MLOCK(ErrorMessageLock);
2236 MesPrint(
"Illegal type of $-variable in RunPermute");
2237 MUNLOCK(ErrorMessageLock);
2242 else if ( *in > totarg )
return(0);
2246 WORD *incopy, *tocopy;
2247 incopy = TermMalloc(
"RunPermute");
2248 tocopy = incopy+1; in = info;
2249 while ( in < infostop ) {
2251 d = Dollars - *in - 1;
2254 int nummodopt, dtype = -1, numdollar = -*in-1;
2255 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2256 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2257 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2259 if ( nummodopt < NumModOptdollars ) {
2260 dtype = ModOptdollars[nummodopt].type;
2261 if ( dtype == MODLOCAL ) {
2262 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2265 LOCK(d->pthreadslock);
2271 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
2272 *tocopy++ = d->where[1] - 1;
2274 else if ( d->type == DOLWILDARGS ) {
2277 *tocopy++ = iw[1] - 1;
2283 else *tocopy++ = *in++;
2286 *incopy = tocopy - incopy;
2288 tt = AT.pWorkSpace[AT.pWorkPointer+*in];
2290 while ( in < tocopy ) {
2291 if ( *in > totarg )
return(0);
2292 AT.pWorkSpace[AT.pWorkPointer+in[-1]] = AT.pWorkSpace[AT.pWorkPointer+*in];
2295 AT.pWorkSpace[AT.pWorkPointer+in[-1]] = tt;
2296 TermFree(incopy,
"RunPermute");
2300 tt = AT.pWorkSpace[AT.pWorkPointer+*info];
2302 while ( info < infostop ) {
2303 if ( *info > totarg )
return(0);
2304 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = AT.pWorkSpace[AT.pWorkPointer+*info];
2307 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = tt;
2329 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2331 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2336 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop-tt;
2337 arg1 = 1; arg2 = totarg;
2339 WantAddPointers(num);
2340 f = fun+FUNHEAD; n = 1; i = 0;
2341 while ( n < arg1 ) { n++; f++; }
2343 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2349 infostop = info + *info;
2351 if ( *info > totarg )
return(0);
2352 tt = AT.pWorkSpace[AT.pWorkPointer+*info];
2354 while ( info < infostop ) {
2355 if ( *info > totarg )
return(0);
2356 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = AT.pWorkSpace[AT.pWorkPointer+*info];
2359 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = tt;
2364 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2366 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++= *f++; }
2372 MLOCK(ErrorMessageLock);
2374 MUNLOCK(ErrorMessageLock);
2383int RunReverse(PHEAD WORD *fun, WORD *args)
2385 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, *f, *f1, *f2, i1, i2;
2386 if ( *args != ARGRANGE ) {
2387 MLOCK(ErrorMessageLock);
2388 MesPrint(
"Illegal range encountered in RunReverse");
2389 MUNLOCK(ErrorMessageLock);
2392 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2393 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2394 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2395 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2403 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2404 if ( arg2 > totarg )
return(0);
2407 WantAddPointers(num);
2408 f = fun+FUNHEAD; n = 1; i = 0;
2409 while ( n < arg1 ) { n++; NEXTARG(f) }
2411 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2414 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2415 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2416 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2419 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2421 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2426 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2427 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2435 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2436 if ( arg2 > totarg )
return(0);
2439 WantAddPointers(num);
2440 f = fun+FUNHEAD; n = 1; i = 0;
2441 while ( n < arg1 ) { n++; f++; }
2443 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2446 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2447 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2448 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2451 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2453 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++ = *f++; }
2459 MLOCK(ErrorMessageLock);
2461 MUNLOCK(ErrorMessageLock);
2470int RunDedup(PHEAD WORD *fun, WORD *args)
2472 WORD *tt, totarg, *tstop, arg1, arg2, n, i, j,k, *f, *f1, *f2, *fd, *fstart;
2473 if ( *args != ARGRANGE ) {
2474 MLOCK(ErrorMessageLock);
2475 MesPrint(
"Illegal range encountered in RunDedup");
2476 MUNLOCK(ErrorMessageLock);
2479 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2480 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2481 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2482 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2484 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2485 if ( arg2 > totarg )
return(0);
2487 f = fun+FUNHEAD; n = 1;
2488 while ( n < arg1 ) { n++; NEXTARG(f) }
2493 for (; n <= arg2; n++ ) {
2495 for ( j = 0; j < i; j++ ) {
2498 for ( k = 0; k < fd-f2; k++ )
2499 if ( f2[k] != f[k] )
break;
2501 if ( k == fd-f2 )
break;
2515 for (j = n; j <= totarg; j++) {
2522 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2523 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2525 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2526 if ( arg2 > totarg )
return(0);
2532 for (; n <= arg2; n++ ) {
2533 for ( j = arg1; j < i; j++ ) {
2534 if ( f[n-1] == f[j-1] )
break;
2545 for (j = n; j <= totarg; j++, i++) {
2549 fun[1] = f + i - 1 - fun;
2559int RunCycle(PHEAD WORD *fun, WORD *args, WORD *info)
2561 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, j, *f, *f1, *f2, x, ncyc, cc;
2562 if ( *args != ARGRANGE ) {
2563 MLOCK(ErrorMessageLock);
2564 MesPrint(
"Illegal range encountered in RunCycle");
2565 MUNLOCK(ErrorMessageLock);
2569 if ( ncyc >= MAXPOSITIVE2 ) {
2570 ncyc -= MAXPOSITIVE2;
2571 if ( ncyc >= MAXPOSITIVE4 ) {
2572 ncyc -= MAXPOSITIVE4;
2576 ncyc = DolToNumber(BHEAD ncyc);
2577 if ( AN.ErrorInDollar ) {
2578 MesPrint(
" Error in Dollar variable in transform,cycle()=$");
2581 if ( ncyc >= MAXPOSITIVE4 || ncyc <= -MAXPOSITIVE4 ) {
2582 MesPrint(
" Illegal value from Dollar variable in transform,cycle()=$");
2587 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2588 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2589 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2590 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2591 if ( arg1 > arg2 ) { n = arg1; arg1 = arg2; arg2 = n; }
2592 if ( arg2 > totarg )
return(0);
2601 WantAddPointers(num);
2602 f = fun+FUNHEAD; n = 1; i = 0;
2603 while ( n < arg1 ) { n++; NEXTARG(f) }
2605 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2612 if ( x > i/2 ) x -= i;
2614 else if ( x <= -i ) {
2616 if ( x <= -i/2 ) x += i;
2620 tt = AT.pWorkSpace[AT.pWorkPointer+i-1];
2621 for ( j = i-1; j > 0; j-- )
2622 AT.pWorkSpace[AT.pWorkPointer+j] = AT.pWorkSpace[AT.pWorkPointer+j-1];
2623 AT.pWorkSpace[AT.pWorkPointer] = tt;
2627 tt = AT.pWorkSpace[AT.pWorkPointer];
2628 for ( j = 1; j < i; j++ )
2629 AT.pWorkSpace[AT.pWorkPointer+j-1] = AT.pWorkSpace[AT.pWorkPointer+j];
2630 AT.pWorkSpace[AT.pWorkPointer+j-1] = tt;
2637 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2639 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2644 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2645 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2646 if ( arg1 > arg2 ) { n = arg1; arg1 = arg2; arg2 = n; }
2647 if ( arg2 > totarg )
return(0);
2656 WantAddPointers(num);
2657 f = fun+FUNHEAD; n = 1; i = 0;
2658 while ( n < arg1 ) { n++; f++; }
2660 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2667 if ( x > i/2 ) x -= i;
2669 else if ( x <= -i ) {
2671 if ( x <= -i/2 ) x += i;
2675 tt = AT.pWorkSpace[AT.pWorkPointer+i-1];
2676 for ( j = i-1; j > 0; j-- )
2677 AT.pWorkSpace[AT.pWorkPointer+j] = AT.pWorkSpace[AT.pWorkPointer+j-1];
2678 AT.pWorkSpace[AT.pWorkPointer] = tt;
2682 tt = AT.pWorkSpace[AT.pWorkPointer];
2683 for ( j = 1; j < i; j++ )
2684 AT.pWorkSpace[AT.pWorkPointer+j-1] = AT.pWorkSpace[AT.pWorkPointer+j];
2685 AT.pWorkSpace[AT.pWorkPointer+j-1] = tt;
2692 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2694 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++ = *f++; }
2700 MLOCK(ErrorMessageLock);
2702 MUNLOCK(ErrorMessageLock);
2711int RunAddArg(PHEAD WORD *fun, WORD *args)
2713 WORD *tt, totarg, *tstop, arg1, arg2, n, num, *f, *f1, *f2;
2714 WORD scribble[10+ARGHEAD];
2716 if ( *args != ARGRANGE ) {
2717 MLOCK(ErrorMessageLock);
2718 MesPrint(
"Illegal range encountered in RunAddArg");
2719 MUNLOCK(ErrorMessageLock);
2722 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
2723 MLOCK(ErrorMessageLock);
2724 MesPrint(
"Illegal attempt to add arguments of a tensor in AddArg");
2725 MUNLOCK(ErrorMessageLock);
2728 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2729 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2731 if ( totarg == 0 )
return(0);
2732 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2743 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2744 if ( arg2 > totarg )
return(0);
2746 if ( num == 1 )
return(0);
2747 f = fun+FUNHEAD; n = 1;
2748 while ( n < arg1 ) { n++; NEXTARG(f) }
2751 while ( n <= arg2 ) {
2753 f2 = f + *f; f += ARGHEAD;
2754 while ( f < f2 ) {
StoreTerm(BHEAD f); f += *f; }
2756 else if ( *f == -SNUMBER && f[1] == 0 ) {
2760 ToGeneral(f,scribble,1);
2766 if (
EndSort(BHEAD tstop+ARGHEAD,1) < 0 )
return(-1);
2769 while ( *f2 ) { f2 += *f2; num++; }
2771 for ( n = 1; n < ARGHEAD; n++ ) tstop[n] = 0;
2772 if ( num == 1 && ToFast(tstop,tstop) == 1 ) {
2773 f2 = tstop; NEXTARG(f2);
2775 if ( *tstop == ARGHEAD ) {
2776 *tstop = -SNUMBER; tstop[1] = 0;
2782 while ( f < tstop ) *f2++ = *f++;
2783 while ( f < f2 ) *f1++ = *f++;
2785 if ( (space+8)*
sizeof(WORD) > (UWORD)AM.MaxTer ) {
2786 MLOCK(ErrorMessageLock);
2788 MUNLOCK(ErrorMessageLock);
2791 fun[1] = (WORD)space;
2800int RunMulArg(PHEAD WORD *fun, WORD *args)
2802 WORD *t, totarg, *tstop, arg1, arg2, n, *f, nb, *m, i, *w;
2803 WORD *scratch, argbuf[20], argsize, *where, *newterm;
2804 LONG oldcpointer_pos;
2805 CBUF *C = cbuf + AT.ebufnum;
2806 if ( *args != ARGRANGE ) {
2807 MLOCK(ErrorMessageLock);
2808 MesPrint(
"Illegal range encountered in RunMulArg");
2809 MUNLOCK(ErrorMessageLock);
2812 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
2813 MLOCK(ErrorMessageLock);
2814 MesPrint(
"Illegal attempt to multiply arguments of a tensor in MulArg");
2815 MUNLOCK(ErrorMessageLock);
2818 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2819 while ( t < tstop ) { totarg++; NEXTARG(t); }
2821 if ( totarg == 0 )
return(0);
2822 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2823 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2824 if ( arg1 > totarg )
return(0);
2825 if ( arg2 < 1 )
return(0);
2826 if ( arg1 < 1 ) arg1 = 1;
2827 if ( arg2 > totarg ) arg2 = totarg;
2828 if ( arg1 == arg2 )
return(0);
2836 f = fun+FUNHEAD; n = 1;
2837 while ( n < arg1 ) { n++; NEXTARG(f) }
2839 if ( fun >= AT.WorkSpace && fun < AT.WorkTop ) {
2840 if ( AT.WorkPointer < fun+fun[1] ) AT.WorkPointer = fun+fun[1];
2842 scratch = AT.WorkPointer;
2846 while ( n <= arg2 ) {
2848 argsize = *t - ARGHEAD; where = t + ARGHEAD; t += *t;
2850 else if ( *t <= -FUNCTION ) {
2851 argbuf[0] = FUNHEAD+4; argbuf[1] = -*t++; argbuf[2] = FUNHEAD;
2852 for ( i = 2; i < FUNHEAD; i++ ) argbuf[i+1] = 0;
2853 argbuf[FUNHEAD+1] = 1;
2854 argbuf[FUNHEAD+2] = 1;
2855 argbuf[FUNHEAD+3] = 3;
2856 argsize = argbuf[0];
2859 else if ( *t == -SYMBOL ) {
2860 argbuf[0] = 8; argbuf[1] = SYMBOL; argbuf[2] = 4;
2861 argbuf[3] = t[1]; argbuf[4] = 1;
2862 argbuf[5] = 1; argbuf[6] = 1; argbuf[7] = 3;
2863 argsize = 8; t += 2;
2866 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
2867 argbuf[0] = 7; argbuf[1] = INDEX; argbuf[2] = 3;
2869 argbuf[4] = 1; argbuf[5] = 1;
2870 if ( *t == -MINVECTOR ) argbuf[6] = -3;
2872 argsize = 7; t += 2;
2875 else if ( *t == -INDEX ) {
2876 argbuf[0] = 7; argbuf[1] = INDEX; argbuf[2] = 3;
2878 argbuf[4] = 1; argbuf[5] = 1; argbuf[6] = 3;
2879 argsize = 7; t += 2;
2882 else if ( *t == -SNUMBER ) {
2884 argbuf[0] = 4; argbuf[1] = -t[1]; argbuf[2] = 1; argbuf[3] = -3;
2887 argbuf[0] = 4; argbuf[1] = t[1]; argbuf[2] = 1; argbuf[3] = 3;
2889 argsize = 4; t += 2;
2899 m =
AddRHS(AT.ebufnum,1);
2901 for ( i = 0; i < argsize; i++ ) m[i] = where[i];
2905 *w++ = SUBEXPRESSION; *w++ = SUBEXPSIZE; *w++ = C->numrhs; *w++ = 1;
2906 *w++ = AT.ebufnum; FILLSUB(w);
2908 *w++ = 1; *w++ = 1; *w++ = 3;
2909 *scratch = w-scratch;
2913 newterm = AT.WorkPointer;
2914 EndSort(BHEAD newterm+ARGHEAD,1);
2917 w = newterm+ARGHEAD;
while ( *w ) w += *w;
2918 *newterm = w-newterm; newterm[1] = 0;
2919 if ( ToFast(newterm,newterm) ) {
2920 if ( *newterm <= -FUNCTION ) w = newterm+1;
2923 while ( t < tstop ) *w++ = *t++;
2925 t = newterm; NCOPY(f,t,i);
2927 AT.WorkPointer = scratch;
2928 if ( AT.WorkPointer > AT.WorkSpace && AT.WorkPointer < f ) AT.WorkPointer = f;
2941int RunIsLyndon(PHEAD WORD *fun, WORD *args,
int par)
2943 WORD *tt, totarg, *tstop, arg1, arg2, arg, num, *f, n, i;
2945 WORD sign, i1, i2, retval;
2946 if ( fun[0] <= GAMMASEVEN && fun[0] >= GAMMA )
return(0);
2947 if ( *args != ARGRANGE ) {
2948 MLOCK(ErrorMessageLock);
2949 MesPrint(
"Illegal range encountered in RunIsLyndon");
2950 MUNLOCK(ErrorMessageLock);
2953 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2954 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2955 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2956 if ( arg1 > totarg || arg2 > totarg )
return(-1);
2960 if ( arg1 == arg2 )
return(1);
2961 if ( arg2 < arg1 ) {
2962 arg = arg1; arg1 = arg2; arg2 = arg; sign = 1;
2967 WantAddPointers(num);
2968 f = fun+FUNHEAD; n = 1; i = 0;
2969 while ( n < arg1 ) { n++; NEXTARG(f) }
2971 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2978 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2979 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2980 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2988 for ( i1 = 1; i1 < num; i1++ ) {
2989 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+i1],
2990 AT.pWorkSpace[AT.pWorkPointer]);
2991 if ( retval > 0 )
continue;
2992 if ( retval < 0 )
return(0);
2993 for ( i2 = 1; i2 < num; i2++ ) {
2994 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num],
2995 AT.pWorkSpace[AT.pWorkPointer+i2]);
2996 if ( retval < 0 )
return(0);
2997 if ( retval > 0 )
goto nexti1;
3019WORD RunToLyndon(PHEAD WORD *fun, WORD *args,
int par)
3021 WORD *tt, totarg, *tstop, arg1, arg2, arg, num, *f, *f1, *f2, n, i;
3022 WORD sign, i1, i2, retval, unique;
3023 if ( fun[0] <= GAMMASEVEN && fun[0] >= GAMMA )
return(0);
3024 if ( *args != ARGRANGE ) {
3025 MLOCK(ErrorMessageLock);
3026 MesPrint(
"Illegal range encountered in RunToLyndon");
3027 MUNLOCK(ErrorMessageLock);
3030 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3031 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3032 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3033 if ( arg1 > totarg || arg2 > totarg )
return(-1);
3037 if ( arg1 == arg2 )
return(1);
3038 if ( arg2 < arg1 ) {
3039 arg = arg1; arg1 = arg2; arg2 = arg; sign = 1;
3044 WantAddPointers((2*num));
3045 f = fun+FUNHEAD; n = 1; i = 0;
3046 while ( n < arg1 ) { n++; NEXTARG(f) }
3048 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
3055 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
3056 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
3057 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3066 for ( i1 = 1; i1 < num; i1++ ) {
3067 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+i1],
3068 AT.pWorkSpace[AT.pWorkPointer]);
3069 if ( retval > 0 )
continue;
3075 for ( i2 = 0; i2 < num; i2++ ) {
3076 AT.pWorkSpace[AT.pWorkPointer+num+i2] =
3077 AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num];
3079 for ( i2 = 0; i2 < num; i2++ ) {
3080 AT.pWorkSpace[AT.pWorkPointer+i2] =
3081 AT.pWorkSpace[AT.pWorkPointer+i2+num];
3086 for ( i2 = 1; i2 < num; i2++ ) {
3087 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num],
3088 AT.pWorkSpace[AT.pWorkPointer+i2]);
3089 if ( retval < 0 )
goto Rotate;
3090 if ( retval > 0 )
goto nexti1;
3101 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
3102 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
3103 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3110 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
3112 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
3120 MLOCK(ErrorMessageLock);
3122 MUNLOCK(ErrorMessageLock);
3131int RunDropArg(PHEAD WORD *fun, WORD *args)
3133 WORD *t, *tstop, *f, totarg, arg1, arg2, n;
3135 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3136 while ( t < tstop ) { totarg++; NEXTARG(t); }
3137 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3138 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
3139 if ( arg1 > totarg )
return(0);
3140 if ( arg2 < 1 )
return(0);
3141 if ( arg1 < 1 ) arg1 = 1;
3142 if ( arg2 > totarg ) arg2 = totarg;
3143 f = fun+FUNHEAD; n = 1;
3144 while ( n < arg1 ) { n++; NEXTARG(f) }
3146 while ( n <= arg2 ) { n++; NEXTARG(t) }
3147 while ( t < tstop ) *f++ = *t++;
3157int RunSelectArg(PHEAD WORD *fun, WORD *args)
3159 WORD *t, *tstop, *f, *tt, totarg, arg1, arg2, n;
3161 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3162 while ( t < tstop ) { totarg++; NEXTARG(t); }
3163 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3164 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
3165 if ( arg1 > totarg )
return(0);
3166 if ( arg2 < 1 )
return(0);
3167 if ( arg1 < 1 ) arg1 = 1;
3168 if ( arg2 > totarg ) arg2 = totarg;
3169 f = fun+FUNHEAD; n = 1; t = f;
3170 while ( n < arg1 ) { n++; NEXTARG(t) }
3171 while ( n <= arg2 ) {
3173 while ( t < tt ) *f++ = *t++;
3185int RunZtoHArg(PHEAD WORD *fun, WORD *args)
3187 WORD *tt, totarg, *tstop, arg1, arg2, n, i, *f, *f1;
3189 WORD *t, *t1, *t2, *t3;
3190 if ( *args != ARGRANGE ) {
3191 MLOCK(ErrorMessageLock);
3192 MesPrint(
"Illegal range encountered in RunZtoHArg.");
3193 MUNLOCK(ErrorMessageLock);
3196 if ( functions[fun[0]-FUNCTION].spec != 0 ) {
3197 MLOCK(ErrorMessageLock);
3198 MesPrint(
"The ZtoH transformation can only be executed on regular functions with nonzero integer arguments.");
3199 MUNLOCK(ErrorMessageLock);
3202 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3203 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3204 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3208 f = fun+FUNHEAD; n = 1;
3209 while ( n < arg1 ) { n++; NEXTARG(f) }
3211 for ( i = arg1; i <= arg2; i++, f += 2 ) {
3212 if ( *f != -SNUMBER || f[1] == 0 )
return(-1);
3217 t = f1; t1 = t2 = tt = TermMalloc(
"RunZtoHArg");
3218 while ( t < f ) { *t1++ = *t++; *t1++ = *t++; }
3224 while ( t3 < f ) { t3[1] = -t3[1]; t3 += 2; }
3228 TermFree(tt,
"RunZtoHArg");
3232 while ( f1 < f ) {
if ( f1[1] < 0 ) sign = 1-sign; f1 += 2; }
3241int RunHtoZArg(PHEAD WORD *fun, WORD *args)
3243 WORD *tt, totarg, *tstop, arg1, arg2, n, i, *f, *f1, *f2;
3246 if ( *args != ARGRANGE ) {
3247 MLOCK(ErrorMessageLock);
3248 MesPrint(
"Illegal range encountered in RunZtoHArg.");
3249 MUNLOCK(ErrorMessageLock);
3252 if ( functions[fun[0]-FUNCTION].spec != 0 ) {
3253 MLOCK(ErrorMessageLock);
3254 MesPrint(
"The HtoZ transformation can only be executed on regular functions with nonzero integer arguments.");
3255 MUNLOCK(ErrorMessageLock);
3258 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3259 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3260 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3264 f = fun+FUNHEAD; n = 1;
3265 while ( n < arg1 ) { n++; NEXTARG(f) }
3267 for ( i = arg1; i <= arg2; i++, f += 2 ) {
3268 if ( *f != -SNUMBER || f[1] == 0 )
return(-1);
3273 while ( f2 < f ) {
if ( f2[1] < 0 ) sign = 1-sign; f2 += 2; }
3277 t = f1; t1 = tt = TermMalloc(
"RunHtoZArg");
3278 while ( t < f ) { *t1++ = *t++; *t1++ = *t++; }
3282 t = f1; t2 = tt + 2;
3285 if ( t2[-1] < 0 ) t[1] = -t[1];
3288 TermFree(tt,
"RunHtoZArg");
3307int TestArgNum(
int n,
int totarg, WORD *args)
3316 if ( n == args[1] )
return(1);
3317 if ( args[1] >= MAXPOSITIVE4 ) {
3318 x1 = args[1]-MAXPOSITIVE4;
3319 if ( totarg-x1 == n )
return(1);
3324 if ( args[1] >= MAXPOSITIVE2 ) {
3325 x1 = args[1] - MAXPOSITIVE2;
3326 if ( x1 > MAXPOSITIVE4 ) {
3327 x1 = x1 - MAXPOSITIVE4;
3328 x1 = DolToNumber(BHEAD x1);
3332 x1 = DolToNumber(BHEAD x1);
3335 else if ( args[1] >= MAXPOSITIVE4 ) {
3336 x1 = totarg-(args[1]-MAXPOSITIVE4);
3339 if ( args[2] >= MAXPOSITIVE2 ) {
3340 x2 = args[2] - MAXPOSITIVE2;
3341 if ( x2 > MAXPOSITIVE4 ) {
3342 x2 = x2 - MAXPOSITIVE4;
3343 x2 = DolToNumber(BHEAD x2);
3347 x2 = DolToNumber(BHEAD x2);
3350 else if ( args[2] >= MAXPOSITIVE4 ) {
3351 x2 = totarg-(args[2]-MAXPOSITIVE4);
3355 if ( n >= x2 && n <= x1 )
return(1);
3358 if ( n >= x1 && n <= x2 )
return(1);
3376WORD PutArgInScratch(WORD *arg,UWORD *scrat)
3379 if ( *arg == -SNUMBER ) {
3380 scrat[0] = ABS(arg[1]);
3381 if ( arg[1] < 0 ) size = -1;
3386 if ( *t < 0 ) { i = ((-*t)-1)/2; size = -i; }
3387 else { i = ( *t -1)/2; size = i; }
3412UBYTE *ReadRange(UBYTE *s, WORD *out,
int par)
3414 UBYTE *in = s, *ss, c;
3418 if ( par == 0 && in[1] !=
'=' ) {
3419 MesPrint(
"&A range in this type of transform statement should be followed by an = sign");
3422 else if ( par == 1 && in[1] !=
',' && in[1] !=
'\0' ) {
3423 MesPrint(
"&A range in this type of transform statement should be followed by a comma or end-of-statement");
3426 else if ( par == 2 && in[1] !=
':' ) {
3427 MesPrint(
"&A range in this type of transform statement should be followed by a :");
3431 if ( FG.cTable[*s] == 0 ) {
3432 ss = s;
while ( FG.cTable[*s] == 0 ) s++;
3434 if ( StrICmp(ss,(UBYTE *)
"first") == 0 ) {
3438 else if ( StrICmp(ss,(UBYTE *)
"last") == 0 ) {
3444 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3446 if ( ( x1 = GetDollar(ss) ) < 0 )
goto Error;
3452 while ( *s >=
'0' && *s <=
'9' ) {
3453 x1 = 10*x1 + *s++ -
'0';
3454 if ( x1 >= MAXPOSITIVE4 ) {
3455 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3462 else x1 = MAXPOSITIVE4;
3465 MesPrint(
"&Illegal keyword inside range specification");
3469 else if ( FG.cTable[*s] == 1 ) {
3471 while ( *s >=
'0' && *s <=
'9' ) {
3472 x1 = x1*10 + *s++ -
'0';
3473 if ( x1 >= MAXPOSITIVE4 ) {
3474 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3479 else if ( *s ==
'$' ) {
3481 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3483 if ( ( x1 = GetDollar(ss) ) < 0 )
goto Error;
3488 MesPrint(
"&Illegal character in range specification");
3492 MesPrint(
"&A range is two indicators, separated by a comma or blank");
3496 if ( FG.cTable[*s] == 0 ) {
3497 ss = s;
while ( FG.cTable[*s] == 0 ) s++;
3499 if ( StrICmp(ss,(UBYTE *)
"first") == 0 ) {
3503 else if ( StrICmp(ss,(UBYTE *)
"last") == 0 ) {
3509 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3511 if ( ( x2 = GetDollar(ss) ) < 0 )
goto Error;
3517 while ( *s >=
'0' && *s <=
'9' ) {
3518 x2 = 10*x2 + *s++ -
'0';
3519 if ( x2 >= MAXPOSITIVE4 ) {
3520 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3527 else x2 = MAXPOSITIVE4;
3530 MesPrint(
"&Illegal keyword inside range specification");
3534 else if ( FG.cTable[*s] == 1 ) {
3536 while ( *s >=
'0' && *s <=
'9' ) {
3537 x2 = x2*10 + *s++ -
'0';
3538 if ( x2 >= MAXPOSITIVE4 ) {
3539 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3544 else if ( *s ==
'$' ) {
3546 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3548 if ( ( x2 = GetDollar(ss) ) < 0 )
goto Error;
3553 MesPrint(
"&Illegal character in range specification");
3557 MesPrint(
"&A range is two indicators, separated by a comma or blank between parentheses");
3560 out[0] = x1; out[1] = x2;
3563 MesPrint(
"&Undefined variable $%s in range",ss);
3572int FindRange(PHEAD WORD *args, WORD *arg1, WORD *arg2, WORD totarg)
3574 WORD n[2], fromlast, i;
3575 for ( i = 0; i < 2; i++ ) {
3578 if ( n[i] >= MAXPOSITIVE2 ) {
3579 n[i] -= MAXPOSITIVE2;
3580 if ( n[i] >= MAXPOSITIVE4 ) {
3582 n[i] -= MAXPOSITIVE4;
3584 n[i] = DolToNumber(BHEAD n[i]);
3585 if ( AN.ErrorInDollar ) {
3586 MLOCK(ErrorMessageLock);
3587 MesPrint(
"Illegal $ value in range while executing transform statement.");
3588 MUNLOCK(ErrorMessageLock);
3591 if ( fromlast ) n[i] = totarg-n[i];
3593 else if ( n[i] >= MAXPOSITIVE4 ) { n[i] = totarg-(n[i]-MAXPOSITIVE4); }
3595 MLOCK(ErrorMessageLock);
3596 MesPrint(
"Illegal non-positive value in range (%d) while executing transform statement.", i+1);
3597 MUNLOCK(ErrorMessageLock);
UBYTE * SkipAName(UBYTE *s)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)