I have been reading this 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.Here is my implementation:package biz.tugay.hack.assembler;/* User: koray.asm@tugay.biz 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: koray@tugay.biz 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.
Assembler for Hack Assembly Language
java;assembly
My two cents:Your lines are long:code gets harder to read the wider it becomesYou pass around ambiguously named variables. At first glance, it's hard to know what args[0] or subString is.Some names are very long.Spaces.for(int i=0;i<zerosToAppend;i++);can easily be for(int i = 0; i < zerosToAppend; i++);There are no comments describing what the code does.Comments can never be replaced by code alone. Strings are hard-coded all over the place. It's much easier to understandassembled = new File(fileName + FILE_SUFFIX);thanassembled = new File(args[0]+.hack);It helps to have these type of things all in one place in anticipation of one of them needing change.Over all, it looks pretty decent. Just remember: K.I.S.S.