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 ) {
260 MesPrint(
"!>Cannot create expression");
265 Expressions[j].sizeprototype = OldWork[2];
266 OldWork[2] = 4+SUBEXPSIZE;
267 OldWork[4] = SUBEXPSIZE;
269 OldWork[SUBEXPSIZE+3] = 1;
270 OldWork[SUBEXPSIZE+4] = 1;
271 OldWork[SUBEXPSIZE+5] = 3;
272 OldWork[SUBEXPSIZE+6] = 0;
273 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0
276 MesPrint(
"!>Cannot create expression");
280 AR.outfile->POfull = AR.outfile->POfill;
288 AT.WorkPointer = OldWork;
289 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
291 AC.ToBeInFactors = 0;
300 MesPrint(
"&Illegal name(s) for expression(s)");
304 if ( GetName(AC.exprnames,inp,&c2,NOAUTO) == NAMENOTFOUND ) {
305 MesPrint(
"&%s is not a valid expression",inp);
309 w = &(Expressions[c2].status);
310 if ( type == LOCALEXPRESSION ) {
312 case GLOBALEXPRESSION:
313 *w = LOCALEXPRESSION;
315 case SKIPGEXPRESSION:
316 *w = SKIPLEXPRESSION;
318 case DROPGEXPRESSION:
319 *w = DROPLEXPRESSION;
321 case HIDDENGEXPRESSION:
322 *w = HIDDENLEXPRESSION;
324 case HIDEGEXPRESSION:
325 *w = HIDELEXPRESSION;
327 case UNHIDEGEXPRESSION:
328 *w = UNHIDELEXPRESSION;
330 case INTOHIDEGEXPRESSION:
331 *w = INTOHIDELEXPRESSION;
333 case DROPHGEXPRESSION:
334 *w = DROPHLEXPRESSION;
338 else if ( type == GLOBALEXPRESSION ) {
340 case LOCALEXPRESSION:
341 *w = GLOBALEXPRESSION;
343 case SKIPLEXPRESSION:
344 *w = SKIPGEXPRESSION;
346 case DROPLEXPRESSION:
347 *w = DROPGEXPRESSION;
349 case HIDDENLEXPRESSION:
350 *w = HIDDENGEXPRESSION;
352 case HIDELEXPRESSION:
353 *w = HIDEGEXPRESSION;
355 case UNHIDELEXPRESSION:
356 *w = UNHIDEGEXPRESSION;
358 case INTOHIDELEXPRESSION:
359 *w = INTOHIDEGEXPRESSION;
361 case DROPHLEXPRESSION:
362 *w = DROPHGEXPRESSION;
373 }
while ( c ==
',' );
375 MesPrint(
"&Illegal object in local or global redefinition");
387int CoIdOld(UBYTE *inp)
390 return(CoIdExpression(inp,TYPEIDOLD));
401 return(CoIdExpression(inp,TYPEIDNEW));
409int CoIdNew(UBYTE *inp)
412 return(CoIdExpression(inp,TYPEIDNEW));
420int CoDisorder(UBYTE *inp)
422 AC.idoption = SUBDISORDER;
423 return(CoIdExpression(inp,TYPEIDNEW));
431int CoMany(UBYTE *inp)
433 AC.idoption = SUBMANY;
434 return(CoIdExpression(inp,TYPEIDNEW));
442int CoMulti(UBYTE *inp)
444 AC.idoption = SUBMULTI;
445 return(CoIdExpression(inp,TYPEIDNEW));
453int CoIfMatch(UBYTE *inp)
455 AC.idoption = SUBAFTER;
456 return(CoIdExpression(inp,TYPEIDNEW));
464int CoIfNoMatch(UBYTE *inp)
466 AC.idoption = SUBAFTERNOT;
467 return(CoIdExpression(inp,TYPEIDNEW));
475int CoOnce(UBYTE *inp)
477 AC.idoption = SUBONCE;
478 return(CoIdExpression(inp,TYPEIDNEW));
486int CoOnly(UBYTE *inp)
488 AC.idoption = SUBONLY;
489 return(CoIdExpression(inp,TYPEIDNEW));
497int CoSelect(UBYTE *inp)
499 AC.idoption = SUBSELECT;
500 return(CoIdExpression(inp,TYPEIDNEW));
510int CoIdExpression(UBYTE *inp,
int type)
513 int i, j, idhead, error = 0, MinusSign = 0, opt, retcode;
514 WORD *w, *s, *m, *mm, *ww, *FirstWork, *OldWork, c1, numsets = 0,
515 oldnumrhs, *ow, oldEside;
517 CBUF *C = cbuf+AC.cbufnum;
519 FirstWork = OldWork = AT.WorkPointer;
530 *w++ = idhead + SUBEXPSIZE;
532 if ( idhead >= IDHEAD ) *w++ = -1;
534 for ( i = 4; i < idhead; i++ ) *w++ = 0;
536 while ( *inp ==
',' ) inp++;
538 if ( AC.idoption == SUBSELECT ) {
542 else if ( ( AC.idoption == SUBAFTER ) || ( AC.idoption == SUBAFTERNOT ) ) {
543 while ( *p && *p !=
'=' && *p !=
',' ) {
544 if ( *p ==
'(' ) SKIPBRA4(p)
545 else if ( *p ==
'{' ) SKIPBRA5(p)
546 else if ( *p ==
'[' ) SKIPBRA1(p)
549 if ( *p ==
'=' || *inp !=
'-' || inp[1] !=
'>' ) {
550 MesPrint(
"&Illegal use if if[no]match in id statement");
551 error = 1;
goto AllDone;
554 MesPrint(
"&id-statement without = sign");
555 error = 1;
goto AllDone;
561 while ( *p && *p !=
'=' && *p !=
',' ) {
562 if ( *p ==
'(' ) SKIPBRA4(p)
563 else if ( *p ==
'{' ) SKIPBRA5(p)
564 else if ( *p ==
'[' ) SKIPBRA1(p)
567 if ( *p ==
'=' )
break;
569 MesPrint(
"&id-statement without = sign");
570 error = 1;
goto AllDone;
576 while ( FG.cTable[*pp] == 0 ) pp++;
578 i =
sizeof(IdOptions)/
sizeof(
struct id_options);
580 if ( StrICmp(inp,IdOptions[i].name) == 0 )
break;
583 MesPrint(
"&Illegal option %s in id-statement",inp);
584 *pp = c; error = 1; p++; inp = p;
continue;
586 opt = IdOptions[i].code;
591 if ( pp != p )
goto IllField;
592 AC.idoption |= SUBDISORDER;
596 if ( p != pp )
goto IllField;
597 if ( ( AC.idoption & SUBMASK ) != 0 ) {
598 if ( AC.idoption == SUBMULTI && type == TYPEIF ) {}
600 MesPrint(
"&Conflicting options in id-statement");
611 while ( *p && *p !=
'=' && *p !=
',' ) {
612 if ( *p ==
'(' ) SKIPBRA4(p)
613 else if ( *p ==
'{' ) SKIPBRA5(p)
614 else if ( *p ==
'[' ) SKIPBRA1(p)
617 if ( *p ==
'=' )
break;
619 MesPrint(
"&id-statement without = sign");
620 error = 1;
goto AllDone;
626 if ( p[-1] !=
'}' ) {
628 MesPrint(
"&Illegal temporary set: %s",inp);
633 c = p[-1]; p[-1] = 0;
634 c1 = DoTempSet(inp,p-1);
638 if ( w[-1] < 0 ) error = 1;
643 if ( GetName(AC.varnames,inp,&c1,NOAUTO) != CSET ) {
644 MesPrint(
"&%s is not a set",inp);
648 if ( c1 < AM.NumFixedSets ) {
649 MesPrint(
"&Built in sets are not allowed in the select option");
652 else if ( Sets[c1].type == CRANGE ) {
653 MesPrint(
"&Ranged sets are not allowed in the select option");
667 for ( i = 0; i < idhead; i++ ) *w++ = FirstWork[i];
668 AC.idoption = SUBSELECT;
672 if ( type == TYPEIF ) {
673 MesPrint(
"&The if[no]match->label option is not allowed in an if statement");
674 error = 1;
goto AllDone;
676 if ( pp[0] !=
'-' || pp[1] !=
'>' )
goto IllField;
681 while ( FG.cTable[*pp] <= 1 ) pp++;
684 MesPrint(
"&Illegal label %s in if[no]match option of id-statement",inp);
685 *p = c; error = 1; inp = p+1;
continue;
688 OldWork[3] = GetLabel(inp);
694 if ( FG.cTable[*inp] == 1 ) {
695 while ( *inp >=
'0' && *inp <=
'9' ) x = 10*x+*inp++ -
'0';
699 while ( FG.cTable[*inp] == 0 ) inp++;
701 if ( StrICont(pp,(UBYTE *)
"normalize") != 0 )
goto IllOpt;
703 OldWork[4] |= NORMALIZEFLAG;
705 if ( *inp !=
')' || inp+1 != p ) {
708 MesPrint(
"&Illegal ALL option in id-statement: ",pp);
719 if ( x > MAXPOSITIVE ) {
720 MesPrint(
"&Requested maximum number of matches %l in ALL option in id-statement is greater than %l ",x,MAXPOSITIVE);
724 if ( type != TYPEIDNEW ) {
725 if ( type == TYPEIDOLD ) {
726 MesPrint(
"&Requested ALL option not allowed in idold/also statement.");
729 else if ( type == TYPEIF ) {
730 MesPrint(
"&Requested ALL option not allowed in if(match())");
734 MesPrint(
"&ALL option only allowed in regular id-statement.");
743IllField: c = *p; *p = 0;
744 MesPrint(
"&Illegal optionfield %s in id-statement",inp);
745 *p = c; error = 1; inp = p+1;
continue;
747 i = AC.idoption & SUBMASK;
748 if ( i && i != opt ) {
749 MesPrint(
"&Conflicting options in id-statement");
752 else AC.idoption |= opt;
753 while ( *p ==
',' ) p++;
758 if ( ( AC.idoption & SUBMASK ) == 0 ) AC.idoption |= SUBMULTI;
759 OldWork[2] = AC.idoption;
765 *w++ = SUBEXPRESSION;
773 AT.WorkPointer = s = w + 4*AM.MaxWildcards + 8;
777 ClearWildcardNames();
781 oldnumrhs = C->numrhs;
782 if ( ( retcode = CompileAlgebra(inp,LHSIDE,AC.ProtoType) ) < 0 ) { error = 1; }
783 else AC.ProtoType[2] = retcode;
786 if ( AC.NwildC &&
SortWild(w,AC.NwildC) ) error = 1;
790 OldWork[1] = AC.WildC-OldWork;
791 OldWork[idhead+1] = OldWork[1] - idhead;
794 s = C->
rhs[C->numrhs];
800 tw = AC.ProtoType; twstop = tw + tw[1]; tw += SUBEXPSIZE;
801 while ( tw < twstop ) {
802 if ( *tw == LOADDOLLAR ) {
816 if ( !error && *s == 0 ) {
817IllLeft:MesPrint(
"&Illegal LHS");
821 if ( !error && *(s+*s) != 0 ) {
822 MesPrint(
"&LHS should be one term only");
826 WORD oldpolyfun = AR.PolyFun;
828 if ( !error ) error = 1;
831 AN.RepPoint = AT.RepCount + 1;
832 ow = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
833 mm = s; ww = ow; i = *mm;
834 while ( --i >= 0 ) {*ww++ = *mm++;} AT.WorkPointer = ww;
835 AC.lhdollarflag = 0; oldEside = AR.Eside; AR.Eside = LHSIDE;
836 AR.Cnumlhs = C->numlhs;
845 AR.PolyFun = oldpolyfun;
846 if ( *w == 0 || *(w+*w) != 0 ) {
847 MesPrint(
"&LHS must be one term");
852 if ( AC.lhdollarflag ) MarkDirty(w,DIRTYFLAG);
854 AT.WorkPointer = w + *w;
863 C->numrhs = oldnumrhs;
867 AC.vectorlikeLHS = 0;
869 if ( m[2] != 3 || m[1] != 1 || *m != 1 ) {
870 if ( *m == 1 && m[1] == 1 && m[2] == -3 ) {
874 MesPrint(
"&Coefficient in LHS");
880 if ( *w == 7 && w[1] == INDEX && w[3] < 0 ) {
881 if ( ( AC.idoption & SUBMASK ) != 0 && ( AC.idoption & SUBMASK ) !=
883 MesPrint(
"&Illegal option for substitution of a vector");
886 AC.DumNum = AM.IndDum;
887 OldWork[2] = ( OldWork[2] - ( OldWork[2] & SUBMASK ) ) | SUBVECTOR;
892 *w++ = AC.DumNum + WILDOFFSET;
898 w[4] = AC.DumNum + WILDOFFSET;
899 OldWork[idhead+1] = w - OldWork - idhead;
900 AC.vectorlikeLHS = 1;
905 i = OldWork[2] & SUBMASK;
907 if ( i == 0 || i == SUBMULTI ) {
910 if ( *s == SYMBOL ) {
913 if ( ABS(s[1]) > 2*MAXPOWER ) {
914 OldWork[2] = ( OldWork[2] - i ) | SUBONCE;
921 else if ( *s == DOTPRODUCT ) {
924 if ( ABS(s[2]) > 2*MAXPOWER ) {
925 OldWork[2] = ( OldWork[2] - i ) | SUBONCE;
928 else if ( s[1] >= -(2*WILDOFFSET) || s[0] >= -(2*WILDOFFSET) ) {
929 OldWork[2] = ( OldWork[2] - i ) | SUBMANY;
937 OldWork[2] = ( OldWork[2] - i ) | SUBMANY;
942 if ( ( OldWork[2] & SUBMASK ) == 0 ) OldWork[2] |= SUBMULTI;
944 if ( ( OldWork[2] & SUBMASK ) == SUBSELECT ) {
954 s = FirstWork + idhead;
955 while ( --numsets >= 0 ) *m++ = *s++;
971 OldWork[1] = m - OldWork;
972 AC.ProtoType = OldWork+idhead;
974 if ( StudyPattern(OldWork) ) error = 1;
976 AT.WorkPointer = OldWork + OldWork[1];
977 if ( AC.lhdollarflag ) OldWork[4] |= DOLLARFLAG;
982 if ( type == TYPEIDOLD ) {
985 if ( C->
lhs[ci][0] == TYPEIDNEW ) {
986 if ( (C->
lhs[ci][2] & SUBMASK) == SUBALL ) {
987 MesPrint(
"&Idold/also cannot follow an id,all statement.");
992 else if ( C->
lhs[ci][0] == TYPEDETCURDUM ) { ci--;
continue; }
993 else if ( C->
lhs[ci][0] == TYPEIDOLD ) { ci--;
continue; }
997 MesPrint(
"&Idold/also should follow an id/idnew statement.");
1004 if ( type != TYPEIF ) {
1005 if ( ( retcode = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) error = 1;
1007 AC.ProtoType[2] = retcode;
1010 w = C->
rhs[retcode];
1011 while ( *w ) { w += *w; w[-1] = -w[-1]; }
1013 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
1019 if ( !error ) {
AddNtoL(OldWork[1],OldWork); }
1021 AC.lhdollarflag = 0;
1022 AT.WorkPointer = FirstWork;
1031static WORD mularray[13] = { TYPEMULT, SUBEXPSIZE+3, 0, SUBEXPRESSION,
1032 SUBEXPSIZE, 0, 1, 0, 0, 0, 0, 0, 0 };
1034int CoMultiply(UBYTE *inp)
1037 int error = 0, RetCode;
1039 while ( *inp ==
',' ) inp++;
1044 if ( StrICont(inp,(UBYTE *)
"left") == 0 ) mularray[2] = 1;
1045 else if ( StrICont(inp,(UBYTE *)
"right") == 0 ) mularray[2] = 0;
1047 MesPrint(
"&Illegal option in multiply statement or ; forgotten.");
1053 ClearWildcardNames();
1054 while ( *inp ==
',' ) inp++;
1055 AC.ProtoType = mularray+3;
1056 mularray[7] = AC.cbufnum;
1057 if ( ( RetCode = CompileAlgebra(inp,RHSIDE,AC.ProtoType) ) < 0 ) error = 1;
1059 mularray[5] = RetCode;
1060 AddNtoL(SUBEXPSIZE+3,mularray);
1061 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
1073int CoFill(UBYTE *inp)
1076 WORD error = 0, x, xx, funnum, type, *oldwp = AT.WorkPointer;
1077 int i, oldcbufnum = AC.cbufnum, nofill = 0, numover, redef = 0;
1078 WORD *w, *wold, *Tprototype;
1079 UBYTE *p = inp, c, *inp1;
1081 LONG newreservation, sum = 0;
1082 UBYTE *p1, *p2, *p3, *p4, *fake = 0;
1084 if ( AC.exprfillwarning == 1 ) AC.exprfillwarning = 0;
1089 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1092 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,WITHAUTO) == NAMENOTFOUND )
1093 || ( T = functions[funnum].tabl ) == 0 || ( T->
numind > 0 && c !=
'(' ) ) {
1094 MesPrint(
"&%s should be a table with argument(s)",inp);
1103 MesPrint(
"&%s should be a table without arguments",inp);
1115 ParseSignedNumber(xx,p);
1116 if ( FG.cTable[p[-1]] != 1 || *p !=
',' || xx < 1 || ( xx > ( -T->
numind - 1 ) ) ) {
1117 MesPrint(
"&No valid number of table indices in *-table fill statement.");
1124 for ( sum = 0, i = 0; i < xx; i++ ) {
1125 ParseSignedNumber(x,p);
1126 if ( FG.cTable[p[-1]] != 1 || ( *p !=
',' && *p !=
')' ) ) {
1127 MesPrint(
"&Table arguments in fill statement should be numbers");
1130 if ( T->
sparse ) *w++ = x;
1131 else if ( x < T->mm[i].mini || x > T->
mm[i].
maxi ) {
1132 MesPrint(
"&Value %d for argument %d of table out of bounds",x,i+1);
1133 error = 1; nofill = 1;
1136 if ( *p ==
')' )
break;
1141 for ( ; i < ABS(T->
numind)-1; i++ ) *w++ = 0;
1144 if ( *p !=
')' || i < ( xx - 1 ) ) {
1145 MesPrint(
"&Incorrect number of table arguments in fill statement. Should be %d"
1147 error = 1; nofill = 1;
1150 if ( T->
sparse == 0 ) sum *= TABLEEXTENSION;
1154 i = FindTableTree(T,oldwp,1);
1156 sum = i + ABS(T->
numind);
1157 if ( tablestub == 0 && ( ( T->
sparse & 2 ) == 2 ) && ( T->
mode != 0 )
1158 && ( AC.vetotablebasefill == 0 ) ) {
1162 functions[funnum].tabl = T = T->
spare;
1170 if ( T->
reserved == 0 ) newreservation = 20;
1172 while ( T->
totind >= newreservation && newreservation < MAXTABLECOMBUF )
1173 newreservation = 2*newreservation;
1174 if ( newreservation > MAXTABLECOMBUF ) newreservation = MAXTABLECOMBUF;
1175 if ( T->
totind >= newreservation ) {
1176 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1177 AC.cbufnum = oldcbufnum;
1180 wold = (WORD *)Malloc1(newreservation*
sizeof(WORD)*
1181 (ABS(T->
numind)+TABLEEXTENSION),
"tablepointers");
1182 for ( i = T->
reserved*(ABS(T->
numind)+TABLEEXTENSION)-1; i >= 0; i-- )
1189 for ( sum = T->
totind*(ABS(T->
numind)+TABLEEXTENSION), i = 0; i < ABS(T->
numind); i++ ) {
1193#if TABLEEXTENSION == 2
1206 if ( AC.vetofilling ) nofill = 1;
1208 Warning(
"Table element was already defined. New definition will be used");
1211#if TABLEEXTENSION == 2
1221 if ( T->
numind ) { p++; }
1223 MesPrint(
"&Fill statement misses = sign after the table element");
1224 AC.cbufnum = oldcbufnum;
1225 AT.WorkPointer = oldwp;
1226 functions[funnum].tabl = oldT;
1229 if ( tablestub == 0 && T->
mode == 1 && AC.vetotablebasefill == 0 ) {
1237 numfake = (p4-T->
argtail)+(p3-p1)+10;
1239 fake = (UBYTE *)Malloc1(numfake*
sizeof(UBYTE),
"Fill fake rhs");
1241 *p++ =
't'; *p++ =
'b'; *p++ =
'l'; *p++ =
'_'; *p++ =
'(';
1242 p4 = p1;
while ( p4 < p2 ) *p++ = *p4++; *p++ =
',';
1243 p4 = p2+1;
while ( p4 < p3 ) *p++ = *p4++;
1246 while ( FG.cTable[*p4] == 1 ) p4++;
1248 if ( *p4 ==
'?' && p[-1] !=
',' ) {
1250 if ( FG.cTable[*p4] == 0 || *p4 ==
'$' || *p4 ==
'[' ) {
1256 else if ( *p4 ==
'{' ) {
1259 else if ( *p4 ) { *p++ = *p4++;
continue; }
1276 AC.tablefilling = funnum;
1285 if ( ( i = CompileAlgebra(inp1,RHSIDE,Tprototype) ) < 0 ) { error = 1; i = 0; }
1292 if ( T->
sparse || c == 0 )
break;
1294#if ( TABLEEXTENSION == 2 )
1300#if ( TABLEEXTENSION == 2 )
1303 sum += TABLEEXTENSION-2;
1306 if ( AC.exprfillwarning == 1 ) {
1307 AC.exprfillwarning = 2;
1308 Warning(
"Use of expressions and/or $variables in Fill statements is potentially very dangerous.");
1310 AC.tablefilling = 0;
1311 if ( T->
sparse && c != 0 ) {
1312 MesPrint(
"&In sparse tables one can fill only one element at a time");
1315 else if ( numover ) {
1317 Warning(
"one element was overwritten. New definition will be used");
1318 else if ( AC.WarnFlag )
1319 MesPrint(
"&Warning: %d elements were overwritten. New definitions will be used",numover);
1322 if ( redef == 0 ) T->
totind++;
1330 M_free(fake,
"Fill fake rhs");
1332 functions[funnum].tabl = T = T->
spare;
1336 AC.cbufnum = oldcbufnum;
1337 AC.SymChangeFlag = 1;
1338 AT.WorkPointer = oldwp;
1339 functions[funnum].tabl = oldT;
1359int CoFillExpression(UBYTE *inp)
1363 WORD type, funnum, expnum, symnum, numsym = 0, *oldwork = AT.WorkPointer;
1364 WORD *brackets, *term, brasize, *b, *m, *w, *pw, *tstop, zero = 0;
1365 WORD oldcbuf = AC.cbufnum, curelement = 0;
1366 int weneedit, i, j, numzero, pow, numfirst;
1368 LONG newreservation, numcommu, sum;
1374 AN.IndDum = AM.IndDum;
1375 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1377 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1378 || ( T = functions[funnum].tabl ) == 0 ) {
1379 MesPrint(
"&%s should be a previously declared table",inp);
1386 MesPrint(
"&No = sign in FillExpression statement");
1390 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1392 if ( ( type = GetName(AC.exprnames,inp,&expnum,NOAUTO) ) == NAMENOTFOUND
1394 Expressions[expnum].status != LOCALEXPRESSION &&
1395 Expressions[expnum].status != SKIPLEXPRESSION &&
1396 Expressions[expnum].status != DROPLEXPRESSION &&
1397 Expressions[expnum].status != GLOBALEXPRESSION &&
1398 Expressions[expnum].status != SKIPGEXPRESSION &&
1399 Expressions[expnum].status != DROPGEXPRESSION ) ) {
1400 MesPrint(
"&%s should be an active expression with arguments",inp);
1403 if ( Expressions[expnum].inmem ) {
1404 MesPrint(
"&%s cannot be used in a FillExpression statement in the same %n\
1405 module that it has been redefined",inp);
1411 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1414 if ( GetVar(inp,&type,&symnum,-1,NOAUTO) == NAMENOTFOUND ) {
1415 MesPrint(
"&%s should be a previously declared symbol or function",inp);
1418 else if ( type == CSYMBOL ) {
1420 *AT.WorkPointer++ = symnum;
1423 else if ( type == CFUNCTION ) {
1427 MesPrint(
"&Argument should be a single function or a list of symbols");
1431 *AT.WorkPointer++ = symnum;
1434 MesPrint(
"&%s should be a previously declared symbol or function",inp);
1437 if ( c ==
')' )
break;
1439 MesPrint(
"&Illegal separator in FillExpression statement");
1444 MesPrint(
"&Illegal end of FillExpression statement");
1454 if ( ( numsym > 0 ) && ( ABS(T->
numind) != numsym ) ) {
1455 MesPrint(
"&This table needs %d symbols for its array indices");
1465 if ( PF.me == MASTER ) {
1470 SetEndScratch(AR.infile, &pos);
1475 PUTZERO(oldposition);
1476 SeekFile(fi->
handle,&oldposition,SEEK_CUR);
1477 SetScratch(fi,&(Expressions[expnum].onfile));
1478 if ( ISNEGPOS(Expressions[expnum].onfile) ) {
1480 MesPrint(
"!>File error in FillExpression");
1491 SETBASEPOSITION(oldposition,(UBYTE *)(fi->POfill)-(UBYTE *)(fi->PObuffer));
1492 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(Expressions[expnum].onfile));
1494 pw = AT.WorkPointer;
1495 if ( numsym < 0 ) { brackets = pw + 1; }
1496 else { brackets = pw + numsym; }
1497 brasize = -1; weneedit = 0;
1498 term = (WORD *)(((UBYTE *)(brackets)) + AM.MaxTer);
1499 AT.WorkPointer = (WORD *)(((UBYTE *)(term)) + AM.MaxTer);
1501 AC.tablefilling = funnum;
1502 if ( GetTerm(BHEAD term) > 0 ) {
1503 while ( GetTerm(BHEAD term) > 0 ) {
1504 GETSTOP(term,tstop);
1506 while ( m < tstop && *m != HAAKJE ) m += m[1];
1507 if ( *m != HAAKJE ) {
1508 MesPrint(
"&Illegal attempt to put an expression without brackets in a table");
1512 if ( brasize == m - w ) {
1514 while ( *b == *w && w < m ) { b++; w++; }
1518 *m = *term - (m-term);
1520 numdummies = DetCurDum(BHEAD term) - AM.IndDum;
1521 if ( numdummies > T->numdummies ) T->numdummies = numdummies;
1527 AddNtoC(AC.cbufnum,1,&zero,4);
1528 numcommu = numcommute(C->
rhs[curelement],&(C->
NumTerms[curelement]));
1529 C->
CanCommu[curelement] = numcommu;
1531 b = brackets; w = term + 1;
1532 if ( numsym < 0 ) pw = oldwork + 1;
1533 else pw = oldwork + numsym;
1534 while ( w < m ) *b++ = *w++;
1535 brasize = b - brackets;
1541 if ( *brackets != symnum || brasize != brackets[1] ) {
1542 weneedit = 0;
continue;
1547 b = brackets + FUNHEAD;
1548 bb = brackets+brackets[1];
1552 if ( bnum > -T->
numind ) {
1553 weneedit = 0;
continue;
1558 if ( *b != -SNUMBER )
break;
1562 if ( b < bb || i != bnum ) {
1563 weneedit = 0;
continue;
1566 else if ( brasize > 0 && ( *brackets != SYMBOL
1567 || brackets[1] < brasize || (brackets[1]-2) > numsym*2 ) ) {
1568 weneedit = 0;
continue;
1570 numzero = 0; sum = 0;
1573 for ( i = 0; i < numsym; i++ ) {
1574 if ( brasize > 0 ) {
1575 b = brackets + 2; j = brackets[1]-2;
1577 if ( *b == oldwork[i] )
break;
1582 if ( 2*numzero+brackets[1]-2 > numsym*2 ) {
1583 weneedit = 0;
goto nextterm;
1593 if ( pow > -T->
numind ) {
1594 weneedit = 0;
goto nextterm;
1597 else if ( i > pow ) {
1598 weneedit = 0;
goto nextterm;
1603 else if ( pow < T->mm[i].mini || pow > T->
mm[i].
maxi ) {
1604 weneedit = 0;
goto nextterm;
1611 b = brackets + FUNHEAD;
1617 xx = (brackets[1]-FUNHEAD)/2;
1618 for ( i = 0; i < xx; i++ ) {
1625 if ( pow >= -T->
numind ) {
1626 weneedit = 0;
goto nextterm;
1632 else if ( pow < T->mm[i].mini || pow > T->
mm[i].
maxi ) {
1633 weneedit = 0;
goto nextterm;
1639 for ( i = numfirst+1; i < -T->
numind; i++ ) *pw++ = 0;
1643 if ( numsym < 0 ) pw = oldwork + 1;
1644 else pw = oldwork + ABS(T->
numind);
1645 i = FindTableTree(T,pw,1);
1655 if ( T->
reserved == 0 ) newreservation = 20;
1658 while ( T->
totind >= newreservation && newreservation < MAXTABLECOMBUF )
1659 newreservation = 2*newreservation;
1660 if ( newreservation > MAXTABLECOMBUF ) newreservation = MAXTABLECOMBUF;
1661 if ( T->
totind >= newreservation ) {
1662 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1663 AC.cbufnum = oldcbuf;
1664 AT.WorkPointer = oldwork;
1668 if ( T->
totind >= newreservation ) {
1669 MesPrint(
"@More than %ld elements in sparse table",MAXTABLECOMBUF);
1670 AC.cbufnum = oldcbuf;
1671 AT.WorkPointer = oldwork;
1674 w = (WORD *)Malloc1(newreservation*
sizeof(WORD)*
1675 (ABS(T->
numind)+TABLEEXTENSION),
"tablepointers");
1676 for ( i = T->
reserved*(ABS(T->
numind)+TABLEEXTENSION)-1; i >= 0; i-- )
1682 if ( numsym < 0 ) pw = oldwork + 1;
1683 else pw = oldwork + numsym;
1684 for ( sum = T->
totind*(ABS(T->
numind)+TABLEEXTENSION), i = 0; i < ABS(T->
numind); i++ ) {
1690#if ( TABLEEXTENSION != 2 )
1692 sum *= TABLEEXTENSION;
1700#if ( TABLEEXTENSION == 2 )
1709newentry:
if ( *m == HAAKJE ) { m += m[1] - 1; }
1711 *m = *term - (m-term);
1717 AddNtoC(AC.cbufnum,1,&zero,6);
1718 numcommu = numcommute(C->
rhs[curelement],&(C->
NumTerms[curelement]));
1719 C->
CanCommu[curelement] = numcommu;
1723 SetScratch(fi,&(oldposition));
1726 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(oldposition));
1729 AC.cbufnum = oldcbuf;
1730 AC.tablefilling = 0;
1731 AT.WorkPointer = oldwork;
1735 AC.cbufnum = oldcbuf;
1736 AC.tablefilling = 0;
1737 AT.WorkPointer = oldwork;
1753int CoPrintTable(UBYTE *inp)
1756 int fflag = 0, sflag = 0, addflag = 0, error = 0, sum, i, j;
1757 UBYTE *filename, *p, c, buffer[100], *s, *oldoutputline = AO.OutputLine;
1758 WORD type, funnum, *expr, *m, num;
1760 WORD oldSkip = AO.OutSkip, oldMode = AC.OutputMode, oldHandle = AC.LogHandle;
1761 WORD oldType = AO.PrintType, *oldwork = AT.WorkPointer;
1762 UBYTE *oldFill = AO.OutFill, *oldLine = AO.OutputLine;
1764 if ( PF.me != MASTER )
return 0;
1769 while ( *inp ==
'+' ) {
1771 if ( *inp ==
'f' || *inp ==
'F' ) { fflag = 1; inp++; }
1772 else if ( *inp ==
's' || *inp ==
'S' ) { sflag = PRINTONETERM; inp++; }
1774 MesPrint(
"&Illegal + option in PrintTable statement");
1777 while ( *inp !=
',' && *inp && *inp !=
'+' ) {
1780 MesPrint(
"&Illegal + option in PrintTable statement");
1784 MesPrint(
"&Unfinished PrintTable statement");
1791 if ( *inp ==
',' ) inp++;
1796 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1798 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1799 || ( T = functions[funnum].tabl ) == 0 ) {
1800 MesPrint(
"&%s should be a previously declared table",inp);
1810 if ( *p ==
'>' ) { addflag = 1; p++; }
1816 if ( addflag ) AC.LogHandle = OpenAddFile((
char *)filename);
1817 else AC.LogHandle = CreateFile((
char *)filename);
1818 if ( AC.LogHandle < 0 ) {
1819 MesPrint(
"&Cannot open file '%s' properly",filename);
1820 error = 1;
goto finally;
1822 AO.PrintType = PRINTLFILE;
1824 else if ( fflag && AC.LogHandle >= 0 ) {
1825 AO.PrintType = PRINTLFILE;
1827 AO.OutFill = AO.OutputLine = (UBYTE *)AT.WorkPointer;
1828 AT.WorkPointer += 2*AC.LineLength;
1830 AO.PrintType |= sflag;
1836 if ( AC.LogHandle == oldHandle ) FiniLine();
1837 AO.OutputLine = AO.OutFill = (UBYTE *)Malloc1(AC.LineLength+20,
"PrintTable");
1838 AO.OutStop = AO.OutFill + AC.LineLength;
1839 for ( i = 0; i < T->
totind; i++ ) {
1841 TokenToLine((UBYTE *)
"Fill ");
1842 TokenToLine((UBYTE *)(VARNAME(functions,funnum)));
1843 TokenToLine((UBYTE *)
"(");
1846 sum = i * ( T->
numind + TABLEEXTENSION );
1847 for ( j = 0; j < T->
numind; j++, sum++ ) {
1848 if ( j > 0 ) TokenToLine((UBYTE *)
",");
1850 s = buffer; s = NumCopy(num,s);
1851 TokenToLine(buffer);
1856 for ( j = 0; j < T->
numind; j++ ) {
1858 TokenToLine((UBYTE *)
",");
1864 s = buffer; s = NumCopy(num,s);
1865 TokenToLine(buffer);
1869 TOKENTOLINE(
") =",
")=");
1872 if ( AC.OutputSpaces != NOSPACEFORMAT ) TokenToLine((UBYTE *)
" ");
1890 while ( *m ) m += *m;
1892 if ( WriteExpression(expr,(LONG)(m-expr)) ) { error = 1;
goto finally; }
1896 TokenToLine((UBYTE *)
"0");
1898 TokenToLine((UBYTE *)
";");
1901 M_free(AO.OutputLine,
"PrintTable");
1902 AO.OutputLine = AO.OutFill = oldoutputline;
1907 AO.OutSkip = oldSkip;
1908 AC.OutputMode = oldMode;
1909 AC.LogHandle = oldHandle;
1910 AO.PrintType = oldType;
1911 AO.OutFill = oldFill;
1912 AO.OutputLine = oldLine;
1913 AT.WorkPointer = oldwork;
1926static WORD AssignLHS[14] = { TYPEASSIGN, 3+SUBEXPSIZE, 0,
1927 SUBEXPRESSION, SUBEXPSIZE, 0, 1, 0, 0,0,0,0,0 };
1929int CoAssign(UBYTE *inp)
1931 int error = 0, retcode;
1934 if ( *inp !=
'$' ) {
1935nolhs: MesPrint(
"&assign statement should have a dollar variable in the LHS");
1939 if ( FG.cTable[*inp] != 0 )
goto nolhs;
1940 while ( FG.cTable[*inp] < 2 ) inp++;
1941 if ( AP.PreAssignFlag == 2 ) {
1942 if ( *inp ==
'_' ) inp++;
1944 if ( ( *inp ==
',' && inp[1] !=
'=' ) && ( *inp !=
'=' ) ) {
1945 MesPrint(
"&assign statement should have only a dollar variable in the LHS");
1950 if ( GetName(AC.dollarnames,name,&number,NOAUTO) == NAMENOTFOUND ) {
1951 number = AddDollar(name,DOLUNDEFINED,0,0);
1954 if ( c ==
',' ) inp++;
1956 if ( *inp ==
',' ) inp++;
1960 AssignLHS[7] = AC.cbufnum;
1961 retcode = CompileAlgebra(inp,RHSIDE,(AssignLHS+3));
1962 if ( retcode < 0 ) error = 1;
1967 AssignLHS[2] = number;
1968 AssignLHS[5] = retcode;
1969 AddNtoL(AssignLHS[1],AssignLHS);
1987int CoDeallocateTable(UBYTE *inp)
1991 WORD type, funnum, i;
1994 while ( *inp ==
',' ) inp++;
1995 if ( *inp == 0 )
break;
1996 if ( ( p =
SkipAName(inp) ) == 0 )
return(1);
1998 if ( ( GetVar(inp,&type,&funnum,CFUNCTION,NOAUTO) == NAMENOTFOUND )
1999 || ( T = functions[funnum].tabl ) == 0 ) {
2000 MesPrint(
"&%s should be a previously declared table",inp);
2004 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)