public void ParseInstruction_Returns_ComputeInstruction_When_Instruction_Is_Valid(
            [Values("", "M", "D", "MD", "A", "AM", "AD", "AMD")]string dest, 
            [Values("", "JGT", "JEQ", "JGE", "JLT", "JNE", "JLE", "JMP")]string jump,
            [Values("0", "1", "-1", "D", "A", "!D", "!A", "-D", "-A", "D+1", "A+1", "D-1", "A-1", "D+A", "D-A",
                "A-D", "D&A", "D|A", "M", "!M", "-M", "M+1", "M-1", "D+M", "D-M", "M-D", "D&M", "D|M")]string comp)
        {
            // arrange
            string equals = "=", semicolon = ";";
            if (string.IsNullOrEmpty(dest))
                equals = string.Empty;
            if (string.IsNullOrEmpty(jump))
                semicolon = string.Empty;
            string line = dest + equals + comp + semicolon + jump;

            var nextParser = Substitute.For<IInstructionParser>();
            var destinationParser = Substitute.For<IComputeDestinationParser>();
            var jumpParser = Substitute.For<IComputeJumpParser>();
            var parser = new ComputeInstructionParser(nextParser, destinationParser, jumpParser);

            // act
            IInstruction result = parser.ParseInstruction(line);

            // assert
            nextParser.DidNotReceive().ParseInstruction(Arg.Any<string>());
            destinationParser.Received().ParseComputeDestination(Arg.Is(dest));
            jumpParser.Received().ParseComputeJump(Arg.Is(jump));
            Assert.AreEqual(typeof(ComputeInstruction), result.GetType());
        }
Beispiel #2
0
        public void ParseInstruction_Returns_ComputeInstruction_When_Instruction_Is_Valid(
            [Values("", "M", "D", "MD", "A", "AM", "AD", "AMD")] string dest,
            [Values("", "JGT", "JEQ", "JGE", "JLT", "JNE", "JLE", "JMP")] string jump,
            [Values("0", "1", "-1", "D", "A", "!D", "!A", "-D", "-A", "D+1", "A+1", "D-1", "A-1", "D+A", "D-A",
                    "A-D", "D&A", "D|A", "M", "!M", "-M", "M+1", "M-1", "D+M", "D-M", "M-D", "D&M", "D|M")] string comp)
        {
            // arrange
            string equals = "=", semicolon = ";";

            if (string.IsNullOrEmpty(dest))
            {
                equals = string.Empty;
            }
            if (string.IsNullOrEmpty(jump))
            {
                semicolon = string.Empty;
            }
            string line = dest + equals + comp + semicolon + jump;

            var nextParser        = Substitute.For <IInstructionParser>();
            var destinationParser = Substitute.For <IComputeDestinationParser>();
            var jumpParser        = Substitute.For <IComputeJumpParser>();
            var parser            = new ComputeInstructionParser(nextParser, destinationParser, jumpParser);

            // act
            IInstruction result = parser.ParseInstruction(line);

            // assert
            nextParser.DidNotReceive().ParseInstruction(Arg.Any <string>());
            destinationParser.Received().ParseComputeDestination(Arg.Is(dest));
            jumpParser.Received().ParseComputeJump(Arg.Is(jump));
            Assert.AreEqual(typeof(ComputeInstruction), result.GetType());
        }
        public void ParseInstruction_Returns_Delegates_To_Next_Parser_When_Instruction_Is_Invalid(string line, int timesDelegated)
        {
            // arrange
            var nextParser = Substitute.For<IInstructionParser>();
            var destinationParser = Substitute.For<IComputeDestinationParser>();
            var jumpParser = Substitute.For<IComputeJumpParser>();
            var parser = new ComputeInstructionParser(nextParser, destinationParser, jumpParser);

            // act
            parser.ParseInstruction(line);

            // assert
            nextParser.Received(timesDelegated).ParseInstruction(Arg.Any<string>());
        }
