Support Statement: gmSL to move a variable declaration

The following gmSL routine moves a declaration to the top of a function.  This may be required when a translated method uses a variable before it is initialized. (See C# Compiler Error CS0165). 

Beginning with gmBasic v40.75 is now a Migrate MoveToTop attribute for moving declarations to the top.  See gmplMigrateStatement.


Note, a simpler temporary workaround is to translate the method to a "Conditional Stub" using Refactor/Remove with migStatus="Conditional".

<gmBasic>
   <Storage Action="Create" Identifier="App" />

... options etc. ...

   <gmSL class="Refactoring">
   void MoveDeclToTop(string identifier)
   {
/// moves the declaration of the specified identifier to the top of the declaring subprogram 

      int        iRoot;   // address of identifier to move
      int        subRoot; // subroutine containing the identifier to move
      tVbSub     subInfo; // information vector for subroutine
      tCodeBlock codPtr;  // code stream
      int        nCode;   // length of code stream
      int        lastNew; // last Statement start
      int        iCode;   // code pointer for code scan
      int        opcd;    // opcode for code scan 
      int        subc;    // subcode for code scan
      int        subLen;  // length of subroutine 
      int        topAddr;

      iRoot = Symbol.FindIdentifier(identifier,0);
      if(iRoot == 0)
      {
         System.LogMessage("MoveDeclToTop failed: could not locate " + identifier);
         return;
      }
      subRoot = Store.GetParent(iRoot);
      nCode = Store.GetLength(subRoot);
      subInfo = Store.DeltaVector(subRoot);
      codPtr = Opcode.GetCode();
      nCode = Store.ReadInfo(codPtr,subInfo.anaCodeStart);
      Opcode.SetLength(nCode);
      subLen = nCode;  
      lastNew = 0;
      topAddr = 0;
      for(iCode = 0; iCode >= 0; iCode = Opcode.GetNext(codPtr,iCode,nCode))
      {
         opcd = Opcode.GetOperation(codPtr,iCode,subc);
         if(opcd == OPC.NEW)
         {
            lastNew = iCode;
            continue;
         }
         if(opcd == OPC.DCL)
         {
            if(subc == iRoot) 
            {
               if((icode - lastNew) != 3)
               {
                  System.LogMessage("MoveDeclToTop failed:" + identifier + " Declaration at " + icode + " Not immediately preceded by a NEW" );
                  Opcode.DumpCode(lastNew,lastNew+20);
                  break;
               }
               topAddr = 0;
               Opcode.MoveCode(topAddr,lastNew,nCode,8);
               subInfo.anaCodeStart = Store.WriteInfo(codPtr,subLen);
               System.LogMessage("Reauthored: " + identifier + " by moving declaration to " + topAddr);         
               break;
            }
            else
            {
               topAddr = iCode;
            }
         }
      }
   }
   </gmSL>
   <Compile Project="\fkgtest\App\src\TOM-Trunk.vbp" />
   <Analyse />

<!-- this RunCommand element invokes the gmSL method above and moves the specified local variable declaration -->
   <RunCommand id="Refactoring.MoveDeclToTop" Prams="App.frmDDProcessingList.delete.xTemp"/>