44static struct id_options {
49 {(UBYTE *)
"multi", SUBMULTI ,0}
50 ,{(UBYTE *)
"many", SUBMANY ,0}
51 ,{(UBYTE *)
"only", SUBONLY ,0}
52 ,{(UBYTE *)
"once", SUBONCE ,0}
53 ,{(UBYTE *)
"ifmatch", SUBAFTER ,0}
54 ,{(UBYTE *)
"ifnomatch", SUBAFTERNOT ,0}
55 ,{(UBYTE *)
"ifnotmatch", SUBAFTERNOT ,0}
56 ,{(UBYTE *)
"disorder", SUBDISORDER ,0}
57 ,{(UBYTE *)
"select", SUBSELECT ,0}
58 ,{(UBYTE *)
"all", SUBALL ,0}
66int CoLocal(UBYTE *inp) {
return(DoExpr(inp,LOCALEXPRESSION,0)); }
73int CoGlobal(UBYTE *inp) {
return(DoExpr(inp,GLOBALEXPRESSION,0)); }
80int CoLocalFactorized(UBYTE *inp) {
return(DoExpr(inp,LOCALEXPRESSION,1)); }
87int CoGlobalFactorized(UBYTE *inp) {
return(DoExpr(inp,GLOBALEXPRESSION,1)); }
96int DoExpr(UBYTE *inp,
int type,
int par)
101 WORD *w, i, j = 0, c1, c2, *OldWork = AT.WorkPointer, osize;
104 while ( *inp ==
',' ) inp++;
105 if ( par ) AC.ToBeInFactors = 1;
106 else AC.ToBeInFactors = 0;
108 while ( *p && *p !=
'=' ) {
109 if ( *p ==
'(' ) SKIPBRA4(p)
110 else if ( *p ==
'{' ) SKIPBRA5(p)
111 else if ( *p ==
'[' ) SKIPBRA1(p)
116 if ( *inp ==
'$' || q == 0 || q[-1] ==
'_' ) {
117 MesPrint(
"&Illegal name for expression");
123 if ( GetVar(inp,&c1,&c2,ALLVARIABLES,NOAUTO) != NAMENOTFOUND ) {
124 if ( c1 == CEXPRESSION ) {
125 if ( Expressions[c2].status == STOREDEXPRESSION ) {
126 MesPrint(
"&Illegal attempt to overwrite a stored expression");
130 HighWarning(
"Expression is replaced by new definition");
131 if ( AO.OptimizeResult.nameofexpr != NULL &&
132 StrCmp(inp,AO.OptimizeResult.nameofexpr) == 0 ) {
135 if ( Expressions[c2].status != DROPPEDEXPRESSION ) {
136 w = &(Expressions[c2].status);
137 if ( *w == LOCALEXPRESSION || *w == SKIPLEXPRESSION )
138 *w = DROPLEXPRESSION;
139 else if ( *w == GLOBALEXPRESSION || *w == SKIPGEXPRESSION )
140 *w = DROPGEXPRESSION;
141 else if ( *w == HIDDENLEXPRESSION )
142 *w = DROPHLEXPRESSION;
143 else if ( *w == HIDDENGEXPRESSION )
144 *w = DROPHGEXPRESSION;
146 AC.TransEname = Expressions[c2].name;
147 j = EntVar(CEXPRESSION,0,type,0,0,0);
148 Expressions[j].node = Expressions[c2].node;
149 Expressions[c2].replace = j;
153 MesPrint(
"&name of expression is also name of a variable");
155 j = EntVar(CEXPRESSION,inp,type,0,0,0);
165 j = EntVar(CEXPRESSION,inp,type,0,0,0);
169 OldWork = w = AT.WorkPointer;
170 *w++ = TYPEEXPRESSION;
175 *w++ = SUBEXPRESSION;
183 while ( *q ==
',' || *q ==
'(' ) {
186 MesPrint(
"&Illegal name for expression argument");
192 if ( GetVar(inp,&c1,&c2,ALLVARIABLES,WITHAUTO) < 0 ) c1 = -1;
195 *w++ = SYMTOSYM; *w++ = 4; *w++ = c2; *w++ = 0;
198 *w++ = INDTOIND; *w++ = 4;
199 *w++ = c2 + AM.OffsetIndex; *w++ = 0;
202 *w++ = VECTOVEC; *w++ = 4;
203 *w++ = c2 + AM.OffsetVector; *w++ = 0;
206 *w++ = FUNTOFUN; *w++ = 4; *w++ = c2 + FUNCTION; *w++ = 0;
209 MesPrint(
"&Illegal expression parameter: %s",inp);
215 if ( *q !=
')' || q+1 != p ) {
216 MesPrint(
"&Illegal use of arguments for expression");
219 AC.ProtoType[1] = w - AC.ProtoType;
221 else if ( c !=
'=' ) {
225 MesPrint(
"&Illegal LHS for expression definition");
232 SeekScratch(AR.outfile,&pos);
233 Expressions[j].counter = 1;
234 Expressions[j].onfile = pos;
235 Expressions[j].whichbuffer = 0;
237 Expressions[j].partodo = AC.inparallelflag;
239 OldWork[2] = w - OldWork - 3;
248 ClearWildcardNames();
249 osize = AC.ProtoType[1]; AC.ProtoType[1] = SUBEXPSIZE;
251 if ( ( i = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) {
252 AC.ProtoType[1] = osize;
255 else if ( error == 0 ) {
256 AC.ProtoType[1] = osize;
258 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0 ) {
259 MesPrint(
"&Cannot create expression");
263 Expressions[j].sizeprototype = OldWork[2];
264 OldWork[2] = 4+SUBEXPSIZE;
265 OldWork[4] = SUBEXPSIZE;
267 OldWork[SUBEXPSIZE+3] = 1;
268 OldWork[SUBEXPSIZE+4] = 1;
269 OldWork[SUBEXPSIZE+5] = 3;
270 OldWork[SUBEXPSIZE+6] = 0;
271 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0
273 MesPrint(
"&Cannot create expression");
276 AR.outfile->POfull = AR.outfile->POfill;
284 AT.WorkPointer = OldWork;
285 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
287 AC.ToBeInFactors = 0;
296 MesPrint(
"&Illegal name(s) for expression(s)");
300 if ( GetName(AC.exprnames,inp,&c2,NOAUTO) == NAMENOTFOUND ) {
301 MesPrint(
"&%s is not a valid expression",inp);
305 w = &(Expressions[c2].status);
306 if ( type == LOCALEXPRESSION ) {
308 case GLOBALEXPRESSION:
309 *w = LOCALEXPRESSION;
311 case SKIPGEXPRESSION:
312 *w = SKIPLEXPRESSION;
314 case DROPGEXPRESSION:
315 *w = DROPLEXPRESSION;
317 case HIDDENGEXPRESSION:
318 *w = HIDDENLEXPRESSION;
320 case HIDEGEXPRESSION:
321 *w = HIDELEXPRESSION;
323 case UNHIDEGEXPRESSION:
324 *w = UNHIDELEXPRESSION;
326 case INTOHIDEGEXPRESSION:
327 *w = INTOHIDELEXPRESSION;
329 case DROPHGEXPRESSION:
330 *w = DROPHLEXPRESSION;
334 else if ( type == GLOBALEXPRESSION ) {
336 case LOCALEXPRESSION:
337 *w = GLOBALEXPRESSION;
339 case SKIPLEXPRESSION:
340 *w = SKIPGEXPRESSION;
342 case DROPLEXPRESSION:
343 *w = DROPGEXPRESSION;
345 case HIDDENLEXPRESSION:
346 *w = HIDDENGEXPRESSION;
348 case HIDELEXPRESSION:
349 *w = HIDEGEXPRESSION;
351 case UNHIDELEXPRESSION:
352 *w = UNHIDEGEXPRESSION;
354 case INTOHIDELEXPRESSION:
355 *w = INTOHIDEGEXPRESSION;
357 case DROPHLEXPRESSION:
358 *w = DROPHGEXPRESSION;
369 }
while ( c ==
',' );
371 MesPrint(
"&Illegal object in local or global redefinition");
383int CoIdOld(UBYTE *inp)
386 return(CoIdExpression(inp,TYPEIDOLD));
397 return(CoIdExpression(inp,TYPEIDNEW));
405int CoIdNew(UBYTE *inp)
408 return(CoIdExpression(inp,TYPEIDNEW));
416int CoDisorder(UBYTE *inp)
418 AC.idoption = SUBDISORDER;
419 return(CoIdExpression(inp,TYPEIDNEW));
427int CoMany(UBYTE *inp)
429 AC.idoption = SUBMANY;
430 return(CoIdExpression(inp,TYPEIDNEW));
438int CoMulti(UBYTE *inp)
440 AC.idoption = SUBMULTI;
441 return(CoIdExpression(inp,TYPEIDNEW));
449int CoIfMatch(UBYTE *inp)
451 AC.idoption = SUBAFTER;
452 return(CoIdExpression(inp,TYPEIDNEW));
460int CoIfNoMatch(UBYTE *inp)
462 AC.idoption = SUBAFTERNOT;
463 return(CoIdExpression(inp,TYPEIDNEW));
471int CoOnce(UBYTE *inp)
473 AC.idoption = SUBONCE;
474 return(CoIdExpression(inp,TYPEIDNEW));
482int CoOnly(UBYTE *inp)
484 AC.idoption = SUBONLY;
485 return(CoIdExpression(inp,TYPEIDNEW));
493int CoSelect(UBYTE *inp)
495 AC.idoption = SUBSELECT;
496 return(CoIdExpression(inp,TYPEIDNEW));
506int CoIdExpression(UBYTE *inp,
int type)
509 int i, j, idhead, error = 0, MinusSign = 0, opt, retcode;
510 WORD *w, *s, *m, *mm, *ww, *FirstWork, *OldWork, c1, numsets = 0,
511 oldnumrhs, *ow, oldEside;
513 CBUF *C = cbuf+AC.cbufnum;
515 FirstWork = OldWork = AT.WorkPointer;
526 *w++ = idhead + SUBEXPSIZE;
528 if ( idhead >= IDHEAD ) *w++ = -1;
530 for ( i = 4; i < idhead; i++ ) *w++ = 0;
532 while ( *inp ==
',' ) inp++;
534 if ( AC.idoption == SUBSELECT ) {
538 else if ( ( AC.idoption == SUBAFTER ) || ( AC.idoption == SUBAFTERNOT ) ) {
539 while ( *p && *p !=
'=' && *p !=
',' ) {
540 if ( *p ==
'(' ) SKIPBRA4(p)
541 else if ( *p ==
'{' ) SKIPBRA5(p)
542 else if ( *p ==
'[' ) SKIPBRA1(p)
545 if ( *p ==
'=' || *inp !=
'-' || inp[1] !=
'>' ) {
546 MesPrint(
"&Illegal use if if[no]match in id statement");
547 error = 1;
goto AllDone;
550 MesPrint(
"&id-statement without = sign");
551 error = 1;
goto AllDone;
557 while ( *p && *p !=
'=' && *p !=
',' ) {
558 if ( *p ==
'(' ) SKIPBRA4(p)
559 else if ( *p ==
'{' ) SKIPBRA5(p)
560 else if ( *p ==
'[' ) SKIPBRA1(p)
563 if ( *p ==
'=' )
break;
565 MesPrint(
"&id-statement without = sign");
566 error = 1;
goto AllDone;
572 while ( FG.cTable[*pp] == 0 ) pp++;
574 i =
sizeof(IdOptions)/
sizeof(
struct id_options);
576 if ( StrICmp(inp,IdOptions[i].name) == 0 )
break;
579 MesPrint(
"&Illegal option %s in id-statement",inp);
580 *pp = c; error = 1; p++; inp = p;
continue;
582 opt = IdOptions[i].code;
587 if ( pp != p )
goto IllField;
588 AC.idoption |= SUBDISORDER;
592 if ( p != pp )
goto IllField;
593 if ( ( AC.idoption & SUBMASK ) != 0 ) {
594 if ( AC.idoption == SUBMULTI && type == TYPEIF ) {}
596 MesPrint(
"&Conflicting options in id-statement");
607 while ( *p && *p !=
'=' && *p !=
',' ) {
608 if ( *p ==
'(' ) SKIPBRA4(p)
609 else if ( *p ==
'{' ) SKIPBRA5(p)
610 else if ( *p ==
'[' ) SKIPBRA1(p)
613 if ( *p ==
'=' )
break;
615 MesPrint(
"&id-statement without = sign");
616 error = 1;
goto AllDone;
622 if ( p[-1] !=
'}' ) {
624 MesPrint(
"&Illegal temporary set: %s",inp);
629 c = p[-1]; p[-1] = 0;
630 c1 = DoTempSet(inp,p-1);
634 if ( w[-1] < 0 ) error = 1;
639 if ( GetName(AC.varnames,inp,&c1,NOAUTO) != CSET ) {
640 MesPrint(
"&%s is not a set",inp);
644 if ( c1 < AM.NumFixedSets ) {
645 MesPrint(
"&Built in sets are not allowed in the select option");
648 else if ( Sets[c1].type == CRANGE ) {
649 MesPrint(
"&Ranged sets are not allowed in the select option");
663 for ( i = 0; i < idhead; i++ ) *w++ = FirstWork[i];
664 AC.idoption = SUBSELECT;
668 if ( type == TYPEIF ) {
669 MesPrint(
"&The if[no]match->label option is not allowed in an if statement");
670 error = 1;
goto AllDone;
672 if ( pp[0] !=
'-' || pp[1] !=
'>' )
goto IllField;
677 while ( FG.cTable[*pp] <= 1 ) pp++;
680 MesPrint(
"&Illegal label %s in if[no]match option of id-statement",inp);
681 *p = c; error = 1; inp = p+1;
continue;
684 OldWork[3] = GetLabel(inp);
690 if ( FG.cTable[*inp] == 1 ) {
691 while ( *inp >=
'0' && *inp <=
'9' ) x = 10*x+*inp++ -
'0';
695 while ( FG.cTable[*inp] == 0 ) inp++;
697 if ( StrICont(pp,(UBYTE *)
"normalize") != 0 )
goto IllOpt;
699 OldWork[4] |= NORMALIZEFLAG;
701 if ( *inp !=
')' || inp+1 != p ) {
704 MesPrint(
"&Illegal ALL option in id-statement: ",pp);
715 if ( x > MAXPOSITIVE ) {
716 MesPrint(
"&Requested maximum number of matches %l in ALL option in id-statement is greater than %l ",x,MAXPOSITIVE);
720 if ( type != TYPEIDNEW ) {
721 if ( type == TYPEIDOLD ) {
722 MesPrint(
"&Requested ALL option not allowed in idold/also statement.");
725 else if ( type == TYPEIF ) {
726 MesPrint(
"&Requested ALL option not allowed in if(match())");
730 MesPrint(
"&ALL option only allowed in regular id-statement.");
739IllField: c = *p; *p = 0;
740 MesPrint(
"&Illegal optionfield %s in id-statement",inp);
741 *p = c; error = 1; inp = p+1;
continue;
743 i = AC.idoption & SUBMASK;
744 if ( i && i != opt ) {
745 MesPrint(
"&Conflicting options in id-statement");
748 else AC.idoption |= opt;
749 while ( *p ==
',' ) p++;
754 if ( ( AC.idoption & SUBMASK ) == 0 ) AC.idoption |= SUBMULTI;
755 OldWork[2] = AC.idoption;
761 *w++ = SUBEXPRESSION;
769 AT.WorkPointer = s = w + 4*AM.MaxWildcards + 8;
773 ClearWildcardNames();
777 oldnumrhs = C->numrhs;
778 if ( ( retcode = CompileAlgebra(inp,LHSIDE,AC.ProtoType) ) < 0 ) { error = 1; }
779 else AC.ProtoType[2] = retcode;
782 if ( AC.NwildC &&
SortWild(w,AC.NwildC) ) error = 1;
786 OldWork[1] = AC.WildC-OldWork;
787 OldWork[idhead+1] = OldWork[1] - idhead;
790 s = C->
rhs[C->numrhs];
796 tw = AC.ProtoType; twstop = tw + tw[1]; tw += SUBEXPSIZE;
797 while ( tw < twstop ) {
798 if ( *tw == LOADDOLLAR ) {
812 if ( !error && *s == 0 ) {
813IllLeft:MesPrint(
"&Illegal LHS");
817 if ( !error && *(s+*s) != 0 ) {
818 MesPrint(
"&LHS should be one term only");
822 WORD oldpolyfun = AR.PolyFun;
824 if ( !error ) error = 1;
827 AN.RepPoint = AT.RepCount + 1;
828 ow = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
829 mm = s; ww = ow; i = *mm;
830 while ( --i >= 0 ) {*ww++ = *mm++;} AT.WorkPointer = ww;
831 AC.lhdollarflag = 0; oldEside = AR.Eside; AR.Eside = LHSIDE;
832 AR.Cnumlhs = C->numlhs;
841 AR.PolyFun = oldpolyfun;
842 if ( *w == 0 || *(w+*w) != 0 ) {
843 MesPrint(
"&LHS must be one term");
848 if ( AC.lhdollarflag ) MarkDirty(w,DIRTYFLAG);
850 AT.WorkPointer = w + *w;
859 C->numrhs = oldnumrhs;
863 AC.vectorlikeLHS = 0;
865 if ( m[2] != 3 || m[1] != 1 || *m != 1 ) {
866 if ( *m == 1 && m[1] == 1 && m[2] == -3 ) {
870 MesPrint(
"&Coefficient in LHS");
876 if ( *w == 7 && w[1] == INDEX && w[3] < 0 ) {
877 if ( ( AC.idoption & SUBMASK ) != 0 && ( AC.idoption & SUBMASK ) !=
879 MesPrint(
"&Illegal option for substitution of a vector");
882 AC.DumNum = AM.IndDum;
883 OldWork[2] = ( OldWork[2] - ( OldWork[2] & SUBMASK ) ) | SUBVECTOR;
888 *w++ = AC.DumNum + WILDOFFSET;
894 w[4] = AC.DumNum + WILDOFFSET;
895 OldWork[idhead+1] = w - OldWork - idhead;
896 AC.vectorlikeLHS = 1;
901 i = OldWork[2] & SUBMASK;
903 if ( i == 0 || i == SUBMULTI ) {
906 if ( *s == SYMBOL ) {
909 if ( ABS(s[1]) > 2*MAXPOWER ) {
910 OldWork[2] = ( OldWork[2] - i ) | SUBONCE;
917 else if ( *s == DOTPRODUCT ) {
920 if ( ABS(s[2]) > 2*MAXPOWER ) {
921 OldWork[2] = ( OldWork[2] - i ) | SUBONCE;
924 else if ( s[1] >= -(2*WILDOFFSET) || s[0] >= -(2*WILDOFFSET) ) {
925 OldWork[2] = ( OldWork[2] - i ) | SUBMANY;
933 OldWork[2] = ( OldWork[2] - i ) | SUBMANY;
938 if ( ( OldWork[2] & SUBMASK ) == 0 ) OldWork[2] |= SUBMULTI;
940 if ( ( OldWork[2] & SUBMASK ) == SUBSELECT ) {
950 s = FirstWork + idhead;
951 while ( --numsets >= 0 ) *m++ = *s++;
967 OldWork[1] = m - OldWork;
968 AC.ProtoType = OldWork+idhead;
970 if ( StudyPattern(OldWork) ) error = 1;
972 AT.WorkPointer = OldWork + OldWork[1];
973 if ( AC.lhdollarflag ) OldWork[4] |= DOLLARFLAG;
978 if ( type == TYPEIDOLD ) {
981 if ( C->
lhs[ci][0] == TYPEIDNEW ) {
982 if ( (C->
lhs[ci][2] & SUBMASK) == SUBALL ) {
983 MesPrint(
"&Idold/also cannot follow an id,all statement.");
988 else if ( C->
lhs[ci][0] == TYPEDETCURDUM ) { ci--;
continue; }
989 else if ( C->
lhs[ci][0] == TYPEIDOLD ) { ci--;
continue; }
993 MesPrint(
"&Idold/also should follow an id/idnew statement.");
1000 if ( type != TYPEIF ) {
1001 if ( ( retcode = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) error = 1;
1003 AC.ProtoType[2] = retcode;
1006 w = C->
rhs[retcode];
1007 while ( *w ) { w += *w; w[-1] = -w[-1]; }
1009 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
1015 if ( !error ) {
AddNtoL(OldWork[1],OldWork); }
1017 AC.lhdollarflag = 0;
1018 AT.WorkPointer = FirstWork;
1027static WORD mularray[13] = { TYPEMULT, SUBEXPSIZE+3, 0, SUBEXPRESSION,
1028 SUBEXPSIZE, 0, 1, 0, 0, 0, 0, 0, 0 };
1030int CoMultiply(UBYTE *inp)
1033 int error = 0, RetCode;
1035 while ( *inp ==
',' ) inp++;
1040 if ( StrICont(inp,(UBYTE *)
"left") == 0 ) mularray[2] = 1;
1041 else if ( StrICont(inp,(UBYTE *)
"right") == 0 ) mularray[2] = 0;
1043 MesPrint(
"&Illegal option in multiply statement or ; forgotten.");
1049 ClearWildcardNames();
1050 while ( *inp ==
',' ) inp++;
1051 AC.ProtoType = mularray+3;
1052 mularray[7] = AC.cbufnum;
1053 if ( ( RetCode = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) error = 1;
1055 mularray[5] = RetCode;
1056 AddNtoL(SUBEXPSIZE+3,mularray);
1057 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
1069int CoFill(UBYTE *inp)
1072 WORD error = 0, x, xx, funnum, type, *oldwp = AT.WorkPointer;
1073 int i, oldcbufnum = AC.cbufnum, nofill = 0, numover, redef = 0;
1074 WORD *w, *wold, *Tprototype;
1075 UBYTE *p = inp, c, *inp1;
1077 LONG newreservation, sum = 0;
1078 UBYTE *p1, *p2, *p3, *p4, *fake = 0;
1080 if ( AC.exprfillwarning == 1 ) AC.exprfillwarning = 0;
1085 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1088 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,WITHAUTO) == NAMENOTFOUND )
1089 || ( T = functions[funnum].tabl ) == 0 || ( T->
numind > 0 && c !=
'(' ) ) {
1090 MesPrint(
"&%s should be a table with argument(s)",inp);
1099 MesPrint(
"&%s should be a table without arguments",inp);
1111 ParseSignedNumber(xx,p);
1112 if ( FG.cTable[p[-1]] != 1 || *p !=
',' || xx < 1 || ( xx > ( -T->
numind - 1 ) ) ) {
1113 MesPrint(
"&No valid number of table indices in *-table fill statement.");
1120 for ( sum = 0, i = 0; i < xx; i++ ) {
1121 ParseSignedNumber(x,p);
1122 if ( FG.cTable[p[-1]] != 1 || ( *p !=
',' && *p !=
')' ) ) {
1123 MesPrint(
"&Table arguments in fill statement should be numbers");
1126 if ( T->
sparse ) *w++ = x;
1127 else if ( x < T->mm[i].mini || x > T->
mm[i].
maxi ) {
1128 MesPrint(
"&Value %d for argument %d of table out of bounds",x,i+1);
1129 error = 1; nofill = 1;
1132 if ( *p ==
')' )
break;
1137 for ( ; i < ABS(T->
numind)-1; i++ ) *w++ = 0;
1140 if ( *p !=
')' || i < ( xx - 1 ) ) {
1141 MesPrint(
"&Incorrect number of table arguments in fill statement. Should be %d"
1143 error = 1; nofill = 1;
1146 if ( T->
sparse == 0 ) sum *= TABLEEXTENSION;
1150 i = FindTableTree(T,oldwp,1);
1152 sum = i + ABS(T->
numind);
1153 if ( tablestub == 0 && ( ( T->
sparse & 2 ) == 2 ) && ( T->
mode != 0 )
1154 && ( AC.vetotablebasefill == 0 ) ) {
1158 functions[funnum].tabl = T = T->
spare;
1166 if ( T->
reserved == 0 ) newreservation = 20;
1168 while ( T->
totind >= newreservation && newreservation < MAXTABLECOMBUF )
1169 newreservation = 2*newreservation;
1170 if ( newreservation > MAXTABLECOMBUF ) newreservation = MAXTABLECOMBUF;
1171 if ( T->
totind >= newreservation ) {
1172 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1173 AC.cbufnum = oldcbufnum;
1176 wold = (WORD *)Malloc1(newreservation*
sizeof(WORD)*
1177 (ABS(T->
numind)+TABLEEXTENSION),
"tablepointers");
1178 for ( i = T->
reserved*(ABS(T->
numind)+TABLEEXTENSION)-1; i >= 0; i-- )
1185 for ( sum = T->
totind*(ABS(T->
numind)+TABLEEXTENSION), i = 0; i < ABS(T->
numind); i++ ) {
1189#if TABLEEXTENSION == 2
1202 if ( AC.vetofilling ) nofill = 1;
1204 Warning(
"Table element was already defined. New definition will be used");
1207#if TABLEEXTENSION == 2
1217 if ( T->
numind ) { p++; }
1219 MesPrint(
"&Fill statement misses = sign after the table element");
1220 AC.cbufnum = oldcbufnum;
1221 AT.WorkPointer = oldwp;
1222 functions[funnum].tabl = oldT;
1225 if ( tablestub == 0 && T->
mode == 1 && AC.vetotablebasefill == 0 ) {
1233 numfake = (p4-T->
argtail)+(p3-p1)+10;
1235 fake = (UBYTE *)Malloc1(numfake*
sizeof(UBYTE),
"Fill fake rhs");
1237 *p++ =
't'; *p++ =
'b'; *p++ =
'l'; *p++ =
'_'; *p++ =
'(';
1238 p4 = p1;
while ( p4 < p2 ) *p++ = *p4++; *p++ =
',';
1239 p4 = p2+1;
while ( p4 < p3 ) *p++ = *p4++;
1242 while ( FG.cTable[*p4] == 1 ) p4++;
1244 if ( *p4 ==
'?' && p[-1] !=
',' ) {
1246 if ( FG.cTable[*p4] == 0 || *p4 ==
'$' || *p4 ==
'[' ) {
1252 else if ( *p4 ==
'{' ) {
1255 else if ( *p4 ) { *p++ = *p4++;
continue; }
1272 AC.tablefilling = funnum;
1281 if ( ( i = CompileAlgebra(inp1,RHSIDE,Tprototype) ) < 0 ) { error = 1; i = 0; }
1288 if ( T->
sparse || c == 0 )
break;
1290#if ( TABLEEXTENSION == 2 )
1296#if ( TABLEEXTENSION == 2 )
1299 sum += TABLEEXTENSION-2;
1302 if ( AC.exprfillwarning == 1 ) {
1303 AC.exprfillwarning = 2;
1304 Warning(
"Use of expressions and/or $variables in Fill statements is potentially very dangerous.");
1306 AC.tablefilling = 0;
1307 if ( T->
sparse && c != 0 ) {
1308 MesPrint(
"&In sparse tables one can fill only one element at a time");
1311 else if ( numover ) {
1313 Warning(
"one element was overwritten. New definition will be used");
1314 else if ( AC.WarnFlag )
1315 MesPrint(
"&Warning: %d elements were overwritten. New definitions will be used",numover);
1318 if ( redef == 0 ) T->
totind++;
1326 M_free(fake,
"Fill fake rhs");
1328 functions[funnum].tabl = T = T->
spare;
1332 AC.cbufnum = oldcbufnum;
1333 AC.SymChangeFlag = 1;
1334 AT.WorkPointer = oldwp;
1335 functions[funnum].tabl = oldT;
1355int CoFillExpression(UBYTE *inp)
1359 WORD type, funnum, expnum, symnum, numsym = 0, *oldwork = AT.WorkPointer;
1360 WORD *brackets, *term, brasize, *b, *m, *w, *pw, *tstop, zero = 0;
1361 WORD oldcbuf = AC.cbufnum, curelement = 0;
1362 int weneedit, i, j, numzero, pow, numfirst;
1364 LONG newreservation, numcommu, sum;
1370 AN.IndDum = AM.IndDum;
1371 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1373 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1374 || ( T = functions[funnum].tabl ) == 0 ) {
1375 MesPrint(
"&%s should be a previously declared table",inp);
1382 MesPrint(
"&No = sign in FillExpression statement");
1386 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1388 if ( ( type = GetName(AC.exprnames,inp,&expnum,NOAUTO) ) == NAMENOTFOUND
1390 Expressions[expnum].status != LOCALEXPRESSION &&
1391 Expressions[expnum].status != SKIPLEXPRESSION &&
1392 Expressions[expnum].status != DROPLEXPRESSION &&
1393 Expressions[expnum].status != GLOBALEXPRESSION &&
1394 Expressions[expnum].status != SKIPGEXPRESSION &&
1395 Expressions[expnum].status != DROPGEXPRESSION ) ) {
1396 MesPrint(
"&%s should be an active expression with arguments",inp);
1399 if ( Expressions[expnum].inmem ) {
1400 MesPrint(
"&%s cannot be used in a FillExpression statement in the same %n\
1401 module that it has been redefined",inp);
1407 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1410 if ( GetVar(inp,&type,&symnum,-1,NOAUTO) == NAMENOTFOUND ) {
1411 MesPrint(
"&%s should be a previously declared symbol or function",inp);
1414 else if ( type == CSYMBOL ) {
1416 *AT.WorkPointer++ = symnum;
1419 else if ( type == CFUNCTION ) {
1423 MesPrint(
"&Argument should be a single function or a list of symbols");
1427 *AT.WorkPointer++ = symnum;
1430 MesPrint(
"&%s should be a previously declared symbol or function",inp);
1433 if ( c ==
')' )
break;
1435 MesPrint(
"&Illegal separator in FillExpression statement");
1440 MesPrint(
"&Illegal end of FillExpression statement");
1450 if ( ( numsym > 0 ) && ( ABS(T->
numind) != numsym ) ) {
1451 MesPrint(
"&This table needs %d symbols for its array indices");
1461 if ( PF.me == MASTER ) {
1466 SetEndScratch(AR.infile, &pos);
1471 PUTZERO(oldposition);
1472 SeekFile(fi->
handle,&oldposition,SEEK_CUR);
1473 SetScratch(fi,&(Expressions[expnum].onfile));
1474 if ( ISNEGPOS(Expressions[expnum].onfile) ) {
1475 MesPrint(
"&File error in FillExpression");
1485 SETBASEPOSITION(oldposition,(UBYTE *)(fi->POfill)-(UBYTE *)(fi->PObuffer));
1486 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(Expressions[expnum].onfile));
1488 pw = AT.WorkPointer;
1489 if ( numsym < 0 ) { brackets = pw + 1; }
1490 else { brackets = pw + numsym; }
1491 brasize = -1; weneedit = 0;
1492 term = (WORD *)(((UBYTE *)(brackets)) + AM.MaxTer);
1493 AT.WorkPointer = (WORD *)(((UBYTE *)(term)) + AM.MaxTer);
1495 AC.tablefilling = funnum;
1496 if ( GetTerm(BHEAD term) > 0 ) {
1497 while ( GetTerm(BHEAD term) > 0 ) {
1498 GETSTOP(term,tstop);
1500 while ( m < tstop && *m != HAAKJE ) m += m[1];
1501 if ( *m != HAAKJE ) {
1502 MesPrint(
"&Illegal attempt to put an expression without brackets in a table");
1506 if ( brasize == m - w ) {
1508 while ( *b == *w && w < m ) { b++; w++; }
1512 *m = *term - (m-term);
1514 numdummies = DetCurDum(BHEAD term) - AM.IndDum;
1515 if ( numdummies > T->numdummies ) T->numdummies = numdummies;
1521 AddNtoC(AC.cbufnum,1,&zero,4);
1522 numcommu = numcommute(C->
rhs[curelement],&(C->
NumTerms[curelement]));
1523 C->
CanCommu[curelement] = numcommu;
1525 b = brackets; w = term + 1;
1526 if ( numsym < 0 ) pw = oldwork + 1;
1527 else pw = oldwork + numsym;
1528 while ( w < m ) *b++ = *w++;
1529 brasize = b - brackets;
1535 if ( *brackets != symnum || brasize != brackets[1] ) {
1536 weneedit = 0;
continue;
1541 b = brackets + FUNHEAD;
1542 bb = brackets+brackets[1];
1546 if ( bnum > -T->
numind ) {
1547 weneedit = 0;
continue;
1552 if ( *b != -SNUMBER )
break;
1556 if ( b < bb || i != bnum ) {
1557 weneedit = 0;
continue;
1560 else if ( brasize > 0 && ( *brackets != SYMBOL
1561 || brackets[1] < brasize || (brackets[1]-2) > numsym*2 ) ) {
1562 weneedit = 0;
continue;
1564 numzero = 0; sum = 0;
1567 for ( i = 0; i < numsym; i++ ) {
1568 if ( brasize > 0 ) {
1569 b = brackets + 2; j = brackets[1]-2;
1571 if ( *b == oldwork[i] )
break;
1576 if ( 2*numzero+brackets[1]-2 > numsym*2 ) {
1577 weneedit = 0;
goto nextterm;
1587 if ( pow > -T->
numind ) {
1588 weneedit = 0;
goto nextterm;
1591 else if ( i > pow ) {
1592 weneedit = 0;
goto nextterm;
1597 else if ( pow < T->mm[i].mini || pow > T->
mm[i].
maxi ) {
1598 weneedit = 0;
goto nextterm;
1605 b = brackets + FUNHEAD;
1611 xx = (brackets[1]-FUNHEAD)/2;
1612 for ( i = 0; i < xx; i++ ) {
1619 if ( pow >= -T->
numind ) {
1620 weneedit = 0;
goto nextterm;
1626 else if ( pow < T->mm[i].mini || pow > T->
mm[i].
maxi ) {
1627 weneedit = 0;
goto nextterm;
1633 for ( i = numfirst+1; i < -T->
numind; i++ ) *pw++ = 0;
1637 if ( numsym < 0 ) pw = oldwork + 1;
1638 else pw = oldwork + ABS(T->
numind);
1639 i = FindTableTree(T,pw,1);
1649 if ( T->
reserved == 0 ) newreservation = 20;
1652 while ( T->
totind >= newreservation && newreservation < MAXTABLECOMBUF )
1653 newreservation = 2*newreservation;
1654 if ( newreservation > MAXTABLECOMBUF ) newreservation = MAXTABLECOMBUF;
1655 if ( T->
totind >= newreservation ) {
1656 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1657 AC.cbufnum = oldcbuf;
1658 AT.WorkPointer = oldwork;
1662 if ( T->
totind >= newreservation ) {
1663 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1664 AC.cbufnum = oldcbuf;
1665 AT.WorkPointer = oldwork;
1668 w = (WORD *)Malloc1(newreservation*
sizeof(WORD)*
1669 (ABS(T->
numind)+TABLEEXTENSION),
"tablepointers");
1670 for ( i = T->
reserved*(ABS(T->
numind)+TABLEEXTENSION)-1; i >= 0; i-- )
1676 if ( numsym < 0 ) pw = oldwork + 1;
1677 else pw = oldwork + numsym;
1678 for ( sum = T->
totind*(ABS(T->
numind)+TABLEEXTENSION), i = 0; i < ABS(T->
numind); i++ ) {
1684#if ( TABLEEXTENSION != 2 )
1686 sum *= TABLEEXTENSION;
1694#if ( TABLEEXTENSION == 2 )
1703newentry:
if ( *m == HAAKJE ) { m += m[1] - 1; }
1705 *m = *term - (m-term);
1711 AddNtoC(AC.cbufnum,1,&zero,6);
1712 numcommu = numcommute(C->
rhs[curelement],&(C->
NumTerms[curelement]));
1713 C->
CanCommu[curelement] = numcommu;
1717 SetScratch(fi,&(oldposition));
1720 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(oldposition));
1723 AC.cbufnum = oldcbuf;
1724 AC.tablefilling = 0;
1725 AT.WorkPointer = oldwork;
1729 AC.cbufnum = oldcbuf;
1730 AC.tablefilling = 0;
1731 AT.WorkPointer = oldwork;
1747int CoPrintTable(UBYTE *inp)
1750 int fflag = 0, sflag = 0, addflag = 0, error = 0, sum, i, j;
1751 UBYTE *filename, *p, c, buffer[100], *s, *oldoutputline = AO.OutputLine;
1752 WORD type, funnum, *expr, *m, num;
1754 WORD oldSkip = AO.OutSkip, oldMode = AC.OutputMode, oldHandle = AC.LogHandle;
1755 WORD oldType = AO.PrintType, *oldwork = AT.WorkPointer;
1756 UBYTE *oldFill = AO.OutFill, *oldLine = AO.OutputLine;
1758 if ( PF.me != MASTER )
return 0;
1763 while ( *inp ==
'+' ) {
1765 if ( *inp ==
'f' || *inp ==
'F' ) { fflag = 1; inp++; }
1766 else if ( *inp ==
's' || *inp ==
'S' ) { sflag = PRINTONETERM; inp++; }
1768 MesPrint(
"&Illegal + option in PrintTable statement");
1771 while ( *inp !=
',' && *inp && *inp !=
'+' ) {
1774 MesPrint(
"&Illegal + option in PrintTable statement");
1778 MesPrint(
"&Unfinished PrintTable statement");
1785 if ( *inp ==
',' ) inp++;
1790 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1792 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1793 || ( T = functions[funnum].tabl ) == 0 ) {
1794 MesPrint(
"&%s should be a previously declared table",inp);
1804 if ( *p ==
'>' ) { addflag = 1; p++; }
1810 if ( addflag ) AC.LogHandle = OpenAddFile((
char *)filename);
1811 else AC.LogHandle = CreateFile((
char *)filename);
1812 if ( AC.LogHandle < 0 ) {
1813 MesPrint(
"&Cannot open file '%s' properly",filename);
1814 error = 1;
goto finally;
1816 AO.PrintType = PRINTLFILE;
1818 else if ( fflag && AC.LogHandle >= 0 ) {
1819 AO.PrintType = PRINTLFILE;
1821 AO.OutFill = AO.OutputLine = (UBYTE *)AT.WorkPointer;
1822 AT.WorkPointer += 2*AC.LineLength;
1824 AO.PrintType |= sflag;
1830 if ( AC.LogHandle == oldHandle ) FiniLine();
1831 AO.OutputLine = AO.OutFill = (UBYTE *)Malloc1(AC.LineLength+20,
"PrintTable");
1832 AO.OutStop = AO.OutFill + AC.LineLength;
1833 for ( i = 0; i < T->
totind; i++ ) {
1835 TokenToLine((UBYTE *)
"Fill ");
1836 TokenToLine((UBYTE *)(VARNAME(functions,funnum)));
1837 TokenToLine((UBYTE *)
"(");
1840 sum = i * ( T->
numind + TABLEEXTENSION );
1841 for ( j = 0; j < T->
numind; j++, sum++ ) {
1842 if ( j > 0 ) TokenToLine((UBYTE *)
",");
1844 s = buffer; s = NumCopy(num,s);
1845 TokenToLine(buffer);
1850 for ( j = 0; j < T->
numind; j++ ) {
1852 TokenToLine((UBYTE *)
",");
1858 s = buffer; s = NumCopy(num,s);
1859 TokenToLine(buffer);
1863 TOKENTOLINE(
") =",
")=");
1866 if ( AC.OutputSpaces != NOSPACEFORMAT ) TokenToLine((UBYTE *)
" ");
1884 while ( *m ) m += *m;
1886 if ( WriteExpression(expr,(LONG)(m-expr)) ) { error = 1;
goto finally; }
1890 TokenToLine((UBYTE *)
"0");
1892 TokenToLine((UBYTE *)
";");
1895 M_free(AO.OutputLine,
"PrintTable");
1896 AO.OutputLine = AO.OutFill = oldoutputline;
1901 AO.OutSkip = oldSkip;
1902 AC.OutputMode = oldMode;
1903 AC.LogHandle = oldHandle;
1904 AO.PrintType = oldType;
1905 AO.OutFill = oldFill;
1906 AO.OutputLine = oldLine;
1907 AT.WorkPointer = oldwork;
1920static WORD AssignLHS[14] = { TYPEASSIGN, 3+SUBEXPSIZE, 0,
1921 SUBEXPRESSION, SUBEXPSIZE, 0, 1, 0, 0,0,0,0,0 };
1923int CoAssign(UBYTE *inp)
1925 int error = 0, retcode;
1928 if ( *inp !=
'$' ) {
1929nolhs: MesPrint(
"&assign statement should have a dollar variable in the LHS");
1933 if ( FG.cTable[*inp] != 0 )
goto nolhs;
1934 while ( FG.cTable[*inp] < 2 ) inp++;
1935 if ( AP.PreAssignFlag == 2 ) {
1936 if ( *inp ==
'_' ) inp++;
1938 if ( ( *inp ==
',' && inp[1] !=
'=' ) && ( *inp !=
'=' ) ) {
1939 MesPrint(
"&assign statement should have only a dollar variable in the LHS");
1944 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
1945 number = AddDollar(name,DOLUNDEFINED,0,0);
1948 if ( c ==
',' ) inp++;
1950 if ( *inp ==
',' ) inp++;
1954 AssignLHS[7] = AC.cbufnum;
1955 retcode = CompileAlgebra(inp,RHSIDE,(AssignLHS+3));
1956 if ( retcode < 0 ) error = 1;
1961 AssignLHS[2] = number;
1962 AssignLHS[5] = retcode;
1963 AddNtoL(AssignLHS[1],AssignLHS);
1981int CoDeallocateTable(UBYTE *inp)
1985 WORD type, funnum, i;
1988 while ( *inp ==
',' ) inp++;
1989 if ( *inp == 0 )
break;
1990 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1992 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1993 || ( T = functions[funnum].tabl ) == 0 ) {
1994 MesPrint(
"&%s should be a previously declared table",inp);
1998 MesPrint(
"&%s should be a sparse table",inp);
UBYTE * SkipAName(UBYTE *s)
int SortWild(WORD *, WORD)
void AddPotModdollar(WORD)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
UBYTE * SkipField(UBYTE *, int)
void LowerSortLevel(void)
int FlushOut(POSITION *, FILEHANDLE *, int)
int PF_BroadcastExpr(EXPRESSIONS e, FILEHANDLE *file)