nand2tetris - chapter 7

vm to hack translator - part 1.

My code is not complete yet.
It does not support multiple files or directories. That is something I will do later.

I will first test with SimpleAdd.tst.

Pre conditions are as follows:
set RAM[0] 256

And the test itself is:
push constant 7
push constant 8
add

And the expected results are as follows:
|  RAM[0]  | RAM[256] |
|     257  |      15  |

So this is the output of my translator:
// Push Constant
@7
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@8
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// add
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = D + M
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End add

And now I will run this translated code in CPU Simulator and make the verification myself. However I will add the the following piece of code at the very beginning to satisfy preconditions:
@256
D = A
@R0
M = D

Ok let 's run the code and see what happens:

Seems ok!!!

Lets move on to the next test: StackTest.

Pre conditions are as follows:
set RAM[0] 256

And the test itself:
push constant 17
push constant 17
eq
push constant 17
push constant 16
eq
push constant 16
push constant 17
eq
push constant 892
push constant 891
lt
push constant 891
push constant 892
lt
push constant 891
push constant 891
lt
push constant 32767
push constant 32766
gt
push constant 32766
push constant 32767
gt
push constant 32766
push constant 32766
gt
push constant 57
push constant 31
push constant 53
add
push constant 112
sub
neg
and
push constant 82
or
not

And the expected results are as follows:
|  RAM[0]  | RAM[256] | RAM[257] | RAM[258] | RAM[259] | RAM[260] |
|     266  |      -1  |       0  |       0  |       0  |      -1  |
| RAM[261] | RAM[262] | RAM[263] | RAM[264] | RAM[265] |
|       0  |      -1  |       0  |       0  |     -91  |

So this is the output of my translator:
// Push Constant
@17
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@17
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// equals 
@R0
M = M - 1
@R0
A = M
D = M
 
@equalstrue.1
D;JEQ
 
@equalsfalse.1
D;JNE
 
(equalstrue.1)
@1
A = - A
D = A
@0
A = M
M = D
@equalsend.1
0;JMP
 
(equalsfalse.1)
@0
D = A
@0
A = M
M = D
@equalsend.1
0;JMP
 
 
(equalsend.1)
@R0
M = M + 1
// end equals
 
 
// Push Constant
@17
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@16
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// equals 
@R0
M = M - 1
@R0
A = M
D = M
 
@equalstrue.2
D;JEQ
 
@equalsfalse.2
D;JNE
 
(equalstrue.2)
@1
A = - A
D = A
@0
A = M
M = D
@equalsend.2
0;JMP
 
(equalsfalse.2)
@0
D = A
@0
A = M
M = D
@equalsend.2
0;JMP
 
 
(equalsend.2)
@R0
M = M + 1
// end equals
 
 
// Push Constant
@16
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@17
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// equals 
@R0
M = M - 1
@R0
A = M
D = M
 
@equalstrue.3
D;JEQ
 
@equalsfalse.3
D;JNE
 
(equalstrue.3)
@1
A = - A
D = A
@0
A = M
M = D
@equalsend.3
0;JMP
 
(equalsfalse.3)
@0
D = A
@0
A = M
M = D
@equalsend.3
0;JMP
 
 
(equalsend.3)
@R0
M = M + 1
// end equals
 
 
// Push Constant
@892
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@891
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// less than 
@R0
M = M - 1
@R0
A = M
D = M
 
@lesstrue.1
D;JLT
 
@lessfalse.1
D;JGE
 
(lesstrue.1)
@1
A = - A
D = A
@0
A = M
M = D
@lessend.1
0;JMP
 
(lessfalse.1)
@0
D = A
@0
A = M
M = D
@lessend.1
0;JMP
 
 
(lessend.1)
@R0
M = M + 1
// less than
 
 
// Push Constant
@891
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@892
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// less than 
@R0
M = M - 1
@R0
A = M
D = M
 
@lesstrue.2
D;JLT
 
@lessfalse.2
D;JGE
 
(lesstrue.2)
@1
A = - A
D = A
@0
A = M
M = D
@lessend.2
0;JMP
 
