// Finds var table entry by VarID // // Returns: VarTableEntry or null on no find public VarTableEntry GetVarTableEntry(int varID) { // Inits bool found = false; VarTableEntry entry = null; VarTableEntry ret = null; // Cycle through block size table entries for (int i = 0; (i < varTable.Count) && !found; i++) { // Get current entry entry = (VarTableEntry)varTable[i]; // Check if Ids match and set found if (entry.VarID == varID) { found = true; } } // Check if found entry if (found) { // Set return value ret = entry; } // Return entry or null return(ret); }
// Gens op codes to find address from var table, // and store value in accumulator. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits VarTableEntry varEntry = null; // Find var in var table varEntry = param.tables.GetVarTableEntry(SymbolTableEntry.EntryID); // Verify var entry exists if (varEntry != null) { try { // Load value into accumlator param.opCodes.AppendFormat("AD V{0} 00 ", varEntry.VarID); param.AddBytes(0xAD); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); } // Catch over 256 byte error, // and throw up catch (IndexOutOfRangeException ex) { throw ex; } } // Return number of bytes return(3); }
// Creates a var table entry based on symbol table entry, // and calculates current in use off set (position). // // Returns: New entry created. public VarTableEntry CreateVarTableEntry(SymbolTableEntry entry) { // Inits VarTableEntry varEntry = new VarTableEntry(entry.EntryID, entry); // Set off set varEntry.Offset = FindNextAvaialbleOffset(); // Add to table varTable.Add(varEntry); // Return entry return(varEntry); }
// Finds next avaialble offset to maximize stack size // // Returns: Next avaialbe (un used) mem location offset from start public int FindNextAvaialbleOffset() { // Inits bool foundOffset = false; bool found = false; VarTableEntry varEntry = null; int offset = 0; int tableCount = varTable.Count; // Cycle through all possible offsets for (int i = 0; ((i < tableCount) && !found); i++) { // Reset found off set flag foundOffset = false; // Cycle through all entries for (int n = 0; ((n < tableCount) && !foundOffset); n++) { // Get var entry varEntry = (VarTableEntry)varTable[n]; // Check if in use and right offet if (varEntry.InUse && varEntry.Offset == i) { // Set found off set flag foundOffset = true; } } // Check if did not find off set if (!foundOffset) { // Record offset offset = i; // Set found next offset flag found = true; } } // Check if not found, than add 1 to count if (!found) { offset = tableCount; } // Return next off set return(offset); }
// Gens code that allocates 00 to a location in memory, // tracked in var table. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits VarTableEntry varEntry = null; // Create var table entry for this varEntry = param.tables.CreateVarTableEntry(id.SymbolTableEntry); // Increment current vars in use param.tables.IncVarIsUseCount(); // Check if entry found incase of some wierd error if (varEntry != null) { try { // Load accumlator with 0 //param.opCodes.Append("A9 00 "); param.AddBytes(0xA9, 0x00); // Add var entry to init value table // for optimization param.tables.AddInitValueEntry(id.Value, param.curByte - 1, param.curBlockID - 1, id.SymbolTableEntry.DataType); // Copy to temp location in memory //param.opCodes.AppendFormat("8D V{0} 00 ",varEntry.VarID); param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); } // Catch over 256 byte error, // and throw up catch (IndexOutOfRangeException ex) { throw ex; } // Add number of bytes // param.curByte += 5; } // Return cur bytes return(5); }
// Get var table entry by index // // Throws: IndexOutOfRangeException // Returns: Entry at given index. public VarTableEntry GetVarTableEntryByIndex(int index) { //Inits VarTableEntry ret = null; if (index >= varTable.Count || index < 0) { throw new IndexOutOfRangeException("OpCodeVarTable entry idex out of range."); } else { ret = (VarTableEntry)varTable[index]; } // Return var table entry return(ret); }
// Creates a new temp var ref, with a new calculated offset. // // Returns: Temp var entry. public VarTableEntry CreateTempVarTableEntry() { // Inits VarTableEntry entry = null; // Create new entry entry = new VarTableEntry(curTempVarID, null); // Increment cur temp var id curTempVarID++; // Set off set entry.Offset = FindNextAvaialbleOffset(); // Add to table varTable.Add(entry); // Return found var or newly created one return(entry); }
// Gens op codes for if statement, and following block. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits int bytes = 0; int bytes2 = 0; VarTableEntry varEntry = null; try { // Gen op codes for boolean exp ( results in accum ) bytes += expr.GenOpCodes(param); // Create new temp var varEntry = param.tables.CreateTempVarTableEntry(); // Set in use flag varEntry.InUse = true; // Increment in use count param.tables.IncVarIsUseCount(); // Move results into temp memory param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Load 1 into accum param.AddBytes(0xA2, 0x01); // Compare temp (res of expr) to true (1) param.AddBytes(0xEC); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Branch to end of block (using curBlockID, as gen op // will use this id and incremement it. The current // block at any time is really curBlockID - 1 ). param.AddBytes(0xD0); param.AddByteForUpdate('B', param.curBlockID); // Incrmeent bytes bytes += 10; // Set temp var not in use varEntry.InUse = false; // Decremeent in use count param.tables.DecVarInUseCount(); // Gen op codes for block bytes += block.GenOpCodes(param); } // Catch over 256 byte error, // and throw up catch (IndexOutOfRangeException ex) { throw ex; } // Return bytes added return(bytes); }
// Gens opp codes for int operation add. // Results are in the accum. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits VarTableEntry varEntry = null; int bytes = 0; int bytes2 = 0; try { // Load accummulator with constant param.AddBytes(0xA9, (byte)intVal.Value); // Get avaialbe stack location varEntry = param.tables.CreateTempVarTableEntry(); // Set in use flag varEntry.InUse = true; // Increment var in use flag param.tables.IncVarIsUseCount(); // Store accumulator in stack location param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Increment bytes bytes += 5; // Check if expr is not null if (expr != null) { // Gen op codes for expr bytes2 += expr.GenOpCodes(param); } // Else expr is null else { // Move 0 to accumulator param.AddBytes(0xA9, 0x00); // Increment bytes bytes2 += 2; } // Add temp var to accumulator param.AddBytes(0x6D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Increment bytes bytes2 += 3; // Set temp var not in use varEntry.InUse = false; // Decrement counter param.tables.DecVarInUseCount(); } // Catch over 256 byte error, // and throw up catch (IndexOutOfRangeException ex) { throw ex; } // Return bytes added return(bytes + bytes2); }
// Gens op codes for while loop. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits int bytes = 0; int bytes2 = 0; int jumpByte = 0; int startByte = param.curByte; VarTableEntry varEntry = null; VarTableEntry varEntry2 = null; try { // Gen op codes for boolean exp ( results in accum ) bytes += expr.GenOpCodes(param); // Create new temp var varEntry = param.tables.CreateTempVarTableEntry(); // Set in use flag varEntry.InUse = true; // Increment in use count param.tables.IncVarIsUseCount(); // Move results into temp memory //param.opCodes.AppendFormat("8D V{0} 00 ", varEntry.VarID); param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Incrmeent bytes bytes += 3; // Capture current byte (where to jump to at end of loop) jumpByte = param.curByte + bytes; // Load 1 into accum //param.opCodes.Append("A2 01 "); param.AddBytes(0xA2, 0x01); // Compare temp (res of expr) to true (1) //param.opCodes.AppendFormat("EC V{0} 00 ", varEntry.VarID); param.AddBytes(0xEC); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Branch to end of block, and 12 more to skip // forced jump to begining of while //param.opCodes.AppendFormat("D0 B{0}S{1} ", param.curBlockID, 12); param.AddBytes(0xD0); param.AddByteForUpdate('B', param.curBlockID, 12); // Incrmeent bytes bytes += 7; // Set current byte (for calling gen op) //param.curByte += 10; // Set temp var not in use varEntry.InUse = false; // Decremeent in use count param.tables.DecVarInUseCount(); // Gen op codes for block bytes2 += block.GenOpCodes(param); // ### Force NE Jump ### // // Create another new temp var varEntry2 = param.tables.CreateTempVarTableEntry(); // Set in use varEntry2.InUse = true; // Inc var in use count param.tables.IncVarIsUseCount(); // Load 0 into acc //param.opCodes.Append("A9 00 "); param.AddBytes(0xA9, 0x00); // Load acc to temp var //param.opCodes.AppendFormat("8D V{0} 00 ", varEntry2.VarID); param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry2.VarID); param.AddBytes(0x00); // Load 1 into x reg //param.opCodes.Append("A2 01 "); param.AddBytes(0xA2, 0x01); // Compare temp to x (which will always be not equal ) //param.opCodes.AppendFormat("EC V{0} 00 ", varEntry2.VarID); param.AddBytes(0xEC); param.AddByteForUpdate('V', varEntry2.VarID); param.AddBytes(0x00); // Incremeent bytes bytes2 += 12; // Update bytes ( I do it before next statmement for // caculation of accurate curByte ) //param.curByte += 12; // Branch to top of while loop ( note these two bytes already // added to curByte ) //param.opCodes.AppendFormat("D0 {0} ",(256 - param.curByte + startByte + 1).ToString("X2")); param.AddBytes(0xD0, (byte)(255 - (param.curByte - startByte + 1))); // Set temp var not in use varEntry2.InUse = false; // Decremeent in use count param.tables.DecVarInUseCount(); } // Catch over 256 byte error, // and throw up catch (IndexOutOfRangeException ex) { throw ex; } // Return bytes added return(bytes + bytes2); }
// Gens op codes for print statment. // Calls system to print based on type of expr. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits int bytes = 0; VarTableEntry varEntry = null; VarTableEntry varEntryTrue = null; VarTableEntry varEntryFalse = null; HeapTableEntry heapEntryTrue = null; HeapTableEntry heapEntryFalse = null; IDASTNode idASTNode = null; try { // Gen op codes for expr. Results in accum bytes += expr.GenOpCodes(param); // Create temp var on stack varEntry = param.tables.CreateTempVarTableEntry(); varEntry.InUse = true; param.tables.IncVarIsUseCount(); // Load accumlator to memory (results from expr ) //param.opCodes.AppendFormat("8D V{0} 00 ", varEntry.VarID); param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); bytes += 3; // Inc cur bytes //param.curByte += 3; // Check if int expr, or var dec of type int if ((expr is IntExprASTNode) || ((expr is IDASTNode) && (((IDASTNode)expr).SymbolTableEntry.DataType == DataType.DT_INT))) { // Load 1 int x reg //param.opCodes.Append("A2 01 "); param.AddBytes(0xA2, 0x01); // Load into y register //param.opCodes.AppendFormat("AC V{0} 00 ",varEntry.VarID); param.AddBytes(0xAC); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Make system call //param.opCodes.Append("FF "); param.AddBytes(0xFF); // Inc bytes bytes += 6; // Inc cur bytes // param.curByte += 6; } // Else check if bool expr, or var dec with boolean type else if ((expr is BooleanExprASTNode) || ((expr is IDASTNode) && (((IDASTNode)expr).SymbolTableEntry.DataType == DataType.DT_BOOLEAN))) { // Create strings for true and false on heap. // If already on their it wont allocate new // ones, but use the same. heapEntryTrue = param.tables.AddHeapTableEntry(param, "true"); heapEntryFalse = param.tables.AddHeapTableEntry(param, "false"); // Create temp vars on stack for true varEntryTrue = param.tables.CreateTempVarTableEntry(); varEntryTrue.InUse = true; param.tables.IncVarIsUseCount(); // Create temp var on stack for false varEntryFalse = param.tables.CreateTempVarTableEntry(); varEntryFalse.InUse = true; param.tables.IncVarIsUseCount(); // Load true string address in acc //param.opCodes.AppendFormat("A9 H{0} ", heapEntryTrue.HeapID); param.AddBytes(0xA9); param.AddByteForUpdate('H', heapEntryTrue.HeapID); // Move to temp var //param.opCodes.AppendFormat("8D V{0} 00 ", varEntryTrue.VarID); param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntryTrue.VarID); param.AddBytes(0x00); // Load true add in acc //param.opCodes.AppendFormat("A9 H{0} ", heapEntryFalse.HeapID); param.AddBytes(0xA9); param.AddByteForUpdate('H', heapEntryFalse.HeapID); // Move to temp var //param.opCodes.AppendFormat("8D V{0} 00 ", varEntryFalse.VarID); param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntryFalse.VarID); param.AddBytes(0x00); // Load false into y reg //param.opCodes.AppendFormat("AC V{0} 00 ", varEntryFalse.VarID); param.AddBytes(0xAC); param.AddByteForUpdate('V', varEntryFalse.VarID); param.AddBytes(0x00); // Load 01 int x reg //param.opCodes.Append("A2 01 "); param.AddBytes(0xA2, 0x01); // Compare results with results from acc //param.opCodes.AppendFormat("EC V{0} 00 ", varEntry.VarID); param.AddBytes(0xEC); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Branch on not equal x bytes //param.opCodes.Append("D0 04 "); param.AddBytes(0xD0, 0x03); // Load true into y reg //param.opCodes.AppendFormat("AC V{0} 00 ", varEntryTrue.VarID); param.AddBytes(0xAC); param.AddByteForUpdate('V', varEntryTrue.VarID); param.AddBytes(0x00); // Load 2 int x reg //param.opCodes.Append("A2 02 "); param.AddBytes(0xA2, 0x02); // Make system call //param.opCodes.Append("FF "); param.AddBytes(0xFF); // Inc bytes bytes += 26; // Inc cur bytes //param.curByte += 26; /* * // Set temp vars not in use * varEntryTrue.InUse = false; * varEntryFalse.InUse = false; * param.tables.DecVarInUseCount(); * param.tables.DecVarInUseCount(); * */ } // Else check if string expr or var of string type else if ((expr is StringExprASTNode) || ((expr is IDASTNode) && (((IDASTNode)expr).SymbolTableEntry.DataType == DataType.DT_STRING))) { // Load into temp var //param.opCodes.AppendFormat("8D // Load expr res into y reg //param.opCodes.AppendFormat("AC V{0} 00 ", varEntry.VarID); param.AddBytes(0xAC); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Load 2 int x reg //param.opCodes.Append("A2 02 "); param.AddBytes(0xA2, 0x02); // Make system call //param.opCodes.Append("FF "); param.AddBytes(0xFF); // Increment bytes bytes += 6; // Inc cur bytes //param.curByte += 6; } // Reset temp var varEntry.InUse = false; param.tables.DecVarInUseCount(); } // Catch over 256 byte error, // and throw up catch (IndexOutOfRangeException ex) { throw ex; } // Return bytes added return(bytes); }
// 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); }
// Gens op codes for comparision of boolean expr == or !=, // and puts results in accum. 1 for true, 0 for false. // // Returns: Number of bytes generated. public override int GenOpCodes(OpCodeGenParam param) { // Inits VarTableEntry varEntryTemp = null; int bytes = 0; int index = 0; // ### Checking Expr 1 ### // // try for error try { // Gen op codes for expr one bytes += exprOne.GenOpCodes(param); // ### Check if not only bool val, as if it was ### // // ### the value is just left in the accumulator ### // // Check if expr 2 is not null if (exprTwo != null) { // ### Add acc results from expr 1 ### // // Add temp var for expr one results varEntryTemp = param.tables.CreateTempVarTableEntry(); // Set in use varEntryTemp.InUse = true; // Increment var in use param.tables.IncVarIsUseCount(); // Move value of accumulator to temp var param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntryTemp.VarID); param.AddBytes(0x00); // ### Generate expr 2 value and put in accumm ### // // Gen op codes for expr two bytes += exprTwo.GenOpCodes(param); // ### Compare values of temp var (expr 1), and accum (expr2) ### // // ### Put results in accumulator. ### // // Load temp value from first expr into reg x param.AddBytes(0xAE); param.AddByteForUpdate('V', varEntryTemp.VarID); param.AddBytes(0x00); // Move accum into same temp val param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntryTemp.VarID); param.AddBytes(0x00); // Increment bytes bytes += 9; // Check if equals if (value == BOOLOP_TYPE.BOOLOP_EQUALS) { // Set false in accum "A9 00 " param.AddBytes(0xA9, 0x00); } else { // Set true in accum param.AddBytes(0xA9, 0x01); } // Compare x to temp var param.AddBytes(0xEC); param.AddByteForUpdate('V', varEntryTemp.VarID); param.AddBytes(0x00); // Branch 2 bytes if equl param.AddBytes(0xD0, 0x02); // Check if equals if (value == BOOLOP_TYPE.BOOLOP_EQUALS) { // Set true in accum (skip in nnot equal) param.AddBytes(0xA9, 0x01); } else { // Set false in accum (skip in nnot equal) param.AddBytes(0xA9, 0x00); } // Increment bytes bytes += 9; // Reset in use flag for temp var varEntryTemp.InUse = false; // Decremeent in use flag param.tables.DecVarInUseCount(); } } // Throw error up catch (IndexOutOfRangeException ex) { throw ex; } // Return number of bytes return(bytes); }
// Generates op codes for expr, which is put in accum. // This value is then loaded into var's value. // // Returns: Number of op code bytes added. public override int GenOpCodes(OpCodeGenParam param) { // Inits VarTableEntry varEntry = null; InitValueEntry initEntry = null; int bytes = 0; int curByte = param.curByte; bool value = false; StringExprASTNode stringNode = null; HeapTableEntry heapEntry = null; bool initVar = false; // Try for over 256 bytes try { // Get init value entry initEntry = param.tables.GetLastInitValueEntry(id.Value, id.SymbolTableEntry.DataType); // Check if value was already init if (initEntry != null) { // Set init var initVar = true; // Check if int value if (expr is IntValASTNode) { // Set byte with value param.SetByte(initEntry.Index, (byte)((IntValASTNode)expr).Value); // Set inital value in symbol table id.SymbolTableEntry.IntValue = ((IntValASTNode)expr).Value; } else if (expr is BoolValASTNode) { // Get bool value if (((BoolValASTNode)expr).Value == BOOLVAL_TYPE.BOOLVAL_TRUE) { value = true; } else { value = false; } // Set byte with value param.SetByte(initEntry.Index, (byte)(value == true ? 1 : 0)); // Set inital value in symbol table id.SymbolTableEntry.IntValue = (value == true ? 1 : 0); } else if (expr is StringExprASTNode) { stringNode = ((StringExprASTNode)expr); heapEntry = param.tables.AddHeapTableEntry(param, stringNode.Value); param.AddInsertByte(initEntry.Index, 'H', heapEntry.HeapID, 0); id.SymbolTableEntry.StringValue = stringNode.Value; } else { initVar = false; } // Remove from table if iniitalized if (initVar) { param.tables.RemoveLastInitValueEntry(initEntry); param.initVars++; } } // Check if initialized optimization if (!initVar) { // Gen op codes for expr , value in accum bytes += expr.GenOpCodes(param); // Retreive temp placehold from var table varEntry = param.tables.GetVarTableEntry(id.SymbolTableEntry.EntryID); // Move accumlator to memory "8D V{0} 00 " param.AddBytes(0x8D); param.AddByteForUpdate('V', varEntry.VarID); param.AddBytes(0x00); // Increment bytes bytes += 3; } } // Catch over 256 bytes catch (IndexOutOfRangeException ex) { throw ex; } // Return bytesa added return(bytes); }