mirror of
https://github.com/hazemKrimi/jack-vm-translator.git
synced 2026-05-01 18:00:27 +00:00
Operators wip
This commit is contained in:
-212
@@ -1,212 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum Segment
|
||||
{
|
||||
LCL,
|
||||
ARG,
|
||||
THIS,
|
||||
THAT,
|
||||
STATIC,
|
||||
CONSTANT,
|
||||
TEMP,
|
||||
};
|
||||
|
||||
// TODO: Complete implementing these
|
||||
// Memory access commands: push, pop
|
||||
// Arithmetic commands: add, sub, neg
|
||||
// Logical commands: eq, gt, lt, and, or, not
|
||||
|
||||
class Code
|
||||
{
|
||||
private:
|
||||
ofstream file;
|
||||
string filename;
|
||||
vector<vector<string>> commands;
|
||||
|
||||
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 == "static")
|
||||
return Segment::STATIC;
|
||||
if (segment == "temp")
|
||||
return Segment::TEMP;
|
||||
if (segment == "constant")
|
||||
return Segment::CONSTANT;
|
||||
|
||||
return Segment::CONSTANT;
|
||||
}
|
||||
|
||||
string translatePush(Segment segment, int index)
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
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 << "A=M" << endl;
|
||||
output << "M=D" << endl;
|
||||
output << "@SP" << endl;
|
||||
output << "M=M+1" << endl;
|
||||
|
||||
return output.str();
|
||||
};
|
||||
|
||||
string translatePop(Segment segment, int index)
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
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 << "@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();
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void translate()
|
||||
{
|
||||
for (const auto &vec : commands)
|
||||
{
|
||||
if (vec.size() > 1)
|
||||
{
|
||||
if (vec[0] == "push")
|
||||
{
|
||||
file << translatePush(determineSegment(vec[1]), stoi(vec[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
file << translatePop(determineSegment(vec[1]), stoi(vec[2]));
|
||||
}
|
||||
}
|
||||
file << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void closeFile()
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ArithmeticOperator determineArithmeticOperator(string arithmeticOperator)
|
||||
{
|
||||
if (arithmeticOperator == "add")
|
||||
return ArithmeticOperator::ADD;
|
||||
if (arithmeticOperator == "sub")
|
||||
return ArithmeticOperator::SUB;
|
||||
if (arithmeticOperator == "neg")
|
||||
return ArithmeticOperator::NEG;
|
||||
|
||||
return ArithmeticOperator::NEG;
|
||||
}
|
||||
|
||||
string translateAdd()
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "M=M-1" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@R" << endl;
|
||||
output << "M=D" << endl;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "M=M-1" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@R" << endl;
|
||||
output << "M=D+M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "M=D" << endl;
|
||||
output << "@SP" << endl;
|
||||
output << "M=M+1" << endl;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
string translateSub()
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "M=M-1" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@R" << endl;
|
||||
output << "M=D" << endl;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "M=M-1" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@R" << endl;
|
||||
output << "M=D-M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "M=D" << endl;
|
||||
output << "@SP" << endl;
|
||||
output << "M=M+1" << endl;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
|
||||
string translateNeg()
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "M=M-1" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@R" << endl;
|
||||
output << "M=D" << endl;
|
||||
output << "M=M-D" << endl;
|
||||
output << "M=M-D" << endl;
|
||||
output << "D=M" << endl;
|
||||
|
||||
output << "@SP" << endl;
|
||||
output << "A=M" << endl;
|
||||
output << "M=D" << endl;
|
||||
output << "@SP" << endl;
|
||||
output << "M=M+1" << endl;
|
||||
|
||||
return output.str();
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "types.h"
|
||||
#include "memory.h"
|
||||
#include "arithmetic.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Code
|
||||
{
|
||||
private:
|
||||
ofstream file;
|
||||
string filename;
|
||||
vector<vector<string>> commands;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void translate()
|
||||
{
|
||||
for (const auto &vec : commands)
|
||||
{
|
||||
if (vec.size() > 1)
|
||||
{
|
||||
if (vec[0] == "push")
|
||||
{
|
||||
file << translatePush(filename, determineSegment(vec[1]), stoi(vec[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
file << translatePop(filename, determineSegment(vec[1]), stoi(vec[2]));
|
||||
}
|
||||
}
|
||||
|
||||
if (vec.size() == 1)
|
||||
{
|
||||
int op = determineArithmeticOperator(vec[0]);
|
||||
|
||||
cout << op << " " << vec[0] << endl;
|
||||
|
||||
switch (determineArithmeticOperator(vec[0]))
|
||||
{
|
||||
case ArithmeticOperator::ADD:
|
||||
file << translateAdd();
|
||||
break;
|
||||
case ArithmeticOperator::SUB:
|
||||
file << translateSub();
|
||||
break;
|
||||
case ArithmeticOperator::NEG:
|
||||
default:
|
||||
file << translateNeg();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
file << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void closeFile()
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,149 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
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 == "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)
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
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 << "A=M" << endl;
|
||||
output << "M=D" << endl;
|
||||
output << "@SP" << endl;
|
||||
output << "M=M+1" << endl;
|
||||
|
||||
return output.str();
|
||||
};
|
||||
|
||||
string translatePop(string filename, Segment segment, int index)
|
||||
{
|
||||
stringstream output;
|
||||
|
||||
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 << "@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();
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
enum Segment
|
||||
{
|
||||
LCL,
|
||||
ARG,
|
||||
THIS,
|
||||
THAT,
|
||||
STATIC,
|
||||
CONSTANT,
|
||||
TEMP,
|
||||
};
|
||||
|
||||
enum ArithmeticOperator {
|
||||
ADD,
|
||||
SUB,
|
||||
NEG
|
||||
};
|
||||
|
||||
enum ComparisonOperator {
|
||||
EQ,
|
||||
GT,
|
||||
LT,
|
||||
};
|
||||
|
||||
enum LogicalOperator {
|
||||
AND,
|
||||
OR,
|
||||
NOT
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <parser.h>
|
||||
#include <code.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string constructTranslatedPath(string path) {
|
||||
size_t position = path.rfind(".vm");
|
||||
|
||||
return path.replace(position, 3, ".hack");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
string sourcePath = argv[1];
|
||||
|
||||
if (!regex_match(sourcePath, regex("^.+\\.vm"))) {
|
||||
cout << "Wrong file extension!" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Parser parser(sourcePath);
|
||||
|
||||
vector<vector<string>> commands = parser.getCommands();
|
||||
|
||||
string translatedPath = constructTranslatedPath(sourcePath);
|
||||
|
||||
Code code(translatedPath, commands);
|
||||
|
||||
code.translate();
|
||||
|
||||
parser.closeFile();
|
||||
code.closeFile();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user