So I have been reading [this][1] great book and I decided to do the Project in Chapter 5: Writing an Assembler for the Hack Assembly Language. You can find the specification for the Hack Machine Language and the Hack Assembly Language [here][2]. Here is my implementation: <!-- language: lang-java --> package biz.tugay.hack.assembler; /* User: [email protected] Date: 07/03/15 Time: 10:47 */ import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class HackAssembler { private static File machineLanguageFile; private static File assembled; private static FileWriter fileWriter; private static int variableAddressCounter = 16; private static Map<String,Integer> variableAddressMap = new HashMap<String,Integer>(); private static Map<String,Integer> loopAddressMap = new HashMap<String, Integer>(); public static void main(String[] args) throws IOException { doChecksForSourceFile(args); checkLabelsAndPopulateLoopAddressMap(machineLanguageFile); Scanner machineLanguageFileScanner = new Scanner(machineLanguageFile); fileWriter = new FileWriter(assembled); while(machineLanguageFileScanner.hasNextLine()){ String nextAssemblyLine = machineLanguageFileScanner.nextLine(); assemble(nextAssemblyLine); } fileWriter.flush(); fileWriter.close(); } private static void assemble(String lineToBeAssembled) throws IOException { if(lineToBeAssembled.startsWith("(")) { } else if(lineToBeAssembled.startsWith("@")) { assemble_A_Instruction(lineToBeAssembled); fileWriter.write(System.lineSeparator()); } else { assemble_C_Instruction(lineToBeAssembled); fileWriter.write(System.lineSeparator()); } } private static void assemble_C_Instruction(String lineToBeAssembled) throws IOException { String compMnemonnic; String destinationMnemonnic = "null"; String jumpMnemonnic = "null"; String compBinaryRepresentation; String jumpBinaryRepresentation; String destinationBinaryRepresentation; String[] split = lineToBeAssembled.split("="); String s = split[split.length - 1]; String[] split1 = s.split(";"); compMnemonnic = split1[0]; compBinaryRepresentation = BInstructionsMap.computationMnemonicMap.get(compMnemonnic); if(lineToBeAssembled.contains("=")) { destinationMnemonnic = lineToBeAssembled.split("=")[0]; } destinationBinaryRepresentation = BInstructionsMap.destinationMnemonnicMap.get(destinationMnemonnic); if(lineToBeAssembled.contains(";")) { String[] x = lineToBeAssembled.split(";"); jumpMnemonnic = x[x.length-1]; } jumpBinaryRepresentation = BInstructionsMap.jumpMnemonnicMap.get(jumpMnemonnic); fileWriter.write("111" + compBinaryRepresentation + destinationBinaryRepresentation + jumpBinaryRepresentation); } private static void assemble_A_Instruction(String lineToBeAssembled) throws IOException { String subString = lineToBeAssembled.substring(1); try { Integer.parseInt(subString); assemble_A_InstructionWithDirectAddress(subString); } catch (NumberFormatException e) { assemble_A_InstructionWithVariableOrLabel(subString); } } private static void assemble_A_InstructionWithVariableOrLabel(String subString) throws IOException { int assignedAddress = variableAddressCounter; if(loopAddressMap.containsKey(subString)) { assignedAddress = loopAddressMap.get(subString); } else if(variableAddressMap.containsKey(subString)) { assignedAddress = variableAddressMap.get(subString); } else if(!variableAddressMap.containsKey(subString)) { variableAddressMap.put(subString,variableAddressCounter); variableAddressCounter++; } fileWriter.write(appendZerosToString(Integer.toBinaryString(assignedAddress))); } private static void assemble_A_InstructionWithDirectAddress(String lineToBeAssembled) throws IOException { fileWriter.write(appendZerosToString(Integer.toBinaryString(Integer.parseInt(lineToBeAssembled)))); } private static String appendZerosToString(String stringToBeAppended) { char[] chars = stringToBeAppended.toCharArray(); int zerosToAppend = 16 - chars.length; StringBuilder stringBuilder = new StringBuilder(); for(int i=0;i<zerosToAppend;i++) { stringBuilder.append("0"); } stringBuilder.append(stringToBeAppended); return stringBuilder.toString(); } public static void doChecksForSourceFile(String[] args) throws IOException { // Check if filename has been passed to the program. if(args.length == 0) { System.out.println("Please pass the filename as parameter without the file extension."); System.exit(0); } // Check if the passed file exists. machineLanguageFile = new File(args[0]+".asm"); if(!machineLanguageFile.exists()) { System.out.println("File does not exist.."); System.exit(0); } // Create the new file which will contain the machine instructions in binary format. assembled = new File(args[0]+".hack"); boolean delete = true; if(assembled.exists()) { delete = assembled.delete(); } boolean newFile = assembled.createNewFile(); if(!delete ||!newFile) { System.out.println("Can not create new file.."); System.exit(0); } } private static void checkLabelsAndPopulateLoopAddressMap(File machineLanguageFile) throws FileNotFoundException { Scanner machineLanguageFileScanner = new Scanner(machineLanguageFile); int counter = 0; while(machineLanguageFileScanner.hasNextLine()){ String nextAssemblyLine = machineLanguageFileScanner.nextLine(); if(nextAssemblyLine.startsWith("(")) { String loopLabel = nextAssemblyLine.substring(1,nextAssemblyLine.length()-1); loopAddressMap.put(loopLabel,counter); counter--; } counter++; } } } package biz.tugay.hack.assembler; /* User: [email protected] Date: 07/03/15 Time: 13:14 */ import java.util.HashMap; import java.util.Map; public class BInstructionsMap { public static Map<String,String> computationMnemonicMap = new HashMap<String,String>(); public static Map<String,String> jumpMnemonnicMap = new HashMap<String, String>(); public static Map<String,String> destinationMnemonnicMap = new HashMap<String, String>(); static { computationMnemonicMap.put("0" ,"0101010"); computationMnemonicMap.put("1" ,"0111111"); computationMnemonicMap.put("-1" ,"0111010"); computationMnemonicMap.put("D" ,"0001100"); computationMnemonicMap.put("A" ,"0110000"); computationMnemonicMap.put("!D" ,"0001101"); computationMnemonicMap.put("!A" ,"0110001"); computationMnemonicMap.put("-D" ,"0001111"); computationMnemonicMap.put("-A" ,"0110011"); computationMnemonicMap.put("D+1","0011111"); computationMnemonicMap.put("A+1","0110111"); computationMnemonicMap.put("D-1","0001110"); computationMnemonicMap.put("A-1","0110010"); computationMnemonicMap.put("D+A","0000010"); computationMnemonicMap.put("D-A","0010011"); computationMnemonicMap.put("A-D","0000111"); computationMnemonicMap.put("D&A","0000000"); computationMnemonicMap.put("D|A","0010101"); computationMnemonicMap.put("M" ,"1110000"); computationMnemonicMap.put("!M" ,"1110001"); computationMnemonicMap.put("-M" ,"1110011"); computationMnemonicMap.put("M+1","1110111"); computationMnemonicMap.put("M-1","1110010"); computationMnemonicMap.put("D+M","1000010"); computationMnemonicMap.put("D-M","1010011"); computationMnemonicMap.put("M-D","1000111"); computationMnemonicMap.put("D&M","1000000"); computationMnemonicMap.put("D|M","1010101"); } static { jumpMnemonnicMap.put("null","000"); jumpMnemonnicMap.put("JGT" ,"001"); jumpMnemonnicMap.put("JEQ" ,"010"); jumpMnemonnicMap.put("JGE" ,"011"); jumpMnemonnicMap.put("JLT" ,"100"); jumpMnemonnicMap.put("JNE" ,"101"); jumpMnemonnicMap.put("JLE" ,"110"); jumpMnemonnicMap.put("JMP" ,"111"); } static { destinationMnemonnicMap.put("null","000"); destinationMnemonnicMap.put("M" ,"001"); destinationMnemonnicMap.put("D" ,"010"); destinationMnemonnicMap.put("MD" ,"011"); destinationMnemonnicMap.put("A" ,"100"); destinationMnemonnicMap.put("AM" ,"101"); destinationMnemonnicMap.put("AD" ,"110"); destinationMnemonnicMap.put("AMD" ,"111"); } } If you would also like to do this exercise, you can find the software [here][3]. [1]: http://www.amazon.com/Elements-Computing-Systems-Building-Principles/dp/0262640686/ref=sr_1_1?ie=UTF8&qid=1425746349&sr=8-1&keywords=Elements%20of%20Computing%20Systems [2]: http://www.cs.huji.ac.il/course/2002/nand2tet/docs/ch_4_machine_language.pdf [3]: http://www.nand2tetris.org/software.php