(lessfalse.2)
@0
D = A
@0
A = M
M = D
@lessend.2
0;JMP
 
 
(lessend.2)
@R0
M = M + 1
// less than
 
 
// Push Constant
@891
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@891
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// less than 
@R0
M = M - 1
@R0
A = M
D = M
 
@lesstrue.3
D;JLT
 
@lessfalse.3
D;JGE
 
(lesstrue.3)
@1
A = - A
D = A
@0
A = M
M = D
@lessend.3
0;JMP
 
(lessfalse.3)
@0
D = A
@0
A = M
M = D
@lessend.3
0;JMP
 
 
(lessend.3)
@R0
M = M + 1
// less than
 
 
// Push Constant
@32767
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@32766
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// greater than 
@R0
M = M - 1
@R0
A = M
D = M
 
@greatertrue.1
D;JGT
 
@greaterfalse.1
D;JLE
 
(greatertrue.1)
@1
A = - A
D = A
@0
A = M
M = D
@greatersend.1
0;JMP
 
(greaterfalse.1)
@0
D = A
@0
A = M
M = D
@greatersend.1
0;JMP
 
 
(greatersend.1)
@R0
M = M + 1
// greater than
 
 
// Push Constant
@32766
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@32767
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// greater than 
@R0
M = M - 1
@R0
A = M
D = M
 
@greatertrue.2
D;JGT
 
@greaterfalse.2
D;JLE
 
(greatertrue.2)
@1
A = - A
D = A
@0
A = M
M = D
@greatersend.2
0;JMP
 
(greaterfalse.2)
@0
D = A
@0
A = M
M = D
@greatersend.2
0;JMP
 
 
(greatersend.2)
@R0
M = M + 1
// greater than
 
 
// Push Constant
@32766
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@32766
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
// greater than 
@R0
M = M - 1
@R0
A = M
D = M
 
@greatertrue.3
D;JGT
 
@greaterfalse.3
D;JLE
 
(greatertrue.3)
@1
A = - A
D = A
@0
A = M
M = D
@greatersend.3
0;JMP
 
(greaterfalse.3)
@0
D = A
@0
A = M
M = D
@greatersend.3
0;JMP
 
 
(greatersend.3)
@R0
M = M + 1
// greater than
 
 
// Push Constant
@57
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@31
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// Push Constant
@53
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// add
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = D + M
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End add
 
 
 
// Push Constant
@112
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// sub
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = M - D
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End sub
 
 
 
// neg
@R0
M = M - 1
@R0
A = M
M = -M
@R0
M = M + 1
// end neg
 
 
// and
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = D & M
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End and
 
 
 
// Push Constant
@82
D = A
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End Push Constant
 
 
 
// or
@R0
M = M - 1
@R0
A = M
D = M
@R0
M = M - 1
@R0
A = M
D = D | M
@R0
A = M
M = D
@R0
D = M
D = D + 1
@R0
M = D
@0
D = A
// End or
 
 
 
// not
@R0
M = M - 1
@R0
A = M
M = !M
@R0
M = M + 1
// end not

And now I will run this translated code in CPU Simulator and make the verification myself. However I will add the the following piece of code at the very beginning to satisfy preconditions:
@256
D = A
@R0
M = D

Ok let 's run the code and see what happens:

Seems like we passed this one as well..

Let 's move on to BasicTest.

Pre conditions:
set RAM[0] 256,
set RAM[1] 300,
set RAM[2] 400,
set RAM[3] 3000,
set RAM[4] 3010,

I will set these manually in CPU Simulator before running my translated code.

And the test itself:
push constant 10
pop local 0
push constant 21
push constant 22
pop argument 2
pop argument 1
push constant 36
pop this 6
push constant 42
push constant 45
pop that 5
pop that 2
push constant 510
pop temp 6
push local 0
push that 5
add
push argument 1
sub
push this 6
push this 6
add
sub
push temp 6
add

