AggregateOrdered ET::match(const Aggregate s,AggregateOrdered positions, Obj pat,AggregateOrdered r){ SWITCHstart CASEIF(pat.isInstanceOf(classInt)) uWord sn=s.elements(); // looping on the positions // if a position is between start and end and the pattern equals // the value at pos then add the next position to the results. for(auto p:positions){ if(0<=p && p<sn && pat.w==s[p]) r&=p+1; //&= adds a single object to an ordered aggregate (if it doesn't exists already) } CASEIF(pat.isInstanceOf(classDouble)) uWord sn=s.elements(); for(auto p:positions){ if(0<=p && p<sn && compare(pat,s[p])==0) r&=p+1; //&= adds a single object to an ordered aggregate (if it doesn't exists already) } CASEIF(pat.isInstanceOf(classPatternAll)) AggregateOrdered r1=positions; for(auto pat1:(Aggregate)pat) r1=match(s,r1,pat1); if(r.elements()==0) r=r1;else r+=r1; CASEIF(pat.isInstanceOf(classPatternAny)) for(auto pat1:(Aggregate)pat) match(s,positions,pat1,r); CASEIF(pat.isInstanceOf(classAggregate)) stack().push(positions); execute(pat,true); // should execute independently from the execution status ? should be explained ! r=stack().pop(); DEFAULT assert0(false,"unexpected in matchAll"); endSWITCH return r; }
// appends to the current aggregate a slice from a given aggregate from position i1 to position i2 void Aggregate::insertSlice(Aggregate a,Word pos,Word i1,Word i2){ ADJUSTOFFSET(elements(),pos);ADJUSTOFFSET2(a.elements(),i1,i2);assert0(i1<=i2,"appendSlice"); Word sz=i2-i1;checkResize(sz); elements(elements()+sz); WordMove(dataP()+pos+sz,dataP()+pos,elements()-pos); WordCpy(dataP()+pos,a.dataP()+i1,sz); }
AggregateOrdered match(const Aggregate s,AggregateOrdered positions, Obj pat,AggregateOrdered r=0,Word pn=1){ // p holds the positions array that may have 1 or 2 columns per raw #define loop(aa,step) for(Word i=0,i1=aa.elements(),p;i<i1 && (p=aa[i],true);i+=step) switch(pat.Class().w){ case _classInt:{ if(!r) r=AggregateOrdered(); uWord sn=s.elements(); loop(positions,pn){ if(0<=p && p+1<=sn && s[p]==pat.w) r.keyExists((Obj)(p+1)); } }; break; case _classAggregate: stack.push(positions); execute(pat,true); r=stack.pop(); break; case _classString: case _classPatternAll:{ AggregateOrdered r1=positions; for(auto pat1:(Aggregate)pat) r1=match(s,r1,pat1); if(!r) r=r1;else r+=r1; break; } case _classPatternAny: if(!r) r=AggregateOrdered(); for(auto pat1:(Aggregate)pat) match(s,positions,pat1,r); break; default: assert0(false,"unexpected in matchAll"); break; } return r; }
AggregateOrdered ET::matchEnd(Aggregate s,AggregateOrdered positions){ AggregateOrdered r; if(positions.keyExists(s.elements(),false)) r.push(s.elements()); return r; }
Aggregate ET::allPos(Aggregate s,Word startPos){ uWord sn=s.elements(),n=(startPos<=sn?sn-startPos:0); Aggregate r(n,n); for(uWord i=0,j=startPos;i<n;i++,j++) r[i]=j; return r; }
Aggregate allPos(Aggregate s){ uWord sn=s.elements();Aggregate r(sn,sn); for(uWord i=0;i<s.elements();i++) r[i]=i; return r; }