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,
THIS,
THAT,
STATIC,
CONSTANT,
TEMP,
};
class Code
{
private:
ofstream file;
string filename;
vector<vector<string>> 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<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);
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;
}
}