Implementation of push and pop commands

This commit is contained in:
Hazem Krimi
2024-03-30 21:58:58 +01:00
parent cfbf4b771e
commit f7865e5946
+114 -19
View File
@@ -10,22 +10,70 @@ enum Segment
ARG, ARG,
THIS, THIS,
THAT, THAT,
STATIC,
CONSTANT,
TEMP,
}; };
class Code class Code
{ {
private: private:
ofstream file; ofstream file;
string filename;
vector<vector<string>> commands; vector<vector<string>> commands;
string translatePush(int constant) string translatePush(Segment segment, int index)
{ {
stringstream output; stringstream output;
output << '@' << constant << endl; switch (segment)
output << "D=A" << endl; {
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 << "@SP" << endl;
output << "D=M" << endl; output << "A=M" << endl;
output << "M=D" << endl;
output << "@SP" << endl; output << "@SP" << endl;
output << "M=M+1" << endl; output << "M=M+1" << endl;
@@ -42,38 +90,78 @@ private:
return Segment::THIS; return Segment::THIS;
if (segment == "that") if (segment == "that")
return 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) string translatePop(Segment segment, int index)
{ {
stringstream output; stringstream output;
output << "@SP" << index << endl;
output << "A=M" << endl;
output << "D=M" << endl;
switch (segment) switch (segment)
{ {
case LCL: case LCL:
output << "@" << index << endl;
output << "D=A" << endl;
output << "@LCL" << endl; output << "@LCL" << endl;
output << "D=D+A" << endl;
output << "@ADDR" << endl;
output << "M=D" << endl;
break; break;
case ARG: case ARG:
output << "@" << index << endl;
output << "D=A" << endl;
output << "@ARG" << endl; output << "@ARG" << endl;
output << "D=D+A" << endl;
output << "@ADDR" << endl;
output << "M=D" << endl;
break; break;
case THIS: case THIS:
output << "@" << index << endl;
output << "D=A" << endl;
output << "@THIS" << endl; output << "@THIS" << endl;
output << "D=D+A" << endl;
output << "@ADDR" << endl;
output << "M=D" << endl;
break; break;
case THAT: case THAT:
output << "@" << index << endl;
output << "D=A" << endl;
output << "@THAT" << 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; break;
default: default:
break; break;
} }
output << "M=D" << endl;
output << "@SP" << endl; output << "@SP" << endl;
output << "M=M-1" << 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(); return output.str();
}; };
@@ -81,6 +169,14 @@ private:
public: public:
Code(string path, vector<vector<string>> tokens) Code(string path, vector<vector<string>> 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); file = ofstream(path);
commands = tokens; commands = tokens;
} }
@@ -91,17 +187,16 @@ public:
{ {
if (vec.size() > 1) if (vec.size() > 1)
{ {
file << vec[0] << "-"; if (vec[0] == "push")
if (vec.size() > 1) {
file << vec[1] << "-"; file << translatePush(determineSegment(vec[1]), stoi(vec[2]));
if (vec.size() > 1) }
file << vec[2]; else
file << endl; {
} file << translatePop(determineSegment(vec[1]), stoi(vec[2]));
else }
{
file << vec[0] << endl;
} }
file << endl;
} }
} }