// Gets block size table entry by block id
        //
        // Returns: BlockSizeTableEntry associated with block ID or null
        public BlockSizeTableEntry GetBlockSizeTableEntry(int blockID)
        {
            // Inits
            bool found = false;
            BlockSizeTableEntry entry = null;
            BlockSizeTableEntry ret   = null;

            // Cycle through block size table entries
            for (int i = 0; (i < blockSizeTable.Count) && !found; i++)
            {
                // Get current entry
                entry = (BlockSizeTableEntry)blockSizeTable[i];

                // Check if Ids match and set found
                if (entry.BlockID == blockID)
                {
                    found = true;
                }
            }

            // Check if found entry
            if (found)
            {
                // Set return value
                ret = entry;
            }

            // Return entry or null
            return(ret);
        }
 // Adds entry to block size table
 public void AddBlockSizeTableEntry(BlockSizeTableEntry entry)
 {
     // Add to blcok size table
     blockSizeTable.Add(entry);
 }
Example #3
0
        // Gens op codes for all statments in block.
        // Manges which symbol table is current.
        // Keeps table of start and end of blocks.
        // All vars allocated on stack in this block
        // are set to not in use.
        //
        // Returns: Number of bytes generated.
        public override int GenOpCodes(OpCodeGenParam param)
        {
            // Inits
            int                 nextSymbIndex = 0;
            int                 bytesAdded    = 0;
            int                 block         = 0;
            ASTNode             curNode       = null;
            BlockSizeTableEntry entry         = null;
            VarTableEntry       varEntry      = null;
            SymbolHashTable     curSymbTable  = null;

            SymbolTableEntry[] symbEntries = null;
            DynamicBranchTreeNode <SymbolHashTable> startSymbolTable = null;

            // Get start symbol table
            startSymbolTable = param.curSymbTable;

            // Check if not root symbol table
            if (!param.firstBlock)
            {
                // Move into next symbol table child
                param.curSymbTable = param.curSymbTable.GetChild(param.curSymbTableIndex);


                // Record last symb index
                nextSymbIndex = param.curSymbTableIndex + 1;

                // Set current symbol table index to 0
                param.curSymbTableIndex = 0;
            }
            // Else root table
            else
            {
                // Set first block flag false
                param.firstBlock = false;
            }

            // Record current symbol table
            curSymbTable = param.curSymbTable.Data;

            // Add new entry to block size table
            entry = new BlockSizeTableEntry(param.curBlockID, param.curByte);
            param.tables.AddBlockSizeTableEntry(entry);
            param.curBlockID++;
            block = param.curBlockID - 1;

            // Cycle through stmts calling their gen op code
            curNode = this.leftMostChild;
            while (curNode != null)
            {
                // Try for over 256 bytes
                try
                {
                    // Call child statment gen op code method
                    bytesAdded += curNode.GenOpCodes(param);
                }

                // Catch over 256 bytes
                catch (IndexOutOfRangeException ex)
                {
                    throw ex;
                }

                // Get next symbling
                curNode = curNode.RightSibling;
            }

            // Reset cur symbol table index
            param.curSymbTableIndex = nextSymbIndex;

            // Reset cur symbol table
            param.curSymbTable = startSymbolTable;

            // Set end byte of block
            entry.EndByte = param.curByte - 1;

            // Remove out of scope vars from init var table
            param.tables.RemoveBlockVarEntries(block);

            // Cycle through symbol table
            symbEntries = curSymbTable.GetAllItems();
            for (int i = 0; i < symbEntries.Length; i++)
            {
                // Get item from temp var table
                varEntry = param.tables.GetVarTableEntry(symbEntries[i].EntryID);

                // Check if exists
                if (varEntry != null)
                {
                    // Set not in use flag
                    varEntry.InUse = false;

                    // Decrement var in use count
                    param.tables.DecVarInUseCount();
                }
            }

            // Return number of bytes
            return(bytesAdded);
        }
        // Fills in variable locations, heap locations, and jump size for
        // blocks in one pase. Collected some meta data about program.
        //
        // Returns: OpCodeData describing memory of program.
        private OpCodeData FillInTempOpCodeValues(OpCodeGenParam param)
        {
            // Inits
            int zeros       = 0;
            int num         = 0;
            int localOffSet = 0;
            int curByte     = 0;

            String[] strings = null;
            String   s       = null;

            String[]            offStrings  = null;
            String              o           = null;
            int                 len         = 0;
            VarTableEntry       varEntry    = null;
            HeapTableEntry      heapEntry   = null;
            BlockSizeTableEntry blockEntry  = null;
            OpCodeData          programData = new OpCodeData();
            TempByteData        byteData    = null;
            int                 location    = 0;

            // Determin stack size
            programData.stackSize  = param.tables.MaxVarUsage;
            programData.stackStart = param.curByte;

            // Determine heap size
            programData.heapSize  = param.tables.TotalHeapSize();
            programData.heapStart = param.curByte + programData.stackSize;



            // Write 00 over stack
            zeros = programData.stackSize;
            for (int i = 0; i < zeros; i++)
            {
                //param.opCodes.Append("00 ");
                param.AddBytes(0x00);
            }

            // Update size of file
            //param.curByte += zeros;

            // Send message
            SendGeneralMessage("Creating strings in memory...");

            // Fill in memory locations for heap
            for (int i = 0; i < param.tables.HeapTableCount(); i++)
            {
                heapEntry = param.tables.GetHeapTableEntryByIndex(i);

                heapEntry.MemoryLocation = programData.heapStart + curByte;

                // Write char
                for (int n = 0; n < heapEntry.StringValue.Length; n++)
                {
                    //param.opCodes.AppendFormat("{0} ", ((int)heapEntry.StringValue[n]).ToString("X2"));
                    param.AddBytes((byte)heapEntry.StringValue[n]);
                }
                //param.opCodes.Append("00 ");
                param.AddBytes(0x00);
                //param.curByte += heapEntry.Length + 1;

                curByte += heapEntry.Length;
            }

            // Send message
            SendGeneralMessage("String creation complete.");

            // Set program data size
            programData.totalBytes = param.curByte;


            // Cycle through codes
            for (int i = 0; i < param.insertBytes.Count; i++)
            {
                // Get byte data
                byteData = (TempByteData)param.insertBytes[i];

                // Get place holder string
                s = byteData.VarSymbol;

                // Check for V (var table
                if (s[0] == 'V')
                {
                    // Get number off string
                    num = int.Parse(s.Substring(1, s.Length - 1));

                    // Find entry
                    varEntry = param.tables.GetVarTableEntry(num);

                    // Replace entry with address
                    if (varEntry != null)
                    {
                        // Set location
                        location = programData.stackStart + varEntry.Offset;
                        param.SetByte(byteData.Index, (byte)(location));

                        if (varEntry.VarEntry != null)
                        {
                            varEntry.VarEntry.MemoryLocation = location;
                        }
                    }
                }
                // Check for H (heap)
                else if (s[0] == 'H')
                {
                    // Find length to s or end
                    len = s.Length;
                    for (int n = 1; n < s.Length; n++)
                    {
                        if (s[n] == 'S')
                        {
                            len = n;
                        }
                    }


                    // Get number off string
                    num = int.Parse(s.Substring(1, len - 1));


                    // Find entry
                    heapEntry = param.tables.GetHeapTableEntry(num);

                    // Split of F
                    offStrings = s.Split('S');


                    // Get offf num if valid
                    if (offStrings.Length > 1)
                    {
                        o = offStrings[1];

                        localOffSet = int.Parse(o.Substring(0, o.Length));
                    }
                    else
                    {
                        localOffSet = 0;
                    }


                    // Replace entry with address
                    if (heapEntry != null)
                    {
                        // strings[i] = String.Format("{0}", (heapEntry.MemoryLocation + localOffSet).ToString("X2"));
                        param.SetByte(byteData.Index, (byte)(heapEntry.MemoryLocation + localOffSet));
                    }
                }
                // Else if block parse flag
                else if (s[0] == 'B')
                {
                    // Find length to s or end
                    len = s.Length;
                    for (int n = 1; n < s.Length; n++)
                    {
                        if (s[n] == 'S')
                        {
                            len = n;
                        }
                    }

                    // Get number off string
                    num = int.Parse(s.Substring(1, len - 1));


                    // Find entry ( happens to work out that block id = index )
                    blockEntry = param.tables.GetBlockSizeTableEntry(num);


                    // Split of F
                    offStrings = s.Split('S');


                    // Get offf num if valid
                    if (offStrings.Length > 1)
                    {
                        o = offStrings[1];

                        localOffSet = int.Parse(o.Substring(0, o.Length));
                    }
                    else
                    {
                        localOffSet = 0;
                    }

                    // Replace entry with address
                    if (blockEntry != null)
                    {
                        //strings[i] = String.Format("{0}", (blockEntry.BlockSize + localOffSet).ToString("X2"));
                        param.SetByte(byteData.Index, (byte)(blockEntry.BlockSize + localOffSet));
                    }
                }
            }

            // Return program data
            return(programData);
        }