And the expected results:
|RAM[256]|RAM[300]|RAM[401]|RAM[402]|RAM[3006|RAM[3012|RAM[3015|RAM[11] |
|    472 |     10 |     21 |     22 |     36 |     42 |     45 |    510 |

Ok I am too lazy to paste the translated code but I can assure you, the code passes..

Lets move on to Pointer Test.. Pass..
Lets move on to Static Test... Pass!!

So here is the first iteration of my code, which already passes all the tests above!
package biz.tugay.vmtranslator;
 
/**
 * User: koray@tugay.biz on 16/04/16 at 10:43.
 */
 
 
public class VMTranslator {
 
    public static String translateVMLine(String vmLine, String fileName) {
        String translatedLine;
 
        if (vmLine.startsWith("push")) {
            translatedLine = translatePush(vmLine, fileName);
        } else if (vmLine.startsWith("pop")) {
            translatedLine = translatePop(vmLine, fileName);
        } else {
            translatedLine = ArithmeticTranslator.translateArithmetic(vmLine);
        }
        return "\n" + translatedLine + "\n";
    }
 
    private static String translatePush(String vmLine, String fileName) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
 
        if (vmLine.startsWith("constant")) {
            return PushTranslator.translatePushConstant(vmLine);
        }
 
        if (vmLine.startsWith("local")) {
            return PushTranslator.translatePushLocal(vmLine);
        }
 
        if (vmLine.startsWith("argument")) {
            return PushTranslator.translatePushArgument(vmLine);
        }
 
        if (vmLine.startsWith("this")) {
            return PushTranslator.translatePushThis(vmLine);
        }
 
        if (vmLine.startsWith("local")) {
            return PushTranslator.translatePushThat(vmLine);
        }
 
        if (vmLine.startsWith("temp")) {
            return PushTranslator.translatePushTemp(vmLine);
        }
 
        if (vmLine.startsWith("that")) {
            return PushTranslator.translatePushThat(vmLine);
        }
 
        if (vmLine.startsWith("pointer")) {
            return PushTranslator.translatePushPointer(vmLine);
        }
 
        if (vmLine.startsWith("static")) {
            return PushTranslator.translatePushStatic(vmLine, fileName);
        }
 
        return null;
    }
 
    private static String translatePop(String vmLine, String fileName) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
 
        if (vmLine.startsWith("local")) {
            return PopTranslator.translatePopLocal(vmLine);
        }
 
        if (vmLine.startsWith("argument")) {
            return PopTranslator.translatePopArgument(vmLine);
        }
 
        if (vmLine.startsWith("this")) {
            return PopTranslator.translatePopThis(vmLine);
        }
 
        if (vmLine.startsWith("that")) {
            return PopTranslator.translatePopThat(vmLine);
        }
 
        if (vmLine.startsWith("temp")) {
            return PopTranslator.translatePopTemp(vmLine);
        }
 
        if (vmLine.startsWith("pointer")) {
            return PopTranslator.translatePopPointer(vmLine);
        }
 
        if (vmLine.startsWith("static")) {
            return PopTranslator.translatePopStatic(vmLine, fileName);
        }
 
        return null;
    }
 
}
 
package biz.tugay.vmtranslator;
 
/**
 * User: koray@tugay.biz on 16/04/16 at 20:37.
 */
public class PushTranslator {
 
    public static String translatePushConstant(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "// Push Constant\n"
                + "@" + vmLine + "\n"
                + "D = A\n"
                + "@R0\n"
                + "A = M\n"
                + "M = D\n"
                + "@R0\n"
                + "D = M\n"
                + "D = D + 1\n"
                + "@R0\n"
                + "M = D\n"
                + "@0\n"
                + "D = A\n"
                + "// End Push Constant\n";
    }
 
    public static String translatePushLocal(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@" + vmLine + "\n" +
                "D = A\n" +
                "@LCL\n" +
                "D = D + M\n" +
                "A = D\n" +
                "D = M\n" +
                "\n" +
                "@R0\n" +
                "A = M\n" +
                "M = D\n" +
                "@R0\n" +
                "D = M\n" +
                "D = D + 1\n" +
                "@R0\n" +
                "M = D\n" +
                "@0\n" +
                "D = A\n";
    }
 
    public static String translatePushArgument(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@" + vmLine + "\n" +
                "D = A\n" +
                "@ARG\n" +
                "D = D + M\n" +
                "\n" +
                "A = D\n" +
                "D = M\n" +
                "@R0\n" +
                "A = M\n" +
                "M = D\n" +
                "@R0\n" +
                "D = M\n" +
                "D = D + 1\n" +
                "@R0\n" +
                "M = D\n" +
                "@0\n" +
                "D = A\n";
    }
 
    public static String translatePushThis(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@" + vmLine + "\n" +
                "D = A\n" +
                "@THIS\n" +
                "D = D + M\n" +
                "\n" +
                "A = D\n" +
                "D = M\n" +
                "@R0\n" +
                "A = M\n" +
                "M = D\n" +
                "@R0\n" +
                "D = M\n" +
                "D = D + 1\n" +
                "@R0\n" +
                "M = D\n" +
                "@0\n" +
                "D = A\n";
    }
 
    public static String translatePushThat(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@" + vmLine + "\n" +
                "D = A\n" +
                "@THAT\n" +
                "D = D + M\n" +
                "\n" +
                "A = D\n" +
                "D = M\n" +
                "@R0\n" +
                "A = M\n" +
                "M = D\n" +
                "@R0\n" +
                "D = M\n" +
                "D = D + 1\n" +
                "@R0\n" +
                "M = D\n" +
                "@0\n" +
                "D = A\n";
    }
 
    public static String translatePushTemp(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        int index = 5 + Integer.valueOf(vmLine);
        return "@R" + index + "\n" +
                "D = M\n" +
                "@R0\n" +
                "A = M\n" +
                "M = D\n" +
                "@R0\n" +
                "M = M + 1\n";
    }
 
    public static String translatePushPointer(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
 
        if (vmLine.equals("0")) {
            return "@THIS\n" +
                    "D = M\n" +
                    "@R0\n" +
                    "A = M\n" +
                    "M = D\n" +
                    "@R0\n" +
                    "M = M + 1\n";
        }
 
        if (vmLine.equals("1")) {
            return "@THAT\n" +
                    "D = M\n" +
                    "@R0\n" +
                    "A = M\n" +
                    "M = D\n" +
                    "@R0\n" +
                    "M = M + 1\n";
        }
 
        return null;
    }
 
    public static String translatePushStatic(String vmLine, String fileName) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@" + fileName + "." + vmLine + "\n" +
                "D = M\n" +
                "@R0\n" +
                "A = M\n" +
                "M = D\n" +
                "@R0\n" +
                "M = M + 1\n";
    }
}
 
