diff --git a/src/code.h b/src/code.h index a6e0573..46aca60 100644 --- a/src/code.h +++ b/src/code.h @@ -10,22 +10,70 @@ enum Segment ARG, THIS, THAT, + STATIC, + CONSTANT, + TEMP, }; class Code { private: ofstream file; + string filename; vector> commands; - string translatePush(int constant) + string translatePush(Segment segment, int index) { stringstream output; - output << '@' << constant << endl; - output << "D=A" << endl; + switch (segment) + { + case LCL: + output << "@" << index << endl; + output << "D=A" << endl; + output << "@LCL" << endl; + output << "A=D+A" << endl; + output << "D=M" << endl; + break; + case ARG: + output << "@" << index << endl; + output << "D=A" << endl; + output << "@ARG" << endl; + output << "A=D+A" << endl; + output << "D=M" << endl; + break; + case THIS: + output << "@" << index << endl; + output << "D=A" << endl; + output << "@THIS" << endl; + output << "A=D+A" << endl; + output << "D=M" << endl; + break; + case THAT: + output << "@" << index << endl; + output << "D=A" << endl; + output << "@THAT" << endl; + output << "A=D+A" << endl; + output << "D=M" << endl; + break; + case STATIC: + output << "@" << filename << "." << index << endl; + output << "D=M" << endl; + break; + case TEMP: + output << "@" << index + 5 << endl; + output << "D=M" << endl; + break; + case CONSTANT: + default: + output << '@' << index << endl; + output << "D=A" << endl; + break; + } + output << "@SP" << endl; - output << "D=M" << endl; + output << "A=M" << endl; + output << "M=D" << endl; output << "@SP" << endl; output << "M=M+1" << endl; @@ -42,38 +90,78 @@ private: return Segment::THIS; if (segment == "that") return Segment::THAT; + if (segment == "static") + return Segment::STATIC; + if (segment == "temp") + return Segment::TEMP; + if (segment == "constant") + return Segment::CONSTANT; + + return Segment::CONSTANT; } string translatePop(Segment segment, int index) { stringstream output; - output << "@SP" << index << endl; - output << "A=M" << endl; - output << "D=M" << endl; - switch (segment) { case LCL: + output << "@" << index << endl; + output << "D=A" << endl; output << "@LCL" << endl; + output << "D=D+A" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; break; case ARG: + output << "@" << index << endl; + output << "D=A" << endl; output << "@ARG" << endl; + output << "D=D+A" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; break; case THIS: + output << "@" << index << endl; + output << "D=A" << endl; output << "@THIS" << endl; + output << "D=D+A" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; break; case THAT: + output << "@" << index << endl; + output << "D=A" << endl; output << "@THAT" << endl; + output << "D=D+A" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; + break; + case STATIC: + output << "@" << filename << "." << index << endl; + output << "D=A" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; + break; + case TEMP: + output << "@" << index + 5 << endl; + output << "D=A" << endl; + output << "@ADDR" << endl; + output << "M=D" << endl; break; default: break; } - output << "M=D" << endl; output << "@SP" << endl; output << "M=M-1" << endl; + output << "A=M" << endl; + output << "D=M" << endl; + output << "@ADDR" << endl; + output << "A=M" << endl; + output << "M=D" << endl; return output.str(); }; @@ -81,6 +169,14 @@ private: public: Code(string path, vector> tokens) { + size_t slashIndex = path.find_last_of('/'); + size_t dotIndex = path.find_last_of('.'); + + if (slashIndex != string::npos && dotIndex != string::npos) + { + filename = path.substr(slashIndex + 1, dotIndex - slashIndex - 1); + } + file = ofstream(path); commands = tokens; } @@ -91,17 +187,16 @@ public: { if (vec.size() > 1) { - file << vec[0] << "-"; - if (vec.size() > 1) - file << vec[1] << "-"; - if (vec.size() > 1) - file << vec[2]; - file << endl; - } - else - { - file << vec[0] << endl; + if (vec[0] == "push") + { + file << translatePush(determineSegment(vec[1]), stoi(vec[2])); + } + else + { + file << translatePop(determineSegment(vec[1]), stoi(vec[2])); + } } + file << endl; } }