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 AT.WildMask = &mask;
1632 if ( *t == -SYMBOL || ( *t > 0 && CheckWild(BHEAD WILDARGSYMBOL,SYMTOSUB,1,t) == 0 )
1638 n1 = SYMBOL; n2 = WILDARGSYMBOL;
1642 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1643 *term3++ = DUMFUN; term3++; FILLFUN(term3)
1644 COPY1ARG(term3,info1)
1647 *term3++ = fun[0]; term3++; FILLFUN(term3)
1650 term2[2] = term3 - term2 - 1;
1652 *term3++ = REPLACEMENT;
1653 term3++; FILLFUN(term3)
1655 if ( n1 < FUNCTION ) *term3++ = n2;
1656 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1658 COPY1ARG(term3,term4)
1664 *term3++ = 1; *term3++ = 1; *term3++ = 3;
1665 *term2 = term3 - term2;
1667 AT.WorkPointer = term3;
1669 if (
Generator(BHEAD term2,AR.Cnumlhs) ) {
1671 AT.WorkPointer = oldwork;
1672 AT.WildMask = oldmask;
1675 term4 = AT.WorkPointer;
1676 if (
EndSort(BHEAD term4,1) < 0 ) {}
1677 if ( ( *term4 && *(term4+*term4) != 0 ) || *term4 == 0 ) {
1678 MLOCK(ErrorMessageLock);
1679 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1680 MUNLOCK(ErrorMessageLock);
1686 i = term4[2]-FUNHEAD;
1687 term3 = term4+FUNHEAD+1;
1689 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1693 AT.WorkPointer = term2;
1697 info1 += 2; NEXTARG(info1)
1699 else if ( ( *info1 == -INDEX )
1700 && ( info[1] == WILDARGINDEX + AM.OffsetIndex ) ) {
1702 wild[2] = WILDARGINDEX+AM.OffsetIndex;
1704 AN.WildValue = wild;
1705 AT.WildMask = &mask;
1708 if ( ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION )
1709 || ( *t == -INDEX || ( *t > 0 && CheckWild(BHEAD WILDARGINDEX,INDTOSUB,1,t) == 0 ) ) ) {
1714 n1 = INDEX; n2 = WILDARGINDEX+AM.OffsetIndex;
1718 info1 += 2; NEXTARG(info1)
1720 else if ( ( *info1 == -VECTOR )
1721 && ( info1[1] == WILDARGVECTOR + AM.OffsetVector ) ) {
1723 wild[2] = WILDARGVECTOR+AM.OffsetVector;
1725 AN.WildValue = wild;
1726 AT.WildMask = &mask;
1729 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
1730 if ( *t < MINSPEC ) {
1731 n1 = VECTOR; n2 = WILDARGVECTOR+AM.OffsetVector;
1736 else if ( *t == -VECTOR || *t == -MINVECTOR ||
1737 ( *t > 0 && CheckWild(BHEAD WILDARGVECTOR,VECTOSUB,1,t) == 0 ) ) {
1742 n1 = VECTOR; n2 = WILDARGVECTOR+AM.OffsetVector;
1746 info1 += 2; NEXTARG(info1)
1748 else if ( *info1 == -WILDARGFUN ) {
1750 wild[2] = WILDARGFUN;
1752 AN.WildValue = wild;
1753 AT.WildMask = &mask;
1756 if ( *t <= -FUNCTION || ( *t > 0 && CheckWild(BHEAD WILDARGFUN,FUNTOFUN,1,t) == 0 ) ) {
1761 n2 = n1 = -WILDARGFUN;
1765 info1++; NEXTARG(info1)
1768 NEXTARG(info1) NEXTARG(info1)
1772 if ( ngeneral > 0 ) {
1780 term3 = term2; term4 = term1; i = *term1;
1781 NCOPY(term3,term4,i)
1783 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1784 *term3++ = DUMFUN; term3++; FILLFUN(term3);
1789 *term3++ = fun[0]; term3++; FILLFUN(term3); *term3++ = *t;
1791 term4[1] = term3-term4;
1792 *term3++ = 1; *term3++ = 1; *term3++ = 3;
1793 *term2 = term3-term2;
1794 AT.WorkPointer = term3;
1796 if (
Generator(BHEAD term2,AR.Cnumlhs) ) {
1798 AT.WorkPointer = oldwork;
1799 AT.WildMask = oldmask;
1802 term4 = AT.WorkPointer;
1803 if (
EndSort(BHEAD term4,1) < 0 ) {}
1804 if ( ( *term4 && *(term4+*term4) != 0 ) || *term4 == 0 ) {
1805 MLOCK(ErrorMessageLock);
1806 MesPrint(
"&information in replace transformation does not evaluate into a single term");
1807 MUNLOCK(ErrorMessageLock);
1813 i = term4[2]-FUNHEAD;
1814 term3 = term4+FUNHEAD+1;
1817 AT.WorkPointer = term2;
1825 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
1826 if ( *t <= -FUNCTION ) { *u++ = *t++; }
1827 else if ( *t < 0 ) { *u++ = *t++; *u++ = *t++; }
1828 else { i = *t; NCOPY(u,t,i) }
1835 i = u - tstop; tstop[1] = i; tstop[2] = dirty;
1836 t = fun; u = tstop; NCOPY(t,u,i)
1837 AT.WorkPointer = oldwork;
1838 AT.WildMask = oldmask;
1849int RunImplode(WORD *fun, WORD *args)
1852 WORD *tt, *tstop, totarg, arg1, arg2, num1, num2, i1, n;
1853 WORD *f, *t, *ttt, *t4, *ff, *fff;
1854 WORD moveup, numzero, outspace;
1855 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
1856 if ( *args != ARGRANGE ) {
1857 MLOCK(ErrorMessageLock);
1858 MesPrint(
"Illegal range encountered in RunImplode");
1859 MUNLOCK(ErrorMessageLock);
1862 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
1863 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
1864 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
1868 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; }
1869 else { num1 = arg1; num2 = arg2; }
1870 if ( num1 > totarg || num2 > totarg )
return(0);
1876 n = 1; f = fun+FUNHEAD;
1877 while ( n < num1 ) {
1878 if ( f >= tstop )
return(0);
1894 while ( n <= num2 ) {
1895 if ( f >= tstop )
return(0);
1896 if ( *f == -SNUMBER ) { *tt++ = -1; *tt++ = 0;
1897 if ( f[1] < 0 ) { *tt++ = -f[1]; *tt++ = -1; }
1898 else { *tt++ = f[1]; *tt++ = 1; }
1901 else if ( *f == -SYMBOL ) { *tt++ = f[1]; *tt++ = 1; *tt++ = 1; *tt++ = 1; f += 2; }
1902 else if ( *f < 0 )
return(0);
1904 if ( *f != ( f[ARGHEAD]+ARGHEAD ) )
return(0);
1907 if ( ( i1 > 3 ) || ( t[-1] != 1 ) )
return(0);
1908 if ( (UWORD)(t[-2]) > MAXPOSITIVE4 )
return(0);
1909 if ( f[ARGHEAD] == i1+1 ) {
1910 *tt++ = -1; *tt++ = 0; *tt++ = t[-2];
1911 if ( *t < 0 ) { *tt++ = -1; }
1914 else if ( ( f[ARGHEAD+1] != SYMBOL )
1915 || ( f[ARGHEAD+2] != 4 )
1916 || ( ( f+ARGHEAD+1+f[ARGHEAD+2] ) < ( t-i1 ) ) )
return(0);
1919 *tt++ = f[ARGHEAD+3];
1920 *tt++ = f[ARGHEAD+4];
1922 if ( *t < 0 ) { *tt++ = -1; }
1935 if ( arg1 > arg2 ) {
1939 t = tt - 4; numzero = 0;
1940 while ( t >= tstop ) {
1941 if ( t[2] == 0 ) numzero++;
1943 if ( numzero > 0 ) {
1946 ttt = t4 + 4*numzero;
1947 while ( ttt < tt ) *t4++ = *ttt++;
1957 numzero = 0; ttt = t;
1959 if ( t[2] == 0 ) numzero++;
1961 if ( numzero > 0 ) {
1964 while ( t4 < tt ) *ttt++ = *t4++;
1984 t = tstop; outspace = 0;
1987 if ( t[2] > MAXPOSITIVE4 ) {
return(0); }
1990 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) { outspace += 2; }
1991 else { outspace += 8 + ARGHEAD; }
1994 if ( outspace < (fff-ff) ) {
1997 if ( t[0] == -1 ) { *ff++ = -SNUMBER; *ff++ = t[2]*t[3]; }
1998 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) {
1999 *ff++ = -SYMBOL; *ff++ = t[0];
2002 *ff++ = 8+ARGHEAD; *ff++ = 0; FILLARG(ff);
2003 *ff++ = 8; *ff++ = SYMBOL; *ff++ = 4; *ff++ = t[0]; *ff++ = t[1];
2004 *ff++ = t[2]; *ff++ = 1; *ff++ = t[3] > 0 ? 3: -3;
2008 while ( fff < tstop ) *ff++ = *fff++;
2011 else if ( outspace > (fff-ff) ) {
2017 moveup = outspace-(fff-ff);
2020 while ( t > fff ) *--ttt = *--t;
2021 tt += moveup; tstop += moveup;
2030 if ( t[0] == -1 ) { *ff++ = -SNUMBER; *ff++ = t[2]*t[3]; }
2031 else if ( t[1] == 1 && t[2] == 1 && t[3] == 1 ) {
2032 *ff++ = -SYMBOL; *ff++ = t[0];
2035 *ff++ = 8+ARGHEAD; *ff++ = 0; FILLARG(ff);
2036 *ff++ = 8; *ff++ = SYMBOL; *ff++ = 4; *ff++ = t[0]; *ff++ = t[1];
2037 *ff++ = t[2]; *ff++ = 1; *ff++ = t[3] > 0 ? 3: -3;
2050int RunExplode(PHEAD WORD *fun, WORD *args)
2052 WORD arg1, arg2, num1, num2, *tt, *tstop, totarg, *tonew, *newfun;
2054 int reverse = 0, iarg, i, numzero;
2055 if ( functions[fun[0]-FUNCTION].spec != 0 )
return(0);
2056 if ( *args != ARGRANGE ) {
2057 MLOCK(ErrorMessageLock);
2058 MesPrint(
"Illegal range encountered in RunExplode");
2059 MUNLOCK(ErrorMessageLock);
2062 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2063 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2064 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2068 if ( arg1 > arg2 ) { num1 = arg2; num2 = arg1; reverse = 1; }
2069 else { num1 = arg1; num2 = arg2; }
2070 if ( num1 > totarg || num2 > totarg )
return(0);
2071 if ( tstop + AM.MaxTer > AT.WorkTop )
goto OverWork;
2076 tonew = newfun = tstop;
2077 ff = fun + FUNHEAD; iarg = 0;
2078 while ( ff < tstop ) {
2080 if ( iarg == num1 ) {
2081 i = ff - fun; f = fun;
2090 while ( iarg <= num2 ) {
2091 if ( *ff == -SYMBOL || ( *ff == -SNUMBER && ff[1] == 0 ) )
2092 { *tonew++ = *ff++; *tonew++ = *ff++; }
2093 else if ( *ff == -SNUMBER ) {
2094 numzero = ABS(ff[1])-1;
2096 *tonew++ = -SNUMBER; *tonew++ = ff[1] < 0 ? -1: 1;
2097 while ( numzero > 0 ) {
2098 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2102 while ( numzero > 0 ) {
2103 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2105 *tonew++ = -SNUMBER; *tonew++ = ff[1] < 0 ? -1: 1;
2109 else if ( *ff < 0 ) {
return(0); }
2111 if ( *ff != ARGHEAD+8 || ff[ARGHEAD] != 8
2112 || ff[ARGHEAD+1] != SYMBOL || ABS(ff[ARGHEAD+7]) != 3
2113 || ff[ARGHEAD+6] != 1 )
return(0);
2114 numzero = ff[ARGHEAD+5];
2115 if ( numzero >= MAXPOSITIVE4 )
return(0);
2118 if ( ff[ARGHEAD+7] > 0 ) { *tonew++ = -SNUMBER; *tonew++ = 1; }
2120 *tonew++ = ARGHEAD+8; *tonew++ = 0; FILLARG(tonew)
2121 *tonew++ = 8; *tonew++ = SYMBOL; *tonew++ = ff[ARGHEAD+3];
2122 *tonew++ = ff[ARGHEAD+4]; *tonew++ = 1; *tonew++ = 1;
2125 while ( numzero > 0 ) {
2126 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2130 while ( numzero > 0 ) {
2131 *tonew++ = -SNUMBER; *tonew++ = 0; numzero--;
2133 *tonew++ = ARGHEAD+8; *tonew++ = 0; FILLARG(tonew)
2134 *tonew++ = 8; *tonew++ = SYMBOL; *tonew++ = 4;
2135 *tonew++ = ff[ARGHEAD+3]; *tonew++ = ff[ARGHEAD+4];
2136 *tonew++ = 1; *tonew++ = 1;
2137 if ( ff[ARGHEAD+7] > 0 ) *tonew++ = 3;
2142 if ( tonew > AT.WorkTop )
goto OverWork;
2148 while ( ff < tstop ) *tonew++ = *ff++;
2149 i = newfun[1] = tonew-newfun;
2153 MLOCK(ErrorMessageLock);
2155 MUNLOCK(ErrorMessageLock);
2164int RunPermute(PHEAD WORD *fun, WORD *args, WORD *info)
2166 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, *f, *f1, *f2, *infostop;
2167 WORD *in, *iw, withdollar;
2169 if ( *args != ARGRANGE ) {
2170 MLOCK(ErrorMessageLock);
2171 MesPrint(
"Illegal range encountered in RunPermute");
2172 MUNLOCK(ErrorMessageLock);
2175 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2176 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2177 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2178 arg1 = 1; arg2 = totarg;
2187 WantAddPointers(num);
2188 f = fun+FUNHEAD; n = 1; i = 0;
2189 while ( n < arg1 ) { n++; NEXTARG(f) }
2191 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2197 infostop = info + *info;
2199 if ( *info > totarg )
return(0);
2204 withdollar = 0; in = info;
2205 while ( in < infostop ) {
2207 d = Dollars - *in - 1;
2210 int nummodopt, dtype = -1, numdollar = -*in-1;
2211 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2212 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2213 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2215 if ( nummodopt < NumModOptdollars ) {
2216 dtype = ModOptdollars[nummodopt].type;
2217 if ( DollarLocalCopy(dtype) ) {
2218 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2221 LOCK(d->pthreadslock);
2227 if ( ( d->type == DOLNUMBER || d->type == DOLTERMS )
2228 && d->where[0] == 4 && d->where[4] == 0 ) {
2229 if ( d->where[3] < 0 || d->where[2] != 1 || d->where[1] > totarg )
return(0);
2231 else if ( d->type == DOLWILDARGS ) {
2234 if ( *iw == -SNUMBER ) {
2235 if ( iw[1] <= 0 || iw[1] > totarg )
return(0);
2243 MLOCK(ErrorMessageLock);
2244 MesPrint(
"Illegal type of $-variable in RunPermute");
2245 MUNLOCK(ErrorMessageLock);
2250 else if ( *in > totarg )
return(0);
2254 WORD *incopy, *tocopy;
2255 incopy = TermMalloc(
"RunPermute");
2256 tocopy = incopy+1; in = info;
2257 while ( in < infostop ) {
2259 d = Dollars - *in - 1;
2262 int nummodopt, dtype = -1, numdollar = -*in-1;
2263 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
2264 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2265 if ( numdollar == ModOptdollars[nummodopt].number )
break;
2267 if ( nummodopt < NumModOptdollars ) {
2268 dtype = ModOptdollars[nummodopt].type;
2269 if ( DollarLocalCopy(dtype) ) {
2270 d = ModOptdollars[nummodopt].dstruct+AT.identity;
2273 LOCK(d->pthreadslock);
2279 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
2280 *tocopy++ = d->where[1] - 1;
2282 else if ( d->type == DOLWILDARGS ) {
2285 *tocopy++ = iw[1] - 1;
2291 else *tocopy++ = *in++;
2294 *incopy = tocopy - incopy;
2296 tt = AT.pWorkSpace[AT.pWorkPointer+*in];
2298 while ( in < tocopy ) {
2299 if ( *in > totarg )
return(0);
2300 AT.pWorkSpace[AT.pWorkPointer+in[-1]] = AT.pWorkSpace[AT.pWorkPointer+*in];
2303 AT.pWorkSpace[AT.pWorkPointer+in[-1]] = tt;
2304 TermFree(incopy,
"RunPermute");
2308 tt = AT.pWorkSpace[AT.pWorkPointer+*info];
2310 while ( info < infostop ) {
2311 if ( *info > totarg )
return(0);
2312 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = AT.pWorkSpace[AT.pWorkPointer+*info];
2315 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = tt;
2337 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2339 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2344 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop-tt;
2345 arg1 = 1; arg2 = totarg;
2347 WantAddPointers(num);
2348 f = fun+FUNHEAD; n = 1; i = 0;
2349 while ( n < arg1 ) { n++; f++; }
2351 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2357 infostop = info + *info;
2359 if ( *info > totarg )
return(0);
2360 tt = AT.pWorkSpace[AT.pWorkPointer+*info];
2362 while ( info < infostop ) {
2363 if ( *info > totarg )
return(0);
2364 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = AT.pWorkSpace[AT.pWorkPointer+*info];
2367 AT.pWorkSpace[AT.pWorkPointer+info[-1]] = tt;
2372 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2374 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++= *f++; }
2380 MLOCK(ErrorMessageLock);
2382 MUNLOCK(ErrorMessageLock);
2391int RunReverse(PHEAD WORD *fun, WORD *args)
2393 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, *f, *f1, *f2, i1, i2;
2394 if ( *args != ARGRANGE ) {
2395 MLOCK(ErrorMessageLock);
2396 MesPrint(
"Illegal range encountered in RunReverse");
2397 MUNLOCK(ErrorMessageLock);
2400 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2401 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2402 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2403 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2411 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2412 if ( arg2 > totarg )
return(0);
2415 WantAddPointers(num);
2416 f = fun+FUNHEAD; n = 1; i = 0;
2417 while ( n < arg1 ) { n++; NEXTARG(f) }
2419 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2422 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2423 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2424 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2427 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2429 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2434 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2435 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2443 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2444 if ( arg2 > totarg )
return(0);
2447 WantAddPointers(num);
2448 f = fun+FUNHEAD; n = 1; i = 0;
2449 while ( n < arg1 ) { n++; f++; }
2451 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2454 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2455 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2456 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2459 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2461 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++ = *f++; }
2467 MLOCK(ErrorMessageLock);
2469 MUNLOCK(ErrorMessageLock);
2478int RunDedup(PHEAD WORD *fun, WORD *args)
2480 WORD *tt, totarg, *tstop, arg1, arg2, n, i, j,k, *f, *f1, *f2, *fd, *fstart;
2481 if ( *args != ARGRANGE ) {
2482 MLOCK(ErrorMessageLock);
2483 MesPrint(
"Illegal range encountered in RunDedup");
2484 MUNLOCK(ErrorMessageLock);
2487 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2488 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2489 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2490 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2492 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2493 if ( arg2 > totarg )
return(0);
2495 f = fun+FUNHEAD; n = 1;
2496 while ( n < arg1 ) { n++; NEXTARG(f) }
2501 for (; n <= arg2; n++ ) {
2503 for ( j = 0; j < i; j++ ) {
2506 for ( k = 0; k < fd-f2; k++ )
2507 if ( f2[k] != f[k] )
break;
2509 if ( k == fd-f2 )
break;
2523 for (j = n; j <= totarg; j++) {
2530 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2531 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2533 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2534 if ( arg2 > totarg )
return(0);
2540 for (; n <= arg2; n++ ) {
2541 for ( j = arg1; j < i; j++ ) {
2542 if ( f[n-1] == f[j-1] )
break;
2553 for (j = n; j <= totarg; j++, i++) {
2557 fun[1] = f + i - 1 - fun;
2567int RunCycle(PHEAD WORD *fun, WORD *args, WORD *info)
2569 WORD *tt, totarg, *tstop, arg1, arg2, n, num, i, j, *f, *f1, *f2, x, ncyc, cc;
2570 if ( *args != ARGRANGE ) {
2571 MLOCK(ErrorMessageLock);
2572 MesPrint(
"Illegal range encountered in RunCycle");
2573 MUNLOCK(ErrorMessageLock);
2577 if ( ncyc >= MAXPOSITIVE2 ) {
2578 ncyc -= MAXPOSITIVE2;
2579 if ( ncyc >= MAXPOSITIVE4 ) {
2580 ncyc -= MAXPOSITIVE4;
2584 ncyc = DolToNumber(BHEAD ncyc);
2585 if ( AN.ErrorInDollar ) {
2586 MesPrint(
" Error in Dollar variable in transform,cycle()=$");
2589 if ( ncyc >= MAXPOSITIVE4 || ncyc <= -MAXPOSITIVE4 ) {
2590 MesPrint(
" Illegal value from Dollar variable in transform,cycle()=$");
2595 if ( functions[fun[0]-FUNCTION].spec != TENSORFUNCTION ) {
2596 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2597 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2598 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2599 if ( arg1 > arg2 ) { n = arg1; arg1 = arg2; arg2 = n; }
2600 if ( arg2 > totarg )
return(0);
2609 WantAddPointers(num);
2610 f = fun+FUNHEAD; n = 1; i = 0;
2611 while ( n < arg1 ) { n++; NEXTARG(f) }
2613 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2620 if ( x > i/2 ) x -= i;
2622 else if ( x <= -i ) {
2624 if ( x <= -i/2 ) x += i;
2628 tt = AT.pWorkSpace[AT.pWorkPointer+i-1];
2629 for ( j = i-1; j > 0; j-- )
2630 AT.pWorkSpace[AT.pWorkPointer+j] = AT.pWorkSpace[AT.pWorkPointer+j-1];
2631 AT.pWorkSpace[AT.pWorkPointer] = tt;
2635 tt = AT.pWorkSpace[AT.pWorkPointer];
2636 for ( j = 1; j < i; j++ )
2637 AT.pWorkSpace[AT.pWorkPointer+j-1] = AT.pWorkSpace[AT.pWorkPointer+j];
2638 AT.pWorkSpace[AT.pWorkPointer+j-1] = tt;
2645 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2647 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
2652 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = tstop - tt;
2653 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2654 if ( arg1 > arg2 ) { n = arg1; arg1 = arg2; arg2 = n; }
2655 if ( arg2 > totarg )
return(0);
2664 WantAddPointers(num);
2665 f = fun+FUNHEAD; n = 1; i = 0;
2666 while ( n < arg1 ) { n++; f++; }
2668 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; f++; }
2675 if ( x > i/2 ) x -= i;
2677 else if ( x <= -i ) {
2679 if ( x <= -i/2 ) x += i;
2683 tt = AT.pWorkSpace[AT.pWorkPointer+i-1];
2684 for ( j = i-1; j > 0; j-- )
2685 AT.pWorkSpace[AT.pWorkPointer+j] = AT.pWorkSpace[AT.pWorkPointer+j-1];
2686 AT.pWorkSpace[AT.pWorkPointer] = tt;
2690 tt = AT.pWorkSpace[AT.pWorkPointer];
2691 for ( j = 1; j < i; j++ )
2692 AT.pWorkSpace[AT.pWorkPointer+j-1] = AT.pWorkSpace[AT.pWorkPointer+j];
2693 AT.pWorkSpace[AT.pWorkPointer+j-1] = tt;
2700 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
2702 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; *f2++ = *f++; }
2708 MLOCK(ErrorMessageLock);
2710 MUNLOCK(ErrorMessageLock);
2719int RunAddArg(PHEAD WORD *fun, WORD *args)
2721 WORD *tt, totarg, *tstop, arg1, arg2, n, num, *f, *f1, *f2;
2722 WORD scribble[10+ARGHEAD];
2724 if ( *args != ARGRANGE ) {
2725 MLOCK(ErrorMessageLock);
2726 MesPrint(
"Illegal range encountered in RunAddArg");
2727 MUNLOCK(ErrorMessageLock);
2730 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
2731 MLOCK(ErrorMessageLock);
2732 MesPrint(
"Illegal attempt to add arguments of a tensor in AddArg");
2733 MUNLOCK(ErrorMessageLock);
2736 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2737 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2739 if ( totarg == 0 )
return(0);
2740 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2751 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2752 if ( arg2 > totarg )
return(0);
2754 if ( num == 1 )
return(0);
2755 f = fun+FUNHEAD; n = 1;
2756 while ( n < arg1 ) { n++; NEXTARG(f) }
2759 while ( n <= arg2 ) {
2761 f2 = f + *f; f += ARGHEAD;
2762 while ( f < f2 ) {
StoreTerm(BHEAD f); f += *f; }
2764 else if ( *f == -SNUMBER && f[1] == 0 ) {
2768 ToGeneral(f,scribble,1);
2774 if (
EndSort(BHEAD tstop+ARGHEAD,1) < 0 )
return(-1);
2777 while ( *f2 ) { f2 += *f2; num++; }
2779 for ( n = 1; n < ARGHEAD; n++ ) tstop[n] = 0;
2780 if ( num == 1 && ToFast(tstop,tstop) == 1 ) {
2781 f2 = tstop; NEXTARG(f2);
2783 if ( *tstop == ARGHEAD ) {
2784 *tstop = -SNUMBER; tstop[1] = 0;
2790 while ( f < tstop ) *f2++ = *f++;
2791 while ( f < f2 ) *f1++ = *f++;
2793 if ( (space+8)*
sizeof(WORD) > (UWORD)AM.MaxTer ) {
2794 MLOCK(ErrorMessageLock);
2796 MUNLOCK(ErrorMessageLock);
2799 fun[1] = (WORD)space;
2808int RunMulArg(PHEAD WORD *fun, WORD *args)
2810 WORD *t, totarg, *tstop, arg1, arg2, n, *f, nb, *m, i, *w;
2811 WORD *scratch, argbuf[20], argsize, *where, *newterm;
2812 LONG oldcpointer_pos;
2813 CBUF *C = cbuf + AT.ebufnum;
2814 if ( *args != ARGRANGE ) {
2815 MLOCK(ErrorMessageLock);
2816 MesPrint(
"Illegal range encountered in RunMulArg");
2817 MUNLOCK(ErrorMessageLock);
2820 if ( functions[fun[0]-FUNCTION].spec == TENSORFUNCTION ) {
2821 MLOCK(ErrorMessageLock);
2822 MesPrint(
"Illegal attempt to multiply arguments of a tensor in MulArg");
2823 MUNLOCK(ErrorMessageLock);
2826 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2827 while ( t < tstop ) { totarg++; NEXTARG(t); }
2829 if ( totarg == 0 )
return(0);
2830 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2831 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
2832 if ( arg1 > totarg )
return(0);
2833 if ( arg2 < 1 )
return(0);
2834 if ( arg1 < 1 ) arg1 = 1;
2835 if ( arg2 > totarg ) arg2 = totarg;
2836 if ( arg1 == arg2 )
return(0);
2844 f = fun+FUNHEAD; n = 1;
2845 while ( n < arg1 ) { n++; NEXTARG(f) }
2847 if ( fun >= AT.WorkSpace && fun < AT.WorkTop ) {
2848 if ( AT.WorkPointer < fun+fun[1] ) AT.WorkPointer = fun+fun[1];
2850 scratch = AT.WorkPointer;
2854 while ( n <= arg2 ) {
2856 argsize = *t - ARGHEAD; where = t + ARGHEAD; t += *t;
2858 else if ( *t <= -FUNCTION ) {
2859 argbuf[0] = FUNHEAD+4; argbuf[1] = -*t++; argbuf[2] = FUNHEAD;
2860 for ( i = 2; i < FUNHEAD; i++ ) argbuf[i+1] = 0;
2861 argbuf[FUNHEAD+1] = 1;
2862 argbuf[FUNHEAD+2] = 1;
2863 argbuf[FUNHEAD+3] = 3;
2864 argsize = argbuf[0];
2867 else if ( *t == -SYMBOL ) {
2868 argbuf[0] = 8; argbuf[1] = SYMBOL; argbuf[2] = 4;
2869 argbuf[3] = t[1]; argbuf[4] = 1;
2870 argbuf[5] = 1; argbuf[6] = 1; argbuf[7] = 3;
2871 argsize = 8; t += 2;
2874 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
2875 argbuf[0] = 7; argbuf[1] = INDEX; argbuf[2] = 3;
2877 argbuf[4] = 1; argbuf[5] = 1;
2878 if ( *t == -MINVECTOR ) argbuf[6] = -3;
2880 argsize = 7; t += 2;
2883 else if ( *t == -INDEX ) {
2884 argbuf[0] = 7; argbuf[1] = INDEX; argbuf[2] = 3;
2886 argbuf[4] = 1; argbuf[5] = 1; argbuf[6] = 3;
2887 argsize = 7; t += 2;
2890 else if ( *t == -SNUMBER ) {
2892 argbuf[0] = 4; argbuf[1] = -t[1]; argbuf[2] = 1; argbuf[3] = -3;
2895 argbuf[0] = 4; argbuf[1] = t[1]; argbuf[2] = 1; argbuf[3] = 3;
2897 argsize = 4; t += 2;
2907 m =
AddRHS(AT.ebufnum,1);
2909 for ( i = 0; i < argsize; i++ ) m[i] = where[i];
2913 *w++ = SUBEXPRESSION; *w++ = SUBEXPSIZE; *w++ = C->numrhs; *w++ = 1;
2914 *w++ = AT.ebufnum; FILLSUB(w);
2916 *w++ = 1; *w++ = 1; *w++ = 3;
2917 *scratch = w-scratch;
2921 newterm = AT.WorkPointer;
2922 EndSort(BHEAD newterm+ARGHEAD,1);
2925 w = newterm+ARGHEAD;
while ( *w ) w += *w;
2926 *newterm = w-newterm; newterm[1] = 0;
2927 if ( ToFast(newterm,newterm) ) {
2928 if ( *newterm <= -FUNCTION ) w = newterm+1;
2931 while ( t < tstop ) *w++ = *t++;
2933 t = newterm; NCOPY(f,t,i);
2935 AT.WorkPointer = scratch;
2936 if ( AT.WorkPointer > AT.WorkSpace && AT.WorkPointer < f ) AT.WorkPointer = f;
2949int RunIsLyndon(PHEAD WORD *fun, WORD *args,
int par)
2951 WORD *tt, totarg, *tstop, arg1, arg2, arg, num, *f, n, i;
2953 WORD sign, i1, i2, retval;
2954 if ( fun[0] <= GAMMASEVEN && fun[0] >= GAMMA )
return(0);
2955 if ( *args != ARGRANGE ) {
2956 MLOCK(ErrorMessageLock);
2957 MesPrint(
"Illegal range encountered in RunIsLyndon");
2958 MUNLOCK(ErrorMessageLock);
2961 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
2962 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
2963 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
2964 if ( arg1 > totarg || arg2 > totarg )
return(-1);
2968 if ( arg1 == arg2 )
return(1);
2969 if ( arg2 < arg1 ) {
2970 arg = arg1; arg1 = arg2; arg2 = arg; sign = 1;
2975 WantAddPointers(num);
2976 f = fun+FUNHEAD; n = 1; i = 0;
2977 while ( n < arg1 ) { n++; NEXTARG(f) }
2979 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
2986 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
2987 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
2988 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
2996 for ( i1 = 1; i1 < num; i1++ ) {
2997 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+i1],
2998 AT.pWorkSpace[AT.pWorkPointer]);
2999 if ( retval > 0 )
continue;
3000 if ( retval < 0 )
return(0);
3001 for ( i2 = 1; i2 < num; i2++ ) {
3002 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num],
3003 AT.pWorkSpace[AT.pWorkPointer+i2]);
3004 if ( retval < 0 )
return(0);
3005 if ( retval > 0 )
goto nexti1;
3027WORD RunToLyndon(PHEAD WORD *fun, WORD *args,
int par)
3029 WORD *tt, totarg, *tstop, arg1, arg2, arg, num, *f, *f1, *f2, n, i;
3030 WORD sign, i1, i2, retval, unique;
3031 if ( fun[0] <= GAMMASEVEN && fun[0] >= GAMMA )
return(0);
3032 if ( *args != ARGRANGE ) {
3033 MLOCK(ErrorMessageLock);
3034 MesPrint(
"Illegal range encountered in RunToLyndon");
3035 MUNLOCK(ErrorMessageLock);
3038 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3039 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3040 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3041 if ( arg1 > totarg || arg2 > totarg )
return(-1);
3045 if ( arg1 == arg2 )
return(1);
3046 if ( arg2 < arg1 ) {
3047 arg = arg1; arg1 = arg2; arg2 = arg; sign = 1;
3052 WantAddPointers((2*num));
3053 f = fun+FUNHEAD; n = 1; i = 0;
3054 while ( n < arg1 ) { n++; NEXTARG(f) }
3056 while ( n <= arg2 ) { AT.pWorkSpace[AT.pWorkPointer+i++] = f; n++; NEXTARG(f) }
3063 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
3064 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
3065 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3074 for ( i1 = 1; i1 < num; i1++ ) {
3075 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+i1],
3076 AT.pWorkSpace[AT.pWorkPointer]);
3077 if ( retval > 0 )
continue;
3083 for ( i2 = 0; i2 < num; i2++ ) {
3084 AT.pWorkSpace[AT.pWorkPointer+num+i2] =
3085 AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num];
3087 for ( i2 = 0; i2 < num; i2++ ) {
3088 AT.pWorkSpace[AT.pWorkPointer+i2] =
3089 AT.pWorkSpace[AT.pWorkPointer+i2+num];
3094 for ( i2 = 1; i2 < num; i2++ ) {
3095 retval = par * CompArg(AT.pWorkSpace[AT.pWorkPointer+(i1+i2)%num],
3096 AT.pWorkSpace[AT.pWorkPointer+i2]);
3097 if ( retval < 0 )
goto Rotate;
3098 if ( retval > 0 )
goto nexti1;
3109 tt = AT.pWorkSpace[AT.pWorkPointer+i1];
3110 AT.pWorkSpace[AT.pWorkPointer+i1] = AT.pWorkSpace[AT.pWorkPointer+i2];
3111 AT.pWorkSpace[AT.pWorkPointer+i2] = tt;
3118 if ( tstop+(f-f1) > AT.WorkTop )
goto OverWork;
3120 for ( i = 0; i < num; i++ ) { f = AT.pWorkSpace[AT.pWorkPointer+i]; COPY1ARG(f2,f) }
3128 MLOCK(ErrorMessageLock);
3130 MUNLOCK(ErrorMessageLock);
3139int RunDropArg(PHEAD WORD *fun, WORD *args)
3141 WORD *t, *tstop, *f, totarg, arg1, arg2, n;
3143 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3144 while ( t < tstop ) { totarg++; NEXTARG(t); }
3145 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3146 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
3147 if ( arg1 > totarg )
return(0);
3148 if ( arg2 < 1 )
return(0);
3149 if ( arg1 < 1 ) arg1 = 1;
3150 if ( arg2 > totarg ) arg2 = totarg;
3151 f = fun+FUNHEAD; n = 1;
3152 while ( n < arg1 ) { n++; NEXTARG(f) }
3154 while ( n <= arg2 ) { n++; NEXTARG(t) }
3155 while ( t < tstop ) *f++ = *t++;
3165int RunSelectArg(PHEAD WORD *fun, WORD *args)
3167 WORD *t, *tstop, *f, *tt, totarg, arg1, arg2, n;
3169 t = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3170 while ( t < tstop ) { totarg++; NEXTARG(t); }
3171 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3172 if ( arg2 < arg1 ) { n = arg1; arg1 = arg2; arg2 = n; }
3173 if ( arg1 > totarg )
return(0);
3174 if ( arg2 < 1 )
return(0);
3175 if ( arg1 < 1 ) arg1 = 1;
3176 if ( arg2 > totarg ) arg2 = totarg;
3177 f = fun+FUNHEAD; n = 1; t = f;
3178 while ( n < arg1 ) { n++; NEXTARG(t) }
3179 while ( n <= arg2 ) {
3181 while ( t < tt ) *f++ = *t++;
3193int RunZtoHArg(PHEAD WORD *fun, WORD *args)
3195 WORD *tt, totarg, *tstop, arg1, arg2, n, i, *f, *f1;
3197 WORD *t, *t1, *t2, *t3;
3198 if ( *args != ARGRANGE ) {
3199 MLOCK(ErrorMessageLock);
3200 MesPrint(
"Illegal range encountered in RunZtoHArg.");
3201 MUNLOCK(ErrorMessageLock);
3204 if ( functions[fun[0]-FUNCTION].spec != 0 ) {
3205 MLOCK(ErrorMessageLock);
3206 MesPrint(
"The ZtoH transformation can only be executed on regular functions with nonzero integer arguments.");
3207 MUNLOCK(ErrorMessageLock);
3210 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3211 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3212 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3216 f = fun+FUNHEAD; n = 1;
3217 while ( n < arg1 ) { n++; NEXTARG(f) }
3219 for ( i = arg1; i <= arg2; i++, f += 2 ) {
3220 if ( *f != -SNUMBER || f[1] == 0 )
return(-1);
3225 t = f1; t1 = t2 = tt = TermMalloc(
"RunZtoHArg");
3226 while ( t < f ) { *t1++ = *t++; *t1++ = *t++; }
3232 while ( t3 < f ) { t3[1] = -t3[1]; t3 += 2; }
3236 TermFree(tt,
"RunZtoHArg");
3240 while ( f1 < f ) {
if ( f1[1] < 0 ) sign = 1-sign; f1 += 2; }
3249int RunHtoZArg(PHEAD WORD *fun, WORD *args)
3251 WORD *tt, totarg, *tstop, arg1, arg2, n, i, *f, *f1, *f2;
3254 if ( *args != ARGRANGE ) {
3255 MLOCK(ErrorMessageLock);
3256 MesPrint(
"Illegal range encountered in RunZtoHArg.");
3257 MUNLOCK(ErrorMessageLock);
3260 if ( functions[fun[0]-FUNCTION].spec != 0 ) {
3261 MLOCK(ErrorMessageLock);
3262 MesPrint(
"The HtoZ transformation can only be executed on regular functions with nonzero integer arguments.");
3263 MUNLOCK(ErrorMessageLock);
3266 tt = fun+FUNHEAD; tstop = fun+fun[1]; totarg = 0;
3267 while ( tt < tstop ) { totarg++; NEXTARG(tt); }
3268 if ( FindRange(BHEAD args,&arg1,&arg2,totarg) )
return(-1);
3272 f = fun+FUNHEAD; n = 1;
3273 while ( n < arg1 ) { n++; NEXTARG(f) }
3275 for ( i = arg1; i <= arg2; i++, f += 2 ) {
3276 if ( *f != -SNUMBER || f[1] == 0 )
return(-1);
3281 while ( f2 < f ) {
if ( f2[1] < 0 ) sign = 1-sign; f2 += 2; }
3285 t = f1; t1 = tt = TermMalloc(
"RunHtoZArg");
3286 while ( t < f ) { *t1++ = *t++; *t1++ = *t++; }
3290 t = f1; t2 = tt + 2;
3293 if ( t2[-1] < 0 ) t[1] = -t[1];
3296 TermFree(tt,
"RunHtoZArg");
3315int TestArgNum(
int n,
int totarg, WORD *args)
3324 if ( n == args[1] )
return(1);
3325 if ( args[1] >= MAXPOSITIVE4 ) {
3326 x1 = args[1]-MAXPOSITIVE4;
3327 if ( totarg-x1 == n )
return(1);
3332 if ( args[1] >= MAXPOSITIVE2 ) {
3333 x1 = args[1] - MAXPOSITIVE2;
3334 if ( x1 > MAXPOSITIVE4 ) {
3335 x1 = x1 - MAXPOSITIVE4;
3336 x1 = DolToNumber(BHEAD x1);
3340 x1 = DolToNumber(BHEAD x1);
3343 else if ( args[1] >= MAXPOSITIVE4 ) {
3344 x1 = totarg-(args[1]-MAXPOSITIVE4);
3347 if ( args[2] >= MAXPOSITIVE2 ) {
3348 x2 = args[2] - MAXPOSITIVE2;
3349 if ( x2 > MAXPOSITIVE4 ) {
3350 x2 = x2 - MAXPOSITIVE4;
3351 x2 = DolToNumber(BHEAD x2);
3355 x2 = DolToNumber(BHEAD x2);
3358 else if ( args[2] >= MAXPOSITIVE4 ) {
3359 x2 = totarg-(args[2]-MAXPOSITIVE4);
3363 if ( n >= x2 && n <= x1 )
return(1);
3366 if ( n >= x1 && n <= x2 )
return(1);
3384WORD PutArgInScratch(WORD *arg,UWORD *scrat)
3387 if ( *arg == -SNUMBER ) {
3388 scrat[0] = ABS(arg[1]);
3389 if ( arg[1] < 0 ) size = -1;
3394 if ( *t < 0 ) { i = ((-*t)-1)/2; size = -i; }
3395 else { i = ( *t -1)/2; size = i; }
3420UBYTE *ReadRange(UBYTE *s, WORD *out,
int par)
3422 UBYTE *in = s, *ss, c;
3426 if ( par == 0 && in[1] !=
'=' ) {
3427 MesPrint(
"&A range in this type of transform statement should be followed by an = sign");
3430 else if ( par == 1 && in[1] !=
',' && in[1] !=
'\0' ) {
3431 MesPrint(
"&A range in this type of transform statement should be followed by a comma or end-of-statement");
3434 else if ( par == 2 && in[1] !=
':' ) {
3435 MesPrint(
"&A range in this type of transform statement should be followed by a :");
3439 if ( FG.cTable[*s] == 0 ) {
3440 ss = s;
while ( FG.cTable[*s] == 0 ) s++;
3442 if ( StrICmp(ss,(UBYTE *)
"first") == 0 ) {
3446 else if ( StrICmp(ss,(UBYTE *)
"last") == 0 ) {
3452 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3454 if ( ( x1 = GetDollar(ss) ) < 0 )
goto Error;
3460 while ( *s >=
'0' && *s <=
'9' ) {
3461 x1 = 10*x1 + *s++ -
'0';
3462 if ( x1 >= MAXPOSITIVE4 ) {
3463 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3470 else x1 = MAXPOSITIVE4;
3473 MesPrint(
"&Illegal keyword inside range specification");
3477 else if ( FG.cTable[*s] == 1 ) {
3479 while ( *s >=
'0' && *s <=
'9' ) {
3480 x1 = x1*10 + *s++ -
'0';
3481 if ( x1 >= MAXPOSITIVE4 ) {
3482 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3487 else if ( *s ==
'$' ) {
3489 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3491 if ( ( x1 = GetDollar(ss) ) < 0 )
goto Error;
3496 MesPrint(
"&Illegal character in range specification");
3500 MesPrint(
"&A range is two indicators, separated by a comma or blank");
3504 if ( FG.cTable[*s] == 0 ) {
3505 ss = s;
while ( FG.cTable[*s] == 0 ) s++;
3507 if ( StrICmp(ss,(UBYTE *)
"first") == 0 ) {
3511 else if ( StrICmp(ss,(UBYTE *)
"last") == 0 ) {
3517 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3519 if ( ( x2 = GetDollar(ss) ) < 0 )
goto Error;
3525 while ( *s >=
'0' && *s <=
'9' ) {
3526 x2 = 10*x2 + *s++ -
'0';
3527 if ( x2 >= MAXPOSITIVE4 ) {
3528 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3535 else x2 = MAXPOSITIVE4;
3538 MesPrint(
"&Illegal keyword inside range specification");
3542 else if ( FG.cTable[*s] == 1 ) {
3544 while ( *s >=
'0' && *s <=
'9' ) {
3545 x2 = x2*10 + *s++ -
'0';
3546 if ( x2 >= MAXPOSITIVE4 ) {
3547 MesPrint(
"&Fixed range indicator bigger than %l",(LONG)MAXPOSITIVE4);
3552 else if ( *s ==
'$' ) {
3554 while ( FG.cTable[*s] == 0 || FG.cTable[*s] == 1 ) s++;
3556 if ( ( x2 = GetDollar(ss) ) < 0 )
goto Error;
3561 MesPrint(
"&Illegal character in range specification");
3565 MesPrint(
"&A range is two indicators, separated by a comma or blank between parentheses");
3568 out[0] = x1; out[1] = x2;
3571 MesPrint(
"&Undefined variable $%s in range",ss);
3580int FindRange(PHEAD WORD *args, WORD *arg1, WORD *arg2, WORD totarg)
3582 WORD n[2], fromlast, i;
3583 for ( i = 0; i < 2; i++ ) {
3586 if ( n[i] >= MAXPOSITIVE2 ) {
3587 n[i] -= MAXPOSITIVE2;
3588 if ( n[i] >= MAXPOSITIVE4 ) {
3590 n[i] -= MAXPOSITIVE4;
3592 n[i] = DolToNumber(BHEAD n[i]);
3593 if ( AN.ErrorInDollar ) {
3594 MLOCK(ErrorMessageLock);
3595 MesPrint(
"Illegal $ value in range while executing transform statement.");
3596 MUNLOCK(ErrorMessageLock);
3599 if ( fromlast ) n[i] = totarg-n[i];
3601 else if ( n[i] >= MAXPOSITIVE4 ) { n[i] = totarg-(n[i]-MAXPOSITIVE4); }
3603 MLOCK(ErrorMessageLock);
3604 MesPrint(
"Illegal non-positive value in range (%d) while executing transform statement.", i+1);
3605 MUNLOCK(ErrorMessageLock);
UBYTE * SkipAName(UBYTE *s)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)