package biz.tugay.vmtranslator;
 
/**
 * User: koray@tugay.biz on 16/04/16 at 20:38.
 */
public class PopTranslator {
 
    public static String translatePopLocal(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@LCL\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D + A\n" +
                "@LCL\n" +
                "M = D\n" +
                "\n" +
                "@R0\n" +
                "M = M - 1\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@LCL\n" +
                "A = M\n" +
                "M = D\n" +
                "@LCL\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D - A\n" +
                "@LCL\n" +
                "M = D\n";
    }
 
    public static String translatePopArgument(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@ARG\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D + A\n" +
                "@ARG\n" +
                "M = D\n" +
                "\n" +
                "@R0\n" +
                "M = M - 1\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@ARG\n" +
                "A = M\n" +
                "M = D\n" +
                "@ARG\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D - A\n" +
                "@ARG\n" +
                "M = D\n";
    }
 
    public static String translatePopThis(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@THIS\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D + A\n" +
                "@THIS\n" +
                "M = D\n" +
                "\n" +
                "@R0\n" +
                "M = M - 1\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@THIS\n" +
                "A = M\n" +
                "M = D\n" +
                "@THIS\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D - A\n" +
                "@THIS\n" +
                "M = D\n";
    }
 
    public static String translatePopThat(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@THAT\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D + A\n" +
                "@THAT\n" +
                "M = D\n" +
                "\n" +
                "@R0\n" +
                "M = M - 1\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@THAT\n" +
                "A = M\n" +
                "M = D\n" +
                "@THAT\n" +
                "D = M\n" +
                "@" + vmLine + "\n" +
                "D = D - A\n" +
                "@THAT\n" +
                "M = D\n";
    }
 
    public static String translatePopTemp(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        int index = 5 + Integer.valueOf(vmLine);
        return "@R0\n" +
                "M = M - 1\n" +
                "@R0\n" +
                "A = M\n" +
                "D = M\n" +
                "@R" + index + "\n" +
                "M = D\n";
    }
 
