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, c3, *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 ) {
136 while ( Expressions[c3].replace >= 0 )
137 c3 = Expressions[c3].replace;
138 if ( Expressions[c3].status != DROPPEDEXPRESSION ) {
139 w = &(Expressions[c3].status);
140 if ( *w == LOCALEXPRESSION || *w == SKIPLEXPRESSION )
141 *w = DROPLEXPRESSION;
142 else if ( *w == GLOBALEXPRESSION || *w == SKIPGEXPRESSION )
143 *w = DROPGEXPRESSION;
144 else if ( *w == HIDDENLEXPRESSION )
145 *w = DROPHLEXPRESSION;
146 else if ( *w == HIDDENGEXPRESSION )
147 *w = DROPHGEXPRESSION;
149 AC.TransEname = Expressions[c3].name;
150 j = EntVar(CEXPRESSION,0,type,0,0,0);
151 Expressions[j].node = Expressions[c3].node;
152 Expressions[c3].replace = j;
156 MesPrint(
"&name of expression is also name of a variable");
158 j = EntVar(CEXPRESSION,inp,type,0,0,0);
168 j = EntVar(CEXPRESSION,inp,type,0,0,0);
172 OldWork = w = AT.WorkPointer;
173 *w++ = TYPEEXPRESSION;
178 *w++ = SUBEXPRESSION;
186 while ( *q ==
',' || *q ==
'(' ) {
189 MesPrint(
"&Illegal name for expression argument");
195 if ( GetVar(inp,&c1,&c2,ALLVARIABLES,WITHAUTO) < 0 ) c1 = -1;
198 *w++ = SYMTOSYM; *w++ = 4; *w++ = c2; *w++ = 0;
201 *w++ = INDTOIND; *w++ = 4;
202 *w++ = c2 + AM.OffsetIndex; *w++ = 0;
205 *w++ = VECTOVEC; *w++ = 4;
206 *w++ = c2 + AM.OffsetVector; *w++ = 0;
209 *w++ = FUNTOFUN; *w++ = 4; *w++ = c2 + FUNCTION; *w++ = 0;
212 MesPrint(
"&Illegal expression parameter: %s",inp);
218 if ( *q !=
')' || q+1 != p ) {
219 MesPrint(
"&Illegal use of arguments for expression");
222 AC.ProtoType[1] = w - AC.ProtoType;
224 else if ( c !=
'=' ) {
228 MesPrint(
"&Illegal LHS for expression definition");
235 SeekScratch(AR.outfile,&pos);
236 Expressions[j].counter = 1;
237 Expressions[j].onfile = pos;
238 Expressions[j].whichbuffer = 0;
240 Expressions[j].partodo = AC.inparallelflag;
242 OldWork[2] = w - OldWork - 3;
251 ClearWildcardNames();
252 osize = AC.ProtoType[1]; AC.ProtoType[1] = SUBEXPSIZE;
254 if ( ( i = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) {
255 AC.ProtoType[1] = osize;
258 else if ( error == 0 ) {
259 AC.ProtoType[1] = osize;
261 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0 ) {
263 MesPrint(
"!>Cannot create expression");
268 Expressions[j].sizeprototype = OldWork[2];
269 OldWork[2] = 4+SUBEXPSIZE;
270 OldWork[4] = SUBEXPSIZE;
272 OldWork[SUBEXPSIZE+3] = 1;
273 OldWork[SUBEXPSIZE+4] = 1;
274 OldWork[SUBEXPSIZE+5] = 3;
275 OldWork[SUBEXPSIZE+6] = 0;
276 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0
279 MesPrint(
"!>Cannot create expression");
283 AR.outfile->POfull = AR.outfile->POfill;
291 AT.WorkPointer = OldWork;
292 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
294 AC.ToBeInFactors = 0;
303 MesPrint(
"&Illegal name(s) for expression(s)");
307 if ( GetName(AC.exprnames,inp,&c2,NOAUTO) == NAMENOTFOUND ) {
308 MesPrint(
"&%s is not a valid expression",inp);
312 w = &(Expressions[c2].status);
313 if ( type == LOCALEXPRESSION ) {
315 case GLOBALEXPRESSION:
316 *w = LOCALEXPRESSION;
318 case SKIPGEXPRESSION:
319 *w = SKIPLEXPRESSION;
321 case DROPGEXPRESSION:
322 *w = DROPLEXPRESSION;
324 case HIDDENGEXPRESSION:
325 *w = HIDDENLEXPRESSION;
327 case HIDEGEXPRESSION:
328 *w = HIDELEXPRESSION;
330 case UNHIDEGEXPRESSION:
331 *w = UNHIDELEXPRESSION;
333 case INTOHIDEGEXPRESSION:
334 *w = INTOHIDELEXPRESSION;
336 case DROPHGEXPRESSION:
337 *w = DROPHLEXPRESSION;
341 else if ( type == GLOBALEXPRESSION ) {
343 case LOCALEXPRESSION:
344 *w = GLOBALEXPRESSION;
346 case SKIPLEXPRESSION:
347 *w = SKIPGEXPRESSION;
349 case DROPLEXPRESSION:
350 *w = DROPGEXPRESSION;
352 case HIDDENLEXPRESSION:
353 *w = HIDDENGEXPRESSION;
355 case HIDELEXPRESSION:
356 *w = HIDEGEXPRESSION;
358 case UNHIDELEXPRESSION:
359 *w = UNHIDEGEXPRESSION;
361 case INTOHIDELEXPRESSION:
362 *w = INTOHIDEGEXPRESSION;
364 case DROPHLEXPRESSION:
365 *w = DROPHGEXPRESSION;
376 }
while ( c ==
',' );
378 MesPrint(
"&Illegal object in local or global redefinition");
390int CoIdOld(UBYTE *inp)
393 return(CoIdExpression(inp,TYPEIDOLD));
404 return(CoIdExpression(inp,TYPEIDNEW));
412int CoIdNew(UBYTE *inp)
415 return(CoIdExpression(inp,TYPEIDNEW));
423int CoDisorder(UBYTE *inp)
425 AC.idoption = SUBDISORDER;
426 return(CoIdExpression(inp,TYPEIDNEW));
434int CoMany(UBYTE *inp)
436 AC.idoption = SUBMANY;
437 return(CoIdExpression(inp,TYPEIDNEW));
445int CoMulti(UBYTE *inp)
447 AC.idoption = SUBMULTI;
448 return(CoIdExpression(inp,TYPEIDNEW));
456int CoIfMatch(UBYTE *inp)
458 AC.idoption = SUBAFTER;
459 return(CoIdExpression(inp,TYPEIDNEW));
467int CoIfNoMatch(UBYTE *inp)
469 AC.idoption = SUBAFTERNOT;
470 return(CoIdExpression(inp,TYPEIDNEW));
478int CoOnce(UBYTE *inp)
480 AC.idoption = SUBONCE;
481 return(CoIdExpression(inp,TYPEIDNEW));
489int CoOnly(UBYTE *inp)
491 AC.idoption = SUBONLY;
492 return(CoIdExpression(inp,TYPEIDNEW));
500int CoSelect(UBYTE *inp)
502 AC.idoption = SUBSELECT;
503 return(CoIdExpression(inp,TYPEIDNEW));
513int CoIdExpression(UBYTE *inp,
int type)
516 int i, j, idhead, error = 0, MinusSign = 0, opt, retcode;
517 WORD *w, *s, *m, *mm, *ww, *FirstWork, *OldWork, c1, numsets = 0,
518 oldnumrhs, *ow, oldEside;
520 CBUF *C = cbuf+AC.cbufnum;
522 FirstWork = OldWork = AT.WorkPointer;
533 *w++ = idhead + SUBEXPSIZE;
535 if ( idhead >= IDHEAD ) *w++ = -1;
537 for ( i = 4; i < idhead; i++ ) *w++ = 0;
539 while ( *inp ==
',' ) inp++;
541 if ( AC.idoption == SUBSELECT ) {
545 else if ( ( AC.idoption == SUBAFTER ) || ( AC.idoption == SUBAFTERNOT ) ) {
546 while ( *p && *p !=
'=' && *p !=
',' ) {
547 if ( *p ==
'(' ) SKIPBRA4(p)
548 else if ( *p ==
'{' ) SKIPBRA5(p)
549 else if ( *p ==
'[' ) SKIPBRA1(p)
552 if ( *p ==
'=' || *inp !=
'-' || inp[1] !=
'>' ) {
553 MesPrint(
"&Illegal use if if[no]match in id statement");
554 error = 1;
goto AllDone;
557 MesPrint(
"&id-statement without = sign");
558 error = 1;
goto AllDone;
564 while ( *p && *p !=
'=' && *p !=
',' ) {
565 if ( *p ==
'(' ) SKIPBRA4(p)
566 else if ( *p ==
'{' ) SKIPBRA5(p)
567 else if ( *p ==
'[' ) SKIPBRA1(p)
570 if ( *p ==
'=' )
break;
572 MesPrint(
"&id-statement without = sign");
573 error = 1;
goto AllDone;
579 while ( FG.cTable[*pp] == 0 ) pp++;
581 i =
sizeof(IdOptions)/
sizeof(
struct id_options);
583 if ( StrICmp(inp,IdOptions[i].name) == 0 )
break;
586 MesPrint(
"&Illegal option %s in id-statement",inp);
587 *pp = c; error = 1; p++; inp = p;
continue;
589 opt = IdOptions[i].code;
594 if ( pp != p )
goto IllField;
595 AC.idoption |= SUBDISORDER;
599 if ( p != pp )
goto IllField;
600 if ( ( AC.idoption & SUBMASK ) != 0 ) {
601 if ( AC.idoption == SUBMULTI && type == TYPEIF ) {}
603 MesPrint(
"&Conflicting options in id-statement");
614 while ( *p && *p !=
'=' && *p !=
',' ) {
615 if ( *p ==
'(' ) SKIPBRA4(p)
616 else if ( *p ==
'{' ) SKIPBRA5(p)
617 else if ( *p ==
'[' ) SKIPBRA1(p)
620 if ( *p ==
'=' )
break;
622 MesPrint(
"&id-statement without = sign");
623 error = 1;
goto AllDone;
629 if ( p[-1] !=
'}' ) {
631 MesPrint(
"&Illegal temporary set: %s",inp);
636 c = p[-1]; p[-1] = 0;
637 c1 = DoTempSet(inp,p-1);
641 if ( w[-1] < 0 ) error = 1;
646 if ( GetName(AC.varnames,inp,&c1,NOAUTO) != CSET ) {
647 MesPrint(
"&%s is not a set",inp);
651 if ( c1 < AM.NumFixedSets ) {
652 MesPrint(
"&Built in sets are not allowed in the select option");
655 else if ( Sets[c1].type == CRANGE ) {
656 MesPrint(
"&Ranged sets are not allowed in the select option");
670 for ( i = 0; i < idhead; i++ ) *w++ = FirstWork[i];
671 AC.idoption = SUBSELECT;
675 if ( type == TYPEIF ) {
676 MesPrint(
"&The if[no]match->label option is not allowed in an if statement");
677 error = 1;
goto AllDone;
679 if ( pp[0] !=
'-' || pp[1] !=
'>' )
goto IllField;
684 while ( FG.cTable[*pp] <= 1 ) pp++;
687 MesPrint(
"&Illegal label %s in if[no]match option of id-statement",inp);
688 *p = c; error = 1; inp = p+1;
continue;
691 OldWork[3] = GetLabel(inp);
697 if ( FG.cTable[*inp] == 1 ) {
698 while ( *inp >=
'0' && *inp <=
'9' ) x = 10*x+*inp++ -
'0';
702 while ( FG.cTable[*inp] == 0 ) inp++;
704 if ( StrICont(pp,(UBYTE *)
"normalize") != 0 )
goto IllOpt;
706 OldWork[4] |= NORMALIZEFLAG;
708 if ( *inp !=
')' || inp+1 != p ) {
711 MesPrint(
"&Illegal ALL option in id-statement: ",pp);
722 if ( x > MAXPOSITIVE ) {
723 MesPrint(
"&Requested maximum number of matches %l in ALL option in id-statement is greater than %l ",x,MAXPOSITIVE);
727 if ( type != TYPEIDNEW ) {
728 if ( type == TYPEIDOLD ) {
729 MesPrint(
"&Requested ALL option not allowed in idold/also statement.");
732 else if ( type == TYPEIF ) {
733 MesPrint(
"&Requested ALL option not allowed in if(match())");
737 MesPrint(
"&ALL option only allowed in regular id-statement.");
746IllField: c = *p; *p = 0;
747 MesPrint(
"&Illegal optionfield %s in id-statement",inp);
748 *p = c; error = 1; inp = p+1;
continue;
750 i = AC.idoption & SUBMASK;
751 if ( i && i != opt ) {
752 MesPrint(
"&Conflicting options in id-statement");
755 else AC.idoption |= opt;
756 while ( *p ==
',' ) p++;
761 if ( ( AC.idoption & SUBMASK ) == 0 ) AC.idoption |= SUBMULTI;
762 OldWork[2] = AC.idoption;
768 *w++ = SUBEXPRESSION;
776 AT.WorkPointer = s = w + 4*AM.MaxWildcards + 8;
780 ClearWildcardNames();
784 oldnumrhs = C->numrhs;
785 if ( ( retcode = CompileAlgebra(inp,LHSIDE,AC.ProtoType) ) < 0 ) { error = 1; }
786 else AC.ProtoType[2] = retcode;
789 if ( AC.NwildC &&
SortWild(w,AC.NwildC) ) error = 1;
793 OldWork[1] = AC.WildC-OldWork;
794 OldWork[idhead+1] = OldWork[1] - idhead;
797 s = C->
rhs[C->numrhs];
803 tw = AC.ProtoType; twstop = tw + tw[1]; tw += SUBEXPSIZE;
804 while ( tw < twstop ) {
805 if ( *tw == LOADDOLLAR ) {
819 if ( !error && *s == 0 ) {
820IllLeft:MesPrint(
"&Illegal LHS");
824 if ( !error && *(s+*s) != 0 ) {
825 MesPrint(
"&LHS should be one term only");
829 WORD oldpolyfun = AR.PolyFun;
831 if ( !error ) error = 1;
834 AN.RepPoint = AT.RepCount + 1;
835 ow = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
836 mm = s; ww = ow; i = *mm;
837 while ( --i >= 0 ) {*ww++ = *mm++;} AT.WorkPointer = ww;
838 AC.lhdollarflag = 0; oldEside = AR.Eside; AR.Eside = LHSIDE;
839 AR.Cnumlhs = C->numlhs;
848 AR.PolyFun = oldpolyfun;
849 if ( *w == 0 || *(w+*w) != 0 ) {
850 MesPrint(
"&LHS must be one term");
855 if ( AC.lhdollarflag ) MarkDirty(w,DIRTYFLAG);
857 AT.WorkPointer = w + *w;
866 C->numrhs = oldnumrhs;
870 AC.vectorlikeLHS = 0;
872 if ( m[2] != 3 || m[1] != 1 || *m != 1 ) {
873 if ( *m == 1 && m[1] == 1 && m[2] == -3 ) {
877 MesPrint(
"&Coefficient in LHS");
883 if ( *w == 7 && w[1] == INDEX && w[3] < 0 ) {
884 if ( ( AC.idoption & SUBMASK ) != 0 && ( AC.idoption & SUBMASK ) !=
886 MesPrint(
"&Illegal option for substitution of a vector");
889 AC.DumNum = AM.IndDum;
890 OldWork[2] = ( OldWork[2] - ( OldWork[2] & SUBMASK ) ) | SUBVECTOR;
895 *w++ = AC.DumNum + WILDOFFSET;
901 w[4] = AC.DumNum + WILDOFFSET;
902 OldWork[idhead+1] = w - OldWork - idhead;
903 AC.vectorlikeLHS = 1;
908 i = OldWork[2] & SUBMASK;
910 if ( i == 0 || i == SUBMULTI ) {
913 if ( *s == SYMBOL ) {
916 if ( ABS(s[1]) > 2*MAXPOWER ) {
917 OldWork[2] = ( OldWork[2] - i ) | SUBONCE;
924 else if ( *s == DOTPRODUCT ) {
927 if ( ABS(s[2]) > 2*MAXPOWER ) {
928 OldWork[2] = ( OldWork[2] - i ) | SUBONCE;
931 else if ( s[1] >= -(2*WILDOFFSET) || s[0] >= -(2*WILDOFFSET) ) {
932 OldWork[2] = ( OldWork[2] - i ) | SUBMANY;
940 OldWork[2] = ( OldWork[2] - i ) | SUBMANY;
945 if ( ( OldWork[2] & SUBMASK ) == 0 ) OldWork[2] |= SUBMULTI;
947 if ( ( OldWork[2] & SUBMASK ) == SUBSELECT ) {
957 s = FirstWork + idhead;
958 while ( --numsets >= 0 ) *m++ = *s++;
974 OldWork[1] = m - OldWork;
975 AC.ProtoType = OldWork+idhead;
977 if ( StudyPattern(OldWork) ) error = 1;
979 AT.WorkPointer = OldWork + OldWork[1];
980 if ( AC.lhdollarflag ) OldWork[4] |= DOLLARFLAG;
985 if ( type == TYPEIDOLD ) {
988 if ( C->
lhs[ci][0] == TYPEIDNEW ) {
989 if ( (C->
lhs[ci][2] & SUBMASK) == SUBALL ) {
990 MesPrint(
"&Idold/also cannot follow an id,all statement.");
995 else if ( C->
lhs[ci][0] == TYPEDETCURDUM ) { ci--;
continue; }
996 else if ( C->
lhs[ci][0] == TYPEIDOLD ) { ci--;
continue; }
1000 MesPrint(
"&Idold/also should follow an id/idnew statement.");
1007 if ( type != TYPEIF ) {
1008 if ( ( retcode = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) error = 1;
1010 AC.ProtoType[2] = retcode;
1013 w = C->
rhs[retcode];
1014 while ( *w ) { w += *w; w[-1] = -w[-1]; }
1016 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
1022 if ( !error ) {
AddNtoL(OldWork[1],OldWork); }
1024 AC.lhdollarflag = 0;
1025 AT.WorkPointer = FirstWork;
1034static WORD mularray[13] = { TYPEMULT, SUBEXPSIZE+3, 0, SUBEXPRESSION,
1035 SUBEXPSIZE, 0, 1, 0, 0, 0, 0, 0, 0 };
1037int CoMultiply(UBYTE *inp)
1040 int error = 0, RetCode;
1042 while ( *inp ==
',' ) inp++;
1047 if ( StrICont(inp,(UBYTE *)
"left") == 0 ) mularray[2] = 1;
1048 else if ( StrICont(inp,(UBYTE *)
"right") == 0 ) mularray[2] = 0;
1050 MesPrint(
"&Illegal option in multiply statement or ; forgotten.");
1056 ClearWildcardNames();
1057 while ( *inp ==
',' ) inp++;
1058 AC.ProtoType = mularray+3;
1059 mularray[7] = AC.cbufnum;
1060 if ( ( RetCode = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) error = 1;
1062 mularray[5] = RetCode;
1063 AddNtoL(SUBEXPSIZE+3,mularray);
1064 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
1076int CoFill(UBYTE *inp)
1079 WORD error = 0, x, xx, funnum, type, *oldwp = AT.WorkPointer;
1080 int i, oldcbufnum = AC.cbufnum, nofill = 0, numover, redef = 0;
1081 WORD *w, *wold, *Tprototype;
1082 UBYTE *p = inp, c, *inp1;
1084 LONG newreservation, sum = 0;
1085 UBYTE *p1, *p2, *p3, *p4, *fake = 0;
1087 if ( AC.exprfillwarning == 1 ) AC.exprfillwarning = 0;
1092 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1095 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,WITHAUTO) == NAMENOTFOUND )
1096 || ( T = functions[funnum].tabl ) == 0 || ( T->
numind > 0 && c !=
'(' ) ) {
1097 MesPrint(
"&%s should be a table with argument(s)",inp);
1106 MesPrint(
"&%s should be a table without arguments",inp);
1118 ParseSignedNumber(xx,p);
1119 if ( FG.cTable[p[-1]] != 1 || *p !=
',' || xx < 1 || ( xx > ( -T->
numind - 1 ) ) ) {
1120 MesPrint(
"&No valid number of table indices in *-table fill statement.");
1127 for ( sum = 0, i = 0; i < xx; i++ ) {
1128 ParseSignedNumber(x,p);
1129 if ( FG.cTable[p[-1]] != 1 || ( *p !=
',' && *p !=
')' ) ) {
1130 MesPrint(
"&Table arguments in fill statement should be numbers");
1133 if ( T->
sparse ) *w++ = x;
1134 else if ( x < T->mm[i].mini || x > T->
mm[i].
maxi ) {
1135 MesPrint(
"&Value %d for argument %d of table out of bounds",x,i+1);
1136 error = 1; nofill = 1;
1139 if ( *p ==
')' )
break;
1144 for ( ; i < ABS(T->
numind)-1; i++ ) *w++ = 0;
1147 if ( *p !=
')' || i < ( xx - 1 ) ) {
1148 MesPrint(
"&Incorrect number of table arguments in fill statement. Should be %d"
1150 error = 1; nofill = 1;
1153 if ( T->
sparse == 0 ) sum *= TABLEEXTENSION;
1157 i = FindTableTree(T,oldwp,1);
1159 sum = i + ABS(T->
numind);
1160 if ( tablestub == 0 && ( ( T->
sparse & 2 ) == 2 ) && ( T->
mode != 0 )
1161 && ( AC.vetotablebasefill == 0 ) ) {
1165 functions[funnum].tabl = T = T->
spare;
1173 if ( T->
reserved == 0 ) newreservation = 20;
1175 while ( T->
totind >= newreservation && newreservation < MAXTABLECOMBUF )
1176 newreservation = 2*newreservation;
1177 if ( newreservation > MAXTABLECOMBUF ) newreservation = MAXTABLECOMBUF;
1178 if ( T->
totind >= newreservation ) {
1179 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1180 AC.cbufnum = oldcbufnum;
1183 wold = (WORD *)Malloc1(newreservation*
sizeof(WORD)*
1184 (ABS(T->
numind)+TABLEEXTENSION),
"tablepointers");
1185 for ( i = T->
reserved*(ABS(T->
numind)+TABLEEXTENSION)-1; i >= 0; i-- )
1192 for ( sum = T->
totind*(ABS(T->
numind)+TABLEEXTENSION), i = 0; i < ABS(T->
numind); i++ ) {
1196#if TABLEEXTENSION == 2
1209 if ( AC.vetofilling ) nofill = 1;
1211 Warning(
"Table element was already defined. New definition will be used");
1214#if TABLEEXTENSION == 2
1224 if ( T->
numind ) { p++; }
1226 MesPrint(
"&Fill statement misses = sign after the table element");
1227 AC.cbufnum = oldcbufnum;
1228 AT.WorkPointer = oldwp;
1229 functions[funnum].tabl = oldT;
1232 if ( tablestub == 0 && T->
mode == 1 && AC.vetotablebasefill == 0 ) {
1240 numfake = (p4-T->
argtail)+(p3-p1)+10;
1242 fake = (UBYTE *)Malloc1(numfake*
sizeof(UBYTE),
"Fill fake rhs");
1244 *p++ =
't'; *p++ =
'b'; *p++ =
'l'; *p++ =
'_'; *p++ =
'(';
1245 p4 = p1;
while ( p4 < p2 ) *p++ = *p4++; *p++ =
',';
1246 p4 = p2+1;
while ( p4 < p3 ) *p++ = *p4++;
1249 while ( FG.cTable[*p4] == 1 ) p4++;
1251 if ( *p4 ==
'?' && p[-1] !=
',' ) {
1253 if ( FG.cTable[*p4] == 0 || *p4 ==
'$' || *p4 ==
'[' ) {
1259 else if ( *p4 ==
'{' ) {
1262 else if ( *p4 ) { *p++ = *p4++;
continue; }
1279 AC.tablefilling = funnum;
1288 if ( ( i = CompileAlgebra(inp1,RHSIDE,Tprototype) ) < 0 ) { error = 1; i = 0; }
1295 if ( T->
sparse || c == 0 )
break;
1297#if ( TABLEEXTENSION == 2 )
1303#if ( TABLEEXTENSION == 2 )
1306 sum += TABLEEXTENSION-2;
1309 if ( AC.exprfillwarning == 1 ) {
1310 AC.exprfillwarning = 2;
1311 Warning(
"Use of expressions and/or $variables in Fill statements is potentially very dangerous.");
1313 AC.tablefilling = 0;
1314 if ( T->
sparse && c != 0 ) {
1315 MesPrint(
"&In sparse tables one can fill only one element at a time");
1318 else if ( numover ) {
1320 Warning(
"one element was overwritten. New definition will be used");
1321 else if ( AC.WarnFlag )
1322 MesPrint(
"&Warning: %d elements were overwritten. New definitions will be used",numover);
1325 if ( redef == 0 ) T->
totind++;
1333 M_free(fake,
"Fill fake rhs");
1335 functions[funnum].tabl = T = T->
spare;
1339 AC.cbufnum = oldcbufnum;
1340 AC.SymChangeFlag = 1;
1341 AT.WorkPointer = oldwp;
1342 functions[funnum].tabl = oldT;
1362int CoFillExpression(UBYTE *inp)
1366 WORD type, funnum, expnum, symnum, numsym = 0, *oldwork = AT.WorkPointer;
1367 WORD *brackets, *term, brasize, *b, *m, *w, *pw, *tstop, zero = 0;
1368 WORD oldcbuf = AC.cbufnum, curelement = 0;
1369 int weneedit, i, j, numzero, pow, numfirst;
1371 LONG newreservation, numcommu, sum;
1377 AN.IndDum = AM.IndDum;
1378 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1380 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1381 || ( T = functions[funnum].tabl ) == 0 ) {
1382 MesPrint(
"&%s should be a previously declared table",inp);
1389 MesPrint(
"&No = sign in FillExpression statement");
1393 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1395 if ( ( type = GetName(AC.exprnames,inp,&expnum,NOAUTO) ) == NAMENOTFOUND
1397 Expressions[expnum].status != LOCALEXPRESSION &&
1398 Expressions[expnum].status != SKIPLEXPRESSION &&
1399 Expressions[expnum].status != DROPLEXPRESSION &&
1400 Expressions[expnum].status != GLOBALEXPRESSION &&
1401 Expressions[expnum].status != SKIPGEXPRESSION &&
1402 Expressions[expnum].status != DROPGEXPRESSION ) ) {
1403 MesPrint(
"&%s should be an active expression with arguments",inp);
1406 if ( Expressions[expnum].inmem ) {
1407 MesPrint(
"&%s cannot be used in a FillExpression statement in the same %n\
1408 module that it has been redefined",inp);
1414 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1417 if ( GetVar(inp,&type,&symnum,-1,NOAUTO) == NAMENOTFOUND ) {
1418 MesPrint(
"&%s should be a previously declared symbol or function",inp);
1421 else if ( type == CSYMBOL ) {
1423 *AT.WorkPointer++ = symnum;
1426 else if ( type == CFUNCTION ) {
1430 MesPrint(
"&Argument should be a single function or a list of symbols");
1434 *AT.WorkPointer++ = symnum;
1437 MesPrint(
"&%s should be a previously declared symbol or function",inp);
1440 if ( c ==
')' )
break;
1442 MesPrint(
"&Illegal separator in FillExpression statement");
1447 MesPrint(
"&Illegal end of FillExpression statement");
1457 if ( ( numsym > 0 ) && ( ABS(T->
numind) != numsym ) ) {
1458 MesPrint(
"&This table needs %d symbols for its array indices");
1468 if ( PF.me == MASTER ) {
1473 SetEndScratch(AR.infile, &pos);
1478 PUTZERO(oldposition);
1479 SeekFile(fi->
handle,&oldposition,SEEK_CUR);
1480 SetScratch(fi,&(Expressions[expnum].onfile));
1481 if ( ISNEGPOS(Expressions[expnum].onfile) ) {
1483 MesPrint(
"!>File error in FillExpression");
1494 SETBASEPOSITION(oldposition,(UBYTE *)(fi->POfill)-(UBYTE *)(fi->PObuffer));
1495 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(Expressions[expnum].onfile));
1497 pw = AT.WorkPointer;
1498 if ( numsym < 0 ) { brackets = pw + 1; }
1499 else { brackets = pw + numsym; }
1500 brasize = -1; weneedit = 0;
1501 term = (WORD *)(((UBYTE *)(brackets)) + AM.MaxTer);
1502 AT.WorkPointer = (WORD *)(((UBYTE *)(term)) + AM.MaxTer);
1504 AC.tablefilling = funnum;
1505 if ( GetTerm(BHEAD term) > 0 ) {
1506 while ( GetTerm(BHEAD term) > 0 ) {
1507 GETSTOP(term,tstop);
1509 while ( m < tstop && *m != HAAKJE ) m += m[1];
1510 if ( *m != HAAKJE ) {
1511 MesPrint(
"&Illegal attempt to put an expression without brackets in a table");
1515 if ( brasize == m - w ) {
1517 while ( *b == *w && w < m ) { b++; w++; }
1521 *m = *term - (m-term);
1523 numdummies = DetCurDum(BHEAD term) - AM.IndDum;
1524 if ( numdummies > T->numdummies ) T->numdummies = numdummies;
1530 AddNtoC(AC.cbufnum,1,&zero,4);
1531 numcommu = numcommute(C->
rhs[curelement],&(C->
NumTerms[curelement]));
1532 C->
CanCommu[curelement] = numcommu;
1534 b = brackets; w = term + 1;
1535 if ( numsym < 0 ) pw = oldwork + 1;
1536 else pw = oldwork + numsym;
1537 while ( w < m ) *b++ = *w++;
1538 brasize = b - brackets;
1544 if ( *brackets != symnum || brasize != brackets[1] ) {
1545 weneedit = 0;
continue;
1550 b = brackets + FUNHEAD;
1551 bb = brackets+brackets[1];
1555 if ( bnum > -T->
numind ) {
1556 weneedit = 0;
continue;
1561 if ( *b != -SNUMBER )
break;
1565 if ( b < bb || i != bnum ) {
1566 weneedit = 0;
continue;
1569 else if ( brasize > 0 && ( *brackets != SYMBOL
1570 || brackets[1] < brasize || (brackets[1]-2) > numsym*2 ) ) {
1571 weneedit = 0;
continue;
1573 numzero = 0; sum = 0;
1576 for ( i = 0; i < numsym; i++ ) {
1577 if ( brasize > 0 ) {
1578 b = brackets + 2; j = brackets[1]-2;
1580 if ( *b == oldwork[i] )
break;
1585 if ( 2*numzero+brackets[1]-2 > numsym*2 ) {
1586 weneedit = 0;
goto nextterm;
1596 if ( pow > -T->
numind ) {
1597 weneedit = 0;
goto nextterm;
1600 else if ( i > pow ) {
1601 weneedit = 0;
goto nextterm;
1606 else if ( pow < T->mm[i].mini || pow > T->
mm[i].
maxi ) {
1607 weneedit = 0;
goto nextterm;
1614 b = brackets + FUNHEAD;
1620 xx = (brackets[1]-FUNHEAD)/2;
1621 for ( i = 0; i < xx; i++ ) {
1628 if ( pow >= -T->
numind ) {
1629 weneedit = 0;
goto nextterm;
1635 else if ( pow < T->mm[i].mini || pow > T->
mm[i].
maxi ) {
1636 weneedit = 0;
goto nextterm;
1642 for ( i = numfirst+1; i < -T->
numind; i++ ) *pw++ = 0;
1646 if ( numsym < 0 ) pw = oldwork + 1;
1647 else pw = oldwork + ABS(T->
numind);
1648 i = FindTableTree(T,pw,1);
1658 if ( T->
reserved == 0 ) newreservation = 20;
1661 while ( T->
totind >= newreservation && newreservation < MAXTABLECOMBUF )
1662 newreservation = 2*newreservation;
1663 if ( newreservation > MAXTABLECOMBUF ) newreservation = MAXTABLECOMBUF;
1664 if ( T->
totind >= newreservation ) {
1665 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1666 AC.cbufnum = oldcbuf;
1667 AT.WorkPointer = oldwork;
1671 if ( T->
totind >= newreservation ) {
1672 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1673 AC.cbufnum = oldcbuf;
1674 AT.WorkPointer = oldwork;
1677 w = (WORD *)Malloc1(newreservation*
sizeof(WORD)*
1678 (ABS(T->
numind)+TABLEEXTENSION),
"tablepointers");
1679 for ( i = T->
reserved*(ABS(T->
numind)+TABLEEXTENSION)-1; i >= 0; i-- )
1685 if ( numsym < 0 ) pw = oldwork + 1;
1686 else pw = oldwork + numsym;
1687 for ( sum = T->
totind*(ABS(T->
numind)+TABLEEXTENSION), i = 0; i < ABS(T->
numind); i++ ) {
1693#if ( TABLEEXTENSION != 2 )
1695 sum *= TABLEEXTENSION;
1703#if ( TABLEEXTENSION == 2 )
1712newentry:
if ( *m == HAAKJE ) { m += m[1] - 1; }
1714 *m = *term - (m-term);
1720 AddNtoC(AC.cbufnum,1,&zero,6);
1721 numcommu = numcommute(C->
rhs[curelement],&(C->
NumTerms[curelement]));
1722 C->
CanCommu[curelement] = numcommu;
1726 SetScratch(fi,&(oldposition));
1729 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(oldposition));
1732 AC.cbufnum = oldcbuf;
1733 AC.tablefilling = 0;
1734 AT.WorkPointer = oldwork;
1738 AC.cbufnum = oldcbuf;
1739 AC.tablefilling = 0;
1740 AT.WorkPointer = oldwork;
1756int CoPrintTable(UBYTE *inp)
1759 int fflag = 0, sflag = 0, addflag = 0, error = 0, sum, i, j;
1760 UBYTE *filename, *p, c, buffer[100], *s, *oldoutputline = AO.OutputLine;
1761 WORD type, funnum, *expr, *m, num;
1763 WORD oldSkip = AO.OutSkip, oldMode = AC.OutputMode, oldHandle = AC.LogHandle;
1764 WORD oldType = AO.PrintType, *oldwork = AT.WorkPointer;
1765 UBYTE *oldFill = AO.OutFill, *oldLine = AO.OutputLine;
1767 if ( PF.me != MASTER )
return 0;
1772 while ( *inp ==
'+' ) {
1774 if ( *inp ==
'f' || *inp ==
'F' ) { fflag = 1; inp++; }
1775 else if ( *inp ==
's' || *inp ==
'S' ) { sflag = PRINTONETERM; inp++; }
1777 MesPrint(
"&Illegal + option in PrintTable statement");
1780 while ( *inp !=
',' && *inp && *inp !=
'+' ) {
1783 MesPrint(
"&Illegal + option in PrintTable statement");
1787 MesPrint(
"&Unfinished PrintTable statement");
1794 if ( *inp ==
',' ) inp++;
1799 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1801 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1802 || ( T = functions[funnum].tabl ) == 0 ) {
1803 MesPrint(
"&%s should be a previously declared table",inp);
1813 if ( *p ==
'>' ) { addflag = 1; p++; }
1819 if ( addflag ) AC.LogHandle = OpenAddFile((
char *)filename);
1820 else AC.LogHandle = CreateFile((
char *)filename);
1821 if ( AC.LogHandle < 0 ) {
1822 MesPrint(
"&Cannot open file '%s' properly",filename);
1823 error = 1;
goto finally;
1825 AO.PrintType = PRINTLFILE;
1827 else if ( fflag && AC.LogHandle >= 0 ) {
1828 AO.PrintType = PRINTLFILE;
1830 AO.OutFill = AO.OutputLine = (UBYTE *)AT.WorkPointer;
1831 AT.WorkPointer += 2*AC.LineLength;
1833 AO.PrintType |= sflag;
1839 if ( AC.LogHandle == oldHandle ) FiniLine();
1840 AO.OutputLine = AO.OutFill = (UBYTE *)Malloc1(AC.LineLength+20,
"PrintTable");
1841 AO.OutStop = AO.OutFill + AC.LineLength;
1842 for ( i = 0; i < T->
totind; i++ ) {
1844 TokenToLine((UBYTE *)
"Fill ");
1845 TokenToLine((UBYTE *)(VARNAME(functions,funnum)));
1846 TokenToLine((UBYTE *)
"(");
1849 sum = i * ( T->
numind + TABLEEXTENSION );
1850 for ( j = 0; j < T->
numind; j++, sum++ ) {
1851 if ( j > 0 ) TokenToLine((UBYTE *)
",");
1853 s = buffer; s = NumCopy(num,s);
1854 TokenToLine(buffer);
1859 for ( j = 0; j < T->
numind; j++ ) {
1861 TokenToLine((UBYTE *)
",");
1867 s = buffer; s = NumCopy(num,s);
1868 TokenToLine(buffer);
1872 TOKENTOLINE(
") =",
")=");
1875 if ( AC.OutputSpaces != NOSPACEFORMAT ) TokenToLine((UBYTE *)
" ");
1893 while ( *m ) m += *m;
1895 if ( WriteExpression(expr,(LONG)(m-expr)) ) { error = 1;
goto finally; }
1899 TokenToLine((UBYTE *)
"0");
1901 TokenToLine((UBYTE *)
";");
1904 M_free(AO.OutputLine,
"PrintTable");
1905 AO.OutputLine = AO.OutFill = oldoutputline;
1910 AO.OutSkip = oldSkip;
1911 AC.OutputMode = oldMode;
1912 AC.LogHandle = oldHandle;
1913 AO.PrintType = oldType;
1914 AO.OutFill = oldFill;
1915 AO.OutputLine = oldLine;
1916 AT.WorkPointer = oldwork;
1929static WORD AssignLHS[14] = { TYPEASSIGN, 3+SUBEXPSIZE, 0,
1930 SUBEXPRESSION, SUBEXPSIZE, 0, 1, 0, 0,0,0,0,0 };
1932int CoAssign(UBYTE *inp)
1934 int error = 0, retcode;
1937 if ( *inp !=
'$' ) {
1938nolhs: MesPrint(
"&assign statement should have a dollar variable in the LHS");
1942 if ( FG.cTable[*inp] != 0 )
goto nolhs;
1943 while ( FG.cTable[*inp] < 2 ) inp++;
1944 if ( AP.PreAssignFlag == 2 ) {
1945 if ( *inp ==
'_' ) inp++;
1947 if ( ( *inp ==
',' && inp[1] !=
'=' ) && ( *inp !=
'=' ) ) {
1948 MesPrint(
"&assign statement should have only a dollar variable in the LHS");
1953 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
1954 number = AddDollar(name,DOLUNDEFINED,0,0);
1957 if ( c ==
',' ) inp++;
1959 if ( *inp ==
',' ) inp++;
1963 AssignLHS[7] = AC.cbufnum;
1964 retcode = CompileAlgebra(inp,RHSIDE,(AssignLHS+3));
1965 if ( retcode < 0 ) error = 1;
1970 AssignLHS[2] = number;
1971 AssignLHS[5] = retcode;
1972 AddNtoL(AssignLHS[1],AssignLHS);
1990int CoDeallocateTable(UBYTE *inp)
1994 WORD type, funnum, i;
1997 while ( *inp ==
',' ) inp++;
1998 if ( *inp == 0 )
break;
1999 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
2001 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
2002 || ( T = functions[funnum].tabl ) == 0 ) {
2003 MesPrint(
"&%s should be a previously declared table",inp);
2007 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)