diff --git a/src/include/code.h b/src/include/code.h index c07a3ef..a62effd 100644 --- a/src/include/code.h +++ b/src/include/code.h @@ -46,14 +46,39 @@ public: } else if (vec.size() == 1) { - if (vec.at(0) == "add") + switch (determineOperation(vec[0])) + { + case ADD: file << translateAdd(); - - if (vec.at(0) == "sub") + break; + case SUB: file << translateSub(); - - if (vec.at(0) == "neg") + break; + case NEG: file << translateNeg(); + break; + case EQ: + file << translateEq(); + break; + case GT: + file << translateGt(); + break; + case LT: + file << translateLt(); + break; + case AND: + file << translateAnd(); + break; + case OR: + file << translateOr(); + break; + case NOT: + file << translateNot(); + break; + default: + file << translateNeg(); + break; + } } file << endl; diff --git a/src/include/memory.h b/src/include/memory.h index 6b21d4c..6dd6bb7 100644 --- a/src/include/memory.h +++ b/src/include/memory.h @@ -14,6 +14,8 @@ Segment determineSegment(string segment) return Segment::THIS; if (segment == "that") return Segment::THAT; + if (segment == "pointer") + return Segment::POINTER; if (segment == "static") return Segment::STATIC; if (segment == "temp") @@ -34,28 +36,32 @@ string translatePush(string filename, Segment segment, int index) output << "@" << index << endl; output << "D=A" << endl; output << "@LCL" << endl; - output << "A=D+A" << endl; + output << "A=D+M" << endl; output << "D=M" << endl; break; case ARG: output << "@" << index << endl; output << "D=A" << endl; output << "@ARG" << endl; - output << "A=D+A" << endl; + output << "A=D+M" << endl; output << "D=M" << endl; break; case THIS: output << "@" << index << endl; output << "D=A" << endl; output << "@THIS" << endl; - output << "A=D+A" << endl; + output << "A=D+M" << endl; output << "D=M" << endl; break; case THAT: output << "@" << index << endl; output << "D=A" << endl; output << "@THAT" << endl; - output << "A=D+A" << endl; + output << "A=D+M" << endl; + output << "D=M" << endl; + break; + case POINTER: + output << (index == 0 ? "@THIS" : "@THAT") << endl; output << "D=M" << endl; break; case STATIC: @@ -92,7 +98,7 @@ string translatePop(string filename, Segment segment, int index) output << "@" << index << endl; output << "D=A" << endl; output << "@LCL" << endl; - output << "D=D+A" << endl; + output << "D=D+M" << endl; output << "@ADDR" << endl; output << "M=D" << endl; break; @@ -100,7 +106,7 @@ string translatePop(string filename, Segment segment, int index) output << "@" << index << endl; output << "D=A" << endl; output << "@ARG" << endl; - output << "D=D+A" << endl; + output << "D=D+M" << endl; output << "@ADDR" << endl; output << "M=D" << endl; break; @@ -108,7 +114,7 @@ string translatePop(string filename, Segment segment, int index) output << "@" << index << endl; output << "D=A" << endl; output << "@THIS" << endl; - output << "D=D+A" << endl; + output << "D=D+M" << endl; output << "@ADDR" << endl; output << "M=D" << endl; break; @@ -116,7 +122,13 @@ string translatePop(string filename, Segment segment, int index) output << "@" << index << endl; output << "D=A" << endl; output << "@THAT" << endl; - output << "D=D+A" << endl; + output << "D=D+M" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; + break; + case POINTER: + output << (index == 0 ? "@THIS" : "@THAT") << endl; + output << "D=A" << endl; output << "@ADDR" << endl; output << "M=D" << endl; break; diff --git a/src/include/operations.h b/src/include/operations.h index 50b7f88..efbd396 100644 --- a/src/include/operations.h +++ b/src/include/operations.h @@ -4,17 +4,29 @@ using namespace std; -// Operation determineOperation(string operation) -// { -// if (operation == "add") -// return Operation::ADD; -// if (operation == "sub") -// return Operation::SUB; -// if (operation == "neg") -// return Operation::NEG; +Operation determineOperation(string operation) +{ + if (operation == "add") + return Operation::ADD; + if (operation == "sub") + return Operation::SUB; + if (operation == "neg") + return Operation::NEG; + if (operation == "eq") + return Operation::EQ; + if (operation == "gt") + return Operation::GT; + if (operation == "lt") + return Operation::LT; + if (operation == "and") + return Operation::AND; + if (operation == "or") + return Operation::OR; + if (operation == "not") + return Operation::NOT; -// return Operation::NEG; -// } + return Operation::NEG; +} string translateAdd() { @@ -98,4 +110,205 @@ string translateNeg() output << "M=M+1" << endl; return output.str(); -} \ No newline at end of file +} + +string translateEq() +{ + stringstream output; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D" << endl; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=M-D" << endl; + output << "@TRUE" << endl; + output << "M;JEQ" << endl; + output << "@FALSE" << endl; + output << "M;JNE" << endl; + + output << "(TRUE)" << endl; + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=-1" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + output << "(FALSE)" << endl; + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=-1" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + return output.str(); +} + +string translateGt() +{ + stringstream output; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D" << endl; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=M-D" << endl; + output << "@TRUE" << endl; + output << "M;JGT" << endl; + output << "@FALSE" << endl; + output << "M;JLT" << endl; + + output << "(TRUE)" << endl; + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=-1" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + output << "(FALSE)" << endl; + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=-1" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + return output.str(); +} + +string translateLt() +{ + stringstream output; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D" << endl; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=M-D" << endl; + output << "@TRUE" << endl; + output << "M;JLT" << endl; + output << "@FALSE" << endl; + output << "M;JGT" << endl; + + output << "(TRUE)" << endl; + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=-1" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + output << "(FALSE)" << endl; + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=-1" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + return output.str(); +} + +string translateAnd() +{ + stringstream output; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D" << endl; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D&M" << endl; + output << "D=M" << endl; + + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=D" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + return output.str(); +} + +string translateOr() +{ + stringstream output; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D" << endl; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@R" << endl; + output << "M=D|M" << endl; + output << "D=M" << endl; + + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=D" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + return output.str(); +} + +string translateNot() +{ + stringstream output; + + output << "@SP" << endl; + output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + + output << "@SP" << endl; + output << "A=M" << endl; + output << "M=!D" << endl; + output << "@SP" << endl; + output << "M=M+1" << endl; + + return output.str(); +} diff --git a/src/include/types.h b/src/include/types.h index 23f3c72..192cf41 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -7,16 +7,18 @@ enum Segment STATIC, CONSTANT, TEMP, + POINTER, }; -// enum Operation { -// ADD, -// SUB, -// NEG, -// EQ, -// GT, -// LT, -// AND, -// OR, -// NOT -// }; +enum Operation +{ + ADD, + SUB, + NEG, + EQ, + GT, + LT, + AND, + OR, + NOT +};