Пример #1
0
        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");
        }
Пример #2
0
        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);
        }
Пример #3
0
        /**
         * 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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        public void JumpTest()
        {
            Parser parser = new Parser();

            parser.currentTxtCommand = "0;JMP";
            Assert.IsTrue(parser.Jump() == "JMP");
        }
Пример #6
0
        /// <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++;
                    }
                }
            }
        }
Пример #7
0
        /// <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

        }