Handle function commands

This commit is contained in:
Hazem Krimi
2024-05-06 18:36:25 +01:00
parent 0171464197
commit e0ef0a9850
6 changed files with 178 additions and 29 deletions
+1
View File
@@ -6,6 +6,7 @@
#include "operations.h" #include "operations.h"
#include "memory.h" #include "memory.h"
#include "branching.h" #include "branching.h"
#include "functions.h"
using namespace std; using namespace std;
+139
View File
@@ -0,0 +1,139 @@
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string translateFunction(string name, int args) {
stringstream output;
output << "(" << name << ")" << endl;
for (int i = 0; i < args; ++i) {
output << "@0" << endl;
output << "D=A" << endl;
output << "@SP" << endl;
output << "A=M" << endl;
output << "M=D" << endl;
output << "@SP" << endl;
output << "M=M+1" << endl;
}
return output.str();
}
string translateCall(string name, int args) {
stringstream output;
string label = name + "$ret" + generateRandomLabel(3);
vector<string> frame = { "LCL", "ARG", "THIS", "THAT" };
output << "@" << label << endl;
output << "D=A" << endl;
output << "@SP" << endl;
output << "A=M" << endl;
output << "M=D" << endl;
output << "@SP" << endl;
output << "M=M+1" << endl;
for (const string &segment : frame) {
output << "@" << segment << endl;
output << "D=M" << endl;
output << "@SP" << endl;
output << "A=M" << endl;
output << "M=D" << endl;
output << "@SP" << endl;
output << "M=M+1" << endl;
}
output << "@SP" << endl;
output << "D=M" << endl;
output << "@LCL" << endl;
output << "M=D" << endl;
output << "@SP" << endl;
output << "D=M" << endl;
output << "@R" << endl;
output << "M=D" << endl;
output << "@5" << endl;
output << "D=A" << endl;
output << "@R" << endl;
output << "M=M-D" << endl;
output << "@" << args << endl;
output << "D=A" << endl;
output << "@R" << endl;
output << "M=M-D" << endl;
output << "D=M" << endl;
output << "@ARG" << endl;
output << "M=D" << endl;
output << "@R" << endl;
output << "@" << name << endl;
output << "0;JMP" << endl;
output << "(" << label << ")" << endl;
return output.str();
}
string translateReturn() {
stringstream output;
output << "@LCL" << endl;
output << "D=A" << endl;
output << "@END_FRAME" << endl;
output << "M=D" << endl;
output << "@RETURN_ADDR" << endl;
output << "M=D" << endl;
output << "@5" << endl;
output << "D=A" << endl;
output << "@RETURN_ADDR" << endl;
output << "M=M-D" << endl;
output << "@ARG" << endl;
output << "D=M" << endl;
output << "@ADDR" << endl;
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;
output << "@ARG" << endl;
output << "D=M+1" << endl;
output << "@SP" << endl;
output << "M=D" << endl;
output << "@END_FRAME" << endl;
output << "D=M" << endl;
output << "@1" << endl;
output << "D=D-A" << endl;
output << "@THAT" << endl;
output << "M=D" << endl;
output << "@END_FRAME" << endl;
output << "D=M" << endl;
output << "@2" << endl;
output << "D=D-A" << endl;
output << "@THIS" << endl;
output << "M=D" << endl;
output << "@END_FRAME" << endl;
output << "D=M" << endl;
output << "@3" << endl;
output << "D=D-A" << endl;
output << "@ARG" << endl;
output << "M=D" << endl;
output << "@END_FRAME" << endl;
output << "D=M" << endl;
output << "@4" << endl;
output << "D=D-A" << endl;
output << "@LCL" << endl;
output << "M=D" << endl;
output << "@RETURN_ADDR" << endl;
output << "0;JMP" << endl;
return output.str();
}
-22
View File
@@ -4,28 +4,6 @@
using namespace std; using namespace std;
Segment determineSegment(string segment)
{
if (segment == "local")
return Segment::LCL;
if (segment == "argument")
return Segment::ARG;
if (segment == "this")
return Segment::THIS;
if (segment == "that")
return Segment::THAT;
if (segment == "pointer")
return Segment::POINTER;
if (segment == "static")
return Segment::STATIC;
if (segment == "temp")
return Segment::TEMP;
if (segment == "constant")
return Segment::CONSTANT;
return Segment::CONSTANT;
}
string translatePush(string filename, Segment segment, int index) string translatePush(string filename, Segment segment, int index)
{ {
stringstream output; stringstream output;
+3 -3
View File
@@ -95,7 +95,7 @@ string translateEq()
srand(static_cast<unsigned int>(time(nullptr))); srand(static_cast<unsigned int>(time(nullptr)));
string LABEL = generateRandomLabel(); string LABEL = generateRandomLabel(8);
output << "@SP" << endl; output << "@SP" << endl;
output << "M=M-1" << endl; output << "M=M-1" << endl;
@@ -147,7 +147,7 @@ string translateGt()
srand(static_cast<unsigned int>(time(nullptr))); srand(static_cast<unsigned int>(time(nullptr)));
string LABEL = generateRandomLabel(); string LABEL = generateRandomLabel(8);
output << "@SP" << endl; output << "@SP" << endl;
output << "M=M-1" << endl; output << "M=M-1" << endl;
@@ -201,7 +201,7 @@ string translateLt()
srand(static_cast<unsigned int>(time(nullptr))); srand(static_cast<unsigned int>(time(nullptr)));
string LABEL = generateRandomLabel(); string LABEL = generateRandomLabel(8);
output << "@SP" << endl; output << "@SP" << endl;
output << "M=M-1" << endl; output << "M=M-1" << endl;
+5 -2
View File
@@ -21,7 +21,8 @@ enum NoArgumentCommand {
LT, LT,
AND, AND,
OR, OR,
NOT NOT,
RETURN,
}; };
enum OneArgumentCommand { enum OneArgumentCommand {
@@ -32,5 +33,7 @@ enum OneArgumentCommand {
enum TwoArgumentCommand { enum TwoArgumentCommand {
PUSH, PUSH,
POP POP,
FUNCTION,
CALL
}; };
+30 -2
View File
@@ -24,13 +24,35 @@ inline void trim(string &str) {
ltrim(str); ltrim(str);
} }
string generateRandomLabel() { Segment determineSegment(string segment)
{
if (segment == "local")
return Segment::LCL;
if (segment == "argument")
return Segment::ARG;
if (segment == "this")
return Segment::THIS;
if (segment == "that")
return Segment::THAT;
if (segment == "pointer")
return Segment::POINTER;
if (segment == "static")
return Segment::STATIC;
if (segment == "temp")
return Segment::TEMP;
if (segment == "constant")
return Segment::CONSTANT;
return Segment::CONSTANT;
}
string generateRandomLabel(int length) {
random_device rd; random_device rd;
mt19937 gen(rd()); mt19937 gen(rd());
uniform_int_distribution<> dis('A', 'Z'); uniform_int_distribution<> dis('A', 'Z');
string label; string label;
for (int i = 0; i < 8; ++i) { for (int i = 0; i < length; ++i) {
label += static_cast<char>(dis(gen)); label += static_cast<char>(dis(gen));
} }
@@ -57,6 +79,8 @@ NoArgumentCommand determineNoArgumentCommand(string command)
return NoArgumentCommand::OR; return NoArgumentCommand::OR;
if (command == "not") if (command == "not")
return NoArgumentCommand::NOT; return NoArgumentCommand::NOT;
if (command == "return")
return NoArgumentCommand::RETURN;
return NoArgumentCommand::NEG; return NoArgumentCommand::NEG;
} }
@@ -79,6 +103,10 @@ TwoArgumentCommand determineTwoArgumentCommand(string command)
return TwoArgumentCommand::PUSH; return TwoArgumentCommand::PUSH;
if (command == "pop") if (command == "pop")
return TwoArgumentCommand::POP; return TwoArgumentCommand::POP;
if (command == "function")
return TwoArgumentCommand::FUNCTION;
if (command == "call")
return TwoArgumentCommand::CALL;
return TwoArgumentCommand::POP; return TwoArgumentCommand::POP;
} }