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