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_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>()); }
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>()); }
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)); }
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])}."); } }