    public static String translatePopPointer(String vmLine) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
 
        if (vmLine.equals("0")) {
            return "@R0\n" +
                    "M = M - 1\n" +
                    "A = M\n" +
                    "D = M\n" +
                    "\n" +
                    "@THIS\n" +
                    "M = D\n";
        }
 
        if (vmLine.equals("1")) {
            return "@R0\n" +
                    "M = M - 1\n" +
                    "A = M\n" +
                    "D = M\n" +
                    "\n" +
                    "@THAT\n" +
                    "M = D\n";
        }
        return null;
    }
 
    public static String translatePopStatic(String vmLine, String fileName) {
        vmLine = vmLine.substring(vmLine.indexOf(' ') + 1, vmLine.length());
        return "@R0\n" +
                "M = M -1\n" +
                "@R0\n" +
                "A = M\n" +
                "D = M\n" +
                "@" + fileName + "." + vmLine + "\n" +
                "M = D";
    }
}
 
package biz.tugay.vmtranslator;
 
/**
 * User: koray@tugay.biz on 16/04/16 at 20:38.
 */
public class ArithmeticTranslator {
 
    public static String translateArithmetic(String vmLine) {
 
        if (vmLine.startsWith("add")) {
            return translateAdd();
        }
 
        if (vmLine.startsWith("sub")) {
            return translateSub();
        }
 
        if (vmLine.startsWith("eq")) {
            return translateEq();
        }
 
        if (vmLine.startsWith("gt")) {
            return translateGt();
        }
 
        if (vmLine.startsWith("lt")) {
            return translateLt();
        }
 
        if (vmLine.startsWith("and")) {
            return translateAnd();
        }
 
        if (vmLine.startsWith("or")) {
            return translateOr();
        }
 
        if (vmLine.startsWith("neg")) {
            return translateNeg();
        }
 
        if (vmLine.startsWith("not")) {
            return translateNot();
        }
 
        return "";
    }
 
    private static String translateAdd() {
        return "// add\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = M\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = D + M\n"
                + "@R0\n"
                + "A = M\n"
                + "M = D\n"
                + "@R0\n"
                + "D = M\n"
                + "D = D + 1\n"
                + "@R0\n"
                + "M = D\n"
                + "@0\n"
                + "D = A\n"
                + "// End add\n";
    }
 
    private static String translateSub() {
        return "// sub\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = M\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = M - D\n"
                + "@R0\n"
                + "A = M\n"
                + "M = D\n"
                + "@R0\n"
                + "D = M\n"
                + "D = D + 1\n"
                + "@R0\n"
                + "M = D\n"
                + "@0\n"
                + "D = A\n"
                + "// End sub\n";
    }
 
    private static String translateNot() {
        return "// not\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "M = !M\n"
                + "@R0\n"
                + "M = M + 1\n"
                + "// end not";
    }
 
    private static String translateNeg() {
        return "// neg\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "M = -M\n"
                + "@R0\n"
                + "M = M + 1\n"
                + "// end neg";
    }
 
    private static String translateOr() {
        return "// or\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = M\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = D | M\n"
                + "@R0\n"
                + "A = M\n"
                + "M = D\n"
                + "@R0\n"
                + "D = M\n"
                + "D = D + 1\n"
                + "@R0\n"
                + "M = D\n"
                + "@0\n"
                + "D = A\n"
                + "// End or\n";
    }
 
    private static String translateAnd() {
        return "// and\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = M\n"
                + "@R0\n"
                + "M = M - 1\n"
                + "@R0\n"
                + "A = M\n"
                + "D = D & M\n"
                + "@R0\n"
                + "A = M\n"
                + "M = D\n"
                + "@R0\n"
                + "D = M\n"
                + "D = D + 1\n"
                + "@R0\n"
                + "M = D\n"
                + "@0\n"
                + "D = A\n"
                + "// End and\n";
    }
 