Beispiel #4
0
        public void ParseInstruction_Returns_Delegates_To_Next_Parser_When_Instruction_Is_Invalid(string line, int timesDelegated)
        {
            // arrange
            var nextParser        = Substitute.For <IInstructionParser>();
            var destinationParser = Substitute.For <IComputeDestinationParser>();
            var jumpParser        = Substitute.For <IComputeJumpParser>();
            var parser            = new ComputeInstructionParser(nextParser, destinationParser, jumpParser);

            // act
            parser.ParseInstruction(line);

            // assert
            nextParser.Received(timesDelegated).ParseInstruction(Arg.Any <string>());
        }
Beispiel #5
0
        public void ParseInstruction_Returns_Delegates_To_Next_Parser_When_Line_Contains_More_Than_One_Semicolon()
        {
            // arrange
            const string line              = "M+1;JMP;JGT";
            var          nextParser        = Substitute.For <IInstructionParser>();
            var          destinationParser = Substitute.For <IComputeDestinationParser>();
            var          jumpParser        = Substitute.For <IComputeJumpParser>();
            var          parser            = new ComputeInstructionParser(nextParser, destinationParser, jumpParser);

            // act
            parser.ParseInstruction(line);

            // assert
            nextParser.Received().ParseInstruction(Arg.Is(line));
        }
        public void ParseInstruction_Returns_Delegates_To_Next_Parser_When_Line_Contains_More_Than_One_Semicolon()
        {
            // arrange
            const string line = "M+1;JMP;JGT";
            var nextParser = Substitute.For<IInstructionParser>();
            var destinationParser = Substitute.For<IComputeDestinationParser>();
            var jumpParser = Substitute.For<IComputeJumpParser>();
            var parser = new ComputeInstructionParser(nextParser, destinationParser, jumpParser);

            // act
            parser.ParseInstruction(line);

            // assert
            nextParser.Received().ParseInstruction(Arg.Is(line));
        }
Beispiel #7
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("No source file provided.");
            }

            IPreprocessor whitespaceRemover = new WhitespaceRemover();
            IPreprocessor commentRemover = new CommentRemover();
            IPreprocessor labelSymbolPreprocessor = new LabelSymbolPreprocessor();
            IPreprocessor emptyLineRemover = new EmptyLineRemover();
            IPreprocessor predefinedSymbolPreprocessor = new PredefinedSymbolPreprocessor();
            IPreprocessor variableSymbolPreprocessor = new VariableSymbolPreprocessor();

            IEnumerable<IPreprocessor> preprocessors = new[] {
                commentRemover,
                whitespaceRemover,
                labelSymbolPreprocessor,
                emptyLineRemover,
                predefinedSymbolPreprocessor,
                variableSymbolPreprocessor
            };

            IDestinationsParser destinationsParser = new DestinationsParser();
            IComputationOptionsParser computationOptionsParser = new ComputationOptionsParser();
            IJumpConditionsParser jumpConditionsParser = new JumpConditionsParser();

            IInstructionParser addressingInstructionParser = new AddressingInstructionParser();
            IInstructionParser computeInstructionParser = new ComputeInstructionParser(destinationsParser, computationOptionsParser, jumpConditionsParser);

            IEnumerable<IInstructionParser> instructionParsers = new[] {
                addressingInstructionParser,
                computeInstructionParser
            };

            IParser parser = new Parser(instructionParsers);

            IDictionary<Type, IInstructionTranslator> translators = new Dictionary<Type, IInstructionTranslator>()
            {
                { typeof(AddressingInstruction), new AddressingInstructionTranslator() },
                { typeof(ComputeInstruction), new ComputeInstructionTranslator() }
            };

            ITranslator translator = new Translator(translators);

            IAssembler assembler = new Assembler(preprocessors, parser, translator);

            for (int i = 0; i < args.Length; i++)
            {
                var lines = File.ReadAllLines(args[i]);

                Result<List<string>> assemblyResult = assembler.Assemble(lines);

                if (assemblyResult.Error != null)
                {
                    Console.WriteLine($"Error: {assemblyResult.Error}");
                }

                File.WriteAllLines(Path.ChangeExtension(args[i], ".hack"), assemblyResult.Value);

                Console.WriteLine($"Successfully assembled {Path.GetFileName(args[i])}."); 
            }
        }