// 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); }
// 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); }