47static KEYWORD formatoptions[] = {
48 {
"allfloat", (TFUN)0, ALLINTEGERDOUBLE, 0}
49 ,{
"c", (TFUN)0, CMODE, 0}
50 ,{
"doublefortran", (TFUN)0, DOUBLEFORTRANMODE, 0}
51 ,{
"float", (TFUN)0, 0, 2}
53 ,{
"floatprecision", (TFUN)0, 0, 5}
55 ,{
"fortran", (TFUN)0, FORTRANMODE, 0}
56 ,{
"fortran90", (TFUN)0, FORTRANMODE, 4}
57 ,{
"maple", (TFUN)0, MAPLEMODE, 0}
58 ,{
"mathematica", (TFUN)0, MATHEMATICAMODE, 0}
59 ,{
"normal", (TFUN)0, NORMALFORMAT, 1}
60 ,{
"nospaces", (TFUN)0, NOSPACEFORMAT, 3}
61 ,{
"pfortran", (TFUN)0, PFORTRANMODE, 0}
62 ,{
"quadfortran", (TFUN)0, QUADRUPLEFORTRANMODE, 0}
63 ,{
"quadruplefortran", (TFUN)0, QUADRUPLEFORTRANMODE, 0}
64 ,{
"rational", (TFUN)0, RATIONALMODE, 1}
65 ,{
"reduce", (TFUN)0, REDUCEMODE, 0}
66 ,{
"spaces", (TFUN)0, NORMALFORMAT, 3}
67 ,{
"vortran", (TFUN)0, VORTRANMODE, 0}
70static KEYWORD trace4options[] = {
71 {
"contract", (TFUN)0, CHISHOLM, 0 }
72 ,{
"nocontract", (TFUN)0, 0, CHISHOLM }
73 ,{
"nosymmetrize",(TFUN)0, 0, ALSOREVERSE}
74 ,{
"notrick", (TFUN)0, NOTRICK, 0 }
75 ,{
"symmetrize", (TFUN)0, ALSOREVERSE, 0 }
76 ,{
"trick", (TFUN)0, 0, NOTRICK }
80 {
"nosymmetrize",(TFUN)0, 0, ALSOREVERSE}
81 ,{
"symmetrize", (TFUN)0, ALSOREVERSE, 0 }
85 {
"stats", &(AC.StatsFlag), 1, 0}
86 ,{
"statistics", &(AC.StatsFlag), 1, 0}
87 ,{
"shortstats", &(AC.ShortStats), 1, 0}
88 ,{
"shortstatistics",&(AC.ShortStats), 1, 0}
89 ,{
"warnings", &(AC.WarnFlag), 1, 0}
90 ,{
"allwarnings", &(AC.WarnFlag), 2, 0}
91 ,{
"setup", &(AC.SetupFlag), 1, 0}
92 ,{
"names", &(AC.NamesFlag), 1, 0}
93 ,{
"allnames", &(AC.NamesFlag), 2, 0}
94 ,{
"codes", &(AC.CodesFlag), 1, 0}
95 ,{
"highfirst", &(AC.SortType), SORTHIGHFIRST, SORTLOWFIRST}
96 ,{
"lowfirst", &(AC.SortType), SORTLOWFIRST, SORTHIGHFIRST}
97 ,{
"powerfirst", &(AC.SortType), SORTPOWERFIRST, SORTHIGHFIRST}
98 ,{
"tokens", &(AC.TokensWriteFlag),1, 0}
102 {
"compress", &(AC.NoCompress), 0, 1}
103 ,{
"checkpoint", &(AC.CheckpointFlag), 1, 0}
104 ,{
"insidefirst", &(AC.insidefirst), 1, 0}
105 ,{
"propercount", &(AC.BottomLevel), 1, 0}
106 ,{
"stats", &(AC.StatsFlag), 1, 0}
107 ,{
"statistics", &(AC.StatsFlag), 1, 0}
108 ,{
"shortstats", &(AC.ShortStats), 1, 0}
109 ,{
"shortstatistics",&(AC.ShortStats), 1, 0}
110 ,{
"names", &(AC.NamesFlag), 1, 0}
111 ,{
"allnames", &(AC.NamesFlag), 2, 0}
112 ,{
"warnings", &(AC.WarnFlag), 1, 0}
113 ,{
"allwarnings", &(AC.WarnFlag), 2, 0}
114 ,{
"highfirst", &(AC.SortType), SORTHIGHFIRST, SORTLOWFIRST}
115 ,{
"lowfirst", &(AC.SortType), SORTLOWFIRST, SORTHIGHFIRST}
116 ,{
"powerfirst", &(AC.SortType), SORTPOWERFIRST, SORTHIGHFIRST}
117 ,{
"setup", &(AC.SetupFlag), 1, 0}
118 ,{
"codes", &(AC.CodesFlag), 1, 0}
119 ,{
"tokens", &(AC.TokensWriteFlag),1,0}
120 ,{
"properorder", &(AC.properorderflag),1,0}
121 ,{
"threadloadbalancing",&(AC.ThreadBalancing),1, 0}
122 ,{
"threads", &(AC.ThreadsFlag),1, 0}
123 ,{
"threadsortfilesynch",&(AC.ThreadSortFileSynch),1, 0}
124 ,{
"threadstats", &(AC.ThreadStats),1, 0}
125 ,{
"finalstats", &(AC.FinalStats),1, 0}
126 ,{
"fewerstats", &(AC.ShortStatsMax), 10, 0}
127 ,{
"fewerstatistics",&(AC.ShortStatsMax), 10, 0}
128 ,{
"processstats", &(AC.ProcessStats),1, 0}
129 ,{
"oldparallelstats",&(AC.OldParallelStats),1,0}
130 ,{
"parallel", &(AC.parallelflag),PARALLELFLAG,NOPARALLEL_USER}
131 ,{
"nospacesinnumbers",&(AO.NoSpacesInNumbers),1,0}
132 ,{
"indentspace", &(AO.IndentSpace),INDENTSPACE,0}
133 ,{
"totalsize", &(AM.PrintTotalSize), 1, 0}
134 ,{
"flag", (
int *)&(AC.debugFlags), 1, 0}
135 ,{
"oldfactarg", &(AC.OldFactArgFlag), 1, 0}
136 ,{
"memdebugflag", &(AC.MemDebugFlag), 1, 0}
137 ,{
"oldgcd", &(AC.OldGCDflag), 1, 0}
138 ,{
"oldprfsign", &(AC.OldPRFSignFlag), 1, 0}
139 ,{
"innertest", &(AC.InnerTest), 1, 0}
140 ,{
"wtimestats", &(AC.WTimeStatsFlag), 1, 0}
141 ,{
"sortreallocate", &(AC.SortReallocateFlag), 1, 0}
142 ,{
"backtrace", &(AC.PrintBacktraceFlag), 1, 0}
143 ,{
"flint", &(AC.FlintPolyFlag), 1, 0}
144 ,{
"humanstats", &(AC.HumanStatsFlag), 1, 0}
145 ,{
"humanstatistics", &(AC.HumanStatsFlag), 1, 0}
146 ,{
"grccverbose", &(AC.GrccVerbose), 1, 0}
147 ,{
"sortverbose", &(AC.SortVerbose), 1, 0}
157int CoFormat(UBYTE *s)
162 while ( *s ==
' ' || *s ==
',' ) s++;
165 AC.OutputSpaces = NORMALFORMAT;
171 if ( *s ==
'O' || *s ==
'o' ) {
172 if ( ( FG.cTable[s[1]] == 1 ) ||
173 ( s[1] ==
'=' && FG.cTable[s[2]] == 1 ) ) {
174 s++;
if ( *s ==
'=' ) s++;
176 while ( *s >=
'0' && *s <=
'9' ) x = 10*x + *s++ -
'0';
177 while ( *s ==
',' ) s++;
178 AO.OptimizationLevel = x;
179 AO.Optimize.greedytimelimit = 0;
180 AO.Optimize.mctstimelimit = 0;
181 AO.Optimize.printstats = 0;
182 AO.Optimize.debugflags = 0;
183 AO.Optimize.schemeflags = 0;
184 AO.Optimize.mctsdecaymode = 1;
186 M_free(AO.inscheme,
"Horner input scheme");
187 AO.inscheme = 0; AO.schemenum = 0;
193 AO.Optimize.mctsconstant.fval = -1.0;
194 AO.Optimize.horner = O_OCCURRENCE;
195 AO.Optimize.hornerdirection = O_FORWARDORBACKWARD;
196 AO.Optimize.method = O_CSE;
199 AO.Optimize.horner = O_OCCURRENCE;
200 AO.Optimize.hornerdirection = O_FORWARDORBACKWARD;
201 AO.Optimize.method = O_GREEDY;
202 AO.Optimize.greedyminnum = 10;
203 AO.Optimize.greedymaxperc = 5;
206 AO.Optimize.mctsconstant.fval = 1.0;
207 AO.Optimize.horner = O_MCTS;
208 AO.Optimize.hornerdirection = O_FORWARDORBACKWARD;
209 AO.Optimize.method = O_GREEDY;
210 AO.Optimize.mctsnumexpand = 1000;
211 AO.Optimize.mctsnumkeep = 10;
212 AO.Optimize.mctsnumrepeat = 1;
213 AO.Optimize.greedyminnum = 10;
214 AO.Optimize.greedymaxperc = 5;
217 AO.Optimize.horner = O_SIMULATED_ANNEALING;
218 AO.Optimize.saIter = 1000;
219 AO.Optimize.saMaxT.fval = 2000;
220 AO.Optimize.saMinT.fval = 1;
224 MesPrint(
"&Illegal optimization specification in format statement");
227 if ( error == 0 && *s != 0 && x > 0 )
return(CoOptimizeOption(s));
233 while ( FG.cTable[*s] == 0 ) s++;
235 if ( StrICont(ss,(UBYTE *)
"optimize") == 0 ) {
237 while ( *s ==
',' ) s++;
238 if ( *s ==
'=' ) s++;
239 AO.OptimizationLevel = 3;
240 AO.Optimize.mctsconstant.fval = 1.0;
241 AO.Optimize.horner = O_MCTS;
242 AO.Optimize.hornerdirection = O_FORWARDORBACKWARD;
243 AO.Optimize.method = O_GREEDY;
244 AO.Optimize.mctstimelimit = 0;
245 AO.Optimize.mctsnumexpand = 1000;
246 AO.Optimize.mctsnumkeep = 10;
247 AO.Optimize.mctsnumrepeat = 1;
248 AO.Optimize.greedytimelimit = 0;
249 AO.Optimize.greedyminnum = 10;
250 AO.Optimize.greedymaxperc = 5;
251 AO.Optimize.printstats = 0;
252 AO.Optimize.debugflags = 0;
253 AO.Optimize.schemeflags = 0;
254 AO.Optimize.mctsdecaymode = 1;
256 M_free(AO.inscheme,
"Horner input scheme");
257 AO.inscheme = 0; AO.schemenum = 0;
259 return(CoOptimizeOption(s));
263 MesPrint(
"&Illegal optimization specification in format statement");
269 else if ( FG.cTable[*s] == 1 ) {
271 while ( FG.cTable[*s] == 1 ) x = 10*x + *s++ -
'0';
272 if ( x <= 0 || x >= MAXLINELENGTH ) {
274 MesPrint(
"&Illegal value for linesize: %d",x);
278 MesPrint(
" ... Too small value for linesize corrected to 39");
291 MesPrint(
"&Illegal linesize field in format statement");
295 key = FindKeyWord(s,formatoptions,
296 sizeof(formatoptions)/
sizeof(
KEYWORD));
298 if ( key->type == FORTRANMODE || key->type == PFORTRANMODE || key->type == DOUBLEFORTRANMODE
299 || key->type == QUADRUPLEFORTRANMODE || key->type == VORTRANMODE ) {
300 if (AC.LineLength > 72) AC.LineLength = 72;
302 if ( key->flags == 0 ) {
303 if ( key->type == FORTRANMODE || key->type == PFORTRANMODE
304 || key->type == DOUBLEFORTRANMODE || key->type == ALLINTEGERDOUBLE
305 || key->type == QUADRUPLEFORTRANMODE || key->type == VORTRANMODE ) {
306 AC.IsFortran90 = ISNOTFORTRAN90;
307 if ( AC.Fortran90Kind ) {
308 M_free(AC.Fortran90Kind,
"Fortran90 Kind");
309 AC.Fortran90Kind = 0;
312 if ( ( key->type == ALLINTEGERDOUBLE ) && AO.DoubleFlag != 0 ) {
317 AC.OutputMode = key->type & NODOUBLEMASK;
318 if ( ( key->type & DOUBLEPRECISIONFLAG ) != 0 ) {
321 else if ( ( key->type & QUADRUPLEPRECISIONFLAG ) != 0 ) {
326 else if ( key->flags == 1 ) {
327 AC.OutputMode = AC.OutNumberType = key->type;
329 else if ( key->flags == 2 ) {
330 while ( FG.cTable[*s] == 0 ) s++;
331 if ( *s == 0 ) AC.OutNumberType = 10;
332 else if ( *s ==
',' ) {
335 while ( FG.cTable[*s] == 1 ) x = 10*x + *s++ -
'0';
338 MesPrint(
"&Illegal float format specifier");
343 MesPrint(
"& ... float format value corrected to 3");
347 MesPrint(
"& ... float format value corrected to 100");
349 AC.OutNumberType = x;
353 else if ( key->flags == 3 ) {
354 AC.OutputSpaces = key->type;
356 else if ( key->flags == 4 ) {
357 AC.IsFortran90 = ISFORTRAN90;
358 if ( AC.Fortran90Kind ) {
359 M_free(AC.Fortran90Kind,
"Fortran90 Kind");
360 AC.Fortran90Kind = 0;
362 while ( FG.cTable[*s] <= 1 ) s++;
365 while ( *ss && *ss !=
',' ) ss++;
367 MesPrint(
"&No white space or comma's allowed in Fortran90 option: %s",s); error = 1;
370 AC.Fortran90Kind = strDup1(s,
"Fortran90 Kind");
374 AC.OutputMode = key->type & NODOUBLEMASK;
377 else if ( key->flags == 5 ) {
382 while ( FG.cTable[*s] == 0 ) s++;
383 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
387 else if ( tolower(*s) ==
'o' && tolower(s[1]) ==
'f'
388 && tolower(s[2]) ==
'f' ) {
391 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
392 if ( *s ) { s = ss;
goto WrongOption; }
395 else if ( FG.cTable[*s] == 1 ) {
397 ParseNumber(AO.FloatPrec,s)
402 if ( tolower(*s) ==
'd' ) { s++; }
403 else if ( tolower(*s) ==
'b' ) { AO.FloatPrec = AO.FloatPrec*log10(2.0); s++; }
404 else { s = ss;
goto WrongOption; }
405 while ( *s ==
' ' || *s ==
'\t' || *s ==
',' ) s++;
406 if ( *s ) { s = ss;
goto WrongOption; }
409WrongOption: MesPrint(
"&Illegal option in Format FloatPrecision: %s",s);
415 else if ( ( *s ==
'c' || *s ==
'C' ) && ( FG.cTable[s[1]] == 1 ) ) {
418 while ( *ss >=
'0' && *ss <=
'9' ) x = 10*x + *ss++ -
'0';
419 if ( *ss != 0 )
goto Unknown;
420 AC.OutputMode = CMODE;
424Unknown: MesPrint(
"&Unknown option: %s",s); error = 1;
437int CoCollect(UBYTE *s)
443 AC.AltCollectFun = 0;
444 if ( t == 0 )
goto syntaxerror;
445 t1 = t;
while ( *t1 ==
',' || *t1 ==
' ' || *t1 ==
'\t' ) t1++;
447 if ( *t1 && ( FG.cTable[*t1] == 0 || *t1 ==
'[' ) ) {
449 if ( t2 == 0 )
goto syntaxerror;
451 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
455 if ( *t && FG.cTable[*t] == 1 ) {
456 while ( *t >=
'0' && *t <=
'9' ) x = 10*x + *t++ -
'0';
457 if ( x > 100 ) x = 100;
458 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
459 if ( *t )
goto syntaxerror;
462 if ( *t )
goto syntaxerror;
465 if ( ( ( type = GetName(AC.varnames,s,&numfun,WITHAUTO) ) != CFUNCTION )
466 || ( functions[numfun].spec != 0 ) ) {
467 MesPrint(
"&%s should be a regular function",s);
469 if ( GetName(AC.exprnames,s,&numfun,NOAUTO) == NAMENOTFOUND )
470 AddFunction(s,0,0,0,0,0,-1,-1);
474 AC.CollectFun = numfun+FUNCTION;
475 AC.CollectPercentage = (WORD)x;
477 if ( ( ( type = GetName(AC.varnames,t1,&numfun,WITHAUTO) ) != CFUNCTION )
478 || ( functions[numfun].spec != 0 ) ) {
479 MesPrint(
"&%s should be a regular function",t1);
481 if ( GetName(AC.exprnames,t1,&numfun,NOAUTO) == NAMENOTFOUND )
482 AddFunction(t1,0,0,0,0,0,-1,-1);
486 AC.AltCollectFun = numfun+FUNCTION;
490 MesPrint(
"&Collect statement needs one or two functions (and a percentage) for its argument(s)");
499int setonoff(UBYTE *s,
int *flag,
int onvalue,
int offvalue)
501 if ( StrICmp(s,(UBYTE *)
"on") == 0 ) *flag = onvalue;
502 else if ( StrICmp(s,(UBYTE *)
"off") == 0 ) *flag = offvalue;
504 MesPrint(
"&Unknown option: %s, on or off expected",s);
515int CoCompress(UBYTE *s)
519 if ( StrICmp(s,(UBYTE *)
"on") == 0 ) {
523 else if ( StrICmp(s,(UBYTE *)
"off") == 0 ) {
528 t = s;
while ( FG.cTable[*t] <= 1 ) t++;
530 if ( StrICmp(s,(UBYTE *)
"gzip") == 0 ) {
532 Warning(
"gzip compression not supported on this platform");
536 AR.gzipCompress = GZIPDEFAULT;
539 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
541 if ( FG.cTable[*s] == 1 ) {
542 AR.gzipCompress = *s -
'0';
544 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
545 if ( *s == 0 )
return(0);
547 MesPrint(
"&Unknown gzip option: %s, a digit was expected",t);
552 MesPrint(
"&Unknown option: %s, on, off or gzip expected",s);
564int CoFlags(UBYTE *s,
int value)
568 MesPrint(
"&Proper syntax is: On/Off Flag,number[s];");
571 while ( *s ==
',' ) {
572 do { s++; }
while ( *s ==
',' );
574 if ( FG.cTable[*s] != 1 ) {
575 MesPrint(
"&Proper syntax is: On/Off Flag,number[s];");
579 while ( FG.cTable[*s] == 1 ) { i = 10*i + *s++ -
'0'; }
580 if ( i <= 0 || i > MAXFLAGS ) {
581 MesPrint(
"&The number of a flag in On/Off Flag should be in the range 0-%d",(
int)MAXFLAGS);
585 AC.debugFlags[i] = value;
588 MesPrint(
"&Proper syntax is: On/Off Flag,number[s];");
603 int i, num =
sizeof(onoffoptions)/
sizeof(
KEYWORD);
605 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
606 if ( *s == 0 )
return(0);
607 if ( chartype[*s] != 0 ) {
608 MesPrint(
"&Illegal character or option encountered in OFF statement");
611 t = s;
while ( chartype[*s] == 0 ) s++;
613 for ( i = 0; i < num; i++ ) {
614 if ( StrICont(t,(UBYTE *)(onoffoptions[i].name)) == 0 )
break;
617 MesPrint(
"&Unrecognized option in OFF statement: %s",t);
620 else if ( StrICont(t,(UBYTE *)
"compress") == 0 ) {
623 else if ( StrICont(t,(UBYTE *)
"checkpoint") == 0 ) {
625 AC.CheckpointInterval = 0;
626 if ( AC.CheckpointRunBefore ) { free(AC.CheckpointRunBefore); AC.CheckpointRunBefore = NULL; }
627 if ( AC.CheckpointRunAfter ) { free(AC.CheckpointRunAfter); AC.CheckpointRunAfter = NULL; }
628 if ( AC.NoShowInput == 0 ) MesPrint(
"Checkpoints deactivated.");
630 else if ( StrICont(t,(UBYTE *)
"threads") == 0 ) {
631 AS.MultiThreaded = 0;
633 else if ( StrICont(t,(UBYTE *)
"flag") == 0 ) {
635 return(CoFlags(s,0));
637 else if ( StrICont(t,(UBYTE *)
"innertest") == 0 ) {
640 if ( AC.TestValue ) {
641 M_free(AC.TestValue,
"InnerTest");
645 else if ( StrICont(t,(UBYTE *)
"sortreallocate") == 0 ) {
646 if ( AC.SortReallocateFlag == 2 ) {
654 *onoffoptions[i].var = onoffoptions[i].flags;
655 AR.SortType = AC.SortType;
656 AC.mparallelflag = AC.parallelflag | AM.hparallelflag;
669 int i, num =
sizeof(onoffoptions)/
sizeof(
KEYWORD);
672 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
673 if ( *s == 0 )
return(0);
674 if ( chartype[*s] != 0 ) {
675 MesPrint(
"&Illegal character or option encountered in ON statement");
678 t = s;
while ( chartype[*s] == 0 ) s++;
680 for ( i = 0; i < num; i++ ) {
681 if ( StrICont(t,(UBYTE *)(onoffoptions[i].name)) == 0 )
break;
684 MesPrint(
"&Unrecognized option in ON statement: %s",t);
687 if ( StrICont(t,(UBYTE *)
"backtrace") == 0 ) {
688#ifndef ENABLE_BACKTRACE
689 Warning(
"backtrace not supported on this platform");
692 else if ( StrICont(t,(UBYTE *)
"compress") == 0 ) {
695 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
698 while ( FG.cTable[*s] <= 1 ) s++;
700 if ( StrICmp(t,(UBYTE *)
"gzip") == 0 ) {
702 Warning(
"gzip compression not supported on this platform");
706 ZWRAP_useZSTDcompression(0);
709 else if ( StrICmp(t,(UBYTE *)
"zstd") == 0 ) {
711 ZWRAP_useZSTDcompression(1);
713 Warning(
"zstd compression not supported on this platform");
717 MesPrint(
"&Unrecognized option in ON compress statement: %s",t);
722 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
723 if ( FG.cTable[*s] == 1 ) {
724 AR.gzipCompress = *s++ -
'0';
725 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
727 MesPrint(
"&Unrecognized option in ON compress gzip/zstd statement: %s",t);
731 else if ( *s == 0 ) {
732 AR.gzipCompress = GZIPDEFAULT;
735 MesPrint(
"&Unrecognized option in ON compress gzip/zstd statement: %s, single digit expected",t);
740 else if ( StrICont(t,(UBYTE *)
"checkpoint") == 0 ) {
742 AC.CheckpointInterval = 0;
743 if ( AC.CheckpointRunBefore ) { free(AC.CheckpointRunBefore); AC.CheckpointRunBefore = NULL; }
744 if ( AC.CheckpointRunAfter ) { free(AC.CheckpointRunAfter); AC.CheckpointRunAfter = NULL; }
747 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
748 if ( FG.cTable[*s] == 1 ) {
751 do { interval = 10*interval + *s++ -
'0'; }
while ( FG.cTable[*s] == 1 );
752 if ( *s ==
's' || *s ==
'S' ) {
755 else if ( *s ==
'm' || *s ==
'M' ) {
758 else if ( *s ==
'h' || *s ==
'H' ) {
759 interval *= 3600; s++;
761 else if ( *s ==
'd' || *s ==
'D' ) {
762 interval *= 86400; s++;
764 if ( *s !=
',' && FG.cTable[*s] != 6 && FG.cTable[*s] != 10 ) {
765 MesPrint(
"&Unrecognized time interval in ON Checkpoint statement: %s", t);
768 AC.CheckpointInterval = interval * 100;
770 else if ( FG.cTable[*s] == 0 ) {
773 while ( FG.cTable[*s] == 0 ) s++;
775 if ( StrICmp(t,(UBYTE *)
"run") == 0 ) {
778 else if ( StrICmp(t,(UBYTE *)
"runafter") == 0 ) {
781 else if ( StrICmp(t,(UBYTE *)
"runbefore") == 0 ) {
785 MesPrint(
"&Unrecognized option in ON Checkpoint statement: %s", t);
789 if ( *s !=
'=' && FG.cTable[*(s+1)] != 9 ) {
790 MesPrint(
"&Unrecognized option in ON Checkpoint statement: %s", t);
796 if ( FG.cTable[*s] == 9 ) {
799 if ( AC.CheckpointRunBefore ) {
800 free(AC.CheckpointRunBefore); AC.CheckpointRunBefore = NULL;
803 AC.CheckpointRunBefore = Malloc1(s-t+1,
"AC.CheckpointRunBefore");
804 StrCopy(t, (UBYTE*)AC.CheckpointRunBefore);
808 if ( AC.CheckpointRunAfter ) {
809 free(AC.CheckpointRunAfter); AC.CheckpointRunAfter = NULL;
812 AC.CheckpointRunAfter = Malloc1(s-t+1,
"AC.CheckpointRunAfter");
813 StrCopy(t, (UBYTE*)AC.CheckpointRunAfter);
821 if ( FG.cTable[*s] != 9 ) {
822 MesPrint(
"&Unrecognized option in ON Checkpoint statement: %s", t);
846 else if ( StrICont(t,(UBYTE *)
"indentspace") == 0 ) {
848 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
851 while ( FG.cTable[*s] == 1 ) { i = 10*i + *s++ -
'0'; }
853 MesPrint(
"&Unrecognized option in ON IndentSpace statement: %s",t);
857 Warning(
"IndentSpace parameter adjusted to 40");
863 AO.IndentSpace = AM.ggIndentSpace;
867 else if ( ( StrICont(t,(UBYTE *)
"fewerstats") == 0 ) ||
868 ( StrICont(t,(UBYTE *)
"fewerstatistics") == 0 ) ) {
870 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
873 while ( FG.cTable[*s] == 1 ) { i = 10*i + *s++ -
'0'; }
875 MesPrint(
"&Unrecognized option in ON FewerStatistics statement: %s",t);
878 if ( i > AM.S0->MaxPatches ) {
880 MesPrint(
"&Warning: FewerStatistics parameter greater than MaxPatches(=%d). Adjusted to %d"
881 ,AM.S0->MaxPatches,(AM.S0->MaxPatches+1)/2);
882 i = (AM.S0->MaxPatches+1)/2;
884 AC.ShortStatsMax = i;
887 AC.ShortStatsMax = 10;
891 else if ( StrICont(t,(UBYTE *)
"threads") == 0 ) {
892 if ( AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
894 else if ( StrICont(t,(UBYTE *)
"flag") == 0 ) {
896 return(CoFlags(s,1));
898 else if ( StrICont(t,(UBYTE *)
"innertest") == 0 ) {
901 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
903 t = s;
while ( *t ) t++;
904 while ( t[-1] ==
' ' || t[-1] ==
'\t' ) t--;
906 if ( AC.TestValue ) M_free(AC.TestValue,
"InnerTest");
907 AC.TestValue = strDup1(s,
"InnerTest");
910 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
913 if ( AC.TestValue ) {
914 M_free(AC.TestValue,
"InnerTest");
919 else if ( StrICont(t,(UBYTE *)
"flint") == 0 ) {
921 MesPrint(
"&Warning: FORM was not built with FLINT support.");
922 MesPrint(
"Statement has no effect.");
926 *onoffoptions[i].var = onoffoptions[i].type;
927 AR.SortType = AC.SortType;
928 AC.mparallelflag = AC.parallelflag | AM.hparallelflag;
937int CoInsideFirst(UBYTE *s) {
return(setonoff(s,&AC.insidefirst,1,0)); }
944int CoProperCount(UBYTE *s) {
return(setonoff(s,&AC.BottomLevel,1,0)); }
951int CoDelete(UBYTE *s)
954 if ( StrICmp(s,(UBYTE *)
"storage") == 0 ) {
955 if ( DeleteStore(1) < 0 ) {
956 MesPrint(
"&Cannot restart storage file");
962 while ( *t && *t !=
',' && *t !=
'>' ) t++;
964 if ( ( StrICmp(s,(UBYTE *)
"extrasymbols") == 0 )
965 || ( StrICmp(s,(UBYTE *)
"extrasymbol") == 0 ) ) {
973 if ( FG.cTable[*s] != 1 )
goto unknown;
974 while ( *s <=
'9' && *s >=
'0' ) x = 10*x + *s++ -
'0';
975 if ( *s )
goto unknown;
977 else if ( *s )
goto unknown;
978 if ( x < AM.gnumextrasym ) x = AM.gnumextrasym;
979 PruneExtraSymbols(x);
984 MesPrint(
"&Unknown option: %s",s);
998 if ( StrICmp(s,(UBYTE *)
"brackets") == 0 ) AC.ComDefer = 1;
999 else { MesPrint(
"&Unknown option: '%s'",s);
return(1); }
1008int CoFixIndex(UBYTE *s)
1010 int x, y, error = 0;
1012 if ( FG.cTable[*s] != 1 ) {
1013proper: MesPrint(
"&Proper syntax is: FixIndex,number:value[,number,value];");
1017 if ( *s !=
':' )
goto proper;
1019 if ( *s !=
'-' && *s !=
'+' && FG.cTable[*s] != 1 )
goto proper;
1020 ParseSignedNumber(y,s)
1021 if ( *s && *s !=
',' )
goto proper;
1022 while ( *s ==
',' ) s++;
1023 if ( x >= AM.OffsetIndex ) {
1024 MesPrint(
"&Fixed index out of allowed range. Change ConstIndex in setup file?");
1025 MesPrint(
"&Current value of ConstIndex = %d",AM.OffsetIndex-1);
1028 if ( y != (
int)((WORD)y) ) {
1029 MesPrint(
"&Value of d_(%d,%d) outside range for this computer",x,x);
1032 if ( error == 0 ) AC.FixIndices[x] = y;
1042int CoMetric(UBYTE *s)
1043{ DUMMYUSE(s); MesPrint(
"&The metric statement does not do anything yet");
return(1); }
1050int DoPrint(UBYTE *s,
int par)
1052 int i, error = 0, numdol = 0, type;
1056 WORD numexpr, tofile = 0, *w, par2 = 0;
1057 CBUF *C = cbuf + AC.cbufnum;
1058 while ( *s ==
',' ) s++;
1059 if ( ( *s ==
'+' || *s ==
'-' ) && ( s[1] ==
'f' || s[1] ==
'F' ) ) {
1060 t = s + 2;
while ( *t ==
' ' || *t ==
',' ) t++;
1062 if ( *s ==
'+' ) { tofile = 1; handle = AC.LogHandle; }
1066 else if ( *s ==
'<' ) {
1069 while ( *s && *s !=
'>' ) s++;
1071 MesPrint(
"&Improper filename in print statement");
1076 if ( ( handle = GetChannel((
char *)filename,1) ) < 0 )
return(1);
1077 SKIPBLANKS(s)
if ( *s ==
',' ) s++; SKIPBLANKS(s)
1078 if ( *s ==
'+' && ( s[1] ==
's' || s[1] ==
'S' ) ) {
1080 par2 |= PRINTONETERM;
1081 if ( *s ==
's' || *s ==
'S' ) {
1083 par2 |= PRINTONEFUNCTION;
1084 if ( *s ==
's' || *s ==
'S' ) {
1089 SKIPBLANKS(s)
if ( *s ==
',' ) s++; SKIPBLANKS(s)
1092 if ( par == PRINTON && *s ==
'"' ) {
1094 if ( tofile == 1 ) code[0] = TYPEFPRINT;
1095 else code[0] = TYPEPRINT;
1099 while ( *s && *s !=
'"' ) {
1100 if ( *s ==
'\\' ) s++;
1101 if ( *s ==
'%' && s[1] ==
'$' ) numdol++;
1105 MesPrint(
"&String in print statement should be enclosed in \"");
1109 AddComString(3,code,name,1);
1111 while ( *s ==
',' ) {
1114 s++; name = s;
while ( FG.cTable[*s] <= 1 ) s++;
1116 type = GetName(AC.dollarnames,name,&numexpr,NOAUTO);
1117 if ( type == NAMENOTFOUND ) {
1118 MesPrint(
"&$ variable %s not (yet) defined",name);
1122 C->
lhs[C->numlhs][1] += 2;
1123 *(C->
Pointer)++ = DOLLAREXPRESSION;
1129 MesPrint(
"&Illegal object in print statement");
1137 s = GetDoParam(s,&(C->
Pointer),-1);
1138 if ( s == 0 )
return(1);
1140 MesPrint(
"&unmatched [] in $ factor");
1148 MesPrint(
"&Illegal object in print statement");
1152 MesPrint(
"&More $ variables asked for than provided");
1160 for ( e = Expressions, i = NumExpressions; i > 0; i--, e++ ) {
1161 if ( e->status == LOCALEXPRESSION || e->status ==
1162 GLOBALEXPRESSION || e->status == UNHIDELEXPRESSION
1163 || e->status == UNHIDEGEXPRESSION ) e->printflag = par;
1170 if ( tolower(*s) ==
'f' ) par |= PRINTLFILE;
1171 else if ( tolower(*s) ==
's' ) {
1172 if ( tolower(s[1]) ==
's' ) {
1173 if ( tolower(s[2]) ==
's' ) {
1174 par |= PRINTONEFUNCTION | PRINTONETERM | PRINTALL;
1177 else if ( ( par & 3 ) < 2 ) par |= PRINTONEFUNCTION | PRINTONETERM;
1181 if ( ( par & 3 ) < 2 ) par |= PRINTONETERM;
1185illeg: MesPrint(
"&Illegal option in (n)print statement");
1189 if ( *s == 0 )
goto AllExpr;
1191 else if ( *s ==
'-' ) {
1193 if ( tolower(*s) ==
'f' ) par &= ~PRINTLFILE;
1194 else if ( tolower(*s) ==
's' ) {
1195 if ( tolower(s[1]) ==
's' ) {
1196 if ( tolower(s[2]) ==
's' ) {
1200 else if ( ( par & 3 ) < 2 ) {
1201 par &= ~PRINTONEFUNCTION;
1207 if ( ( par & 3 ) < 2 ) {
1208 par &= ~PRINTONETERM;
1209 par &= ~PRINTONEFUNCTION;
1216 if ( *s == 0 )
goto AllExpr;
1218 else if ( FG.cTable[*s] == 0 || *s ==
'[' ) {
1221 MesPrint(
"&Improper name in (n)print statement");
1225 if ( ( GetName(AC.exprnames,name,&numexpr,NOAUTO) == CEXPRESSION )
1226 && ( Expressions[numexpr].status == LOCALEXPRESSION
1227 || Expressions[numexpr].status == GLOBALEXPRESSION ) ) {
1229 if ( c ==
'[' && s[1] ==
']' ) {
1230 Expressions[numexpr].printflag = par | PRINTCONTENTS;
1234 Expressions[numexpr].printflag = par;
1236 else if ( GetLastExprName(name,&numexpr)
1237 && ( Expressions[numexpr].status == LOCALEXPRESSION
1238 || Expressions[numexpr].status == GLOBALEXPRESSION
1239 || Expressions[numexpr].status == UNHIDELEXPRESSION
1240 || Expressions[numexpr].status == UNHIDEGEXPRESSION
1245 MesPrint(
"&%s is not the name of an active expression",name);
1249 if ( c == 0 )
return(0);
1250 if ( c ==
'-' || c ==
'+' ) s--;
1252 else if ( *s ==
',' ) s++;
1254 MesPrint(
"&Illegal object in (n)print statement");
1266int CoPrint(UBYTE *s) {
return(DoPrint(s,PRINTON)); }
1273int CoPrintB(UBYTE *s) {
return(DoPrint(s,PRINTCONTENT)); }
1280int CoNPrint(UBYTE *s) {
return(DoPrint(s,PRINTOFF)); }
1287int CoPushHide(UBYTE *s)
1292 if ( AR.Fscr[2].PObuffer == 0 ) {
1293 ScratchBuf = (WORD *)Malloc1(AM.HideSize*
sizeof(WORD),
"hidesize");
1294 AR.Fscr[2].POsize = AM.HideSize *
sizeof(WORD);
1295 AR.Fscr[2].POfull = AR.Fscr[2].POfill = AR.Fscr[2].PObuffer = ScratchBuf;
1296 AR.Fscr[2].POstop = AR.Fscr[2].PObuffer + AM.HideSize;
1297 PUTZERO(AR.Fscr[2].POposition);
1299 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1302 MesPrint(
"&PushHide statement should have no arguments");
1305 for ( i = 0; i < NumExpressions; i++ ) {
1306 switch ( Expressions[i].status ) {
1307 case DROPLEXPRESSION:
1308 case SKIPLEXPRESSION:
1309 case LOCALEXPRESSION:
1310 Expressions[i].status = HIDELEXPRESSION;
1311 Expressions[i].hidelevel = AC.HideLevel-1;
1313 case DROPGEXPRESSION:
1314 case SKIPGEXPRESSION:
1315 case GLOBALEXPRESSION:
1316 Expressions[i].status = HIDEGEXPRESSION;
1317 Expressions[i].hidelevel = AC.HideLevel-1;
1331int CoPopHide(UBYTE *s)
1334 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1335 if ( AC.HideLevel <= 0 ) {
1336 MesPrint(
"&PopHide statement without corresponding PushHide statement");
1341 MesPrint(
"&PopHide statement should have no arguments");
1344 for ( i = 0; i < NumExpressions; i++ ) {
1345 switch ( Expressions[i].status ) {
1346 case HIDDENLEXPRESSION:
1347 if ( Expressions[i].hidelevel > AC.HideLevel )
1348 Expressions[i].status = UNHIDELEXPRESSION;
1350 case HIDDENGEXPRESSION:
1351 if ( Expressions[i].hidelevel > AC.HideLevel )
1352 Expressions[i].status = UNHIDEGEXPRESSION;
1366int SetExprCases(
int par,
int setunset,
int val)
1371 case SKIPLEXPRESSION:
1372 if ( !setunset ) val = LOCALEXPRESSION;
1374 case SKIPGEXPRESSION:
1375 if ( !setunset ) val = GLOBALEXPRESSION;
1377 case LOCALEXPRESSION:
1378 if ( setunset ) val = SKIPLEXPRESSION;
1380 case GLOBALEXPRESSION:
1381 if ( setunset ) val = SKIPGEXPRESSION;
1383 case INTOHIDEGEXPRESSION:
1384 case INTOHIDELEXPRESSION:
1391 case SKIPLEXPRESSION:
1392 case LOCALEXPRESSION:
1393 case HIDELEXPRESSION:
1394 if ( setunset ) val = DROPLEXPRESSION;
1396 case DROPLEXPRESSION:
1397 if ( !setunset ) val = LOCALEXPRESSION;
1399 case SKIPGEXPRESSION:
1400 case GLOBALEXPRESSION:
1401 case HIDEGEXPRESSION:
1402 if ( setunset ) val = DROPGEXPRESSION;
1404 case DROPGEXPRESSION:
1405 if ( !setunset ) val = GLOBALEXPRESSION;
1407 case HIDDENLEXPRESSION:
1408 case UNHIDELEXPRESSION:
1409 if ( setunset ) val = DROPHLEXPRESSION;
1411 case HIDDENGEXPRESSION:
1412 case UNHIDEGEXPRESSION:
1413 if ( setunset ) val = DROPHGEXPRESSION;
1415 case DROPHLEXPRESSION:
1416 if ( !setunset ) val = HIDDENLEXPRESSION;
1418 case DROPHGEXPRESSION:
1419 if ( !setunset ) val = HIDDENGEXPRESSION;
1421 case INTOHIDEGEXPRESSION:
1422 case INTOHIDELEXPRESSION:
1429 case DROPLEXPRESSION:
1430 case SKIPLEXPRESSION:
1431 case LOCALEXPRESSION:
1432 if ( setunset ) val = HIDELEXPRESSION;
1434 case HIDELEXPRESSION:
1435 if ( !setunset ) val = LOCALEXPRESSION;
1437 case DROPGEXPRESSION:
1438 case SKIPGEXPRESSION:
1439 case GLOBALEXPRESSION:
1440 if ( setunset ) val = HIDEGEXPRESSION;
1442 case HIDEGEXPRESSION:
1443 if ( !setunset ) val = GLOBALEXPRESSION;
1445 case INTOHIDEGEXPRESSION:
1446 case INTOHIDELEXPRESSION:
1453 case HIDDENLEXPRESSION:
1454 case DROPHLEXPRESSION:
1455 if ( setunset ) val = UNHIDELEXPRESSION;
1457 case UNHIDELEXPRESSION:
1458 if ( !setunset ) val = HIDDENLEXPRESSION;
1460 case HIDDENGEXPRESSION:
1461 case DROPHGEXPRESSION:
1462 if ( setunset ) val = UNHIDEGEXPRESSION;
1464 case UNHIDEGEXPRESSION:
1465 if ( !setunset ) val = HIDDENGEXPRESSION;
1467 case INTOHIDEGEXPRESSION:
1468 case INTOHIDELEXPRESSION:
1475 case HIDDENLEXPRESSION:
1476 case HIDDENGEXPRESSION:
1477 MesPrint(
"&Expression is already hidden");
1479 case DROPHLEXPRESSION:
1480 case DROPHGEXPRESSION:
1481 case UNHIDELEXPRESSION:
1482 case UNHIDEGEXPRESSION:
1484 MesPrint(
"&Cannot unhide/drop and put intohide expression in the same module");
1488 case LOCALEXPRESSION:
1489 case DROPLEXPRESSION:
1490 case SKIPLEXPRESSION:
1491 case HIDELEXPRESSION:
1492 if ( setunset ) val = INTOHIDELEXPRESSION;
1494 case GLOBALEXPRESSION:
1495 case DROPGEXPRESSION:
1496 case SKIPGEXPRESSION:
1497 case HIDEGEXPRESSION:
1498 if ( setunset ) val = INTOHIDEGEXPRESSION;
1500 case INTOHIDELEXPRESSION:
1501 if ( !setunset ) val = LOCALEXPRESSION;
1503 case INTOHIDEGEXPRESSION:
1504 if ( !setunset ) val = GLOBALEXPRESSION;
1521int SetExpr(UBYTE *s,
int setunset,
int par)
1527 for ( i = 0; i < NumExpressions; i++ ) {
1528 w = &(Expressions[i].status);
1529 *w = SetExprCases(par,setunset,*w);
1530 if ( *w < 0 ) error = 1;
1531 if ( ( par == HIDE || par == INTOHIDE ) && setunset == 1 )
1532 Expressions[i].hidelevel = AC.HideLevel;
1537 if ( *s ==
',' ) { s++;
continue; }
1538 if ( *s ==
'0' ) { s++;
continue; }
1541 MesPrint(
"&Improper name for an expression: '%s'",name);
1545 if ( GetName(AC.exprnames,name,&numexpr,NOAUTO) == CEXPRESSION ) {
1546 w = &(Expressions[numexpr].status);
1547 *w = SetExprCases(par,setunset,*w);
1548 if ( *w < 0 ) error = 1;
1549 if ( ( par == HIDE || par == INTOHIDE ) && setunset == 1 )
1550 Expressions[numexpr].hidelevel = AC.HideLevel;
1552 else if ( GetName(AC.varnames,name,&numexpr,NOAUTO) != NAMENOTFOUND ) {
1553 MesPrint(
"&%s is not an expression",name);
1566int CoDrop(UBYTE *s) {
return(SetExpr(s,1,DROP)); }
1573int CoNoDrop(UBYTE *s) {
return(SetExpr(s,0,DROP)); }
1580int CoSkip(UBYTE *s) {
return(SetExpr(s,1,SKIP)); }
1587int CoNoSkip(UBYTE *s) {
return(SetExpr(s,0,SKIP)); }
1594int CoHide(UBYTE *inp) {
1597 if ( AR.Fscr[2].PObuffer == 0 ) {
1598 ScratchBuf = (WORD *)Malloc1(AM.HideSize*
sizeof(WORD),
"hidesize");
1599 AR.Fscr[2].POsize = AM.HideSize *
sizeof(WORD);
1600 AR.Fscr[2].POfull = AR.Fscr[2].POfill = AR.Fscr[2].PObuffer = ScratchBuf;
1601 AR.Fscr[2].POstop = AR.Fscr[2].PObuffer + AM.HideSize;
1602 PUTZERO(AR.Fscr[2].POposition);
1604 return(SetExpr(inp,1,HIDE));
1612int CoIntoHide(UBYTE *inp) {
1615 if ( AR.Fscr[2].PObuffer == 0 ) {
1616 ScratchBuf = (WORD *)Malloc1(AM.HideSize*
sizeof(WORD),
"hidesize");
1617 AR.Fscr[2].POsize = AM.HideSize *
sizeof(WORD);
1618 AR.Fscr[2].POfull = AR.Fscr[2].POfill = AR.Fscr[2].PObuffer = ScratchBuf;
1619 AR.Fscr[2].POstop = AR.Fscr[2].PObuffer + AM.HideSize;
1620 PUTZERO(AR.Fscr[2].POposition);
1622 return(SetExpr(inp,1,INTOHIDE));
1630int CoNoIntoHide(UBYTE *inp) {
return(SetExpr(inp,0,INTOHIDE)); }
1637int CoNoHide(UBYTE *inp) {
return(SetExpr(inp,0,HIDE)); }
1644int CoUnHide(UBYTE *inp) {
return(SetExpr(inp,1,UNHIDE)); }
1651int CoNoUnHide(UBYTE *inp) {
return(SetExpr(inp,0,UNHIDE)); }
1658void AddToCom(
int n, WORD *array)
1660 CBUF *C = cbuf+AC.cbufnum;
1662 MesPrint(
" %a",n,array);
1665 while ( --n >= 0 ) *(C->
Pointer)++ = *array++;
1673int AddComString(
int n, WORD *array, UBYTE *thestring,
int par)
1675 CBUF *C = cbuf+AC.cbufnum;
1676 UBYTE *s = thestring, *w;
1681 int i, numchars = 0, size, zeroes;
1683 if ( *s ==
'\\' ) s++;
1684 else if ( par == 1 &&
1685 ( ( *s ==
'%' && s[1] !=
't' && s[1] !=
'T' && s[1] !=
'$' &&
1686 s[1] !=
'w' && s[1] !=
'W' && s[1] !=
'r' && s[1] != 0 ) || *s ==
'#'
1687 || *s ==
'@' || *s ==
'&' ) ) {
1693 size = numchars/
sizeof(WORD)+1;
1700 for ( i = 1; i < n; i++ ) *(C->
Pointer)++ = array[i];
1706 zeroes = size*
sizeof(WORD)-numchars;
1709 if ( *s ==
'\\' ) s++;
1710 else if ( par == 1 && ( ( *s ==
'%' &&
1711 s[1] !=
't' && s[1] !=
'T' && s[1] !=
'$' &&
1712 s[1] !=
'w' && s[1] !=
'W' && s[1] !=
'r' && s[1] != 0 ) || *s ==
'#'
1713 || *s ==
'@' || *s ==
'&' ) ) {
1718 while ( --zeroes >= 0 ) *w++ = 0;
1721 MesPrint(
"LH: %a",size+1+n,cc);
1722 MesPrint(
" %s",thestring);
1732int Add2ComStrings(
int n, WORD *array, UBYTE *string1, UBYTE *string2)
1734 CBUF *C = cbuf+AC.cbufnum;
1735 UBYTE *s1 = string1, *s2 = string2, *w;
1736 int i, num1chars = 0, num2chars = 0, size1, size2, zeroes1, zeroes2;
1738 while ( *s1 ) { s1++; num1chars++; }
1739 size1 = num1chars/
sizeof(WORD)+1;
1741 while ( *s2 ) { s2++; num2chars++; }
1742 size2 = num2chars/
sizeof(WORD)+1;
1747 *(C->
Pointer)++ = size1+size2+n+3;
1748 for ( i = 1; i < n; i++ ) *(C->
Pointer)++ = array[i];
1751 zeroes1 = size1*
sizeof(WORD)-num1chars;
1753 while ( *s1 ) { *w++ = *s1++; }
1754 while ( --zeroes1 >= 0 ) *w++ = 0;
1759 zeroes2 = size2*
sizeof(WORD)-num2chars;
1761 while ( *s2 ) { *w++ = *s2++; }
1762 while ( --zeroes2 >= 0 ) *w++ = 0;
1773int CoDiscard(UBYTE *s)
1776 Add2Com(TYPEDISCARD)
1779 MesPrint(
"&Illegal argument in discard statement: '%s'",s);
1794static WORD ccarray[5] = { TYPEOPERATION,5,CONTRACT,0,0 };
1796int CoContract(UBYTE *s)
1802 if ( *s !=
',' && *s ) {
1803proper: MesPrint(
"&Illegal number in contract statement");
1809 else ccarray[4] = 0;
1810 if ( FG.cTable[*s] == 1 ) {
1812 if ( *s )
goto proper;
1815 else if ( *s )
goto proper;
1816 else ccarray[3] = -1;
1825int CoGoTo(UBYTE *inp)
1829 while ( FG.cTable[*s] <= 1 ) s++;
1831 MesPrint(
"&Label should be an alpha-numeric string");
1835 Add3Com(TYPEGOTO,x);
1844int CoLabel(UBYTE *inp)
1848 while ( FG.cTable[*s] <= 1 ) s++;
1850 MesPrint(
"&Label should be an alpha-numeric string");
1854 if ( AC.Labels[x] >= 0 ) {
1855 MesPrint(
"&Label %s defined more than once",AC.LabelNames[x]);
1858 AC.Labels[x] = cbuf[AC.cbufnum].numlhs;
1871int DoArgument(UBYTE *s,
int par)
1874 UBYTE *name, *t, *v, c;
1875 WORD *oldworkpointer = AT.WorkPointer, *w, *ww, number, *scale;
1876 int error = 0, zeroflag, type, x;
1877 AC.lhdollarflag = 0;
1878 while ( *s ==
',' ) s++;
1884 if ( AC.arglevel >= MAXNEST ) {
1885 MesPrint(
"@Nesting of argument statements more than %d levels"
1889 AC.argsumcheck[AC.arglevel] = NestingChecksum();
1890 AC.argstack[AC.arglevel] = cbuf[AC.cbufnum].Pointer
1891 - cbuf[AC.cbufnum].Buffer + 2;
1893 *w++ = cbuf[AC.cbufnum].numlhs;
1898 case TYPESPLITFIRSTARG:
1899 case TYPESPLITLASTARG:
1901 case TYPEARGTOEXTRASYMBOL:
1902 *w++ = cbuf[AC.cbufnum].numlhs+1;
1910 s++; ParseSignedNumber(x,s)
1911 while ( *s ==
',' ) s++;
1915 t = s+1; SKIPBRA3(s)
1916 if ( par == TYPEARG ) {
1917 MesPrint(
"&Illegal () entry in argument statement");
1918 error = 1; s++;
goto skipbracks;
1920 else if ( par == TYPESPLITFIRSTARG ) {
1921 MesPrint(
"&Illegal () entry in splitfirstarg statement");
1922 error = 1; s++;
goto skipbracks;
1924 else if ( par == TYPESPLITLASTARG ) {
1925 MesPrint(
"&Illegal () entry in splitlastarg statement");
1926 error = 1; s++;
goto skipbracks;
1931 MesPrint(
"&Wildcarding not allowed in this type of statement");
1937 if ( *t ==
'(' && v[-1] ==
')' ) {
1939 if ( par == TYPESPLITARG ) oldworkpointer[0] = TYPESPLITARG2;
1940 else if ( par == TYPEFACTARG ) oldworkpointer[0] = TYPEFACTARG2;
1941 else if ( par == TYPENORM4 ) oldworkpointer[0] = TYPENORM4;
1942 else if ( par == TYPENORM ) {
1943 if ( *t ==
'-' ) { oldworkpointer[0] = TYPENORM3; t++; }
1944 else { oldworkpointer[0] = TYPENORM2; *scale = 0; }
1948 CBUF *C = cbuf+AC.cbufnum;
1949 WORD oldnumrhs = C->numrhs, oldnumlhs = C->numlhs;
1950 WORD prototype[SUBEXPSIZE+40];
1955 prototype[0] = SUBEXPRESSION;
1956 prototype[1] = SUBEXPSIZE;
1957 prototype[2] = C->numrhs+1;
1959 prototype[4] = AC.cbufnum;
1960 AT.WorkPointer += TYPEARGHEADSIZE+1;
1962 if ( ( retcode = CompileAlgebra(t,LHSIDE,prototype) ) < 0 )
1965 prototype[2] = retcode;
1966 ww = C->
lhs[retcode];
1967 AC.lhdollarflag = 0;
1969 *w++ = -2; *w++ = 0;
1971 else if ( ww[ww[0]] != 0 ) {
1972 MesPrint(
"&There should be only one term between ()");
1975 else if (
NewSort(BHEAD0) ) {
if ( !error ) error = 1; }
1978 if ( !error ) error = 1;
1981 AN.RepPoint = AT.RepCount + 1;
1984 while ( --i >= 0 ) *m++ = *mm++;
1985 mm = AT.WorkPointer; AT.WorkPointer = m;
1986 AR.Cnumlhs = C->numlhs;
1990 else if (
EndSort(BHEAD mm,0) < 0 ) {
1992 AT.WorkPointer = mm;
1994 else if ( *mm == 0 ) {
1995 *w++ = -2; *w++ = 0;
1996 AT.WorkPointer = mm;
1998 else if ( mm[mm[0]] != 0 ) {
2000 AT.WorkPointer = mm;
2003 AT.WorkPointer = mm;
2005 if ( par == TYPEFACTARG ) {
2006 if ( *mm != ABS(m[-1])+1 ) {
2009 mm[-1] = -*mm-1; w += *mm+1;
2017 { mm[-1] = -*mm-1; w += *mm+1; }
2019 oldworkpointer[1] = w - oldworkpointer;
2023 oldworkpointer[5] = AC.lhdollarflag;
2026 C->numrhs = oldnumrhs;
2027 C->numlhs = oldnumlhs;
2032 if ( *s == 0 ) { *w++ = 0; *w++ = 2; *w++ = 1; }
2035 if ( *s ==
',' ) { s++;
continue; }
2036 ww = w; *w++ = 0; w++;
2037 if ( FG.cTable[*s] > 1 && *s !=
'[' && *s !=
'{' ) {
2038 MesPrint(
"&Illegal parameters in statement");
2042 while ( FG.cTable[*s] == 0 || *s ==
'[' || *s ==
'{' ) {
2047 number = DoTempSet(name,s);
2048 name--; *s++ = c; c = *s; *s = 0;
2054 MesPrint(
"&Illegal name '%s'",name);
2058 if ( ( type = GetName(AC.varnames,name,&number,WITHAUTO) ) == CSET ) {
2059doset:
if ( Sets[number].type != CFUNCTION )
goto nofun;
2062 r1 = SetElements + Sets[number].first;
2063 r2 = SetElements + Sets[number].last;
2065 if ( *r1++ == FLOATFUN ) {
2066 MesPrint(
"&Illegal use of argument environment and float_.");
2071 *w++ = CSET; *w++ = number;
2073 else if ( type == CFUNCTION ) {
2075 if ( (number + FUNCTION) == FLOATFUN ) {
2076 MesPrint(
"&Illegal use of argument environment and float_.");
2080 *w++ = CFUNCTION; *w++ = number + FUNCTION;
2083nofun: MesPrint(
"&%s is not a function or a set of functions"
2089 while ( *s ==
',' ) s++;
2092 ww = w; w++; zeroflag = 0;
2093 while ( FG.cTable[*s] == 1 ) {
2095 if ( *s && *s !=
',' ) {
2096 MesPrint(
"&Illegal separator after number");
2098 while ( *s && *s !=
',' ) s++;
2100 while ( *s ==
',' ) s++;
2101 if ( x == 0 ) zeroflag = 1;
2102 if ( !zeroflag ) *w++ = (WORD)x;
2107 oldworkpointer[1] = w - oldworkpointer;
2108 if ( par == TYPEARG ) {
2109 AC.argstack[AC.arglevel-1] = cbuf[AC.cbufnum].Pointer
2110 - cbuf[AC.cbufnum].Buffer + 2;
2112 AddNtoL(oldworkpointer[1],oldworkpointer);
2113 AT.WorkPointer = oldworkpointer;
2122int CoArgument(UBYTE *s) {
return(DoArgument(s,TYPEARG)); }
2129int CoEndArgument(UBYTE *s)
2131 CBUF *C = cbuf+AC.cbufnum;
2132 while ( *s ==
',' ) s++;
2134 MesPrint(
"&Illegal syntax for EndArgument statement");
2137 if ( AC.arglevel <= 0 ) {
2138 MesPrint(
"&EndArgument without corresponding Argument statement");
2142 cbuf[AC.cbufnum].Buffer[AC.argstack[AC.arglevel]] = C->numlhs;
2143 if ( AC.argsumcheck[AC.arglevel] != NestingChecksum() ) {
2155int CoInside(UBYTE *s) {
return(ExecInside(s)); }
2162int CoEndInside(UBYTE *s)
2164 CBUF *C = cbuf+AC.cbufnum;
2165 while ( *s ==
',' ) s++;
2167 MesPrint(
"&Illegal syntax for EndInside statement");
2170 if ( AC.insidelevel <= 0 ) {
2171 MesPrint(
"&EndInside without corresponding Inside statement");
2175 cbuf[AC.cbufnum].Buffer[AC.insidestack[AC.insidelevel]] = C->numlhs;
2176 if ( AC.insidesumcheck[AC.insidelevel] != NestingChecksum() ) {
2188int CoNormalize(UBYTE *s) {
return(DoArgument(s,TYPENORM)); }
2195int CoMakeInteger(UBYTE *s) {
return(DoArgument(s,TYPENORM4)); }
2202int CoSplitArg(UBYTE *s) {
return(DoArgument(s,TYPESPLITARG)); }
2209int CoSplitFirstArg(UBYTE *s) {
return(DoArgument(s,TYPESPLITFIRSTARG)); }
2216int CoSplitLastArg(UBYTE *s) {
return(DoArgument(s,TYPESPLITLASTARG)); }
2223int CoFactArg(UBYTE *s) {
2224 if ( ( AC.topolynomialflag & TOPOLYNOMIALFLAG ) != 0 ) {
2225 MesPrint(
"&ToPolynomial statement and FactArg statement are not allowed in the same module");
2228 AC.topolynomialflag |= FACTARGFLAG;
2229 return(DoArgument(s,TYPEFACTARG));
2243int DoSymmetrize(UBYTE *s,
int par)
2246 int extra = 0, error = 0, err, fix, x, groupsize, num, i;
2248 WORD funnum, *w, *ww, type;
2252 MesPrint(
"&Improper function name");
2256 if ( c !=
',' || ( FG.cTable[s[1]] != 0 && s[1] !=
'[' ) )
break;
2257 if ( par <= 0 && StrICmp(name,(UBYTE *)
"cyclic") == 0 ) extra = 2;
2258 else if ( par <= 0 && StrICmp(name,(UBYTE *)
"rcyclic") == 0 ) extra = 6;
2260 MesPrint(
"&Illegal option: '%s'",name);
2265 if ( ( err = GetVar(name,&type,&funnum,CFUNCTION,WITHAUTO) ) == NAMENOTFOUND ) {
2266 MesPrint(
"&Undefined function: %s",name);
2267 AddFunction(name,0,0,0,0,0,-1,-1);
2272 if ( err == -1 ) error = 1;
2276 if ( *s ==
',' || *s ==
'(' || *s == 0 ) fix = -1;
2277 else if ( FG.cTable[*s] == 1 ) {
2280 Warning(
"Restriction to zero arguments removed");
2283 MesPrint(
"&Illegal character after :");
2289 *w++ = TYPEOPERATION;
2298 w += 2; ww = w; groupsize = -1;
2299 while ( *s ==
',' ) s++;
2303 while ( *s && *s !=
')' ) {
2304 if ( *s ==
',' ) { s++;
continue; }
2305 if ( FG.cTable[*s] != 1 )
goto illarg;
2307 if ( x <= 0 || ( fix > 0 && x > fix ) )
goto illnum;
2312 MesPrint(
"&Improper termination of statement");
2315 if ( groupsize < 0 ) groupsize = num;
2316 else if ( groupsize != num )
goto group;
2319 else if ( FG.cTable[*s] == 1 ) {
2320 if ( groupsize < 0 ) groupsize = 1;
2321 else if ( groupsize != 1 ) {
2322group: MesPrint(
"&All groups should have the same number of arguments");
2326 if ( x <= 0 || ( fix > 0 && x > fix ) ) {
2327illnum: MesPrint(
"&Illegal argument number: %d",x);
2333illarg: MesPrint(
"&Illegal argument");
2336 while ( *s ==
',' ) s++;
2345 for ( i = 0; i < fix; i++ ) *w++ = i;
2351 ww[-2] = (w-ww)/groupsize;
2353 AT.WorkPointer[1] = w - AT.WorkPointer;
2354 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
2363int CoSymmetrize(UBYTE *s) {
return(DoSymmetrize(s,SYMMETRIC)); }
2370int CoAntiSymmetrize(UBYTE *s) {
return(DoSymmetrize(s,ANTISYMMETRIC)); }
2377int CoCycleSymmetrize(UBYTE *s) {
return(DoSymmetrize(s,CYCLESYMMETRIC)); }
2384int CoRCycleSymmetrize(UBYTE *s) {
return(DoSymmetrize(s,RCYCLESYMMETRIC)); }
2391int CoWrite(UBYTE *s)
2397 if ( ( ( s =
SkipAName(s) ) == 0 ) || *s != 0 ) {
2398 MesPrint(
"&Proper use of write statement is: write option");
2403 MesPrint(
"&Unrecognized option in write statement");
2406 *key->var = key->type;
2407 AR.SortType = AC.SortType;
2416int CoNWrite(UBYTE *s)
2422 if ( ( ( s =
SkipAName(s) ) == 0 ) || *s != 0 ) {
2423 MesPrint(
"&Proper use of nwrite statement is: nwrite option");
2428 MesPrint(
"&Unrecognized option in nwrite statement");
2431 *key->var = key->flags;
2432 AR.SortType = AC.SortType;
2441static WORD ratstring[6] = { TYPEOPERATION, 6, RATIO, 0, 0, 0 };
2443int CoRatio(UBYTE *s)
2446 int i, type, error = 0;
2449 for ( i = 0; i < 3; i++ ) {
2454 if ( ( ( type = GetName(AC.varnames,t,&numsym,WITHAUTO) ) != CSYMBOL )
2455 && type != CDUBIOUS ) {
2456 MesPrint(
"&%s is not a symbol",t);
2458 if ( type < 0 ) numsym = AddSymbol(t,-MAXPOWER,MAXPOWER,0,0);
2461 if ( *s ==
',' ) s++;
2465 MesPrint(
"&The ratio statement needs three symbols for its arguments");
2483int CoRedefine(UBYTE *s)
2485 UBYTE *name, c, *args = 0;
2489 if ( FG.cTable[*s] || ( s =
SkipAName(s) ) == 0 || s[-1] ==
'_' ) {
2490 MesPrint(
"&Illegal name for preprocessor variable in redefine statement");
2494 for ( numprevar = NumPre-1; numprevar >= 0; numprevar-- ) {
2495 if ( StrCmp(name,PreVar[numprevar].name) == 0 )
break;
2497 if ( numprevar < 0 ) {
2498 MesPrint(
"&There is no preprocessor variable with the name `%s'",name);
2510 if ( chartype[*s] != 0 )
goto illarg;
2512 while ( chartype[*s] <= 1 ) s++;
2513 while ( *s ==
' ' || *s ==
'\t' ) s++;
2514 if ( *s ==
')' )
break;
2515 if ( *s !=
',' )
goto illargs;
2517 while ( *s ==
' ' || *s ==
'\t' ) s++;
2520 while ( *s ==
' ' || *s ==
'\t' ) s++;
2522 while ( *s ==
',' ) s++;
2524encl: MesPrint(
"&Value for %s should be enclosed in double quotes"
2525 ,PreVar[numprevar].name);
2529 while ( *s && *s !=
'"' ) {
if ( *s ==
'\\' ) s++; s++; }
2530 if ( *s !=
'"' )
goto encl;
2532 code[0] = TYPEREDEFPRE; code[1] = numprevar;
2536 Add2ComStrings(2,code,name,args);
2548 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2549 if ( numprevar == AC.pfirstnum[j] )
break;
2551 if ( j >= AC.numpfirstnum ) {
2552 if ( j >= AC.sizepfirstnum ) {
2553 if ( AC.sizepfirstnum <= 0 ) { AC.sizepfirstnum = 10; }
2554 else { AC.sizepfirstnum = 2 * AC.sizepfirstnum; }
2555 newin = (LONG *)Malloc1(AC.sizepfirstnum*(
sizeof(WORD)+
sizeof(LONG)),
"AC.pfirstnum");
2556 newpf = (WORD *)(newin+AC.sizepfirstnum);
2557 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2558 newpf[j] = AC.pfirstnum[j];
2559 newin[j] = AC.inputnumbers[j];
2561 if ( AC.inputnumbers ) M_free(AC.inputnumbers,
"AC.pfirstnum");
2562 AC.inputnumbers = newin;
2563 AC.pfirstnum = newpf;
2565 AC.pfirstnum[AC.numpfirstnum] = numprevar;
2566 AC.inputnumbers[AC.numpfirstnum] = -1;
2573 MesPrint(
"&Illegally formed name in argument of redefine statement");
2576 MesPrint(
"&Illegally formed arguments in redefine statement");
2588int CoRenumber(UBYTE *s)
2592 while ( *s ==
',' ) s++;
2594 if ( *s == 0 ) { x = 0; }
2595 else ParseNumber(x,s)
2596 if ( *s == 0 && x >= 0 && x <= 1 ) {
2597 Add3Com(TYPERENUMBER,x);
2600 MesPrint(
"&Illegal argument in Renumber statement: '%s'",inp);
2611 CBUF *C = cbuf+AC.cbufnum;
2612 UBYTE *ss = 0, c, *t;
2613 int error = 0, i = 0, type, x;
2614 WORD numindex,number;
2618 t++; s++;
while ( FG.cTable[*s] < 2 ) s++;
2620 if ( ( number = GetDollar(t) ) < 0 ) {
2621 MesPrint(
"&Undefined variable $%s",t);
2622 if ( !error ) error = 1;
2623 number = AddDollar(t,0,0,0);
2628 if ( ( s =
SkipAName(s) ) == 0 )
return(1);
2630 if ( ( ( type = GetOName(AC.exprnames,t,&numindex,NOAUTO) ) != NAMENOTFOUND )
2631 || ( ( type = GetOName(AC.varnames,t,&numindex,WITHAUTO) ) != CINDEX ) ) {
2632 if ( type != NAMENOTFOUND ) error = NameConflict(type,t);
2634 MesPrint(
"&%s should have been declared as an index",t);
2636 numindex = AddIndex(s,AC.lDefDim,AC.lDefDim4) + AM.OffsetIndex;
2640 Add3Com(TYPESUM,numindex);
2642 if ( *s == 0 )
break;
2644 MesPrint(
"&Illegal separator between objects in sum statement.");
2648 if ( FG.cTable[*s] == 0 || *s ==
'[' || *s ==
'$' ) {
2649 while ( FG.cTable[*s] == 0 || *s ==
'[' || *s ==
'$' ) {
2653 while ( FG.cTable[*s] < 2 ) s++;
2655 if ( ( number = GetDollar(t) ) < 0 ) {
2656 MesPrint(
"&Undefined variable $%s",t);
2657 if ( !error ) error = 1;
2658 number = AddDollar(t,0,0,0);
2664 if ( ( s =
SkipAName(s) ) == 0 )
return(1);
2666 if ( ( ( type = GetOName(AC.exprnames,t,&numindex,NOAUTO) ) != NAMENOTFOUND )
2667 || ( ( type = GetOName(AC.varnames,t,&numindex,WITHAUTO) ) != CINDEX ) ) {
2668 if ( type != NAMENOTFOUND ) error = NameConflict(type,t);
2670 MesPrint(
"&%s should have been declared as an index",t);
2672 numindex = AddIndex(s,AC.lDefDim,AC.lDefDim4) + AM.OffsetIndex;
2680 if ( *s == 0 )
return(error);
2682 MesPrint(
"&Illegal separator between objects in sum statement.");
2687 if ( FG.cTable[*s] == 1 ) {
2691 else if ( FG.cTable[*s] == 1 ) {
2692 while ( FG.cTable[*s] == 1 ) {
2695 while( FG.cTable[*s] == 1 ) x = 10*x + *s++ -
'0';
2696 if ( *s && *s !=
',' ) {
2697 MesPrint(
"&%s is not a legal fixed index",t);
2700 else if ( x >= AM.OffsetIndex ) {
2701 MesPrint(
"&%d is too large to be a fixed index",x);
2710 if ( *s == 0 )
break;
2715 MesPrint(
"&Illegal object in sum statement");
2727static WORD cttarray[7] = { TYPEOPERATION,7,TENVEC,0,0,1,0 };
2729int CoToTensor(UBYTE *s)
2732 int type, j, nargs, error = 0;
2733 WORD number, dol[2] = { 0, 0 };
2745 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2746 if ( *s == 0 )
break;
2753 if ( ( s =
SkipAName(s) ) == 0 )
goto syntax_error;
2756 if ( ( s =
SkipAName(s) ) == 0 )
goto syntax_error;
2760 if ( nargs < 2 )
goto not_enough_arguments;
2765 for ( j = 2; j < nargs; j++ ) {
2766 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2775 if ( FG.cTable[*s] == 0 || *s ==
'[' || *s ==
'_' ) {
2777 if ( ( s =
SkipAName(s) ) == 0 )
goto syntax_error;
2779 type = GetName(AC.varnames,t,&number,WITHAUTO);
2780 if ( type == CVECTOR ) {
2784 cttarray[6] = DoTempSet(t,s);
2788 else if ( type != CSET ) {
2789 MesPrint(
"&%s is not the name of a set or a vector",t);
2793 cttarray[6] = number;
2795 else if ( *s ==
'{' ) {
2796 t = ++s; SKIPBRA2(s) *s = 0;
2797 cttarray[6] = DoTempSet(t,s);
2800 if ( cttarray[6] < 0 ) {
2803 if ( AC.wildflag ) {
2804 MesPrint(
"&Improper use of wildcard(s) in set specification");
2813 if ( ( s =
SkipAName(s) ) == 0 )
goto syntax_error;
2815 if ( StrICmp(t,(UBYTE *)
"nosquare") == 0 ) cttarray[5] |= 2;
2816 else if ( StrICmp(t,(UBYTE *)
"functions") == 0 ) cttarray[5] |= 4;
2818 MesPrint(
"&Unrecognized option in ToTensor statement: '%s'",t);
2828 for ( j = 0; j < 2; j++ ) {
2829 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2831 if ( ( s =
SkipAName(s) ) == 0 )
goto syntax_error;
2833 if ( t[0] ==
'$' ) {
2834 dol[j] = GetDollar(t+1);
2835 if ( dol[j] < 0 ) dol[j] = AddDollar(t+1,DOLUNDEFINED,0,0);
2837 type = GetName(AC.varnames,t,&number,WITHAUTO);
2838 if ( type == CVECTOR ) {
2839 cttarray[4] = number + AM.OffsetVector;
2841 else if ( type == CFUNCTION && ( functions[number].spec > 0 ) ) {
2842 cttarray[3] = number + FUNCTION;
2845 MesPrint(
"&%s is not a vector or a tensor",t);
2851 if ( cttarray[3] == 0 || cttarray[4] == 0 ) {
2852 if ( dol[0] == 0 && dol[1] == 0 ) {
2853 goto not_enough_arguments;
2855 else if ( cttarray[3] ) {
2856 if ( dol[1] ) cttarray[4] = dol[1];
2857 else if ( dol[0] ) { cttarray[4] = dol[0]; }
2859 goto not_enough_arguments;
2862 else if ( cttarray[4] ) {
2863 if ( dol[1] ) { cttarray[3] = -dol[1]; }
2864 else if ( dol[0] ) cttarray[3] = -dol[0];
2866 goto not_enough_arguments;
2870 if ( dol[0] == 0 || dol[1] == 0 ) {
2871 goto not_enough_arguments;
2874 cttarray[3] = -dol[0]; cttarray[4] = dol[1];
2878 AddNtoL(cttarray[1],cttarray);
2882 MesPrint(
"&Syntax error in ToTensor statement");
2885not_enough_arguments:
2886 MesPrint(
"&ToTensor statement needs a vector and a tensor");
2895static WORD ctvarray[6] = { TYPEOPERATION,6,TENVEC,0,0,0 };
2897int CoToVector(UBYTE *s)
2900 int j, type, error = 0;
2901 WORD number, dol[2];
2902 dol[0] = dol[1] = 0;
2903 ctvarray[3] = ctvarray[4] = ctvarray[5] = 0;
2904 for ( j = 0; j < 2; j++ ) {
2907proper: MesPrint(
"&Arguments of ToVector statement should be a vector and a tensor");
2912 dol[j] = GetDollar(t+1);
2913 if ( dol[j] < 0 ) dol[j] = AddDollar(t+1,DOLUNDEFINED,0,0);
2915 else if ( ( type = GetName(AC.varnames,t,&number,WITHAUTO) ) == CVECTOR )
2916 ctvarray[4] = number + AM.OffsetVector;
2917 else if ( type == CFUNCTION && ( functions[number].spec > 0 ) )
2918 ctvarray[3] = number+FUNCTION;
2920 MesPrint(
"&%s is not a vector or a tensor",t);
2923 *s = c;
if ( *s && *s !=
',' )
goto proper;
2926 if ( *s != 0 )
goto proper;
2927 if ( ctvarray[3] == 0 || ctvarray[4] == 0 ) {
2928 if ( dol[0] == 0 && dol[1] == 0 ) {
2929 MesPrint(
"&ToVector statement needs a vector and a tensor");
2932 else if ( ctvarray[3] ) {
2933 if ( dol[1] ) ctvarray[4] = dol[1];
2934 else if ( dol[0] ) ctvarray[4] = dol[0];
2936 MesPrint(
"&ToVector statement needs a vector and a tensor");
2940 else if ( ctvarray[4] ) {
2941 if ( dol[1] ) ctvarray[3] = -dol[1];
2942 else if ( dol[0] ) ctvarray[3] = -dol[0];
2944 MesPrint(
"&ToVector statement needs a vector and a tensor");
2949 if ( dol[0] == 0 || dol[1] == 0 ) {
2950 MesPrint(
"&ToVector statement needs a vector and a tensor");
2954 ctvarray[3] = -dol[0]; ctvarray[4] = dol[1];
2967int CoTrace4(UBYTE *s)
2969 int error = 0, type, option = CHISHOLM;
2971 WORD numindex, one = 1;
2975 if ( FG.cTable[*s] == 1 )
break;
2977proper: MesPrint(
"&Proper syntax for Trace4 is 'Trace4[,options],index;'");
2980 if ( *s == 0 )
break;
2982 if ( ( key = FindKeyWord(t,trace4options,
2983 sizeof(trace4options)/
sizeof(
KEYWORD)) ) == 0 )
break;
2985 option |= key->type;
2986 option &= ~key->flags;
2988 if ( ( *s++ = c ) !=
',' ) {
2989 MesPrint(
"&Illegal separator in Trace4 statement");
2992 if ( *s == 0 )
goto proper;
2995 if ( FG.cTable[*s] == 1 ) {
2997 ParseNumber(numindex,s)
2999 MesPrint(
"&Last argument of Trace4 should be an index");
3002 if ( numindex >= AM.OffsetIndex ) {
3003 MesPrint(
"&fixed index >= %d. Change value of OffsetIndex in setup file"
3008 else if ( *s ==
'$' ) {
3009 if ( ( type = GetName(AC.dollarnames,s+1,&numindex,NOAUTO) ) == CDOLLAR )
3010 numindex = -numindex;
3012 MesPrint(
"&%s is undefined",s);
3013 numindex = AddDollar(s+1,DOLINDEX,&one,1);
3018 MesPrint(
"&Trace4 should have a single index or $variable for its argument");
3022 else if ( ( type = GetName(AC.varnames,s,&numindex,WITHAUTO) ) == CINDEX ) {
3023 numindex += AM.OffsetIndex;
3026 else if ( type != -1 ) {
3027 if ( type != CDUBIOUS ) {
3028 if ( ( FG.cTable[*s] != 0 ) && ( *s !=
'[' ) ) {
3029 if ( *s ==
'+' && FG.cTable[s[1]] == 1 ) { s++;
goto retry; }
3032 NameConflict(type,s);
3033 type = MakeDubious(AC.varnames,s,&numindex);
3038 MesPrint(
"&%s is not an index",s);
3039 numindex = AddIndex(s,AC.lDefDim,AC.lDefDim4) + AM.OffsetIndex;
3042 if ( error )
return(error);
3043 if ( ( option & CHISHOLM ) != 0 )
3044 Add4Com(TYPECHISHOLM,numindex,(option & ALSOREVERSE));
3045 Add5Com(TYPEOPERATION,TAKETRACE,4 + (option & NOTRICK),numindex);
3054int CoTraceN(UBYTE *s)
3056 WORD numindex, one = 1;
3058 if ( FG.cTable[*s] == 1 ) {
3060 ParseNumber(numindex,s)
3062proper: MesPrint(
"&TraceN should have a single index for its argument");
3065 if ( numindex >= AM.OffsetIndex ) {
3066 MesPrint(
"&fixed index >= %d. Change value of OffsetIndex in setup file"
3071 else if ( *s ==
'$' ) {
3072 if ( ( type = GetName(AC.dollarnames,s+1,&numindex,NOAUTO) ) == CDOLLAR )
3073 numindex = -numindex;
3075 MesPrint(
"&%s is undefined",s);
3076 numindex = AddDollar(s+1,DOLINDEX,&one,1);
3081 MesPrint(
"&TraceN should have a single index or $variable for its argument");
3085 else if ( ( type = GetName(AC.varnames,s,&numindex,WITHAUTO) ) == CINDEX ) {
3086 numindex += AM.OffsetIndex;
3089 else if ( type != -1 ) {
3090 if ( type != CDUBIOUS ) {
3091 if ( ( FG.cTable[*s] != 0 ) && ( *s !=
'[' ) ) {
3092 if ( *s ==
'+' && FG.cTable[s[1]] == 1 ) { s++;
goto retry; }
3095 NameConflict(type,s);
3096 type = MakeDubious(AC.varnames,s,&numindex);
3101 MesPrint(
"&%s is not an index",s);
3102 numindex = AddIndex(s,AC.lDefDim,AC.lDefDim4) + AM.OffsetIndex;
3105 Add5Com(TYPEOPERATION,TAKETRACE,0,numindex);
3114int CoChisholm(UBYTE *s)
3116 int error = 0, type, option = CHISHOLM;
3118 WORD numindex, one = 1;
3122 if ( FG.cTable[*s] == 1 )
break;
3124proper: MesPrint(
"&Proper syntax for Chisholm is 'Chisholm[,options],index;'");
3127 if ( *s == 0 )
break;
3129 if ( ( key = FindKeyWord(t,chisoptions,
3130 sizeof(chisoptions)/
sizeof(
KEYWORD)) ) == 0 )
break;
3132 option |= key->type;
3133 option &= ~key->flags;
3135 if ( ( *s++ = c ) !=
',' ) {
3136 MesPrint(
"&Illegal separator in Chisholm statement");
3139 if ( *s == 0 )
goto proper;
3142 if ( FG.cTable[*s] == 1 ) {
3143 ParseNumber(numindex,s)
3145 MesPrint(
"&Last argument of Chisholm should be an index");
3148 if ( numindex >= AM.OffsetIndex ) {
3149 MesPrint(
"&fixed index >= %d. Change value of OffsetIndex in setup file"
3154 else if ( *s ==
'$' ) {
3155 if ( ( type = GetName(AC.dollarnames,s+1,&numindex,NOAUTO) ) == CDOLLAR )
3156 numindex = -numindex;
3158 MesPrint(
"&%s is undefined",s);
3159 numindex = AddDollar(s+1,DOLINDEX,&one,1);
3164 MesPrint(
"&Chisholm should have a single index or $variable for its argument");
3168 else if ( ( type = GetName(AC.varnames,s,&numindex,WITHAUTO) ) == CINDEX ) {
3169 numindex += AM.OffsetIndex;
3172 else if ( type != -1 ) {
3173 if ( type != CDUBIOUS ) {
3174 NameConflict(type,s);
3175 type = MakeDubious(AC.varnames,s,&numindex);
3180 MesPrint(
"&%s is not an index",s);
3181 numindex = AddIndex(s,AC.lDefDim,AC.lDefDim4) + AM.OffsetIndex;
3184 if ( error )
return(error);
3185 Add4Com(TYPECHISHOLM,numindex,(option & ALSOREVERSE));
3196int DoChain(UBYTE *s,
int option)
3200 if ( ( type = GetName(AC.dollarnames,s+1,&numfunc,NOAUTO) ) == CDOLLAR )
3203 MesPrint(
"&%s is undefined",s);
3204 numfunc = AddDollar(s+1,DOLINDEX,&one,1);
3209 MesPrint(
"&ChainIn/ChainOut should have a single function or $variable for its argument");
3213 else if ( ( type = GetName(AC.varnames,s,&numfunc,WITHAUTO) ) == CFUNCTION ) {
3214 numfunc += FUNCTION;
3217 else if ( type != -1 ) {
3218 if ( type != CDUBIOUS ) {
3219 NameConflict(type,s);
3220 type = MakeDubious(AC.varnames,s,&numfunc);
3225 MesPrint(
"&%s is not a function",s);
3226 numfunc = AddFunction(s,0,0,0,0,0,-1,-1) + FUNCTION;
3229 Add3Com(option,numfunc);
3240int CoChainin(UBYTE *s)
3242 return(DoChain(s,TYPECHAININ));
3252int CoChainout(UBYTE *s)
3254 return(DoChain(s,TYPECHAINOUT));
3265 WORD code = TYPEEXIT;
3266 while ( *s ==
',' ) s++;
3268 Add3Com(TYPEEXIT,0);
3273 while ( *s ) {
if ( *s ==
'\\' ) s++; s++; }
3274 if ( name[-1] !=
'"' || s[-1] !=
'"' ) {
3275 MesPrint(
"&Illegal syntax for exit statement");
3279 AddComString(1,&code,name,0);
3289int CoInParallel(UBYTE *s)
3291 return(DoInParallel(s,1));
3299int CoNotInParallel(UBYTE *s)
3301 return(DoInParallel(s,0));
3314int DoInParallel(UBYTE *s,
int par)
3327 AC.inparallelflag = par;
3329 for ( i = NumExpressions-1; i >= 0; i-- ) {
3331 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
3332 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
3341 while ( *s ==
',' ) s++;
3342 if ( *s == 0 )
break;
3343 if ( *s ==
'[' || FG.cTable[*s] == 0 ) {
3346 MesPrint(
"&Improper name for an expression: '%s'",t);
3350 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
3352 e = Expressions+number;
3353 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
3354 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
3360 else if ( GetName(AC.varnames,t,&number,NOAUTO) != NAMENOTFOUND ) {
3361 MesPrint(
"&%s is not an expression",t);
3367 MesPrint(
"&Illegal object in InParallel statement");
3369 while ( *s && *s !=
',' ) s++;
3370 if ( *s == 0 )
break;
3383int CoInExpression(UBYTE *s)
3390 if ( AC.inexprlevel >= MAXNEST ) {
3391 MesPrint(
"@Nesting of inexpression statements more than %d levels",(WORD)MAXNEST);
3394 AC.inexprsumcheck[AC.inexprlevel] = NestingChecksum();
3395 AC.inexprstack[AC.inexprlevel] = cbuf[AC.cbufnum].Pointer
3396 - cbuf[AC.cbufnum].Buffer + 2;
3398 *w++ = TYPEINEXPRESSION;
3401 while ( *s ==
',' ) s++;
3402 if ( *s == 0 )
break;
3403 if ( *s ==
'[' || FG.cTable[*s] == 0 ) {
3406 MesPrint(
"&Improper name for an expression: '%s'",t);
3410 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
3413 else if ( GetName(AC.varnames,t,&number,NOAUTO) != NAMENOTFOUND ) {
3414 MesPrint(
"&%s is not an expression",t);
3420 MesPrint(
"&Illegal object in InExpression statement");
3422 while ( *s && *s !=
',' ) s++;
3423 if ( *s == 0 )
break;
3426 AT.WorkPointer[1] = w - AT.WorkPointer;
3427 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
3436int CoEndInExpression(UBYTE *s)
3438 CBUF *C = cbuf+AC.cbufnum;
3439 while ( *s ==
',' ) s++;
3441 MesPrint(
"&Illegal syntax for EndInExpression statement");
3444 if ( AC.inexprlevel <= 0 ) {
3445 MesPrint(
"&EndInExpression without corresponding InExpression statement");
3449 cbuf[AC.cbufnum].Buffer[AC.inexprstack[AC.inexprlevel]] = C->numlhs;
3450 if ( AC.inexprsumcheck[AC.inexprlevel] != NestingChecksum() ) {
3462int CoSetExitFlag(UBYTE *s)
3465 MesPrint(
"&Illegal syntax for the SetExitFlag statement");
3468 Add2Com(TYPESETEXIT);
3476int CoTryReplace(UBYTE *p)
3480 WORD *w, error = 0, i, which = -1, c1, minvec = 0;
3497 if ( *p ==
'-' && minvec == 0 && which == (CVECTOR+1) ) {
3500 if ( *p ==
'[' || FG.cTable[*p] == 0 ) {
3502 if ( ( p =
SkipAName(p) ) == 0 )
return(1);
3504 i = GetName(AC.varnames,name,&c1,WITHAUTO);
3505 if ( which >= 0 && i >= 0 && i != CDUBIOUS && which != (i+1) ) {
3506 MesPrint(
"&Illegal combination of objects in TryReplace");
3509 else if ( minvec && i != CVECTOR && i != CDUBIOUS ) {
3510 MesPrint(
"&Currently a - sign can be used only with a vector in TryReplace");
3514 case CSYMBOL: *w++ = -SYMBOL; *w++ = c1;
break;
3516 if ( minvec ) *w++ = -MINVECTOR;
3517 else *w++ = -VECTOR;
3518 *w++ = c1 + AM.OffsetVector;
3521 case CINDEX: *w++ = -INDEX; *w++ = c1 + AM.OffsetIndex;
3522 if ( c1 >= AM.WilInd && c ==
'?' ) { *p++ = c; c = *p; }
3524 case CFUNCTION: *w++ = -c1-FUNCTION;
break;
3525 case CDUBIOUS: minvec = 0; error = 1;
break;
3527 MesPrint(
"&Illegal object type in TryReplace: %s",name);
3532 if ( which < 0 ) which = i+1;
3535 if ( *p ==
',' ) p++;
3539 MesPrint(
"&Illegal object in TryReplace");
3541 while ( *p && *p !=
',' ) {
3542 if ( *p ==
'(' ) SKIPBRA3(p)
3543 else if ( *p ==
'{' ) SKIPBRA2(p)
3544 else if ( *p ==
'[' ) SKIPBRA1(p)
3548 if ( *p ==
',' ) p++;
3549 if ( which < 0 ) which = 0;
3553 MesPrint(
"&Odd number of arguments in TryReplace");
3556 i = w - AT.WorkPointer;
3557 AT.WorkPointer[1] = i;
3558 AT.WorkPointer[2] = i - 3;
3559 AT.WorkPointer[4] = i - 3;
3560 AddNtoL((
int)i,AT.WorkPointer);
3579int CoModulus(UBYTE *inp)
3582 int Retval = 0, sign = 1;
3584 while ( *inp ==
',' || *inp ==
' ' || *inp ==
'\t' ) inp++;
3587 if ( AC.modpowers ) M_free(AC.modpowers,
"AC.modpowers");
3589 AN.ncmod = AC.ncmod = 0;
3590 if ( AC.halfmod ) M_free(AC.halfmod,
"halfmod");
3591 AC.halfmod = 0; AC.nhalfmod = 0;
3592 if ( AC.modinverses ) M_free(AC.modinverses,
"modinverses");
3598 if ( AT.aux_ != 0 ) {
3599 MesPrint(
"&Simultaneous use of floating point and modulus arithmetic makes no sense.");
3604 if ( *inp ==
'-' ) {
3609 while ( FG.cTable[*inp] == 0 ) {
3611 while ( FG.cTable[*inp] == 0 ) inp++;
3613 if ( StrICmp(p,(UBYTE *)
"nofunctions") == 0 ) {
3614 AC.modmode &= ~ALSOFUNARGS;
3616 else if ( StrICmp(p,(UBYTE *)
"alsofunctions") == 0 ) {
3617 AC.modmode |= ALSOFUNARGS;
3619 else if ( StrICmp(p,(UBYTE *)
"coefficientsonly") == 0 ) {
3620 AC.modmode &= ~ALSOFUNARGS;
3621 AC.modmode &= ~ALSOPOWERS;
3624 else if ( StrICmp(p,(UBYTE *)
"plusmin") == 0 ) {
3625 AC.modmode |= POSNEG;
3627 else if ( StrICmp(p,(UBYTE *)
"positive") == 0 ) {
3628 AC.modmode &= ~POSNEG;
3630 else if ( StrICmp(p,(UBYTE *)
"inversetable") == 0 ) {
3631 AC.modmode |= INVERSETABLE;
3633 else if ( StrICmp(p,(UBYTE *)
"noinversetable") == 0 ) {
3634 AC.modmode &= ~INVERSETABLE;
3636 else if ( StrICmp(p,(UBYTE *)
"nodollars") == 0 ) {
3637 AC.modmode &= ~ALSODOLLARS;
3639 else if ( StrICmp(p,(UBYTE *)
"alsodollars") == 0 ) {
3640 AC.modmode |= ALSODOLLARS;
3642 else if ( StrICmp(p,(UBYTE *)
"printpowersof") == 0 ) {
3644 if ( *inp !=
'(' ) {
3646 MesPrint(
"&Bad syntax in argument of PrintPowersOf(number) in Modulus statement");
3649 while ( *inp ==
',' || *inp ==
' ' || *inp ==
'\t' ) inp++;
3651 if ( FG.cTable[*inp] != 1 )
goto badsyntax;
3652 do { inp++; }
while ( FG.cTable[*inp] == 1 );
3654 if ( GetLong(p,(UWORD *)AC.powmod,&AC.npowmod) ) Retval = -1;
3655 if ( TakeModulus((UWORD *)AC.powmod,&AC.npowmod,AC.cmod,AC.ncmod,NOUNPACK) ) Retval = -1;
3656 if ( AC.npowmod == 0 ) {
3657 MesPrint(
"&Improper value for generator");
3660 if ( MakeModTable() ) Retval = -1;
3663 while ( *inp ==
',' || *inp ==
' ' || *inp ==
'\t' ) inp++;
3664 if ( *inp !=
')' )
goto badsyntax;
3668 else if ( StrICmp(p,(UBYTE *)
"alsopowers") == 0 ) {
3669 AC.modmode |= ALSOPOWERS;
3672 else if ( StrICmp(p,(UBYTE *)
"nopowers") == 0 ) {
3673 AC.modmode &= ~ALSOPOWERS;
3677 MesPrint(
"&Unrecognized option %s in Modulus statement",inp);
3681 while ( *inp ==
',' || *inp ==
' ' || *inp ==
'\t' ) inp++;
3683 MesPrint(
"&Modulus statement with no value!!!");
3689 if ( FG.cTable[*inp] != 1 ) {
3690 MesPrint(
"&Invalid value for modulus:%s",inp);
3691 if ( AC.modpowers ) M_free(AC.modpowers,
"AC.modpowers");
3693 AN.ncmod = AC.ncmod = 0;
3694 if ( AC.halfmod ) M_free(AC.halfmod,
"halfmod");
3695 AC.halfmod = 0; AC.nhalfmod = 0;
3696 if ( AC.modinverses ) M_free(AC.modinverses,
"modinverses");
3700 do { inp++; }
while ( FG.cTable[*inp] == 1 );
3702 Retval = GetLong(p,(UWORD *)AC.cmod,&AC.ncmod);
3703 if ( Retval == 0 && AC.ncmod == 0 )
goto SwitchOff;
3704 if ( sign < 0 ) AC.ncmod = -AC.ncmod;
3705 AN.ncmod = AC.ncmod;
3706 if ( ( AC.modmode & INVERSETABLE ) != 0 )
MakeInverses();
3707 if ( AC.halfmod ) M_free(AC.halfmod,
"halfmod");
3708 AC.halfmod = 0; AC.nhalfmod = 0;
3717int CoRepeat(UBYTE *inp)
3720 AC.RepSumCheck[AC.RepLevel] = NestingChecksum();
3722 if ( AC.RepLevel > AM.RepMax ) {
3723 MesPrint(
"&Too many repeat levels. Maximum is %d",AM.RepMax);
3726 Add3Com(TYPEREPEAT,-1)
3727 while ( *inp == ' ' || *inp == ',' || *inp == '\t' ) inp++;
3729 error = CompileStatement(inp);
3730 if ( CoEndRepeat(inp) ) error = 1;
3740int CoEndRepeat(UBYTE *inp)
3742 CBUF *C = cbuf+AC.cbufnum;
3743 int level, error = 0, repeatlevel = 0;
3746 if ( AC.RepLevel < 0 ) {
3747 MesPrint(
"&EndRepeat without Repeat");
3751 else if ( AC.RepSumCheck[AC.RepLevel] != NestingChecksum() ) {
3755 level = C->numlhs+1;
3756 while ( level > 0 ) {
3757 if ( C->
lhs[--level][0] == TYPEREPEAT ) {
3758 if ( repeatlevel == 0 ) {
3759 Add3Com(TYPEENDREPEAT,level)
3764 else if ( C->
lhs[level][0] == TYPEENDREPEAT ) repeatlevel++;
3778int DoBrackets(UBYTE *inp,
int par)
3782 WORD *to, i, type, *w, error = 0;
3783 WORD c1,c2, *WorkSave;
3786 WorkSave = to = AT.WorkPointer;
3788 if ( AT.BrackBuf == 0 ) {
3789 AR.MaxBracket = 100;
3790 AT.BrackBuf = (WORD *)Malloc1(
sizeof(WORD)*(AR.MaxBracket+1),
"bracket buffer");
3794 AC.bracketindexflag = 0;
3795 AT.bracketindexflag = 0;
3796 if ( *p ==
'+' || *p ==
'-' ) p++;
3797 if ( p[-1] ==
',' && *p ) p--;
3798 if ( p[-1] ==
'+' && *p ) { biflag = 1;
if ( *p !=
',' ) { *--p =
','; } }
3799 else if ( p[-1] ==
'-' && *p ) { biflag = -1;
if ( *p !=
',' ) { *--p =
','; } }
3801 while ( *p ==
',' ) {
3802redo: AR.BracketOn++;
3803 while ( *p ==
',' ) p++;
3804 if ( *p == 0 )
break;
3806 p++;
while ( *p ==
'0' ) p++;
3811 if ( p == 0 )
return(1);
3814 type = GetName(AC.varnames,inp,&c1,WITHAUTO);
3816 if ( type == CVECTOR || type == CDUBIOUS ) {
3820 if ( p == 0 )
return(1);
3823 type = GetName(AC.varnames,inp,&c2,WITHAUTO);
3824 if ( type != CVECTOR && type != CDUBIOUS ) {
3825 MesPrint(
"&Not a vector in dotproduct in bracket statement: %s",inp);
3828 else type = CDOTPRODUCT;
3831 MesPrint(
"&Illegal use of . after %s in bracket statement",inp);
3839 *to++ = SYMBOL; *to++ = 4; *to++ = c1; *to++ = 1;
break;
3841 *to++ = INDEX; *to++ = 3; *to++ = AM.OffsetVector + c1;
break;
3843 *to++ = c1+FUNCTION; *to++ = FUNHEAD; *to++ = 0;
3847 *to++ = DOTPRODUCT; *to++ = 5; *to++ = c1 + AM.OffsetVector;
3848 *to++ = c2 + AM.OffsetVector; *to++ = 1;
break;
3850 *to++ = DELTA; *to++ = 4; *to++ = EMPTYINDEX; *to++ = EMPTYINDEX;
break;
3852 *to++ = SETSET; *to++ = 4; *to++ = c1; *to++ = Sets[c1].type;
break;
3854 MesPrint(
"&Illegal bracket request for %s",pp);
3860 MesCerr(
"separator",p);
3861 AC.BracketNormalize = 0;
3862 AT.WorkPointer = WorkSave;
3866 *to++ = 1; *to++ = 1; *to++ = 3;
3867 *AT.WorkPointer = to - AT.WorkPointer;
3868 AT.WorkPointer = to;
3869 AC.BracketNormalize = 1;
3870 if ( BracketNormalize(BHEAD WorkSave) ) { error = 1; AR.BracketOn = 0; }
3873 if ( *w == 4 || !*w ) { AR.BracketOn = 0; }
3876 if ( i < 0 ) i = -i;
3879 if ( i > AR.MaxBracket ) {
3881 newbuf = (WORD *)Malloc1(
sizeof(WORD)*(i+1),
"bracket buffer");
3883 if ( AT.BrackBuf != 0 ) M_free(AT.BrackBuf,
"bracket buffer");
3884 AT.BrackBuf = newbuf;
3890 AC.BracketNormalize = 0;
3891 if ( par == 1 ) AR.BracketOn = -AR.BracketOn;
3893 AC.bracketindexflag = biflag;
3894 AT.bracketindexflag = biflag;
3896 AT.WorkPointer = WorkSave;
3905int CoBracket(UBYTE *inp)
3906{
return(DoBrackets(inp,0)); }
3913int CoAntiBracket(UBYTE *inp)
3914{
return(DoBrackets(inp,1)); }
3924int CoMultiBracket(UBYTE *inp)
3927 int i, error = 0, error1, type, num;
3931 if ( *inp !=
':' ) {
3932 MesPrint(
"&Illegal Multiple Bracket separator: %s",inp);
3936 if ( AC.MultiBracketBuf == 0 ) {
3937 AC.MultiBracketBuf = (WORD **)Malloc1(
sizeof(WORD *)*MAXMULTIBRACKETLEVELS,
"multi bracket buffer");
3938 for ( i = 0; i < MAXMULTIBRACKETLEVELS; i++ ) {
3939 AC.MultiBracketBuf[i] = 0;
3943 for ( i = 0; i < MAXMULTIBRACKETLEVELS; i++ ) {
3944 if ( AC.MultiBracketBuf[i] ) {
3945 M_free(AC.MultiBracketBuf[i],
"bracket buffer i");
3946 AC.MultiBracketBuf[i] = 0;
3949 AC.MultiBracketLevels = 0;
3951 AC.MultiBracketLevels = 0;
3955 if ( AT.BrackBuf == 0 ) {
3956 AR.MaxBracket = 100;
3957 AT.BrackBuf = (WORD *)Malloc1(
sizeof(WORD)*(AR.MaxBracket+1),
"bracket buffer");
3961 AC.bracketindexflag = 0;
3962 AT.bracketindexflag = 0;
3966 for ( i = 0; i < MAXMULTIBRACKETLEVELS; i++ ) {
3967 if ( *inp == 0 )
goto RegEnd;
3972 while ( *s && *s !=
':' ) {
3973 if ( *s ==
'[' ) { SKIPBRA1(s) s++; }
3974 else if ( *s ==
'{' ) { SKIPBRA2(s) s++; }
3978 if ( StrICont(inp,(UBYTE *)
"antibrackets") == 0 ) { type = 1; }
3979 else if ( StrICont(inp,(UBYTE *)
"brackets") == 0 ) { type = 0; }
3981 MesPrint(
"&Illegal (anti)bracket specification in MultiBracket statement");
3982 if ( error == 0 ) error = 1;
3985 while ( FG.cTable[*inp] == 0 ) inp++;
3986 if ( *inp !=
',' ) {
3987 MesPrint(
"&Illegal separator after (anti)bracket specification in MultiBracket statement");
3988 if ( error == 0 ) error = 1;
3995 error1 = DoBrackets(inp, type);
3996 if ( error < 0 )
return(error1);
3997 if ( error1 > error ) error = error1;
4001 if ( AR.BracketOn ) {
4002 num = AT.BrackBuf[0];
4003 to = AC.MultiBracketBuf[i] = (WORD *)Malloc1((num+2)*
sizeof(WORD),
"bracket buffer i");
4005 *to++ = AR.BracketOn;
4013 *s = c;
if ( c ==
':' ) s++;
4019 MesPrint(
"&More than %d levels in MultiBracket statement",(WORD)MAXMULTIBRACKETLEVELS);
4020 if ( error == 0 ) error = 1;
4023 AC.MultiBracketLevels = i;
4026 AC.bracketindexflag = 0;
4027 AT.bracketindexflag = 0;
4056WORD *CountComp(UBYTE *inp, WORD *to)
4060 WORD *w, mini = 0, type, c1, c2;
4068 while ( *p ==
',' ) {
4070 if ( *p ==
'[' || FG.cTable[*p] == 0 ) {
4071 if ( ( p =
SkipAName(inp) ) == 0 )
return(0);
4073 type = GetName(AC.varnames,inp,&c1,WITHAUTO);
4075 if ( type == CVECTOR || type == CDUBIOUS ) {
4079 if ( p == 0 )
return(0);
4082 type = GetName(AC.varnames,inp,&c2,WITHAUTO);
4083 if ( type != CVECTOR && type != CDUBIOUS ) {
4084 MesPrint(
"&Not a vector in dotproduct in if statement: %s",inp);
4087 else type = CDOTPRODUCT;
4090 MesPrint(
"&Illegal use of . after %s in if statement",inp);
4091 if ( type == NAMENOTFOUND )
4092 MesPrint(
"&%s is not a properly declared variable",inp);
4095 while ( *p && *p !=
')' && *p !=
',' ) p++;
4096 if ( *p ==
',' && FG.cTable[p[1]] == 1 ) {
4098 while ( *p && *p !=
')' && *p !=
',' ) p++;
4106 *w++ = SYMBOL; *w++ = 4; *w++ = c1;
4107Sgetnum:
if ( *p !=
',' ) {
4108 MesCerr(
"sequence",p);
4109 while ( *p && *p !=
')' && *p !=
',' ) p++;
4113 ParseSignedNumber(mini,p)
4114 if ( FG.cTable[p[-1]] != 1 || ( *p && *p !=
')' && *p !=
',' ) ) {
4115 while ( *p && *p !=
')' && *p !=
',' ) p++;
4118 MesPrint(
"&Improper value in count: %s",inp);
4120 while ( *p && *p !=
')' && *p !=
',' ) p++;
4125 *w++ = FUNCTION; *w++ = 4; *w++ = c1+FUNCTION;
goto Sgetnum;
4127 *w++ = DOTPRODUCT; *w++ = 5;
4128 *w++ = c2 + AM.OffsetVector;
4129 *w++ = c1 + AM.OffsetVector;
4132 *w++ = VECTOR; *w++ = 5;
4133 *w++ = c1 + AM.OffsetVector;
4135 *w++ = VECTBIT | DOTPBIT | FUNBIT;
4138 else if ( *p ==
'+' ) {
4141 while ( *p && *p !=
',' ) {
4142 if ( *p ==
'v' || *p ==
'V' ) {
4145 else if ( *p ==
'd' || *p ==
'D' ) {
4148 else if ( *p ==
'f' || *p ==
'F'
4149 || *p ==
't' || *p ==
'T' ) {
4152 else if ( *p ==
'?' ) {
4156 if ( p == 0 )
return(0);
4157 if ( ( c1 = DoTempSet(inp+1,p) ) < 0 )
return(0);
4158 if ( Sets[c1].type != CFUNCTION ) {
4159 MesPrint(
"&set type conflict: Function expected");
4167 if ( p == 0 )
return(0);
4169 type = GetName(AC.varnames,inp,&c1,WITHAUTO);
4171 if ( type != CSET && type != CDUBIOUS ) {
4172 MesPrint(
"&%s is not a set",inp);
4182 MesCerr(
"specifier for vector",p);
4190 MesCerr(
"specifier for vector",p);
4191 while ( *p && *p !=
')' && *p !=
',' ) p++;
4193 *w++ = VECTBIT | DOTPBIT | FUNBIT;
4200 MesPrint(
"&%s is not a symbol, function, vector or dotproduct",inp);
4202skipfield:
while ( *p && *p !=
')' && *p !=
',' ) p++;
4203 if ( *p && FG.cTable[p[1]] == 1 ) {
4205 while ( *p && *p !=
')' && *p !=
',' ) p++;
4212 while ( *p && *p !=
',' ) p++;
4217 if ( *p ==
')' ) p++;
4218 if ( *p ) { MesCerr(
"end of statement",p);
return(0); }
4219 if ( error )
return(0);
4244static UWORD *CIscratC = 0;
4249 int error = 0, level;
4250 WORD *w, *ww, *u, *s, *OldWork, *OldSpace = AT.WorkSpace;
4252 WORD lenpp, lenlev, ncoef, i, number;
4253 UBYTE *p, *pp, *ppp, c;
4254 CBUF *C = cbuf+AC.cbufnum;
4261 if ( *inp ==
'(' && inp[1] ==
',' ) inp += 2;
4262 else if ( *inp ==
'(' ) inp++;
4264 if ( CIscratC == 0 )
4265 CIscratC = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"CoIf");
4268 if ( AC.IfLevel >= AC.MaxIf ) DoubleIfBuffers();
4269 AC.IfCount[lenpp++] = 0;
4277 AC.IfSumCheck[AC.IfLevel] = NestingChecksum();
4279 w = OldWork = AT.WorkPointer;
4287 if ( FG.cTable[*p] == 1 ) {
4288 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4291 pp = CheckFloat(p,&spec);
4295 MesPrint(
"&The floating point system has not been started: %s",p);
4296 if ( !error ) error = 1;
4299 WORD *ow = AT.WorkPointer;
4302 ReadFloat((SBYTE *)p);
4305 AT.WorkPointer[0] = IFFLOATNUMBER;
4306 w = AT.WorkPointer + AT.WorkPointer[1];
4307 AT.WorkPointer = ow;
4308 if ( level ) w[FUNHEAD+3] = -w[FUNHEAD+3];
4310 goto DoneWithNumber;
4325 if ( GetLong(p,(UWORD *)w,&ncoef) ) { ncoef = 1; error = 1; }
4327 while ( FG.cTable[*++p] == 1 );
4330 if ( FG.cTable[*p] != 1 ) {
4331 MesCerr(
"sequence",p); error = 1;
goto OnlyNum;
4333 if ( GetLong(p,CIscratC,&ncoef) ) {
4334 ncoef = 1; error = 1;
4336 while ( FG.cTable[*++p] == 1 );
4338 MesPrint(
"&Division by zero!");
4343 if ( Simplify(BHEAD (UWORD *)w,(WORD *)(w-1),
4344 CIscratC,&ncoef) ) error = 1;
4351 s = (WORD *)CIscratC;
4353 while ( --i >= 0 ) *w++ = 0;
4358 while ( --i >= 0 ) *w++ = 0;
4359 s = (WORD *)CIscratC;
4371 while ( --ncoef >= 0 ) *w++ = 0;
4374 u[1] = WORDDIF(w,u);
4375 u[2] = (u[1] - 3)/2;
4376 if ( level ) u[2] = -u[2];
4384 else if ( *p ==
'+' ) { p++;
goto ReDo; }
4385 else if ( *p ==
'-' ) { level ^= 1; p++;
goto ReDo; }
4386 else if ( *p ==
'c' || *p ==
'C' ) {
4387 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4388 while ( FG.cTable[*++p] == 0 );
4390 if ( !StrICmp(inp,(UBYTE *)
"count") ) {
4393 MesPrint(
"&no ( after count");
4399 c = *++p; *p = 0; *inp =
',';
4400 w = CountComp(inp,w);
4402 if ( w == 0 ) { error = 1;
goto endofif; }
4405 else if ( ConWord(inp,(UBYTE *)
"coefficient") && ( p - inp ) > 3 ) {
4414 else if ( *p ==
'm' || *p ==
'M' ) {
4415 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4416 while ( !FG.cTable[*++p] );
4418 if ( !StrICmp(inp,(UBYTE *)
"match") ) {
4421 MesPrint(
"&no ( after match");
4432 AT.WorkSpace = AT.WorkPointer = w;
4434 while ( FG.cTable[*ppp] == 0 && ppp < p ) ppp++;
4435 if ( *ppp ==
',' ) AC.idoption = 0;
4436 else AC.idoption = SUBMULTI;
4437 level = CoIdExpression(inp,TYPEIF);
4438 AT.WorkSpace = OldSpace;
4439 AT.WorkPointer = OldWork;
4441 if ( level < 0 ) { error = -1;
goto endofif; }
4447 s = u = C->
lhs[C->numlhs];
4448 while ( u < C->Pointer ) *w++ = *u++;
4454 else if ( !StrICmp(inp,(UBYTE *)
"multipleof") ) {
4455 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4458 MesPrint(
"&no ( after multipleof");
4459 error = 1;
goto endofif;
4462 if ( FG.cTable[*p] != 1 ) {
4463Nomulof: MesPrint(
"&multipleof needs a short positive integer argument");
4464 error = 1;
goto endofif;
4467 if ( *p !=
')' || x <= 0 || x > MAXPOSITIVE )
goto Nomulof;
4469 *w++ = MULTIPLEOF; *w++ = 3; *w++ = (WORD)x;
4474NoGood: MesPrint(
"&Unrecognized word: %s",inp);
4478 if ( c ==
'(' ) SKIPBRA4(p)
4483 else if ( *p ==
'f' || *p ==
'F' ) {
4484 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4485 while ( FG.cTable[*++p] == 0 );
4487 if ( !StrICmp(inp,(UBYTE *)
"findloop") ) {
4490 MesPrint(
"&no ( after findloop");
4496 c = *++p; *p = 0; *inp =
',';
4497 if ( CoFindLoop(inp) ) { error = 1;
goto endofif; }
4498 s = u = C->
lhs[C->numlhs];
4499 while ( u < C->Pointer ) *w++ = *u++;
4502 if ( w == 0 ) { error = 1;
goto endofif; }
4505 else if ( !StrICmp(inp,(UBYTE *)
"flag") ) {
4506 UBYTE cc = c, *pppp;
4509 MesPrint(
"&no ( after flag");
4515 cc = *++p; *p = 0; *inp =
','; pppp = p;
4517 *w++ = IFUSERFLAG; *w++ = 0;
4520 while ( *inp ==
',' ) inp++;
4521 if ( *inp == 0 || *inp ==
')' )
break;
4522 while ( *inp >=
'0' && *inp <=
'9' ) x = 10*x+(*inp++-
'0');
4523 if ( x < 1 || x > BITSINWORD ) {
4524 MesPrint(
"&Flag number %d outside the permitted range 1-%d.",BITSINWORD);
4530 p = pppp; *p = cc; *inp =
'(';
4533 MesPrint(
"&The userflag condition in the if statement needs arguments.");
4541 else if ( *p ==
'e' || *p ==
'E' ) {
4542 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4543 while ( FG.cTable[*++p] == 0 );
4545 if ( !StrICmp(inp,(UBYTE *)
"expression") ) {
4548 MesPrint(
"&no ( after expression");
4552 p++; ww = w; *w++ = IFEXPRESSION; w++;
4553 while ( *p !=
')' ) {
4554 if ( *p ==
',' ) { p++;
continue; }
4555 if ( *p ==
'[' || FG.cTable[*p] == 0 ) {
4558 MesPrint(
"&Improper name for an expression: '%s'",pp);
4563 if ( GetName(AC.exprnames,pp,&number,NOAUTO) == CEXPRESSION ) {
4566 else if ( GetName(AC.varnames,pp,&number,NOAUTO) != NAMENOTFOUND ) {
4567 MesPrint(
"&%s is not an expression",pp);
4574 MesPrint(
"&Illegal object in Expression in if-statement");
4576 while ( *p && *p !=
',' && *p !=
')' ) p++;
4577 if ( *p == 0 || *p ==
')' )
break;
4587 else if ( *p ==
'i' || *p ==
'I' ) {
4588 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4589 while ( FG.cTable[*++p] == 0 );
4591 if ( !StrICmp(inp,(UBYTE *)
"isfactorized") ) {
4594 ww = w; *w++ = IFISFACTORIZED; w++;
4597 p++; ww = w; *w++ = IFISFACTORIZED; w++;
4598 while ( *p !=
')' ) {
4599 if ( *p ==
',' ) { p++;
continue; }
4600 if ( *p ==
'[' || FG.cTable[*p] == 0 ) {
4603 MesPrint(
"&Improper name for an expression: '%s'",pp);
4608 if ( GetName(AC.exprnames,pp,&number,NOAUTO) == CEXPRESSION ) {
4611 else if ( GetName(AC.varnames,pp,&number,NOAUTO) != NAMENOTFOUND ) {
4612 MesPrint(
"&%s is not an expression",pp);
4619 MesPrint(
"&Illegal object in IsFactorized in if-statement");
4621 while ( *p && *p !=
',' && *p !=
')' ) p++;
4622 if ( *p == 0 || *p ==
')' )
break;
4633 else if ( *p ==
'o' || *p ==
'O' ) {
4645 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4646 while ( FG.cTable[*++p] == 0 );
4647 c = cc = *p; *p = 0;
4648 if ( !StrICmp(inp,(UBYTE *)
"occurs") ) {
4652 MesPrint(
"&no ( after occurs");
4658 cc = *++p; *p = 0; *inp =
','; pp = p;
4660 *w++ = IFOCCURS; *w++ = 0;
4662 while ( *inp ==
',' ) inp++;
4663 if ( *inp == 0 || *inp ==
')' )
break;
4669 if ( *inp ==
'[' || FG.cTable[*inp] == 0 ) {
4670 if ( ( p =
SkipAName(inp) ) == 0 )
return(0);
4672 type = GetName(AC.varnames,inp,&c1,WITHAUTO);
4674 if ( type == CVECTOR || type == CDUBIOUS ) {
4678 if ( p == 0 )
return(0);
4681 type = GetName(AC.varnames,inp,&c2,WITHAUTO);
4682 if ( type != CVECTOR && type != CDUBIOUS ) {
4683 MesPrint(
"&Not a vector in dotproduct in if statement: %s",inp);
4686 else type = CDOTPRODUCT;
4689 MesPrint(
"&Illegal use of . after %s in if statement",inp);
4690 if ( type == NAMENOTFOUND )
4691 MesPrint(
"&%s is not a properly declared variable",inp);
4694 while ( *p && *p !=
')' && *p !=
',' ) p++;
4695 if ( *p ==
',' && FG.cTable[p[1]] == 1 ) {
4697 while ( *p && *p !=
')' && *p !=
',' ) p++;
4710 *w++ = c1 + AM.OffsetIndex;
4714 *w++ = c1 + AM.OffsetVector;
4718 *w++ = c1 + AM.OffsetVector;
4719 *w++ = c2 + AM.OffsetVector;
4726 MesPrint(
"&Illegal variable %s in occurs condition in if statement",inp);
4733 MesPrint(
"&Illegal object %s in occurs condition in if statement",inp);
4739 p = pp; *p = cc; *inp =
'(';
4742 MesPrint(
"&The occurs condition in the if statement needs arguments.");
4749 else if ( *p ==
'$' ) {
4750 if ( gotexp == 1 ) { MesCerr(
"position for )",p); error = 1; }
4752 while ( FG.cTable[*p] == 0 || FG.cTable[*p] == 1 ) p++;
4754 if ( ( i = GetDollar(inp) ) < 0 ) {
4755 MesPrint(
"&undefined dollar expression %s",inp);
4757 i = AddDollar(inp,DOLUNDEFINED,0,0);
4760 *w++ = IFDOLLAR; *w++ = 3; *w++ = i;
4766 if ( ( w = GetIfDollarFactor(&p,w) ) == 0 ) {
4770 else if ( *p !=
']' ) {
4781 else if ( *p ==
'.' ) {
4782 pp = CheckFloat(p,&spec);
4783 if ( pp > p )
goto HaveFloat;
4787 else if ( *p ==
'(' ) {
4789 MesCerr(
"parenthesis",p);
4794 if ( ++lenlev >= AC.MaxIf ) DoubleIfBuffers();
4795 AC.IfCount[lenpp++] = w-OldWork;
4800 else if ( *p ==
')' ) {
4801 if ( gotexp == 0 ) { MesCerr(
"position for )",p); error = 1; }
4803 u = AC.IfCount[--lenpp]+OldWork;
4806 if ( lenlev <= 0 ) {
4807 AT.WorkSpace = OldSpace;
4808 AT.WorkPointer = OldWork;
4812 MesPrint(
"&unmatched parenthesis in if/while ()");
4814 while ( *++p ==
')' );
4817 level = CompileStatement(p);
4818 if ( level ) error = level;
4820 if ( CoEndIf(p) && error == 0 ) error = 1;
4826 else if ( *p ==
'>' ) {
4827 if ( gotexp == 0 )
goto NoExp;
4828 if ( p[1] ==
'=' ) { *w++ = GREATEREQUAL; *w++ = 2; p += 2; }
4829 else { *w++ = GREATER; *w++ = 2; p++; }
4832 else if ( *p ==
'<' ) {
4833 if ( gotexp == 0 )
goto NoExp;
4834 if ( p[1] ==
'=' ) { *w++ = LESSEQUAL; *w++ = 2; p += 2; }
4835 else { *w++ = LESS; *w++ = 2; p++; }
4838 else if ( *p ==
'=' ) {
4839 if ( gotexp == 0 )
goto NoExp;
4840 if ( p[1] ==
'=' ) p++;
4841 *w++ = EQUAL; *w++ = 2; p++;
4844 else if ( *p ==
'!' && p[1] ==
'=' ) {
4845 if ( gotexp == 0 ) { p++;
goto NoExp; }
4846 *w++ = NOTEQUAL; *w++ = 2; p += 2;
4849 else if ( *p ==
'|' && p[1] ==
'|' ) {
4850 if ( gotexp == 0 ) { p++;
goto NoExp; }
4851 *w++ = ORCOND; *w++ = 2; p += 2;
4854 else if ( *p ==
'&' && p[1] ==
'&' ) {
4855 if ( gotexp == 0 ) {
4858 MesCerr(
"sequence",p);
4862 *w++ = ANDCOND; *w++ = 2; p += 2;
4866 else if ( *p == 0 ) {
4867 MesPrint(
"&Unmatched parentheses");
4872 if ( FG.cTable[*p] == 0 ) {
4875 while ( ( ij = FG.cTable[*++p] ) == 0 || ij == 1 );
4879 MesCerr(
"sequence",p);
4896 CBUF *C = cbuf+AC.cbufnum;
4898 while ( *p ==
',' ) p++;
4899 if ( tolower(*p) ==
'i' && tolower(p[1]) ==
'f' && p[2] ==
'(' )
4900 return(CoElseIf(p+2));
4901 MesPrint(
"&No extra text allowed as part of an else statement");
4904 if ( AC.IfLevel <= 0 ) { MesPrint(
"&else statement without if");
return(1); }
4905 if ( AC.IfSumCheck[AC.IfLevel-1] != NestingChecksum() - 1 ) {
4909 Add3Com(TYPEELSE,AC.IfLevel)
4910 C->Buffer[AC.IfStack[-1]] = C->numlhs;
4911 AC.IfStack[-1] = C->Pointer - C->Buffer - 1;
4920int CoElseIf(UBYTE *inp)
4922 CBUF *C = cbuf+AC.cbufnum;
4923 if ( AC.IfLevel <= 0 ) { MesPrint(
"&elseif statement without if");
return(1); }
4924 Add3Com(TYPEELSE,-AC.IfLevel)
4926 C->Buffer[*--AC.IfStack] = C->numlhs;
4947int CoEndIf(UBYTE *inp)
4949 CBUF *C = cbuf+AC.cbufnum;
4950 WORD i = C->numlhs, to, k = -AC.IfLevel;
4952 while ( *inp ==
',' ) inp++;
4955 MesPrint(
"&No extra text allowed as part of an endif/elseif statement");
4957 if ( AC.IfLevel <= 0 ) {
4958 MesPrint(
"&Endif statement without corresponding if");
return(1);
4961 C->
Buffer[*--AC.IfStack] = i+1;
4962 if ( AC.IfSumCheck[AC.IfLevel] != NestingChecksum() ) {
4966 Add3Com(TYPEENDIF,i+1)
4972 if ( C->
lhs[i][0] == TYPEELSE && C->
lhs[i][2] == to ) to = i;
4973 if ( C->
lhs[i][0] == TYPEIF ) {
4974 if ( C->
lhs[i][2] == to ) {
4976 if ( i <= 0 || C->lhs[i][0] != TYPEELSE
4977 || C->
lhs[i][2] != k )
break;
4978 C->
lhs[i][2] = C->numlhs;
4992int CoWhile(UBYTE *inp)
4994 CBUF *C = cbuf+AC.cbufnum;
4995 WORD startnum = C->numlhs + 1;
4999 if ( C->numlhs > startnum && C->
lhs[startnum][2] == C->numlhs
5000 && C->
lhs[C->numlhs][0] == TYPEENDIF ) {
5001 C->
lhs[C->numlhs][2] = startnum-1;
5004 else C->
lhs[startnum][2] = startnum;
5013int CoEndWhile(UBYTE *inp)
5017 CBUF *C = cbuf+AC.cbufnum;
5018 if ( AC.WhileLevel <= 0 ) {
5019 MesPrint(
"&EndWhile statement without corresponding While");
return(1);
5022 i = C->
Buffer[AC.IfStack[-1]];
5023 error = CoEndIf(inp);
5024 C->
lhs[C->numlhs][2] = i - 1;
5035static char *messfind[] = {
5036 "Findloop(function,arguments=#,loopsize(=#|<#)[,include=index])"
5037 ,
"Replaceloop,function,arguments=#,loopsize(=#|<#),outfun=function[,include=index]"
5039static WORD comfindloop[7] = { TYPEFINDLOOP,7,0,0,0,0,0 };
5041int DoFindLoop(UBYTE *inp,
int mode)
5044 WORD funnum, nargs = 0, nloop = 0, indexnum = 0, outfun = 0;
5045 int type, aflag, lflag, indflag, outflag, error = 0, sym;
5046 while ( *inp ==
',' ) inp++;
5049 MesPrint(
"&Proper syntax is:");
5050 MesPrint(
"%s",messfind[mode]);
5054 if ( ( ( type = GetName(AC.varnames,inp,&funnum,WITHAUTO) ) == NAMENOTFOUND )
5055 || type != CFUNCTION || ( ( sym = (functions[funnum].symmetric) & ~REVERSEORDER )
5056 != SYMMETRIC && sym != ANTISYMMETRIC ) ) {
5057 MesPrint(
"&%s should be a (anti)symmetric function or tensor",inp);
5062 aflag = lflag = indflag = outflag = 0;
5063 while ( *inp ==
',' ) {
5064 while ( *inp ==
',' ) inp++;
5066 if ( ( s =
SkipAName(inp) ) == 0 )
goto syntax;
5068 if ( StrICont(inp,(UBYTE *)
"arguments") == 0 ) {
5069 if ( c !=
'=' )
goto syntax;
5071 NeedNumber(nargs,s,syntax)
5075 else if ( StrICont(inp,(UBYTE *)
"loopsize") == 0 ) {
5076 if ( c !=
'=' && c !=
'<' )
goto syntax;
5078 if ( FG.cTable[*s] == 1 ) {
5079 NeedNumber(nloop,s,syntax)
5081 MesPrint(
"&loopsize should be at least 2");
5084 if ( c ==
'<' ) nloop = -nloop;
5086 else if ( tolower(*s) ==
'a' && tolower(s[1]) ==
'l'
5087 && tolower(s[2]) ==
'l' && FG.cTable[s[3]] > 1 ) {
5089 if ( c !=
'=' )
goto syntax;
5094 else if ( StrICont(inp,(UBYTE *)
"include") == 0 ) {
5095 if ( c !=
'=' )
goto syntax;
5097 if ( ( inp =
SkipAName(s) ) == 0 )
goto syntax;
5099 if ( ( type = GetName(AC.varnames,s,&indexnum,WITHAUTO) ) != CINDEX ) {
5100 MesPrint(
"&%s is not a proper index",s);
5103 else if ( indexnum < WILDOFFSET
5104 && indices[indexnum].dimension == 0 ) {
5105 MesPrint(
"&%s should be a summable index",s);
5108 indexnum += AM.OffsetIndex;
5112 else if ( StrICont(inp,(UBYTE *)
"outfun") == 0 ) {
5113 if ( c !=
'=' )
goto syntax;
5115 if ( ( inp =
SkipAName(s) ) == 0 )
goto syntax;
5117 if ( ( type = GetName(AC.varnames,s,&outfun,WITHAUTO) ) != CFUNCTION ) {
5118 MesPrint(
"&%s is not a proper function or tensor",s);
5126 MesPrint(
"&Unrecognized option in FindLoop or ReplaceLoop: %s",inp);
5129 while ( *inp && *inp !=
',' ) inp++;
5132 if ( *inp != 0 && mode == REPLACELOOP )
goto syntax;
5133 if ( mode == FINDLOOP && outflag > 0 ) {
5134 MesPrint(
"&outflag option is illegal in FindLoop");
5137 if ( mode == REPLACELOOP && outflag == 0 )
goto syntax;
5138 if ( aflag == 0 || lflag == 0 )
goto syntax;
5139 comfindloop[3] = funnum;
5140 comfindloop[4] = nloop;
5141 comfindloop[5] = nargs;
5142 comfindloop[6] = outfun;
5145 if ( mode == 0 ) comfindloop[2] = indexnum + 5;
5146 else comfindloop[2] = -indexnum - 5;
5148 else comfindloop[2] = mode;
5149 AddNtoL(comfindloop[1],comfindloop);
5158int CoFindLoop(UBYTE *inp)
5159{
return(DoFindLoop(inp,FINDLOOP)); }
5166int CoReplaceLoop(UBYTE *inp)
5168 int error = DoFindLoop(inp,REPLACELOOP);
5180static UBYTE *FunPowOptions[] = {
5181 (UBYTE *)
"nofunpowers"
5182 ,(UBYTE *)
"commutingonly"
5183 ,(UBYTE *)
"allfunpowers"
5186int CoFunPowers(UBYTE *inp)
5189 int i, maxoptions =
sizeof(FunPowOptions)/
sizeof(UBYTE *);
5190 while ( *inp ==
',' ) inp++;
5192 inp =
SkipAName(inp); c = *inp; *inp = 0;
5193 for ( i = 0; i < maxoptions; i++ ) {
5194 if ( StrICont(option,FunPowOptions[i]) == 0 ) {
5197 MesPrint(
"&Illegal FunPowers statement");
5204 MesPrint(
"&Illegal option in FunPowers statement: %s",option);
5213int CoUnitTrace(UBYTE *s)
5216 if ( FG.cTable[*s] == 1 ) {
5219nogood: MesPrint(
"&Value of UnitTrace should be a (positive) number or a symbol");
5222 AC.lUniTrace[0] = SNUMBER;
5223 AC.lUniTrace[2] = num;
5226 if ( GetName(AC.varnames,s,&num,WITHAUTO) == CSYMBOL ) {
5227 AC.lUniTrace[0] = SYMBOL;
5228 AC.lUniTrace[2] = num;
5233 if ( *s )
goto nogood;
5235 AC.lUnitTrace = num;
5251 WORD *w = AT.WorkPointer;
5253 while ( *s ==
',' ) s++;
5255 MesPrint(
"&Illegal syntax for Term statement");
5258 if ( AC.termlevel+1 >= AC.maxtermlevel ) {
5259 if ( AC.maxtermlevel <= 0 ) {
5260 AC.maxtermlevel = 20;
5261 AC.termstack = (LONG *)Malloc1(AC.maxtermlevel*
sizeof(LONG),
"termstack");
5262 AC.termsortstack = (LONG *)Malloc1(AC.maxtermlevel*
sizeof(LONG),
"termsortstack");
5263 AC.termsumcheck = (WORD *)Malloc1(AC.maxtermlevel*
sizeof(WORD),
"termsumcheck");
5266 DoubleBuffer((
void **)AC.termstack,(
void **)AC.termstack+AC.maxtermlevel,
5267 sizeof(LONG),
"doubling termstack");
5268 DoubleBuffer((
void **)AC.termsortstack,
5269 (
void **)AC.termsortstack+AC.maxtermlevel,
5270 sizeof(LONG),
"doubling termsortstack");
5271 DoubleBuffer((
void **)AC.termsumcheck,
5272 (
void **)AC.termsumcheck+AC.maxtermlevel,
5273 sizeof(LONG),
"doubling termsumcheck");
5274 AC.maxtermlevel *= 2;
5277 AC.termsumcheck[AC.termlevel] = NestingChecksum();
5278 AC.termstack[AC.termlevel] = cbuf[AC.cbufnum].Pointer
5279 - cbuf[AC.cbufnum].Buffer + 2;
5280 AC.termsortstack[AC.termlevel] = AC.termstack[AC.termlevel] + 1;
5284 *w++ = cbuf[AC.cbufnum].numlhs;
5285 *w++ = cbuf[AC.cbufnum].numlhs;
5286 AT.WorkPointer[1] = w - AT.WorkPointer;
5287 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
5296int CoEndTerm(UBYTE *s)
5298 CBUF *C = cbuf+AC.cbufnum;
5299 while ( *s ==
',' ) s++;
5301 MesPrint(
"&Illegal syntax for EndTerm statement");
5304 if ( AC.termlevel <= 0 ) {
5305 MesPrint(
"&EndTerm without corresponding Argument statement");
5309 cbuf[AC.cbufnum].Buffer[AC.termstack[AC.termlevel]] = C->numlhs;
5310 cbuf[AC.cbufnum].Buffer[AC.termsortstack[AC.termlevel]] = C->numlhs;
5311 if ( AC.termsumcheck[AC.termlevel] != NestingChecksum() ) {
5326 WORD *w = AT.WorkPointer;
5328 while ( *s ==
',' ) s++;
5330 MesPrint(
"&Illegal syntax for Sort statement");
5333 if ( AC.termlevel <= 0 ) {
5334 MesPrint(
"&The Sort statement can only be used inside a term environment");
5337 if ( error )
return(error);
5341 cbuf[AC.cbufnum].Buffer[AC.termsortstack[AC.termlevel-1]] =
5342 *w = cbuf[AC.cbufnum].numlhs+1;
5344 AC.termsortstack[AC.termlevel-1] = cbuf[AC.cbufnum].Pointer
5345 - cbuf[AC.cbufnum].Buffer + 3;
5346 if ( AC.termsumcheck[AC.termlevel-1] != NestingChecksum() - 1 ) {
5350 AT.WorkPointer[1] = w - AT.WorkPointer;
5351 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
5362int CoPolyFun(UBYTE *s)
5366 int type, error = 0;
5368 AR.PolyFun = AC.lPolyFun = 0;
5369 AR.PolyFunInv = AC.lPolyFunInv = 0;
5370 AR.PolyFunType = AC.lPolyFunType = 0;
5371 AR.PolyFunExp = AC.lPolyFunExp = 0;
5372 AR.PolyFunVar = AC.lPolyFunVar = 0;
5373 AR.PolyFunPow = AC.lPolyFunPow = 0;
5374 if ( *s == 0 ) {
return(0); }
5376 if ( t == 0 || *t != 0 ) {
5377 MesPrint(
"&PolyFun statement needs a single commuting function for its argument");
5380 if ( ( ( type = GetName(AC.varnames,s,&numfun,WITHAUTO) ) != CFUNCTION )
5381 || ( functions[numfun].spec != 0 ) || ( functions[numfun].commute != 0 ) ) {
5382 MesPrint(
"&%s should be a regular commuting function",s);
5384 if ( GetName(AC.exprnames,s,&numfun,NOAUTO) == NAMENOTFOUND )
5385 AddFunction(s,0,0,0,0,0,-1,-1);
5390 AR.PolyFun = AC.lPolyFun = numfun+FUNCTION;
5391 AR.PolyFunType = AC.lPolyFunType = 1;
5394 if ( mpfaux_ != 0 ) {
5395 MesPrint(
"&Simultaneous use of PolyFun and float_ is not allowed.");
5409int CoPolyRatFun(UBYTE *s)
5413 int type, error = 0;
5415 AR.PolyFun = AC.lPolyFun = 0;
5416 AR.PolyFunInv = AC.lPolyFunInv = 0;
5417 AR.PolyFunType = AC.lPolyFunType = 0;
5418 AR.PolyFunExp = AC.lPolyFunExp = 0;
5419 AR.PolyFunVar = AC.lPolyFunVar = 0;
5420 AR.PolyFunPow = AC.lPolyFunPow = 0;
5421 if ( *s == 0 )
return(error);
5423 if ( t == 0 )
goto NumErr;
5426 if ( mpfaux_ != 0 ) {
5427 MesPrint(
"&Simultaneous use of PolyFun and float_ is not allowed.");
5431 if ( ( ( type = GetName(AC.varnames,s,&numfun,WITHAUTO) ) != CFUNCTION )
5432 || ( functions[numfun].spec != 0 ) || ( functions[numfun].commute != 0 ) ) {
5433 MesPrint(
"&%s should be a regular commuting function",s);
5435 if ( GetName(AC.exprnames,s,&numfun,NOAUTO) == NAMENOTFOUND )
5436 AddFunction(s,0,0,0,0,0,-1,-1);
5440 AR.PolyFun = AC.lPolyFun = numfun+FUNCTION;
5441 AR.PolyFunInv = AC.lPolyFunInv = 0;
5442 AR.PolyFunType = AC.lPolyFunType = 2;
5443 AC.PolyRatFunChanged = 1;
5444 if ( c == 0 )
return(error);
5446 if ( *t ==
'-' ) { AC.PolyRatFunChanged = 0; t++; }
5447 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5448 if ( *t == 0 )
return(error);
5452 if ( t == 0 )
goto NumErr;
5454 if ( ( ( type = GetName(AC.varnames,s,&numfun,WITHAUTO) ) != CFUNCTION )
5455 || ( functions[numfun].spec != 0 ) || ( functions[numfun].commute != 0 ) ) {
5456 MesPrint(
"&%s should be a regular commuting function",s);
5458 if ( GetName(AC.exprnames,s,&numfun,NOAUTO) == NAMENOTFOUND )
5459 AddFunction(s,0,0,0,0,0,-1,-1);
5463 AR.PolyFunInv = AC.lPolyFunInv = numfun+FUNCTION;
5464 if ( c == 0 )
return(error);
5466 if ( *t ==
'-' ) { AC.PolyRatFunChanged = 0; t++; }
5467 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5468 if ( *t == 0 )
return(error);
5472 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5480 if ( t == 0 )
goto NumErr;
5482 if ( ( StrICmp(s,(UBYTE *)
"divergence") == 0 )
5483 || ( StrICmp(s,(UBYTE *)
"finddivergence") == 0 ) ) {
5485 MesPrint(
"&Illegal option field in PolyRatFun statement.");
5489 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5492 if ( t == 0 )
goto NumErr;
5494 if ( ( type = GetName(AC.varnames,s,&AC.lPolyFunVar,WITHAUTO) ) != CSYMBOL ) {
5495 MesPrint(
"&Illegal symbol %s in option field in PolyRatFun statement.",s);
5499 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5501 MesPrint(
"&Illegal termination of option in PolyRatFun statement.");
5504 AR.PolyFunExp = AC.lPolyFunExp = 1;
5505 AR.PolyFunVar = AC.lPolyFunVar;
5506 symbols[AC.lPolyFunVar].minpower = -MAXPOWER;
5507 symbols[AC.lPolyFunVar].maxpower = MAXPOWER;
5509 else if ( StrICmp(s,(UBYTE *)
"expand") == 0 ) {
5510 WORD x = 0, etype = 2;
5512 MesPrint(
"&Illegal option field in PolyRatFun statement.");
5516 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5519 if ( t == 0 )
goto NumErr;
5521 if ( ( type = GetName(AC.varnames,s,&AC.lPolyFunVar,WITHAUTO) ) != CSYMBOL ) {
5522 MesPrint(
"&Illegal symbol %s in option field in PolyRatFun statement.",s);
5526 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5527 if ( *t >
'9' || *t <
'0' ) {
5528 MesPrint(
"&Illegal option field in PolyRatFun statement.");
5531 while ( *t <=
'9' && *t >=
'0' ) x = 10*x + *t++ -
'0';
5532 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5536 if ( t == 0 )
goto ParErr;
5538 if ( StrICmp(s,(UBYTE *)
"fixed") == 0 ) {
5541 else if ( StrICmp(s,(UBYTE *)
"relative") == 0 ) {
5545 MesPrint(
"&Illegal termination of option in PolyRatFun statement.");
5549 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5551 MesPrint(
"&Illegal termination of option in PolyRatFun statement.");
5555 AR.PolyFunExp = AC.lPolyFunExp = etype;
5556 AR.PolyFunVar = AC.lPolyFunVar;
5557 AR.PolyFunPow = AC.lPolyFunPow = x;
5558 symbols[AC.lPolyFunVar].minpower = -MAXPOWER;
5559 symbols[AC.lPolyFunVar].maxpower = MAXPOWER;
5562ParErr: MesPrint(
"&Illegal option %s in PolyRatFun statement.",s);
5566 while ( *t ==
',' || *t ==
' ' || *t ==
'\t' ) t++;
5567 if ( *t == 0 )
return(error);
5570 MesPrint(
"&PolyRatFun statement needs one or two commuting function(s) for its argument(s)");
5579int CoMerge(UBYTE *inp)
5583 WORD numfunc, option = 0;
5584 if ( tolower(s[0]) ==
'o' && tolower(s[1]) ==
'n' && tolower(s[2]) ==
'c' &&
5585 tolower(s[3]) ==
'e' && tolower(s[4]) ==
',' ) {
5588 else if ( tolower(s[0]) ==
'a' && tolower(s[1]) ==
'l' && tolower(s[2]) ==
'l' &&
5589 tolower(s[3]) ==
',' ) {
5593 if ( ( type = GetName(AC.dollarnames,s+1,&numfunc,NOAUTO) ) == CDOLLAR )
5596 MesPrint(
"&%s is undefined",s);
5597 numfunc = AddDollar(s+1,DOLINDEX,&one,1);
5602 MesPrint(
"&Merge/shuffle should have a single function or $variable for its argument");
5606 else if ( ( type = GetName(AC.varnames,s,&numfunc,WITHAUTO) ) == CFUNCTION ) {
5607 numfunc += FUNCTION;
5610 else if ( type != -1 ) {
5611 if ( type != CDUBIOUS ) {
5612 NameConflict(type,s);
5613 type = MakeDubious(AC.varnames,s,&numfunc);
5618 MesPrint(
"&%s is not a function",s);
5619 numfunc = AddFunction(s,0,0,0,0,0,-1,-1) + FUNCTION;
5622 Add4Com(TYPEMERGE,numfunc,option);
5635int CoStuffle(UBYTE *inp)
5637 UBYTE *s = inp, *ss, c;
5639 WORD numfunc, option = 0;
5640 if ( tolower(s[0]) ==
'o' && tolower(s[1]) ==
'n' && tolower(s[2]) ==
'c' &&
5641 tolower(s[3]) ==
'e' && tolower(s[4]) ==
',' ) {
5644 else if ( tolower(s[0]) ==
'a' && tolower(s[1]) ==
'l' && tolower(s[2]) ==
'l' &&
5645 tolower(s[3]) ==
',' ) {
5651 if ( ( type = GetName(AC.dollarnames,s+1,&numfunc,NOAUTO) ) == CDOLLAR )
5654 MesPrint(
"&%s is undefined",s);
5655 numfunc = AddDollar(s+1,DOLINDEX,&one,1);
5659 if ( *ss !=
'+' && *ss !=
'-' && ss[1] != 0 ) {
5660 MesPrint(
"&Stuffle should have a single function or $variable for its argument, followed by either + or -");
5663 if ( *ss ==
'-' ) option += 2;
5665 else if ( ( type = GetName(AC.varnames,s,&numfunc,WITHAUTO) ) == CFUNCTION ) {
5666 numfunc += FUNCTION;
5669 else if ( type != -1 ) {
5670 if ( type != CDUBIOUS ) {
5671 NameConflict(type,s);
5672 type = MakeDubious(AC.varnames,s,&numfunc);
5677 MesPrint(
"&%s is not a function",s);
5678 numfunc = AddFunction(s,0,0,0,0,0,-1,-1) + FUNCTION;
5681 Add4Com(TYPESTUFFLE,numfunc,option);
5690int CoProcessBucket(UBYTE *s)
5693 while ( *s ==
',' || *s ==
'=' ) s++;
5695 if ( *s && *s !=
' ' && *s !=
'\t' ) {
5696 MesPrint(
"&Numerical value expected for ProcessBucketSize");
5699 AC.ProcessBucketSize = x;
5708int CoThreadBucket(UBYTE *s)
5711 while ( *s ==
',' || *s ==
'=' ) s++;
5713 if ( *s && *s !=
' ' && *s !=
'\t' ) {
5714 MesPrint(
"&Numerical value expected for ThreadBucketSize");
5718 Warning(
"Negative of zero value not allowed for ThreadBucketSize. Adjusted to 1.");
5721 AC.ThreadBucketSize = x;
5723 if ( AS.MultiThreaded ) MakeThreadBuckets(-1,1);
5738int DoArgPlode(UBYTE *s,
int par)
5741 WORD numfunc, type, error = 0, *w, n;
5747 while ( *s ==
',' ) s++;
5750 MesPrint(
"&We don't do dollar variables yet in ArgImplode/ArgExplode");
5754 if ( ( s =
SkipAName(s) ) == 0 )
return(1);
5756 if ( ( type = GetName(AC.varnames,t,&numfunc,WITHAUTO) ) == CFUNCTION ) {
5757 numfunc += FUNCTION;
5759 else if ( type != -1 ) {
5760 if ( type != CDUBIOUS ) {
5761 NameConflict(type,t);
5762 type = MakeDubious(AC.varnames,t,&numfunc);
5767 MesPrint(
"&%s is not a function",t);
5768 numfunc = AddFunction(s,0,0,0,0,0,-1,-1) + FUNCTION;
5775 for ( i = 2; i < FUNHEAD; i++ ) *w++ = 0;
5777 if ( *s && *s !=
',' ) {
5778 MesPrint(
"&Illegal character in ArgImplode/ArgExplode statement: %s",s);
5781 while ( *s ==
',' ) s++;
5783 n = w - AT.WorkPointer;
5784 AT.WorkPointer[1] = n;
5794int CoArgExplode(UBYTE *s) {
return(DoArgPlode(s,TYPEARGEXPLODE)); }
5801int CoArgImplode(UBYTE *s) {
return(DoArgPlode(s,TYPEARGIMPLODE)); }
5808int CoClearTable(UBYTE *s)
5811 int j, type, error = 0;
5815 MesPrint(
"&The ClearTable statement needs at least one (table) argument.");
5822 if ( ( ( type = GetName(AC.varnames,t,&numfun,WITHAUTO) ) != CFUNCTION )
5823 && type != CDUBIOUS ) {
5824nofunc: MesPrint(
"&%s is not a table",t);
5826 if ( type < 0 ) numfun = AddFunction(t,0,0,0,0,0,-1,-1);
5828 if ( *s ==
',' ) s++;
5835 else if ( ( T = functions[numfun].tabl ) == 0 )
goto nofunc;
5838 if ( *s ==
',' ) s++;
5874 if ( TT->
mm ) M_free(TT->
mm,
"tableminmax");
5875 if ( TT->
flags ) M_free(TT->
flags,
"tableflags");
5890int CoDenominators(UBYTE *s)
5895 if ( t == 0 )
goto syntaxerror;
5896 t1 = t;
while ( *t1 ==
',' || *t1 ==
' ' || *t1 ==
'\t' ) t1++;
5897 if ( *t1 )
goto syntaxerror;
5899 if ( ( ( type = GetName(AC.varnames,s,&numfun,WITHAUTO) ) != CFUNCTION )
5900 || ( functions[numfun].spec != 0 ) ) {
5902 if ( GetName(AC.exprnames,s,&numfun,NOAUTO) == NAMENOTFOUND )
5903 AddFunction(s,0,0,0,0,0,-1,-1);
5907 Add3Com(TYPEDENOMINATORS,numfun+FUNCTION);
5910 MesPrint(
"&Denominators statement needs one regular function for its argument");
5919int CoDropCoefficient(UBYTE *s)
5922 Add2Com(TYPEDROPCOEFFICIENT)
5925 MesPrint(
"&Illegal argument in DropCoefficient statement: '%s'",s);
5933int CoDropSymbols(UBYTE *s)
5936 Add2Com(TYPEDROPSYMBOLS)
5939 MesPrint(
"&Illegal argument in DropSymbols statement: '%s'",s);
5956int CoToPolynomial(UBYTE *inp)
5959 while ( *inp ==
' ' || *inp ==
',' || *inp ==
'\t' ) inp++;
5960 if ( ( AC.topolynomialflag & ~TOPOLYNOMIALFLAG ) != 0 ) {
5961 MesPrint(
"&ToPolynomial statement and FactArg statement are not allowed in the same module");
5964 if ( AO.OptimizeResult.code != NULL ) {
5965 MesPrint(
"&Using ToPolynomial statement when there are still optimization results active.");
5966 MesPrint(
"&Please use #ClearOptimize instruction first.");
5967 MesPrint(
"&This will loose the optimized expression.");
5971 Add3Com(TYPETOPOLYNOMIAL,DOALL)
5975 WORD *funnums = 0, type, num;
5978 if ( s == 0 )
return(1);
5980 if ( StrICmp(inp,(UBYTE *)
"onlyfunctions") ) {
5981 MesPrint(
"&Illegal option %s in ToPolynomial statement",inp);
5987 while ( *inp ==
' ' || *inp ==
',' || *inp ==
'\t' ) inp++;
5993 funnums = (WORD *)Malloc1(((LONG)(s-inp)+3)*
sizeof(WORD),
"ToPlynomial");
5996 if ( s == 0 )
return(1);
5998 type = GetName(AC.varnames,inp,&num,WITHAUTO);
5999 if ( type != CFUNCTION ) {
6000 MesPrint(
"&%s is not a function in ToPolynomial statement",inp);
6003 funnums[3+numargs++] = num+FUNCTION;
6006 while ( *inp ==
' ' || *inp ==
',' || *inp ==
'\t' ) inp++;
6008 funnums[0] = TYPETOPOLYNOMIAL;
6009 funnums[1] = numargs+3;
6010 funnums[2] = ONLYFUNCTIONS;
6013 if ( funnums ) M_free(funnums,
"ToPolynomial");
6015 AC.topolynomialflag |= TOPOLYNOMIALFLAG;
6018 AC.mparallelflag |= NOPARALLEL_CONVPOLY;
6031int CoFromPolynomial(UBYTE *inp)
6033 while ( *inp ==
' ' || *inp ==
',' || *inp ==
'\t' ) inp++;
6035 if ( AO.OptimizeResult.code != NULL ) {
6036 MesPrint(
"&Using FromPolynomial statement when there are still optimization results active.");
6037 MesPrint(
"&Please use #ClearOptimize instruction first.");
6038 MesPrint(
"&This will loose the optimized expression.");
6041 Add2Com(TYPEFROMPOLYNOMIAL)
6044 MesPrint(
"&Illegal argument in FromPolynomial statement: '%s'",inp);
6057int CoArgToExtraSymbol(UBYTE *s)
6059 CBUF *C = cbuf + AC.cbufnum;
6063 if ( ( AC.topolynomialflag & ~TOPOLYNOMIALFLAG ) != 0 ) {
6064 MesPrint(
"&ArgToExtraSymbol statement and FactArg statement are not allowed in the same module");
6067 if ( AO.OptimizeResult.code != NULL ) {
6068 MesPrint(
"&Using ArgToExtraSymbol statement when there are still optimization results active.");
6069 MesPrint(
"&Please use #ClearOptimize instruction first.");
6070 MesPrint(
"&This will loose the optimized expression.");
6075 int tonumber = ConsumeOption(&s,
"tonumber");
6077 int ret = DoArgument(s,TYPEARGTOEXTRASYMBOL);
6078 if ( ret )
return(ret);
6084 lhs = C->
lhs[C->numlhs];
6085 if ( lhs[4] != 1 ) {
6086 Warning(
"scale parameter (^n) is ignored in ArgToExtraSymbol");
6090 AC.topolynomialflag |= TOPOLYNOMIALFLAG;
6096 AC.mparallelflag |= NOPARALLEL_CONVPOLY;
6107int CoExtraSymbols(UBYTE *inp)
6109 UBYTE *arg1, *arg2, c, *s;
6110 WORD i, j, type, number;
6111 while ( *inp ==
' ' || *inp ==
',' || *inp ==
'\t' ) inp++;
6112 if ( FG.cTable[*inp] != 0 ) {
6113 MesPrint(
"&Illegal argument in ExtraSymbols statement: '%s'",inp);
6117 while ( FG.cTable[*inp] == 0 ) inp++;
6119 if ( ( StrICmp(arg1,(UBYTE *)
"array") == 0 )
6120 || ( StrICmp(arg1,(UBYTE *)
"vector") == 0 ) ) {
6121 AC.extrasymbols = 1;
6123 else if ( StrICmp(arg1,(UBYTE *)
"underscore") == 0 ) {
6124 AC.extrasymbols = 0;
6132 MesPrint(
"&Illegal keyword in ExtraSymbols statement: '%s'",arg1);
6136 while ( *inp ==
' ' || *inp ==
',' || *inp ==
'\t' ) inp++;
6137 if ( FG.cTable[*inp] != 0 ) {
6138 MesPrint(
"&Illegal argument in ExtraSymbols statement: '%s'",inp);
6142 while ( FG.cTable[*inp] <= 1 ) inp++;
6144 MesPrint(
"&Illegal end of ExtraSymbols statement: '%s'",inp);
6151 if ( AC.extrasymbols == 1 ) {
6152 type = GetName(AC.varnames,arg2,&number,NOAUTO);
6153 if ( type != NAMENOTFOUND ) {
6154 MesPrint(
"&ExtraSymbols statement: '%s' has already been declared before",arg2);
6158 else if ( AC.extrasymbols == 0 ) {
6159 if ( *arg2 ==
'N' ) {
6161 while ( FG.cTable[*s] == 1 ) s++;
6163 MesPrint(
"&ExtraSymbols statement: '%s' creates conflicts with summed indices",arg2);
6168 if ( AC.extrasym ) { M_free(AC.extrasym,
"extrasym"); AC.extrasym = 0; }
6170 AC.extrasym = (UBYTE *)Malloc1(i*
sizeof(UBYTE),
"extrasym");
6171 for ( j = 0; j < i; j++ ) AC.extrasym[j] = arg2[j];
6180WORD *GetIfDollarFactor(UBYTE **inp, WORD *w)
6186 if ( FG.cTable[*s] == 1 ) {
6188 while ( FG.cTable[*s] == 1 ) {
6189 x = 10*x + *s++ -
'0';
6190 if ( x >= MAXPOSITIVE ) {
6191 MesPrint(
"&Value in dollar factor too large");
6192 while ( FG.cTable[*s] == 1 ) s++;
6197 *w++ = IFDOLLAREXTRA;
6204 MesPrint(
"&Factor indicator for $-variable should be a number or a $-variable.");
6208 while ( FG.cTable[*s] < 2 ) s++;
6210 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6211 MesPrint(
"&dollar in if statement should have been defined previously");
6215 *w++ = IFDOLLAREXTRA;
6221 if ( ( w = GetIfDollarFactor(inp,w) ) == 0 )
return(0);
6224 MesPrint(
"&unmatched [] in $ in if statement");
6238UBYTE *GetDoParam(UBYTE *inp, WORD **wp,
int par)
6243 if ( FG.cTable[*inp] == 1 ) {
6245 while ( *inp >=
'0' && *inp <=
'9' ) {
6246 x = 10*x + *inp++ -
'0';
6247 if ( x > MAXPOSITIVE ) {
6249 MesPrint(
"&Value in dollar factor too large");
6252 MesPrint(
"&Value in do loop boundaries too large");
6254 while ( FG.cTable[*inp] == 1 ) inp++;
6263 *(*wp)++ = DOLLAREXPR2;
6264 *(*wp)++ = -((WORD)x)-1;
6268 if ( *inp !=
'$' ) {
6272 while ( FG.cTable[*inp] < 2 ) inp++;
6274 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
6276 MesPrint(
"&dollar in print statement should have been defined previously");
6279 MesPrint(
"&dollar in do loop boundaries should have been defined previously");
6285 *(*wp)++ = DOLLAREXPRESSION;
6289 *(*wp)++ = DOLLAREXPR2;
6294 inp = GetDoParam(inp,wp,0);
6295 if ( inp == 0 )
return(0);
6296 if ( *inp !=
']' ) {
6298 MesPrint(
"&unmatched [] in $ in print statement");
6301 MesPrint(
"&unmatched [] in do loop boundaries");
6318 CBUF *C = cbuf+AC.cbufnum;
6322 if ( AC.doloopstack == 0 ) {
6323 AC.doloopstacksize = 20;
6324 AC.doloopstack = (WORD *)Malloc1(AC.doloopstacksize*2*
sizeof(WORD),
"doloop stack");
6325 AC.doloopnest = AC.doloopstack + AC.doloopstacksize;
6327 if ( AC.dolooplevel >= AC.doloopstacksize ) {
6328 WORD *newstack, *newnest, newsize;
6329 newsize = AC.doloopstacksize * 2;
6330 newstack = (WORD *)Malloc1(newsize*2*
sizeof(WORD),
"doloop stack");
6331 newnest = newstack + newsize;
6332 for ( i = 0; i < newsize; i++ ) {
6333 newstack[i] = AC.doloopstack[i];
6334 newnest[i] = AC.doloopnest[i];
6336 M_free(AC.doloopstack,
"doloop stack");
6337 AC.doloopstack = newstack;
6338 AC.doloopnest = newnest;
6339 AC.doloopstacksize = newsize;
6341 AC.doloopnest[AC.dolooplevel] = NestingChecksum();
6349 while ( *inp ==
',' ) inp++;
6350 if ( *inp !=
'$' ) {
6352 MesPrint(
"&do loop parameter should be a dollar variable");
6357 if ( FG.cTable[*inp] != 0 ) {
6359 MesPrint(
"&illegal name for do loop parameter");
6361 while ( FG.cTable[*inp] < 2 ) inp++;
6363 if ( GetName(AC.dollarnames,name,&numparam,NOAUTO) == NAMENOTFOUND ) {
6364 numparam = AddDollar(name,DOLUNDEFINED,0,0);
6371 while ( *inp ==
',' ) inp++;
6372 if ( *inp !=
'=' )
goto IllSyntax;
6374 while ( *inp ==
',' ) inp++;
6378 inp = GetDoParam(inp,&w,1);
6379 if ( inp == 0 || *inp !=
',' )
goto IllSyntax;
6380 while ( *inp ==
',' ) inp++;
6384 inp = GetDoParam(inp,&w,1);
6385 if ( inp == 0 || ( *inp != 0 && *inp !=
',' ) )
goto IllSyntax;
6389 if ( *inp !=
',' ) {
6390 if ( *inp == 0 ) { *w++ = SNUMBER; *w++ = 1; }
6391 else goto IllSyntax;
6394 while ( *inp ==
',' ) inp++;
6395 inp = GetDoParam(inp,&w,1);
6397 if ( inp == 0 || *inp != 0 )
goto IllSyntax;
6399 AT.WorkPointer[1] = w - AT.WorkPointer;
6403 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
6404 AC.doloopstack[AC.dolooplevel++] = C->numlhs;
6409 MesPrint(
"&Illegal syntax for do statement");
6418int CoEndDo(UBYTE *inp)
6420 CBUF *C = cbuf+AC.cbufnum;
6422 while ( *inp ==
',' ) inp++;
6424 MesPrint(
"&Illegal syntax for EndDo statement");
6427 if ( AC.dolooplevel <= 0 ) {
6428 MesPrint(
"&EndDo without corresponding Do statement");
6432 scratch[0] = TYPEENDDOLOOP;
6434 scratch[2] = AC.doloopstack[AC.dolooplevel];
6436 cbuf[AC.cbufnum].lhs[AC.doloopstack[AC.dolooplevel]][3] = C->numlhs;
6437 if ( AC.doloopnest[AC.dolooplevel] != NestingChecksum() ) {
6449int CoFactDollar(UBYTE *inp)
6452 if ( *inp ==
'$' ) {
6453 if ( GetName(AC.dollarnames,inp+1,&numdollar,NOAUTO) != CDOLLAR ) {
6454 MesPrint(
"&%s is undefined",inp);
6455 numdollar = AddDollar(inp+1,DOLINDEX,&one,1);
6460 MesPrint(
"&FactDollar should have a single $variable for its argument");
6466 MesPrint(
"&%s is not a $-variable",inp);
6469 Add3Com(TYPEFACTOR,numdollar);
6478int CoFactorize(UBYTE *s) {
return(DoFactorize(s,1)); }
6485int CoNFactorize(UBYTE *s) {
return(DoFactorize(s,0)); }
6492int CoUnFactorize(UBYTE *s) {
return(DoFactorize(s,3)); }
6499int CoNUnFactorize(UBYTE *s) {
return(DoFactorize(s,2)); }
6506int DoFactorize(UBYTE *s,
int par)
6512 int error = 0, keepzeroflag = 0;
6515 while ( *s !=
')' && *s ) {
6516 if ( FG.cTable[*s] == 0 ) {
6517 t = s;
while ( FG.cTable[*s] == 0 ) s++;
6519 if ( StrICmp((UBYTE *)
"keepzero",t) == 0 ) {
6523 MesPrint(
"&Illegal option in [N][Un]Factorize statement: %s",t);
6528 while ( *s ==
',' ) s++;
6529 if ( *s && *s !=
')' && FG.cTable[*s] != 0 ) {
6530 MesPrint(
"&Illegal character in option field of [N][Un]Factorize statement");
6536 while ( *s ==
',' || *s ==
' ' ) s++;
6539 for ( i = NumExpressions-1; i >= 0; i-- ) {
6541 if ( e->replace >= 0 ) {
6542 e = Expressions + e->replace;
6544 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
6545 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
6546 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION
6550 e->vflags &= ~TOBEFACTORED;
6553 e->vflags |= TOBEFACTORED;
6554 e->vflags &= ~TOBEUNFACTORED;
6557 e->vflags &= ~TOBEUNFACTORED;
6560 e->vflags |= TOBEUNFACTORED;
6561 e->vflags &= ~TOBEFACTORED;
6565 if ( ( e->vflags & TOBEFACTORED ) != 0 ) {
6566 if ( keepzeroflag ) e->vflags |= KEEPZERO;
6567 else e->vflags &= ~KEEPZERO;
6569 else e->vflags &= ~KEEPZERO;
6574 while ( *s ==
',' ) s++;
6575 if ( *s == 0 )
break;
6576 if ( *s ==
'[' || FG.cTable[*s] == 0 ) {
6579 MesPrint(
"&Improper name for an expression: '%s'",t);
6583 if ( GetName(AC.exprnames,t,&number,NOAUTO) == CEXPRESSION ) {
6584 e = Expressions+number;
6585 if ( e->replace >= 0 ) {
6586 e = Expressions + e->replace;
6588 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
6589 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
6590 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION
6594 e->vflags &= ~TOBEFACTORED;
6597 e->vflags |= TOBEFACTORED;
6598 e->vflags &= ~TOBEUNFACTORED;
6601 e->vflags &= ~TOBEUNFACTORED;
6604 e->vflags |= TOBEUNFACTORED;
6605 e->vflags &= ~TOBEFACTORED;
6609 if ( ( e->vflags & TOBEFACTORED ) != 0 ) {
6610 if ( keepzeroflag ) e->vflags |= KEEPZERO;
6611 else e->vflags &= ~KEEPZERO;
6613 else e->vflags &= ~KEEPZERO;
6615 else if ( GetName(AC.varnames,t,&number,NOAUTO) != NAMENOTFOUND ) {
6616 MesPrint(
"&%s is not an expression",t);
6622 MesPrint(
"&Illegal object in (N)Factorize statement");
6624 while ( *s && *s !=
',' ) s++;
6625 if ( *s == 0 )
break;
6639int CoOptimizeOption(UBYTE *s)
6641 UBYTE *name, *t1, *t2, c1, c2, *value, *u;
6644 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
6646 name = s;
while ( FG.cTable[*s] == 0 ) s++;
6648 while ( *s ==
' ' || *s ==
'\t' ) s++;
6651 MesPrint(
"&Correct use in Format,Optimize statement is Optionname=value");
6653 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' || *s ==
'=' ) s++;
6659 while ( *s ==
' ' || *s ==
'\t' ) s++;
6660 if ( *s == 0 )
goto correctuse;
6662 while ( FG.cTable[*s] <= 1 || *s==
'.' || *s==
'*' || *s ==
'(' || *s ==
')' ) {
6663 if ( *s ==
'(' ) { SKIPBRA4(s) }
6667 while ( *s ==
' ' || *s ==
'\t' ) s++;
6668 if ( *s && *s !=
',' )
goto correctuse;
6671 while ( *s ==
' ' || *s ==
'\t' ) s++;
6677 if ( StrICmp(name,(UBYTE *)
"horner") == 0 ) {
6678 if ( StrICmp(value,(UBYTE *)
"occurrence") == 0 ) {
6679 AO.Optimize.horner = O_OCCURRENCE;
6681 else if ( StrICmp(value,(UBYTE *)
"mcts") == 0 ) {
6682 AO.Optimize.horner = O_MCTS;
6684 else if ( StrICmp(value,(UBYTE *)
"sa") == 0 ) {
6685 AO.Optimize.horner = O_SIMULATED_ANNEALING;
6688 AO.Optimize.horner = -1;
6689 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
6693 else if ( StrICmp(name,(UBYTE *)
"hornerdirection") == 0 ) {
6694 if ( StrICmp(value,(UBYTE *)
"forward") == 0 ) {
6695 AO.Optimize.hornerdirection = O_FORWARD;
6697 else if ( StrICmp(value,(UBYTE *)
"backward") == 0 ) {
6698 AO.Optimize.hornerdirection = O_BACKWARD;
6700 else if ( StrICmp(value,(UBYTE *)
"forwardorbackward") == 0 ) {
6701 AO.Optimize.hornerdirection = O_FORWARDORBACKWARD;
6703 else if ( StrICmp(value,(UBYTE *)
"forwardandbackward") == 0 ) {
6704 AO.Optimize.hornerdirection = O_FORWARDANDBACKWARD;
6707 AO.Optimize.method = -1;
6708 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
6712 else if ( StrICmp(name,(UBYTE *)
"method") == 0 ) {
6713 if ( StrICmp(value,(UBYTE *)
"none") == 0 ) {
6714 AO.Optimize.method = O_NONE;
6716 else if ( StrICmp(value,(UBYTE *)
"cse") == 0 ) {
6717 AO.Optimize.method = O_CSE;
6719 else if ( StrICmp(value,(UBYTE *)
"csegreedy") == 0 ) {
6720 AO.Optimize.method = O_CSEGREEDY;
6722 else if ( StrICmp(value,(UBYTE *)
"greedy") == 0 ) {
6723 AO.Optimize.method = O_GREEDY;
6726 AO.Optimize.method = -1;
6727 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
6731 else if ( StrICmp(name,(UBYTE *)
"timelimit") == 0 ) {
6733 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6735 MesPrint(
"&Option TimeLimit in Format,Optimize statement should be a positive number: %s",value);
6736 AO.Optimize.mctstimelimit = 0;
6737 AO.Optimize.greedytimelimit = 0;
6741 AO.Optimize.mctstimelimit = x/2;
6742 AO.Optimize.greedytimelimit = x/2;
6745 else if ( StrICmp(name,(UBYTE *)
"mctstimelimit") == 0 ) {
6747 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6749 MesPrint(
"&Option MCTSTimeLimit in Format,Optimize statement should be a positive number: %s",value);
6750 AO.Optimize.mctstimelimit = 0;
6754 AO.Optimize.mctstimelimit = x;
6757 else if ( StrICmp(name,(UBYTE *)
"mctsnumexpand") == 0 ) {
6760 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6761 if ( *u ==
'*' || *u ==
'x' || *u ==
'X' ) {
6764 while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6768 MesPrint(
"&Option MCTSNumExpand in Format,Optimize statement should be a positive number: %s",value);
6769 AO.Optimize.mctsnumexpand= 0;
6770 AO.Optimize.mctsnumrepeat= 1;
6774 AO.Optimize.mctsnumexpand= x;
6775 AO.Optimize.mctsnumrepeat= y;
6778 else if ( StrICmp(name,(UBYTE *)
"mctsnumrepeat") == 0 ) {
6780 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6782 MesPrint(
"&Option MCTSNumExpand in Format,Optimize statement should be a positive number: %s",value);
6783 AO.Optimize.mctsnumrepeat= 1;
6787 AO.Optimize.mctsnumrepeat= x;
6790 else if ( StrICmp(name,(UBYTE *)
"mctsnumkeep") == 0 ) {
6792 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6794 MesPrint(
"&Option MCTSNumKeep in Format,Optimize statement should be a positive number: %s",value);
6795 AO.Optimize.mctsnumkeep= 0;
6799 AO.Optimize.mctsnumkeep= x;
6802 else if ( StrICmp(name,(UBYTE *)
"mctsconstant") == 0 ) {
6804 if ( sscanf ((
char*)value,
"%lf", &d) != 1 ) {
6805 MesPrint(
"&Option MCTSConstant in Format,Optimize statement should be a positive number: %s",value);
6806 AO.Optimize.mctsconstant.fval = 0;
6810 AO.Optimize.mctsconstant.fval = d;
6813 else if ( StrICmp(name,(UBYTE *)
"greedytimelimit") == 0 ) {
6815 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6817 MesPrint(
"&Option GreedyTimeLimit in Format,Optimize statement should be a positive number: %s",value);
6818 AO.Optimize.greedytimelimit = 0;
6822 AO.Optimize.greedytimelimit = x;
6825 else if ( StrICmp(name,(UBYTE *)
"greedyminnum") == 0 ) {
6827 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6829 MesPrint(
"&Option GreedyMinNum in Format,Optimize statement should be a positive number: %s",value);
6830 AO.Optimize.greedyminnum= 0;
6834 AO.Optimize.greedyminnum= x;
6837 else if ( StrICmp(name,(UBYTE *)
"greedymaxperc") == 0 ) {
6839 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6841 MesPrint(
"&Option GreedyMaxPerc in Format,Optimize statement should be a positive number: %s",value);
6842 AO.Optimize.greedymaxperc= 0;
6846 AO.Optimize.greedymaxperc= x;
6849 else if ( StrICmp(name,(UBYTE *)
"stats") == 0 ) {
6850 if ( StrICmp(value,(UBYTE *)
"on") == 0 ) {
6851 AO.Optimize.printstats = 1;
6853 else if ( StrICmp(value,(UBYTE *)
"off") == 0 ) {
6854 AO.Optimize.printstats = 0;
6857 AO.Optimize.printstats = 0;
6858 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
6862 else if ( StrICmp(name,(UBYTE *)
"printscheme") == 0 ) {
6863 if ( StrICmp(value,(UBYTE *)
"on") == 0 ) {
6864 AO.Optimize.schemeflags |= 1;
6866 else if ( StrICmp(value,(UBYTE *)
"off") == 0 ) {
6867 AO.Optimize.schemeflags &= ~1;
6870 AO.Optimize.schemeflags &= ~1;
6871 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
6875 else if ( StrICmp(name,(UBYTE *)
"debugflag") == 0 ) {
6883 if ( FG.cTable[*u] == 1 ) {
6884 while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
6886 MesPrint(
"&Numerical value for DebugFlag in Format,Optimize statement should be a nonnegative number: %s",value);
6887 AO.Optimize.debugflags = 0;
6891 AO.Optimize.debugflags = x;
6894 else if ( StrICmp(value,(UBYTE *)
"on") == 0 ) {
6895 AO.Optimize.debugflags = 1;
6897 else if ( StrICmp(value,(UBYTE *)
"off") == 0 ) {
6898 AO.Optimize.debugflags = 0;
6901 AO.Optimize.debugflags = 0;
6902 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
6906 else if ( StrICmp(name,(UBYTE *)
"scheme") == 0 ) {
6913 MesPrint(
"&Option Scheme in Format,Optimize statement should be an array of names or integers between (): %s",value);
6918 while ( *ss ==
' ' || *ss ==
'\t' || *ss ==
',' ) ss++;
6919 if ( FG.cTable[*ss] == 0 || *ss ==
'$' || *ss ==
'[' ) {
6920 s1 = u; SKIPBRA3(s1)
6921 if ( *s1 !=
')' )
goto noscheme;
6922 while ( ss < s1 ) {
if ( *ss++ ==
',' ) AO.schemenum++; }
6923 *ss++ = 0;
while ( *ss ==
' ' ) ss++;
6924 if ( *ss != 0 )
goto noscheme;
6926 if ( AO.schemenum < 1 ) {
6927 MesPrint(
"&Option Scheme in Format,Optimize statement should have at least one name or number between ()");
6931 if ( AO.inscheme ) M_free(AO.inscheme,
"Horner input scheme");
6932 AO.inscheme = (WORD *)Malloc1((AO.schemenum+1)*
sizeof(WORD),
"Horner input scheme");
6933 while ( *ss ==
' ' || *ss ==
'\t' || *ss ==
',' ) ss++;
6936 if ( *ss == 0 )
break;
6937 s1 = ss; ss =
SkipAName(s1); c = *ss; *ss = 0;
6939 if ( ss[-1] ==
'_' ) {
6944 u1 = s1; u2 = AC.extrasym;
6945 while ( *u1 == *u2 ) { u1++; u2++; }
6948 while ( *u1 >=
'0' && *u1 <=
'9' ) numsym = 10*numsym + *u1++ -
'0';
6949 if ( u1 != ss-1 || numsym == 0 || AC.extrasymbols != 0 ) {
6950 MesPrint(
"&Improper use of extra symbol in scheme format option");
6953 numsym = MAXVARIABLES-numsym;
6958 else if ( *s1 ==
'$' ) {
6961 if ( ( numdollar = GetDollar(s1+1) ) < 0 ) {
6962 MesPrint(
"&Undefined variable %s",s1);
6965 else if ( ( numsym = DolToSymbol(BHEAD numdollar) ) < 0 ) {
6966 MesPrint(
"&$%s does not evaluate to a symbol",s1);
6972 else if ( c ==
'(' ) {
6973 if ( StrCmp(s1,AC.extrasym) == 0 ) {
6974 if ( (AC.extrasymbols&1) != 1 ) {
6975 MesPrint(
"&Improper use of extra symbol in scheme format option");
6980 while ( *ss >=
'0' && *ss <=
'9' ) numsym = 10*numsym + *ss++ -
'0';
6982 MesPrint(
"&Extra symbol should have a number for its argument.");
6985 numsym = MAXVARIABLES-numsym;
6990 type = GetName(AC.varnames,s1,&numsym,WITHAUTO);
6991 if ( ( type != CSYMBOL ) && type != CDUBIOUS ) {
6992 MesPrint(
"&%s is not a symbol",s1);
6994 if ( type < 0 ) numsym = AddSymbol(s1,-MAXPOWER,MAXPOWER,0,0);
6998 AO.inscheme[AO.schemenum++] = numsym;
6999 while ( *ss ==
' ' || *ss ==
'\t' || *ss ==
',' ) ss++;
7003 else if ( StrICmp(name,(UBYTE *)
"mctsdecaymode") == 0 ) {
7006 if ( FG.cTable[*u] == 1 ) {
7007 while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
7009 MesPrint(
"&Option MCTSDecayMode in Format,Optimize statement should be a nonnegative integer: %s",value);
7010 AO.Optimize.mctsdecaymode = 0;
7014 AO.Optimize.mctsdecaymode = x;
7018 AO.Optimize.mctsdecaymode = 0;
7019 MesPrint(
"&Unrecognized option value in Format,Optimize statement: %s=%s",name,value);
7023 else if ( StrICmp(name,(UBYTE *)
"saiter") == 0 ) {
7025 u = value;
while ( *u >=
'0' && *u <=
'9' ) x = 10*x + *u++ -
'0';
7027 MesPrint(
"&Option SAIter in Format,Optimize statement should be a positive integer: %s",value);
7028 AO.Optimize.saIter = 0;
7032 AO.Optimize.saIter= x;
7035 else if ( StrICmp(name,(UBYTE *)
"samaxt") == 0 ) {
7037 if ( sscanf ((
char*)value,
"%lf", &d) != 1 ) {
7038 MesPrint(
"&Option SAMaxT in Format,Optimize statement should be a positive number: %s",value);
7039 AO.Optimize.saMaxT.fval = 0;
7043 AO.Optimize.saMaxT.fval = d;
7046 else if ( StrICmp(name,(UBYTE *)
"samint") == 0 ) {
7048 if ( sscanf ((
char*)value,
"%lf", &d) != 1 ) {
7049 MesPrint(
"&Option SAMinT in Format,Optimize statement should be a positive number: %s",value);
7050 AO.Optimize.saMinT.fval = 0;
7054 AO.Optimize.saMinT.fval = d;
7058 MesPrint(
"&Unrecognized option name in Format,Optimize statement: %s",name);
7075int CoPutInside(UBYTE *inp) {
return(DoPutInside(inp,1)); }
7076int CoAntiPutInside(UBYTE *inp) {
return(DoPutInside(inp,-1)); }
7078int DoPutInside(UBYTE *inp,
int par)
7082 WORD *to, type, c1,c2,funnum, *WorkSave;
7084 while ( *inp ==
' ' || *inp ==
'\t' || *inp ==
',' ) inp++;
7089 if ( p == 0 )
return(1);
7091 type = GetName(AC.varnames,inp,&funnum,WITHAUTO);
7092 if ( type != CFUNCTION || functions[funnum].tabl != 0 || functions[funnum].spec ) {
7093 MesPrint(
"&PutInside/AntiPutInside expects a regular function for its first argument");
7094 MesPrint(
"&Argument is %s",inp);
7100 while ( *inp ==
' ' || *inp ==
'\t' || *inp ==
',' ) inp++;
7104 tocompiler[0] = TYPEPUTINSIDE;
7107 tocompiler[3] = funnum;
7111 MesPrint(
"&AntiPutInside needs inside information.");
7116 WorkSave = to = AT.WorkPointer;
7117 *to++ = TYPEPUTINSIDE;
7123 while ( *inp ==
' ' || *inp ==
'\t' || *inp ==
',' ) inp++;
7124 if ( *inp == 0 )
break;
7126 if ( p == 0 ) { error = 1;
break; }
7128 type = GetName(AC.varnames,inp,&c1,WITHAUTO);
7130 if ( type == CVECTOR || type == CDUBIOUS ) {
7134 if ( p == 0 )
return(1);
7136 type = GetName(AC.varnames,inp,&c2,WITHAUTO);
7137 if ( type != CVECTOR && type != CDUBIOUS ) {
7138 MesPrint(
"&Not a vector in dotproduct in PutInside/AntiPutInside statement: %s",inp);
7141 else type = CDOTPRODUCT;
7144 MesPrint(
"&Illegal use of . after %s in PutInside/AntiPutInside statement",inp);
7152 *to++ = SYMBOL; *to++ = 4; *to++ = c1; *to++ = 1;
break;
7154 *to++ = INDEX; *to++ = 3; *to++ = AM.OffsetVector + c1;
break;
7156 *to++ = c1+FUNCTION; *to++ = FUNHEAD; *to++ = 0;
7160 *to++ = DOTPRODUCT; *to++ = 5; *to++ = c1 + AM.OffsetVector;
7161 *to++ = c2 + AM.OffsetVector; *to++ = 1;
break;
7163 *to++ = DELTA; *to++ = 4; *to++ = EMPTYINDEX; *to++ = EMPTYINDEX;
break;
7165 MesPrint(
"&Illegal variable request for %s in PutInside/AntiPutInside statement",inp);
7171 *to++ = 1; *to++ = 1; *to++ = 3;
7172 AT.WorkPointer[1] = to - AT.WorkPointer;
7173 AT.WorkPointer[4] = AT.WorkPointer[1]-4;
7174 AT.WorkPointer = to;
7175 AC.BracketNormalize = 1;
7176 if ( Normalize(BHEAD WorkSave+4) ) { error = 1; }
7178 WorkSave[1] = WorkSave[4]+4;
7179 to = WorkSave + WorkSave[1] - 1;
7183 AddNtoL(WorkSave[1],WorkSave);
7185 AC.BracketNormalize = 0;
7186 AT.WorkPointer = WorkSave;
7198int CoSwitch(UBYTE *s)
7203 if ( GetName(AC.dollarnames,s+1,&numdollar,NOAUTO) != CDOLLAR ) {
7204 MesPrint(
"&%s is undefined in switch statement",s);
7205 numdollar = AddDollar(s+1,DOLINDEX,&one,1);
7210 MesPrint(
"&Switch should have a single $variable for its argument");
7216 MesPrint(
"&%s is not a $-variable in switch statement",s);
7225 if ( AC.SwitchInArray >= AC.MaxSwitch ) DoubleSwitchBuffers();
7226 AC.SwitchHeap[AC.SwitchLevel] = AC.SwitchInArray;
7227 sw = AC.SwitchArray + AC.SwitchInArray;
7229 sw->iflevel = AC.IfLevel;
7230 sw->whilelevel = AC.WhileLevel;
7231 sw->nestingsum = NestingChecksum();
7233 Add4Com(TYPESWITCH,numdollar,AC.SwitchInArray);
7246 SWITCH *sw = AC.SwitchArray + AC.SwitchHeap[AC.SwitchLevel];
7247 WORD x = 0, sign = 1;
7248 while ( *s ==
',' ) s++;
7250 while ( *s ==
'-' || *s ==
'+' ) {
7251 if ( *s ==
'-' ) sign = -sign;
7254 while ( FG.cTable[*s] == 1 ) { x = 10*x + *s++ -
'0'; }
7257 if ( sw->iflevel != AC.IfLevel || sw->whilelevel != AC.WhileLevel
7258 || sw->nestingsum != NestingChecksum() ) {
7259 MesPrint(
"&Illegal nesting of switch/case/default with if/while/repeat/loop/argument/term/...");
7265 if ( sw->numcases >= sw->tablesize ) {
7269 if ( sw->tablesize == 0 ) newsize = 10;
7270 else newsize = 2*sw->tablesize;
7273 for ( i = 0; i < sw->tablesize; i++ ) newtable[i] = sw->table[i];
7274 M_free(sw->table,
"Switch table");
7276 sw->table = newtable;
7277 sw->tablesize = newsize;
7279 if ( sw->numcases == 0 ) { sw->mincase = sw->maxcase = x; }
7280 else if ( x > sw->maxcase ) sw->maxcase = x;
7281 else if ( x < sw->mincase ) sw->mincase = x;
7282 sw->table[sw->numcases].ncase = x;
7283 sw->table[sw->numcases].value = cbuf[AC.cbufnum].numlhs;
7284 sw->table[sw->numcases].compbuffer = AC.cbufnum;
7294int CoBreak(UBYTE *s)
7301 SWITCH *sw = AC.SwitchArray + AC.SwitchHeap[AC.SwitchLevel];
7302 if ( sw->iflevel != AC.IfLevel || sw->whilelevel != AC.WhileLevel
7303 || sw->nestingsum != NestingChecksum() ) {
7304 MesPrint(
"&Illegal nesting of switch/case/default with if/while/repeat/loop/argument/term/...");
7308 MesPrint(
"&No parameters allowed in Break statement");
7311 Add3Com(TYPEENDSWITCH,AC.SwitchHeap[AC.SwitchLevel]);
7320int CoDefault(UBYTE *s)
7326 SWITCH *sw = AC.SwitchArray + AC.SwitchHeap[AC.SwitchLevel];
7327 if ( sw->iflevel != AC.IfLevel || sw->whilelevel != AC.WhileLevel
7328 || sw->nestingsum != NestingChecksum() ) {
7329 MesPrint(
"&Illegal nesting of switch/case/default with if/while/repeat/loop/argument/term/...");
7333 MesPrint(
"&No parameters allowed in Default statement");
7336 sw->defaultcase.ncase = 0;
7337 sw->defaultcase.value = cbuf[AC.cbufnum].numlhs;
7338 sw->defaultcase.compbuffer = AC.cbufnum;
7347int CoEndSwitch(UBYTE *s)
7356 SWITCH *sw = AC.SwitchArray + AC.SwitchHeap[AC.SwitchLevel];
7358 WORD totcases = sw->maxcase-sw->mincase+1;
7359 while ( *s ==
',' ) s++;
7362 MesPrint(
"&No parameters allowed in EndSwitch statement");
7365 if ( sw->iflevel != AC.IfLevel || sw->whilelevel != AC.WhileLevel
7366 || sw->nestingsum != NestingChecksum() ) {
7367 MesPrint(
"&Illegal nesting of switch/case/default with if/while/repeat/loop/argument/term/...");
7370 if ( sw->defaultcase.value == 0 ) CoDefault(s);
7371 if ( totcases > sw->numcases*AM.jumpratio ) {
7373 sw->typetable = SPARSETABLE;
7377 SwitchSplitMerge(sw->table,sw->numcases);
7381 sw->caseoffset = sw->mincase;
7382 sw->typetable = DENSETABLE;
7384 for ( i = 0; i < totcases; i++ ) {
7385 ntable[i].ncase = i+sw->caseoffset;
7386 ntable[i].value = sw->defaultcase.value;
7387 ntable[i].compbuffer = sw->defaultcase.compbuffer;
7389 for ( i = 0; i < sw->numcases; i++ ) {
7390 ntable[sw->table[i].ncase-sw->caseoffset] = sw->table[i];
7392 M_free(sw->table,
"Switch table");
7394 sw->numcases = totcases;
7396 sw->endswitch.ncase = 0;
7397 sw->endswitch.value = cbuf[AC.cbufnum].numlhs;
7398 sw->endswitch.compbuffer = AC.cbufnum;
7399 if ( sw->defaultcase.value == 0 ) {
7400 sw->defaultcase = sw->endswitch;
7402 Add3Com(TYPEENDSWITCH,AC.SwitchHeap[AC.SwitchLevel]);
7415int CoSetUserFlag(UBYTE *s)
7418 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
7419 while ( *s && ( FG.cTable[*s] == 1 ) ) {
7421 while ( *s && ( FG.cTable[*s] == 1 ) ) x = 10*x+(*s++ -
'0');
7422 if ( x < 1 || x > BITSINWORD ) {
7423 MesPrint(
"&Flag number %d outside the permitted range 1-%d.",BITSINWORD);
7427 Add3Com(TYPESETUSERFLAG,x-1);
7429 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
7432 MesPrint(
"&Illegal character in SetUserFlag statement: %s",s);
7443int CoClearUserFlag(UBYTE *s)
7446 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
7447 while ( *s && ( FG.cTable[*s] == 1 ) ) {
7449 while ( *s && ( FG.cTable[*s] == 1 ) ) x = 10*x+(*s++ -
'0');
7450 if ( x < 1 || x > BITSINWORD ) {
7451 MesPrint(
"&Flag number %d outside the permitted range 1-%d.",BITSINWORD);
7455 Add3Com(TYPECLEARUSERFLAG,x);
7457 while ( *s && ( *s ==
',' || *s ==
' ' || *s ==
'\t' ) ) s++;
7460 MesPrint(
"&Illegal character in SetUserFlag statement: %s",s);
7480int CoCreateAllLoops(UBYTE *s)
7483 UBYTE *inname, *outname, *stype, c;
7484 WORD infun, outfun, x, type, tensorflag, typenum;
7485 WORD *WorkSave, *to;
7486 while ( *s ==
',' || *s ==
' ' ) s++;
7489 if ( ( ( type = GetName(AC.varnames,inname,&infun,WITHAUTO) ) != CFUNCTION )
7490 || ( ( functions[infun].spec != 0 ) && ( functions[infun].spec != TENSORFUNCTION ) ) ) {
7491 MesPrint(
"&%s should be a regular function or a tensor.",inname);
7493 if ( GetName(AC.exprnames,s,&infun,NOAUTO) == NAMENOTFOUND )
7494 AddFunction(s,0,0,0,0,0,-1,-1);
7500 while ( *s ==
',' || *s ==
' ' ) s++;
7503 if ( ( ( type = GetName(AC.varnames,outname,&outfun,WITHAUTO) ) != CFUNCTION )
7504 || ( ( functions[outfun].spec != 0 ) && ( functions[outfun].spec != TENSORFUNCTION ) ) ) {
7505 MesPrint(
"&%s should be a regular function or a tensor.",outname);
7507 if ( GetName(AC.exprnames,s,&outfun,NOAUTO) == NAMENOTFOUND )
7508 AddFunction(s,0,0,0,0,0,-1,-1);
7514 if ( functions[infun].spec == TENSORFUNCTION ||
7515 functions[outfun].spec == TENSORFUNCTION ) tensorflag = 1;
7516 else tensorflag = 0;
7520 while ( *s ==
',' || *s ==
' ' ) s++;
7522 while ( FG.cTable[*s] == 0 ) s++;
7524 if ( StrICmp(stype,(UBYTE *)
"type") != 0 || c !=
'=' ) {
7525 MesPrint(
"&In CreateAllLoops statement: expected type=vartype.");
7530 while ( FG.cTable[*s] == 0 ) s++;
7532 if ( StrICmp(stype,(UBYTE *)
"vector") == 0 ) {
7535 else if ( StrICmp(stype,(UBYTE *)
"index") == 0 ) {
7538 else if ( StrICmp(stype,(UBYTE *)
"symbol") == 0 ) {
7539 if ( tensorflag )
goto notintensor;
7542 else if ( StrICmp(stype,(UBYTE *)
"snumber") == 0 ) {
7543 if ( tensorflag )
goto notintensor;
7547 MesPrint(
"&Unknown/not allowed variable type in CreateAllLoops: %s",stype);
7551 while ( *s ==
',' || *s ==
' ' ) s++;
7554 while ( FG.cTable[*s] == 0 ) s++;
7556 if ( StrICmp(stype,(UBYTE *)
"ifnoloop") != 0 || c !=
'=' ) {
7557 MesPrint(
"&Unrecognised option in CreateAllLoops statement: %s",stype);
7562 if ( FG.cTable[*s] == 1 ) {
7564 do { x = 10*x + (*s++-
'0'); }
while (FG.cTable[*s] == 1);
7566 if ( x != 0 && x != 1 ) {
7567 MesPrint(
"&Only options allowed for ifnoloop are 0 or 1.");
7570 WorkSave = to = AT.WorkPointer;
7571 *to++ = TYPEALLLOOPS;
7578 AddNtoL(WorkSave[1],WorkSave);
7582 MesPrint(
"&Variable type not allowed in tensors: %s",stype);
7600int CoCreateAllPaths(UBYTE *s)
7603 UBYTE *endname,*inname, *outname, *stype, c;
7604 WORD endfun, infun, outfun, x, type, tensorflag, typenum;
7605 WORD *WorkSave, *to;
7606 while ( *s ==
',' || *s ==
' ' ) s++;
7609 if ( ( ( type = GetName(AC.varnames,endname,&endfun,WITHAUTO) ) != CFUNCTION )
7610 || ( ( functions[endfun].spec != 0 ) && ( functions[endfun].spec != TENSORFUNCTION ) ) ) {
7611 MesPrint(
"&%s should be a regular function or a tensor.",endname);
7613 if ( GetName(AC.exprnames,s,&endfun,NOAUTO) == NAMENOTFOUND )
7614 AddFunction(s,0,0,0,0,0,-1,-1);
7620 while ( *s ==
',' || *s ==
' ' ) s++;
7623 if ( ( ( type = GetName(AC.varnames,inname,&infun,WITHAUTO) ) != CFUNCTION )
7624 || ( ( functions[infun].spec != 0 ) && ( functions[infun].spec != TENSORFUNCTION ) ) ) {
7625 MesPrint(
"&%s should be a regular function or a tensor.",inname);
7627 if ( GetName(AC.exprnames,s,&infun,NOAUTO) == NAMENOTFOUND )
7628 AddFunction(s,0,0,0,0,0,-1,-1);
7634 while ( *s ==
',' || *s ==
' ' ) s++;
7637 if ( ( ( type = GetName(AC.varnames,outname,&outfun,WITHAUTO) ) != CFUNCTION )
7638 || ( ( functions[outfun].spec != 0 ) && ( functions[outfun].spec != TENSORFUNCTION ) ) ) {
7639 MesPrint(
"&%s should be a regular function or a tensor.",outname);
7641 if ( GetName(AC.exprnames,s,&outfun,NOAUTO) == NAMENOTFOUND )
7642 AddFunction(s,0,0,0,0,0,-1,-1);
7648 if ( functions[infun].spec == TENSORFUNCTION ||
7649 functions[outfun].spec == TENSORFUNCTION ) tensorflag = 1;
7650 else tensorflag = 0;
7654 while ( *s ==
',' || *s ==
' ' ) s++;
7656 while ( FG.cTable[*s] == 0 ) s++;
7658 if ( StrICmp(stype,(UBYTE *)
"type") != 0 || c !=
'=' ) {
7659 MesPrint(
"&In CreateAllPaths statement: expected type=vartype.");
7664 while ( FG.cTable[*s] == 0 ) s++;
7666 if ( StrICmp(stype,(UBYTE *)
"vector") == 0 ) {
7669 else if ( StrICmp(stype,(UBYTE *)
"index") == 0 ) {
7672 else if ( StrICmp(stype,(UBYTE *)
"symbol") == 0 ) {
7673 if ( tensorflag )
goto notintensor;
7676 else if ( StrICmp(stype,(UBYTE *)
"snumber") == 0 ) {
7677 if ( tensorflag )
goto notintensor;
7681 MesPrint(
"&Unknown/not allowed variable type in CreateAllPaths: %s",stype);
7685 while ( *s ==
',' || *s ==
' ' ) s++;
7688 while ( FG.cTable[*s] == 0 ) s++;
7690 if ( StrICmp(stype,(UBYTE *)
"ifnopath") != 0 || c !=
'=' ) {
7691 MesPrint(
"&Unrecognised option in CreateAllPaths statement: %s",stype);
7696 if ( FG.cTable[*s] == 1 ) {
7698 do { x = 10*x + (*s++-
'0'); }
while (FG.cTable[*s] == 1);
7700 if ( x != 0 && x != 1 ) {
7701 MesPrint(
"&Only options allowed for ifnopath are 0 or 1.");
7704 WorkSave = to = AT.WorkPointer;
7705 *to++ = TYPEALLPATHS;
7713 AddNtoL(WorkSave[1],WorkSave);
7717 MesPrint(
"&CreateAllPaths: Variable type not allowed in tensors: %s",stype);
7728int CoCreateAll(UBYTE *s)
7731 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7733 while ( FG.cTable[*s] == 0 ) s++;
7734 if ( *s !=
' ' && *s !=
',' && *s !=
'\t' ) {
7735 MesPrint(
"&Illegal subkey in CoCreate statement.");
7739 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
7740 if ( StrICmp(subkey,(UBYTE *)
"loops") == 0 ) {
7741 return(CoCreateAllLoops(s));
7743 else if ( StrICmp(subkey,(UBYTE *)
"paths") == 0 ) {
7744 return(CoCreateAllPaths(s));
7755 MesPrint(
"&Illegal subkey in CoCreate statement: %s.",subkey);
UBYTE * SkipAName(UBYTE *s)
void PrintDeprecation(const char *, const char *)
void AddPotModdollar(WORD)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)