mirror of
https://github.com/avinal/The-Hack-Assembler.git
synced 2026-01-10 07:08:32 +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 <vector>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
|
||||
class parser : public code
|
||||
class parser
|
||||
{
|
||||
private:
|
||||
std::ifstream asmfile;
|
||||
std::string filename;
|
||||
int count_ins = 0;
|
||||
|
||||
public:
|
||||
parser(std::string input_file);
|
||||
~parser();
|
||||
parser() {}
|
||||
parser(std::string input_file) : filename(input_file) {}
|
||||
|
||||
bool has_more_commands();
|
||||
void advance();
|
||||
char command_type();
|
||||
void assemble();
|
||||
std::vector<std::array<char, 16>> get_machine_code;
|
||||
char command_type(std::string mnemonic);
|
||||
std::string symbol();
|
||||
std::array<char, 3> dest();
|
||||
std::array<char, 7> comp();
|
||||
std::array<char, 3> jump();
|
||||
std::string dest(std::string des);
|
||||
std::string comp(std::string com);
|
||||
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