mirror of
https://github.com/hazemKrimi/jack-vm-translator.git
synced 2026-05-02 02:10:27 +00:00
Handle function commands
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user