public void SomeTest() { Parser parser = new Parser(); parser.currentTxtCommand = "D=A"; String destMnemonic = parser.Dest(); Assert.IsTrue(destMnemonic == "D", "parser failed"); String compMnemonic = parser.Comp(); Assert.IsTrue(compMnemonic == "A", "parser failed"); string destBin = CodeGenerator.Dest(destMnemonic); Assert.IsTrue(destBin == "010"); string compbin = CodeGenerator.Comp(compMnemonic); Assert.IsTrue(compbin == "0110000"); }
public void CompTest() { Parser parser = new Parser(); parser.currentTxtCommand = "D=A"; Assert.IsTrue(parser.Comp() == "A"); parser.currentTxtCommand = "M=D"; Assert.IsTrue(parser.Comp() == "D"); parser.currentTxtCommand = ";JMP"; parser.Comp(); Assert.IsTrue(parser.Comp() == String.Empty); parser.currentTxtCommand = "0;JMP"; Assert.IsTrue(parser.Comp() == "0"); parser.currentTxtCommand = "M=D+M"; Assert.IsTrue(parser.Comp() == "D+M"); parser.currentTxtCommand = "MD=M+1"; Assert.IsTrue(parser.Comp() == "M+1"); parser.currentTxtCommand = "D;JNE"; Assert.IsTrue(parser.Comp() == "D"); bool exceptionThrown = false; try { parser.currentTxtCommand = "@0"; parser.Comp(); } catch { exceptionThrown = true; } Assert.IsTrue(exceptionThrown); }
/** * Drives the Assembler. * * @param args program runtime arguments * * @refcode N/A * @errtest * Differing program arguments. * @errmsg * - Incorrect number of arguments. * - Usage information * @author Mark * @creation April 5, 2011 * @modlog * - April 6, 2011 - Mark - Initializes Logger. * - April 8, 2011 - Mark - Reads files in from the command line. * - April 8, 2011 - Mark - Initializes and uses a Parser object. * - April 8, 2011 - Mark - Outputs results to screen. * - April 9, 2011 - Mark - Uses an IntermediateFile object. * - April 9, 2011 - Mark - Catches problem with improper number of arguments. * - April 10, 2011 - Mark - Uses a SymbolTable object. * - May 8, 2011 - Jacob - Only process one file. * @teststandard Andrew Buelow * @codestandard Mark Mathis */ public static void Main(string[] args) { string infile = null; string outfile = null; // single arg given, output to stdout if (args.Length == 1) { infile = args[0]; outfile = System.IO.Path.GetFileNameWithoutExtension(args[0]) + ".obj"; } // two args given, read in the first and output to the second else if (args.Length == 2) { infile = args[0]; outfile = args[1]; } // invalid; print usage else { Usage(); System.Environment.Exit(1); } Errors.SetResource(Properties.Resources.errors); // pass 1 Logger.Log("Starting up", "Main"); SymbolTable symb = new SymbolTable(); Parser pars = new Parser(); IntermediateFile interSource; pars.ParseSource(infile, out interSource, out symb); bool fatalerr = false; AssemblyReport report = new AssemblyReport(); // Checking for fatal errors and creating an Assembly Report to display if a fatal error is found. foreach (IntermediateLine line in interSource) { if (line.Fatal) { fatalerr = true; } report.Add(line.ProgramCounter, "0000", ' ', line.SourceLineNumber, line.SourceLine, line.GetThreeErrors()); } if (fatalerr) { // Output the report Console.WriteLine(report); // and symbol table Console.WriteLine(symb); // Stop the assembler System.Environment.Exit(10); } #if DEBUG Console.WriteLine(interSource); #endif // pass 2 Logger.Log("Starting pass 2", "Main"); interSource.CalculateModuleLength(); report = new AssemblyReport(); ObjectFile obj = new ObjectFile(ref interSource, ref symb, ref report); obj.Render(outfile); // print out assembly report Console.WriteLine(report); // and symbol table Console.WriteLine(symb); }
public void SymbolTest() { Parser parser = new Parser(); parser.currentTxtCommand = "@0"; Assert.IsTrue(parser.Symbol() == "0"); parser.currentTxtCommand = "@Something"; Assert.IsTrue(parser.Symbol() == "Something"); parser.currentTxtCommand = "(foo)"; Assert.IsTrue(parser.Symbol() == "foo"); bool exceptionThrown = false; try { parser.currentTxtCommand = "M=D+M"; parser.Symbol(); } catch { exceptionThrown = true; } Assert.IsTrue(exceptionThrown); }
public void JumpTest() { Parser parser = new Parser(); parser.currentTxtCommand = "0;JMP"; Assert.IsTrue(parser.Jump() == "JMP"); }
/// <summary> /// First pass of the assembly file. /// Finds all symbols and stores them in a Dictionary along (with the next line number) /// i.e. fills the symbol table /// </summary> /// <param name="inputBytes">The input bytes.</param> /// <param name="symbolTable">The symbol table.</param> private void FillSymbolTable(byte[] inputBytes) { using (MemoryStream inputStream = new MemoryStream(inputBytes)) using (Parser parser = new Parser(inputStream)) { int lineCounter = 0; while (parser.HasMoreCommands()) { parser.Advance(); if (parser.CommandType() == Command.L_COMMAND) { // store the lable and next line this.SymbolTable.AddEntry(parser.Symbol(), lineCounter); } else if (parser.CommandType() == Command.C_COMMAND || parser.CommandType() == Command.A_COMMAND) { // ignore non label commands in the asm file. lineCounter++; } } } }
/// <summary> /// Seconds the pass. /// TODO - refactor! break into smaller methods!!! /// after the first symbol table filling pass, /// we march thru the lines again, the parser gives us each command and its type /// we pass these to the code generator to build our binary representation /// </summary> /// <param name="inputBytes">The input bytes.</param> /// <param name="symbolTable">The symbol table.</param> /// <returns></returns> private string FinalPass(byte[] inputBytes) { MemoryStream inputStream = new MemoryStream(inputBytes); using (Parser parser = new Parser(inputStream)) { StringBuilder fullBinaryListing = new StringBuilder(); // magic number, new variables in the hack platform are stored from address 16 upwards. int addressCounter = 16; //TODO - horrible nested while and if chain - break into methods while (parser.HasMoreCommands()) { String binaryLine = String.Empty; parser.Advance(); if (parser.CommandType() == Command.C_COMMAND) { binaryLine = CodeGenerator.GetFullCInstruction(parser.Comp(), parser.Dest(), parser.Jump()) + Environment.NewLine; fullBinaryListing.Append(binaryLine); } else if (parser.CommandType() == Command.A_COMMAND) { binaryLine = this.Handle_A_Command(parser.Symbol(), ref addressCounter); fullBinaryListing.Append(binaryLine + Environment.NewLine); } } return fullBinaryListing.ToString(); } #endregion }