mirror of
https://github.com/avinal/The-Hack-Assembler.git
synced 2026-01-10 23:28:33 +05:30
working without symbols
This commit is contained in:
@@ -1,26 +1,26 @@
|
|||||||
#pragma once
|
|
||||||
#ifdef PARSER_HPP
|
|
||||||
#define PARSER_HPP
|
|
||||||
|
|
||||||
#include "code.hpp"
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
class parser : public code
|
class parser
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::ifstream asmfile;
|
std::string filename;
|
||||||
|
int count_ins = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
parser(std::string input_file);
|
parser() {}
|
||||||
~parser();
|
parser(std::string input_file) : filename(input_file) {}
|
||||||
|
|
||||||
bool has_more_commands();
|
void assemble();
|
||||||
void advance();
|
std::vector<std::array<char, 16>> get_machine_code;
|
||||||
char command_type();
|
char command_type(std::string mnemonic);
|
||||||
std::string symbol();
|
std::string symbol();
|
||||||
std::array<char, 3> dest();
|
std::string dest(std::string des);
|
||||||
std::array<char, 7> comp();
|
std::string comp(std::string com);
|
||||||
std::array<char, 3> jump();
|
std::string jump(std::string jum);
|
||||||
|
std::array<std::string, 3> split(std::string mnemonic);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
185
src/parser.cpp
185
src/parser.cpp
@@ -1 +1,184 @@
|
|||||||
#include "../include/parser.hpp"
|
#include "../include/parser.hpp"
|
||||||
|
|
||||||
|
void parser::assemble()
|
||||||
|
{
|
||||||
|
std::ifstream asmfile(filename);
|
||||||
|
int pos = filename.find(".");
|
||||||
|
filename.erase(pos);
|
||||||
|
std::string outfile = filename + ".hack";
|
||||||
|
|
||||||
|
std::ofstream genfile(outfile);
|
||||||
|
|
||||||
|
std::string instruction;
|
||||||
|
if (asmfile.is_open())
|
||||||
|
{
|
||||||
|
while (std::getline(asmfile, instruction))
|
||||||
|
{
|
||||||
|
std::string converted = "";
|
||||||
|
std::string binary;
|
||||||
|
instruction.erase(instruction.size() - 1);
|
||||||
|
if (instruction.empty() ||
|
||||||
|
instruction.substr(0, 2) == "//")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (command_type(instruction))
|
||||||
|
{
|
||||||
|
case 'A':
|
||||||
|
{
|
||||||
|
count_ins++;
|
||||||
|
converted += "0";
|
||||||
|
int address;
|
||||||
|
instruction = instruction.substr(1);
|
||||||
|
if (std::all_of(instruction.begin(),instruction.end(),::isdigit)){
|
||||||
|
address = std::stoi(instruction);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
binary = std::bitset<15>(std::stoi(instruction.substr(1))).to_string();
|
||||||
|
converted += binary;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
{
|
||||||
|
count_ins++;
|
||||||
|
auto token = split(instruction);
|
||||||
|
binary = comp(token[1]) + dest(token[0]) + jump(token[2]);
|
||||||
|
converted += "111" + binary;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (genfile.is_open())
|
||||||
|
{
|
||||||
|
genfile << converted << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genfile.close();
|
||||||
|
asmfile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<std::string, 3> parser::split(std::string mnemonic)
|
||||||
|
{
|
||||||
|
std::array<std::string, 3> token;
|
||||||
|
int pos;
|
||||||
|
if ((pos = mnemonic.find(';')) != std::string::npos)
|
||||||
|
{
|
||||||
|
token.at(2) = mnemonic.substr(pos + 1);
|
||||||
|
mnemonic.erase(pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
token.at(2) = "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pos = mnemonic.find("=")) != std::string::npos)
|
||||||
|
{
|
||||||
|
token.at(1) = mnemonic.substr(pos + 1);
|
||||||
|
mnemonic.erase(pos);
|
||||||
|
token.at(0) = mnemonic;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
token.at(1) = mnemonic;
|
||||||
|
token.at(0) = "null";
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parser::comp(std::string com)
|
||||||
|
{
|
||||||
|
const std::unordered_map<std::string, std::string> compare({{"0", "101010"},
|
||||||
|
{"1", "111111"},
|
||||||
|
{"-1", "111010"},
|
||||||
|
{"D", "001100"},
|
||||||
|
{"C", "110000"},
|
||||||
|
{"!D", "001101"},
|
||||||
|
{"!C", "110001"},
|
||||||
|
{"-D", "001111"},
|
||||||
|
{"-C", "110011"},
|
||||||
|
{"D+1", "011111"},
|
||||||
|
{"C+1", "110111"},
|
||||||
|
{"D-1", "001110"},
|
||||||
|
{"C-1", "110010"},
|
||||||
|
{"D+C", "000010"},
|
||||||
|
{"D-C", "010011"},
|
||||||
|
{"C-D", "000111"},
|
||||||
|
{"D&C", "000000"},
|
||||||
|
{"D|C", "010101"}});
|
||||||
|
|
||||||
|
std::string recomp = "";
|
||||||
|
int pos;
|
||||||
|
char am;
|
||||||
|
if ((pos = com.find("M")) != std::string::npos)
|
||||||
|
{
|
||||||
|
com.replace(pos, 1, "C");
|
||||||
|
recomp += "1";
|
||||||
|
}
|
||||||
|
else if ((pos = com.find("A")) != std::string::npos)
|
||||||
|
{
|
||||||
|
com.replace(pos, 1, "C");
|
||||||
|
recomp += "0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recomp += "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compare.find(com) != compare.end())
|
||||||
|
{
|
||||||
|
recomp += compare.at(com);
|
||||||
|
}
|
||||||
|
return recomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parser::dest(std::string des)
|
||||||
|
{
|
||||||
|
const std::unordered_map<std::string, std::string> destination({{"null", "000"},
|
||||||
|
{"M", "001"},
|
||||||
|
{"D", "010"},
|
||||||
|
{"MD", "011"},
|
||||||
|
{"A", "100"},
|
||||||
|
{"AM", "101"},
|
||||||
|
{"AD", "110"},
|
||||||
|
{"AMD", "111"}});
|
||||||
|
return destination.at(des);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parser::jump(std::string jum)
|
||||||
|
{
|
||||||
|
const std::unordered_map<std::string, std::string> jumpto({{"null", "000"},
|
||||||
|
{"JGT", "001"},
|
||||||
|
{"JEQ", "010"},
|
||||||
|
{"JGE", "011"},
|
||||||
|
{"JLT", "100"},
|
||||||
|
{"JNE", "101"},
|
||||||
|
{"JLE", "110"},
|
||||||
|
{"JMP", "111"}});
|
||||||
|
return jumpto.at(jum);
|
||||||
|
}
|
||||||
|
|
||||||
|
char parser::command_type(std::string mnemonic)
|
||||||
|
{
|
||||||
|
if (mnemonic.front() == '@')
|
||||||
|
{
|
||||||
|
return 'A';
|
||||||
|
}
|
||||||
|
else if (mnemonic.front() == '(' && mnemonic.back() == ')')
|
||||||
|
{
|
||||||
|
return 'L';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'C';
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user