real_het

het.parser.for.pas

Oct 2nd, 2012
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 6.35 KB | None | 0 0
  1. type
  2.   TForType=(ftTo,ftDownTo,ftTowards,ftIn);
  3.   TNodeFor              =class(TNodeManyOp)
  4.   private
  5.     FForType:TForType;
  6.     FDescending:Boolean;
  7.   public
  8.     procedure Eval(var AContext:TContext;var AResult:variant);override;
  9.     function Clone:TNodeBase;override;
  10.   end;
  11.  
  12. ...
  13.  
  14. procedure TNodeFor.Eval(var AContext: TContext; var AResult: Variant);
  15. var i,j:integer;
  16.     nIndex,nStep,nBlock,nWhere:TNodeBase;
  17.     dest,step,tmp:variant;
  18.     pidx,pset:PVariant;
  19.     worked:boolean;
  20.     ft:TForType;
  21.     s:ansistring;
  22.     o:tobject;
  23.  
  24.     iStep,iDest:integer;piIdx:pinteger;
  25.     i64Step,i64Dest:int64;pi64Idx:pint64;
  26.  
  27.     vWhere:variant;
  28.  
  29.   procedure Iterate;//pidx^ must be set
  30.   begin
  31.     if nWhere<>nil then begin
  32.       nWhere.Eval(AContext,vWhere);
  33.       if not boolean(vWhere) then exit;
  34.     end;
  35.     if nBlock<>nil then
  36.       nBlock.Eval(AContext,AResult);
  37.     worked:=true;
  38.   end;
  39.  
  40.   var isInt64:boolean;//reset to false
  41.   function VarIsInt(const v:variant):boolean;
  42.   begin with TVarData(v)do begin
  43.     if VType in[varByte,varShortInt,varWord,varSmallint,varInteger]then exit(true);
  44.     if VType in[varLongWord,varInt64]then begin isInt64:=true;exit(true)end;
  45.     result:=false;
  46.   end;end;
  47.  
  48. begin
  49.   nIndex:=SubNode(0).SubNode(0);
  50.   nStep:=SubNode(2);
  51.   nWhere:=SubNode(3);
  52.   nBlock:=SubNode(4);
  53.  
  54.   if FForType=ftIn then begin //for in
  55.     pidx:=nIndex.RefPtr(AContext);//ref to index
  56.     pset:=SubNode(0).SubNode(1).RefPtr(AContext,tmp);
  57.  
  58.     if VarIsObject(pset^) then begin
  59.       o:=VarAsObject(pset^);
  60.       if o=nil then
  61.         ExecError('For-loop: Cannot enumerate NIL object');
  62.  
  63.       if o is TList then with TList(o)do begin
  64.         if FDescending then for i:=Count-1 downto 0 do begin pidx^:=VObject(TObject(Items[i]));Iterate;end
  65.                        else for i:=0 to Count-1     do begin pidx^:=VObject(TObject(Items[i]));Iterate;end
  66.       end else if o is TComponent then with TComponent(o)do begin
  67.         if FDescending then for i:=ComponentCount-1 downto 0 do begin pidx^:=VObject(Components[i]);Iterate;end
  68.                        else for i:=0 to ComponentCount-1     do begin pidx^:=VObject(Components[i]);Iterate;end
  69.       end else if o is TCollection then with TCollection(o)do begin
  70.         if FDescending then for i:=Count-1 downto 0 do begin pidx^:=VObject(Items[i]);Iterate;end
  71.                        else for i:=0 to Count-1     do begin pidx^:=VObject(Items[i]);Iterate;end
  72.       end else if o is THetObjectList then with THetObjectList(o)do begin
  73.         if FDescending then for i:=Count-1 downto 0 do begin pidx^:=VObject(GetHetObjByIndex(i));Iterate;end
  74.                        else for i:=0 to Count-1     do begin pidx^:=VObject(GetHetObjByIndex(i));Iterate;end;
  75.       end else
  76.         ExecError('For-loop: Cannot enumerate '+toPas(o.ClassName)+' object');
  77.  
  78.     end else if VarIsStr(pset^)then begin
  79.       s:=ansistring(pset^);
  80.       for i:=1 to length(s)do begin
  81.         pidx^:=s[i];//value
  82.         Iterate;
  83.       end;
  84.     end else if VarIsArray(pset^)then begin
  85.       for i:=VarLow(pset^) to varHigh(pset^)do begin
  86.         pidx^:=VReference(VarArrayAccess(pset^,i));//value
  87.         Iterate;
  88.       end;
  89.     end else if VarIsSet(pset^) then begin
  90.       with VarAsSetArray(pset^)do for j:=0 to Elements.FCount-1 do with Elements.FItems[j]do begin
  91.         if typ=stSingle then begin //single
  92.           pidx^:=VReference(e1);
  93.           Iterate;
  94.         end else if e1<=e2 then begin//range
  95.           pidx^:=e1;
  96.  
  97.           isInt64:=false;
  98.           if VarIsInt(e1)and VarIsInt(e2)then
  99.             if isInt64 then begin//optimized int64
  100.               pi64Idx:=@TVarData(pidx^).VInt64;i64Dest:=e2;
  101.               while pi64idx^<=i64Dest do begin
  102.                 Iterate;
  103.                 Inc(pi64idx^);
  104.               end;
  105.             end else begin//int32 optimization
  106.               piIdx:=@TVarData(pidx^).VInteger;iDest:=e2;
  107.               while piIdx^<=iDest do begin
  108.                 Iterate;
  109.                 Inc(piIdx^);
  110.               end;
  111.             end
  112.           else begin//other types, variants
  113.             while pidx^<=e2 do begin
  114.               Iterate;
  115.               VarInc(pidx^);
  116.             end;
  117.           end;
  118.         end;
  119.       end;
  120.     end else
  121.       ExecError('Fol-loop: Cannot enumerate type '+topas(VarTypeAsText(VarType(pset^))));
  122.  
  123.   end else begin //standard for
  124.     pidx:=nIndex.RefPtr(AContext);//ref to index
  125.     SubNode(0).SubNode(1).Eval(AContext,pIdx^);//idx:=source
  126.     SubNode(1).Eval(AContext,Dest);//read dest
  127.  
  128.     worked:=false;
  129.     if nStep=nil then begin //no step
  130.       if FForType=ftTowards then begin
  131.         if pidx^<=dest then begin ft:=ftTo;end
  132.                        else begin ft:=ftDownTo;end;
  133.       end else
  134.         ft:=FForType;
  135.       case ft of
  136.         ftTo:step:=1;
  137.         ftDownTo:step:=-1;
  138.       end;
  139.     end else begin//step
  140.       nStep.Eval(AContext,step);
  141.       if Step=0 then ExecError('Step cannot be 0 in for-loop');
  142.       if Step>0 then ft:=ftTo
  143.                 else ft:=ftDownTo;
  144.     end;
  145.  
  146.     isInt64:=false;
  147.     if varIsInt(pidx^)and varIsInt(dest)and varIsInt(step)then begin//optimizations
  148.       if isInt64 then begin
  149.         pi64Idx:=@TVarData(pidx^).VInt64;i64Dest:=dest;i64Step:=step;
  150.         case ft of  //int64 optimization
  151.           ftTo:while pi64idx^<=i64dest do begin
  152.             Iterate;
  153.             pi64idx^:=pi64idx^+i64Step;
  154.           end;
  155.           ftDownTo:while pi64idx^>=i64dest do begin
  156.             Iterate;
  157.             pi64idx^:=pi64idx^+i64Step;
  158.           end;
  159.         end;
  160.       end else begin  //int32 optimization
  161.         piIdx:=@TVarData(pidx^).VInteger;iDest:=dest;iStep:=step;
  162.         case ft of  //int32 optimization
  163.           ftTo:while piidx^<=idest do begin
  164.             Iterate;
  165.             piidx^:=piidx^+iStep;
  166.           end;
  167.           ftDownTo:while piidx^>=idest do begin
  168.             Iterate;
  169.             piidx^:=piidx^+iStep;
  170.           end;
  171.         end;
  172.       end;
  173.     end else//other types ->variant
  174.       case ft of
  175.         ftTo:while pidx^<=dest do begin
  176.           Iterate;
  177.           pidx^:=pidx^+step; //C-s stilusuan, dest+step a vége
  178.         end;
  179.         ftDownTo:while pidx^>=dest do begin
  180.           Iterate;
  181.           pidx^:=pidx^+step;
  182.         end;
  183.       end;
  184.   end;
  185.  
  186.   if(not worked)and(SubNode(5)<>nil)then begin//unless
  187.     SubNode(5).Eval(AContext,AResult);
  188.   end;
  189. end;
Advertisement
Add Comment
Please, Sign In to add comment