    private static int ltCounter = 1;
    private static String translateLt() {
        String sub = translateSub();
        sub = sub + "// less than \n"
                + "@R0\n" +
                "M = M - 1\n" +
                "@R0\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@lesstrue." + ltCounter + "\n" +
                "D;JLT\n" +
                "\n" +
                "@lessfalse." + ltCounter + "\n" +
                "D;JGE\n" +
                "\n" +
                "(lesstrue." + ltCounter + ")\n" +
                "@1\n" +
                "A = - A\n" +
                "D = A\n" +
                "@0\n" +
                "A = M\n" +
                "M = D\n" +
                "@lessend." + ltCounter + "\n" +
                "0;JMP\n" +
                "\n" +
                "(lessfalse." + ltCounter + ")\n" +
                "@0\n" +
                "D = A\n" +
                "@0\n" +
                "A = M\n" +
                "M = D\n" +
                "@lessend." + ltCounter + "\n" +
                "0;JMP\n" +
                "\n" +
                "\n" +
                "(lessend." + ltCounter + ")\n"
                + "@R0\n"
                + "M = M + 1\n"
                + "// less than";
        ltCounter++;
        return sub;
    }
 
    private static int gtCounter = 1;
    private static String translateGt() {
        String sub = translateSub();
        sub = sub + "// greater than \n"
                + "@R0\n" +
                "M = M - 1\n" +
                "@R0\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@greatertrue." + gtCounter + "\n" +
                "D;JGT\n" +
                "\n" +
                "@greaterfalse." + gtCounter + "\n" +
                "D;JLE\n" +
                "\n" +
                "(greatertrue." + gtCounter + ")\n" +
                "@1\n" +
                "A = - A\n" +
                "D = A\n" +
                "@0\n" +
                "A = M\n" +
                "M = D\n" +
                "@greatersend." + gtCounter + "\n" +
                "0;JMP\n" +
                "\n" +
                "(greaterfalse." + gtCounter + ")\n" +
                "@0\n" +
                "D = A\n" +
                "@0\n" +
                "A = M\n" +
                "M = D\n" +
                "@greatersend." + gtCounter + "\n" +
                "0;JMP\n" +
                "\n" +
                "\n" +
                "(greatersend." + gtCounter + ")\n"
                + "@R0\n"
                + "M = M + 1\n"
                + "// greater than";
        gtCounter++;
        return sub;
    }
 
    private static int eqCounter = 1;
    private static String translateEq() {
        String sub = translateSub();
        sub = sub + "// equals \n"
                + "@R0\n" +
                "M = M - 1\n" +
                "@R0\n" +
                "A = M\n" +
                "D = M\n" +
                "\n" +
                "@equalstrue." + eqCounter + "\n" +
                "D;JEQ\n" +
                "\n" +
                "@equalsfalse." + eqCounter + "\n" +
                "D;JNE\n" +
                "\n" +
                "(equalstrue." + eqCounter + ")\n" +
                "@1\n" +
                "A = - A\n" +
                "D = A\n" +
                "@0\n" +
                "A = M\n" +
                "M = D\n" +
                "@equalsend." + eqCounter + "\n" +
                "0;JMP\n" +
                "\n" +
                "(equalsfalse." + eqCounter + ")\n" +
                "@0\n" +
                "D = A\n" +
                "@0\n" +
                "A = M\n" +
                "M = D\n" +
                "@equalsend." + eqCounter + "\n" +
                "0;JMP\n" +
                "\n" +
                "\n" +
                "(equalsend." + eqCounter + ")\n"
                + "@R0\n"
                + "M = M + 1\n"
                + "// end equals";
        eqCounter++;
        return sub;
    }
}

And this is how I feed the file into my program:
package biz.tugay.vmtranslator;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
 
/**
 * User: koray@tugay.biz on 16/04/16 at 10:54.
 */
public class VMTranslatorTest {
    public static void main(String[] args) throws FileNotFoundException {
        final String fileName = "koray.vm";
 
        final File file = new File(fileName);
 
        final String fName = file.getName().substring(0, file.getName().indexOf('.'));
 
        final Scanner scanner = new Scanner(file);
        while (scanner.hasNextLine()) {
            final String vmline = scanner.nextLine();
            final String hackAssemblyCode = VMTranslator.translateVMLine(vmline, fName);
            System.out.println(hackAssemblyCode);
        }
    }
}

It took me a while to get this project done, and it is not absolutely complete I guess.