<file_sep>#ifndef UTILITY_H_
#define UTILITY_H_
#include<string>
#include<regex>
#include<fstream>
#include<algorithm>
#include<cmath>

bool is_number(const std::string& num);
std::string intToBinaryString(const int num, const int numOfHexDigits);
int binaryStringToInt(const std::string& binaryString);
std::string hextobin(const std::string &s);
std::string bintohex(const std::string &s);
bool exists_test0 (const std::string& name);

bool iequals(const std::string& str1, const std::string& str2);
std::string getUpperVersion(const std::string& x);

#endif /* UTILITY_H_ */
<file_sep>#include<iostream>
#include<map>
#include<string>
#include<fstream>
#include<regex>

#include"assemblerdata.h"
#include"utility.h"

bool is_mnemonicOrDirective(string x) {
	string temp = getUpperVersion(x);
	if ((opTable.find(temp) != opTable.end()) || isDirective(temp)) {
		return true;
	} else if (temp.at(0) == '+'
			&& opTable.find(temp.substr(1, temp.size() - 1)) != opTable.end()) {
		return true;
	}
	return false;
}

bool parse_label(string x, int i) {
	smatch m;
	regex r("^([A-Za-z]\\w*)$");
	regex_search(x, m, r);
	if (m.size() > 0) {
		listing_table[i].label = m[1].str();
		return true;
	}
	return false;
}

bool parse_mnemonic(string x, int i) {
	smatch m;
	regex r("^(\\+?(\\w+))$");
	regex_search(x, m, r);
	if (m.size() > 0) {
		if (m[1].str().at(0) == '+') {
			listing_table[i].isFormat4 = true;
		}
		listing_table[i].mnemonic = m[2].str();
		return true;
	}
	return false;
}

bool parse_operand(string x, int i) {
	smatch m;
	regex r("^(\\*|([#@]?\\w+)|(\\w+(\\'|\\,|\\+|\\-|\\*|\\/)\\w+)(\\')?)$");
	regex_search(x, m, r);
	if (m.size() > 0) {
		listing_table[i].operand = m[1].str();
		return true;
	}
	regex r2("^(-?\\d+(\\,-?\\d+)+)$");
	regex_search(x, m, r2);
	if (m.size() > 0) {
		listing_table[i].operand = m[1].str();
		return true;
	}
	return false;
}

//3 cases
bool parse_instruction(string x[], int i) {
	bool noError = true;
	//case 1 mnemonic only
	if (x[0].empty() && !x[1].empty() && x[2].empty()) {
		noError = parse_mnemonic(x[1], i);
	} //case 2 label, mnemonic and operand exists
	else if (!x[0].empty() && !x[1].empty() && !x[2].empty()) {
		noError = parse_label(x[0], i) & parse_mnemonic(x[1], i)
				& parse_operand(x[2], i);
	} //case 3 (label and mnemonic) OR (mnemonic and operand)
	else if (!x[0].empty() && !x[1].empty() && x[2].empty()) {
		//label and mnemonic
		if (is_mnemonicOrDirective(x[1])) {
			noError = parse_label(x[0], i) & parse_mnemonic(x[1], i);
		} //mnemonic and operand
		else if (is_mnemonicOrDirective(x[0])) {
			noError = parse_mnemonic(x[0], i) & parse_operand(x[1], i);
		} else {
			return false;
		}
	} else {
		return false;
	}
	return noError;

}

void build_listing_table(string path) {
	if (exists_test0(path)) {
		string line;
		ifstream infile;
		infile.open(path);
		int i = 0;
		while (getline(infile, line)) {
			regex rComment("^(\\.)(.*)");
			smatch m;
			regex_search(line, m, rComment);
			if (m.size() > 0 && m.position(0) == 0) {
				listing_table[i].isAllComment = true;
				listing_table[i].comment = m[0].str();
				i++;
				continue;
			} else {
				//ensure that label, mnemonic and operand don't start with "." (comment filter)
				regex rInstruction(
						"^\\s*(([^\\.]\\S*)\\s+)?([^\\.]\\S*)\\s*(\\s+([^\\.]\\S*))?\\s*(\\s+(\\..*))?$");
				regex_search(line, m, rInstruction);
				if (m.size() > 0) {
					listing_table[i].comment = m[7].str();
					string instruction[] =
							{ m[2].str(), m[3].str(), m[5].str() };
					if (!parse_instruction(instruction, i)) {
						listing_table[i].error.insert(
								listing_table[i].error.begin(),
								"Invalid Instruction");
					}
				} else {
					listing_table[i].error.insert(
							listing_table[i].error.begin(),
							"Invalid Instruction");
				}
			}
			i++;
		}
		infile.close();
	}
}
<file_sep>/*
 * directivesHandler.cpp
 *
 *  Created on: Apr 23, 2019
 *      Author: OWNER
 */
#include <sstream>
#include"assemblerdata.h"
#include"utility.h"

using namespace std;
int address;
int arrayLength;
bool isArray(string exp) {
	smatch m;
	regex r("-?\\d+(\\,-?\\d+)+");
	if (regex_match(exp, m, r)) {
		stringstream ss(exp);
		vector<string> result;

		while (ss.good()) {
			string substr;
			getline(ss, substr, ',');
			result.push_back(substr);
		}
		arrayLength = result.size();
		return true;
	}
	return false;
}
bool isInt(string op) {
	try {
		stoi(op);
		return true;
	} catch (invalid_argument& e) {
		return false;
	}
}
bool isRelative(string symbol) {
	return symbol_table.find(symbol) != symbol_table.end()
			&& symbol_table[symbol].type == 'R';
}
bool isAbslute(string symbol) {
	return symbol_table.find(symbol) != symbol_table.end()
			&& symbol_table[symbol].type == 'A';
}
bool isRelocatable(string exp) {
	smatch m;
	regex r("(\\w+)(\\+|\\-)(\\w+)");
	if (regex_match(exp, m, r)) {
		string operand1 = getUpperVersion(m[1]);
		string operat = getUpperVersion(m[2]);
		string operand2 = getUpperVersion(m[3]);
		if (iequals("+", operat)) {
			if ((isRelative(operand1) && isAbslute(operand2))
					|| (isRelative(operand2) && isAbslute(operand1))) {
				address = symbol_table[operand1].address
						+ symbol_table[operand2].address;
				return address >= 0;
			} else if (isRelative(operand1) && isInt(operand2)) {
				address = symbol_table[operand1].address + stoi(operand2);
				return address >= 0;
			} else if (isRelative(operand2) && isInt(operand1)) {
				address = symbol_table[operand2].address + stoi(operand1);
				return address >= 0;
			}
		} else if (iequals("-", operat)) {
			if (isRelative(operand1) && isInt(operand2)) {
				address = symbol_table[operand1].address - stoi(operand2);
				return address >= 0;
			}else if(isRelative(operand1) && isAbslute(operand2)){
				address = symbol_table[operand1].address
										- symbol_table[operand2].address;
				return address >= 0;
			}
		}
	}
	regex r2("(\\*)(\\+|\\-)(\\w+)");
	if (regex_match(exp, m, r2)) {
		string operat = getUpperVersion(m[2]);
		string operand2 = getUpperVersion(m[3]);
		if (iequals("+", operat)) {
			if (isAbslute(operand2)) {
				address = symbol_table[operand2].address + LOCCTR;
				return address >= 0;
			} else if (isInt(operand2)) {
				address = LOCCTR + stoi(operand2);
				return address >= 0;
			}
		} else if (iequals("-", operat)) {
			if (isInt(operand2)) {
				address = LOCCTR - stoi(operand2);
				return address >= 0;
			} else if (isAbslute(operand2)) {
				address = -symbol_table[operand2].address + LOCCTR;
				return address >= 0;
			}
		}
	}
	regex r3("(\\w+)(\\+|\\-)(\\*)");
	if (regex_match(exp, m, r3)) {
		string operat = getUpperVersion(m[2]);
		string operand1 = getUpperVersion(m[1]);
		if (iequals("+", operat)) {
			if (isAbslute(operand1)) {
				address = symbol_table[operand1].address + LOCCTR;
				return address >= 0;
			} else if (isInt(operand1)) {
				address = LOCCTR + stoi(operand1);
				return address >= 0;
			}
		}
	}
	return false;
}
bool isAbsluteExp(string exp) {
	smatch m;
	regex r("(\\w+)(\\+|\\-|\\*|\\/)(\\w+)");
	if (regex_match(exp, m, r)) {
		string operand1 = getUpperVersion(m[1]);
		string operat = getUpperVersion(m[2]);
		string operand2 = getUpperVersion(m[3]);
		if (iequals("+", operat)) {
			if (isAbslute(operand1) && isAbslute(operand2)) {
				address = symbol_table[operand1].address
						+ symbol_table[operand2].address;
				return true;
			} else if (isAbslute(operand1) && isInt(operand2)) {
				address = symbol_table[operand1].address + stoi(operand2);
				return true;
			} else if (isAbslute(operand2) && isInt(operand1)) {
				address = symbol_table[operand2].address + stoi(operand1);
				return true;
			} else if (isInt(operand1) && isInt(operand2)) {
				address = stoi(operand1) + stoi(operand2);
				return true;
			} else {
				return false;
			}
		} else if (iequals("-", operat)) {
			if (isAbslute(operand1) && isAbslute(operand2)) {
				address = symbol_table[operand1].address
						- symbol_table[operand2].address;
				return true;
			} else if (isAbslute(operand1) && isInt(operand2)) {
				address = symbol_table[operand1].address - stoi(operand2);
				return true;
			} else if (isAbslute(operand2) && isInt(operand1)) {
				address = -symbol_table[operand2].address + stoi(operand1);
				return true;
			} else if (isInt(operand1) && isInt(operand2)) {
				address = stoi(operand1) - stoi(operand2);
				return true;
			} else if (isRelative(operand1) && isRelative(operand2)) {
				address = symbol_table[operand1].address
						- symbol_table[operand2].address;
				;
				return true;
			} else {
				return false;
			}
		} else if (iequals("*", operat)) {
			if (isAbslute(operand1) && isAbslute(operand2)) {
				address = symbol_table[operand1].address
						* symbol_table[operand2].address;
				return true;
			} else if (isAbslute(operand1) && isInt(operand2)) {
				address = symbol_table[operand1].address * stoi(operand2);
				return true;
			} else if (isAbslute(operand2) && isInt(operand1)) {
				address = symbol_table[operand2].address * stoi(operand1);
				return true;
			} else if (isInt(operand1) && isInt(operand2)) {
				address = stoi(operand1) * stoi(operand2);
				return true;
			} else {
				return false;
			}
		} else if (iequals("/", operat)) {
			if (isAbslute(operand1) && isAbslute(operand2)) {
				address = symbol_table[operand1].address
						/ symbol_table[operand2].address;
				return true;
			} else if (isAbslute(operand1) && isInt(operand2)) {
				address = symbol_table[operand1].address / stoi(operand2);
				return true;
			} else if (isAbslute(operand2) && isInt(operand1)) {
				address = stoi(operand1) / symbol_table[operand2].address;
				return true;
			} else if (isInt(operand1) && isInt(operand2)) {
				address = stoi(operand1) / stoi(operand2);
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	} else {
		regex r2("(*)(\\-)(\\w+)");
		if (regex_match(exp, m, r2)) {
			string operat = getUpperVersion(m[2]);
			string operand2 = getUpperVersion(m[3]);
			if (isRelative(operand2)) {
				address = -symbol_table[operand2].address + LOCCTR;
				return address >= 0;
			}
		}
		regex r3("(\\w+)(\\-)(\\*)");
				if (regex_match(exp, m, r3)) {
					string operat = getUpperVersion(m[2]);
					string operand2 = getUpperVersion(m[1]);
					if (isRelative(operand2)) {
						address = symbol_table[operand2].address - LOCCTR;
						return address >= 0;
					}
				}
		return false;
	}
}
bool handleByte(listing_line x);
bool handleWord(listing_line x);
bool handleRes(listing_line x, int increase_val);
bool handleOrg(listing_line x);
bool handleEqu(listing_line x);
bool handleBase(listing_line x);

bool isDirective(string x) {
	if (iequals(x, "START") || iequals(x, "END") || iequals(x, "BYTE")
			|| iequals(x, "WORD") || iequals(x, "RESW") || iequals(x, "RESB")
			|| iequals(x, "EQU") || iequals(x, "ORG") || iequals(x, "BASE")
			|| iequals(x, "NOBASE")) {
		return true;
	}
	return false;
}

bool handleDirective(listing_line x) {
	if (iequals(x.mnemonic, "byte")) {
		return handleByte(x);
	} else if (iequals(x.mnemonic, "word")) {
		return handleWord(x);
	} else if (iequals(x.mnemonic, "resw")) {
		return handleRes(x, 3);
	} else if (iequals(x.mnemonic, "resb")) {
		return handleRes(x, 1);
	} else if (iequals(x.mnemonic, "equ")) {
		return handleEqu(x);
	} else if (iequals(x.mnemonic, "org")) {
		return handleOrg(x);
	} else if (iequals(x.mnemonic, "base")) {
		return handleBase(x);
	} else if (iequals(x.mnemonic, "nobase")) {
		if (!(x.operand.empty() && x.label.empty())) {
			return false;
		}
	} else {
		return false;
	}
	return true;
}
bool handleByte(listing_line x) {
	if (x.operand.size() < 3) {
		return false;
	}
	if ((x.operand[0] == 'x' || x.operand[0] == 'X')
			&& x.operand.size() % 2 == 1) {
		if (x.operand[1] == '\'' && x.operand[x.operand.size() - 1] == '\'') {
			try {
				stoi(x.operand.substr(2, x.operand.size() - 3), 0, 16);
			} catch (invalid_argument& e) {
				return false;
			}
			LOCCTR += (x.operand.size() - 3) / 2;
			return true;
		}
	} else if (x.operand[0] == 'c' || x.operand[0] == 'C') {
		if (x.operand[1] == '\'' && x.operand[x.operand.size() - 1] == '\'') {
			LOCCTR += x.operand.size() - 3;
			return true;
		}
	}
	return false;
}
bool handleWord(listing_line x) {
	if (isArray(x.operand)) {
		LOCCTR += 3 * arrayLength;
	} else
		try {
			stoi(x.operand);
			LOCCTR += 3;
		} catch (invalid_argument& e) {

			return false;
		}

	return true;
}
bool handleRes(listing_line x, int increase_val) {
	try {
		int z = stoi(x.operand);
		LOCCTR += increase_val * z;
	} catch (invalid_argument& e) {
		return false;
	}
	return true;
}

bool handleOrg(listing_line x) {
	string operand = getUpperVersion(x.operand);
	if (!x.label.empty()) {
		return false;
	} else if (symbol_table.find(operand) != symbol_table.end()) {
		LOCCTR = symbol_table[operand].address;
		return true;
	} else if (operand[0] == '*' && operand.size() == 1) {
		return true;
	} else if (isRelocatable(operand)) {
		LOCCTR = address;
		return true;
	}
	try {
		int z = stoi(x.operand);
		LOCCTR = z;
		return true;
	} catch (invalid_argument& e) {
		return false;
	}

}

bool handleEqu(listing_line x) {
	string label = getUpperVersion(x.label);
	string operand = getUpperVersion(x.operand);
	if (x.label.empty() || operand.empty()) {
		return false;
	} else if (symbol_table.find(operand) != symbol_table.end()) {
		symbol_table[label].address = symbol_table[operand].address;
	} else if (iequals("*", operand)) {
		symbol_table[label].address = LOCCTR;
	} else {

		if (isRelocatable(operand)) {
			symbol_table[label].address = address;
			return true;
		} else if (isAbsluteExp(operand)) {
			symbol_table[label].address = address;
			symbol_table[label].type = 'A';
			return true;
		}
		try {
			int z = stoi(x.operand);
			symbol_table[label].address = z;
			symbol_table[label].type = 'A';
		} catch (invalid_argument& e) {

			return false;
		}
	}
	return true;

}

bool handleBase(listing_line x) {
	string operand = getUpperVersion(x.operand);
	if (!x.label.empty() || x.operand.empty()) {
		return false;

	}
	return true;
}

string wordObCode(unsigned int lineNumber) {
	string operand = listing_table[lineNumber].operand;
	string ans = "";
	if (isArray(operand)) {
		stringstream ss(operand);
		while (ss.good()) {
			string substr;
			getline(ss, substr, ',');
			ans = ans + bintohex(intToBinaryString(stoi(substr), 6));
		}
	} else {
		int x = stoi(operand);
		ans = ans + bintohex(intToBinaryString(x, 6));
	}
	return ans;
}
string byteObCode(unsigned int lineNumber) {
	string operand = listing_table[lineNumber].operand;
	string ans = "";
	if (operand[0] == 'x' || operand[0] == 'X') {
//		int i = 2;
		ans = operand.substr(2, operand.size() - 3);
//		while (i <= operand.size() - 3) {
//			ans = ans+ bintohex(intToBinaryString(stoi(operand.substr(i, 2), 0, 16),1));
//			i += 2;
//		}
	} else {
		unsigned int i = 2;
		while (i <= operand.size() - 2) {
			ans = ans + bintohex(intToBinaryString(operand[i], 2));
			i++;
		}
	}
	return ans;
}

bool handleBasePass2(unsigned int lineNumber) {
	string operand = listing_table[lineNumber].operand;
	if (symbol_table.find(operand) != symbol_table.end()) {
		base = symbol_table[operand].address;
	} else if (iequals("*", operand)) {
		//TODO locctr?
		base = LOCCTR;
	} else {

		if (isRelocatable(operand)) {
			base = address;
		} else if (isAbsluteExp(operand)) {
			base = address;
		}
		try {
			int z = stoi(operand);
			base = z;
		} catch (invalid_argument& e) {
			return false;
		}
	}
	return true;
}
<file_sep>#include<iostream>
#include<map>
#include<string>
#include<fstream>
#include<vector>
#include<iterator>
#include <sstream>

#include"assemblerdata.h"
#include"utility.h"

using namespace std;

map<string, struct_opcode> opTable;
map<unsigned int, listing_line> listing_table;
map<string, symbol_struct> symbol_table;

unsigned int starting_address;
unsigned int program_length;

unsigned int current_line_number;
unsigned int LOCCTR;
listing_line current_line;
bool errorInPass1 = false;

void loadOpTable(string path) {
	if (exists_test0(path)) {
		string line;
		ifstream infile;
		infile.open(path);
		while (getline(infile, line)) {
			regex r("(\\w+)\\s+(\\w+)\\s+(\\w+)");
			smatch m;
			regex_search(line, m, r);
			opTable[m[1].str()].format = stoi(m[2].str());
			opTable[m[1].str()].opcode = m[3].str();
		}
		infile.close();
	}
}
void write_symbol_table() {
	ofstream file;
	file.open("SymbolTable.txt");
	file << "Symbol   Value   Relative(R)/Absolute(A)\n\n";
	map<string, symbol_struct>::iterator itr;
	for (itr = symbol_table.begin(); itr != symbol_table.end(); itr++) {
		string k = itr->first;
		file << k;
		unsigned int spaces = 9 - k.size();
		while (spaces > 0) {
			file << " ";
			spaces--;
		}
		std::stringstream ss;
		ss << std::hex << itr->second.address; // int decimal_value
		std::string res(ss.str());

		int temp = 6 - res.length();
		while (temp > 0) {
			res = "0" + res;
			temp--;
		}
		file << res;
		unsigned int spaces1 = 19 - res.size();
		while (spaces1 > 0) {
			file << " ";
			spaces1--;
		}
		file << itr->second.type;
		file << "\n";
	}
}
void write_listing_file2(string fileName) {
	ofstream file;
	file.open(fileName);
	file << "Line no. Address Label    Mnemonic  Operand          Object Code\n\n";
	map<unsigned int, listing_line>::iterator itr;
	int i = 0;
	bool flag = false;
	for (itr = listing_table.begin(); itr != listing_table.end(); itr++) {
		if (itr->second.isAllComment) {
			continue;
		}
		i++;
		if (flag) {
			unsigned int t = 0;
			for (t = 0; t < listing_table[i - 2].error.size(); t++) {
				file << "      ****Error: ";
				file << listing_table[i - 2].error.at(t);
				file << "\n";
			}
			flag = false;
		} else if (!listing_table[i - 1].error.empty()) {
			flag = true;
		}
		if (i < 10) {
			file << i;
			file << "        ";
		} else if (i < 100) {
			file << i;
			file << "       ";
		} else if (i < 1000) {
			file << i;
			file << "      ";
		}
		std::stringstream ss;
		ss << std::hex << itr->second.address; // int decimal_value
		std::string res(ss.str());

		int temp = 6 - res.length();
		while (temp > 0) {
			res = "0" + res;
			temp--;
		}
		file << getUpperVersion(res);
		file << "  ";
		file << itr->second.label;
		unsigned int spaces2 = 9 - itr->second.label.size();
		while (spaces2 > 0) {
			file << " ";
			spaces2--;
		}
		if (itr->second.isFormat4) {
			file << '+' << itr->second.mnemonic;
		} else {
			file << itr->second.mnemonic;
		}
		unsigned int spaces1 = 10 - itr->second.mnemonic.size();
		if (itr->second.isFormat4) {
			spaces1--;
		}
		while (spaces1 > 0) {
			file << " ";
			spaces1--;
		}

		file << itr->second.operand;
		unsigned int spaces = 17 - itr->second.operand.size();
		while (spaces > 0) {
			file << " ";
			spaces--;
		}
		file << itr->second.objectCode;
		file << "\n";
	}
	if (flag) {
		unsigned int t = 0;
		for (t = 0; t < listing_table[i - 1].error.size(); t++) {
			file << "      ****Error: ";
			file << listing_table[i - 1].error.at(t);
			file << "\n";
		}
		flag = false;
	}
	file.close();
}


void write_listing_file(string fileName) {
	ofstream file;
	file.open(fileName);
	file << "Line no. Address Label    Mnemonic  Operand          Comments\n\n";
	map<unsigned int, listing_line>::iterator itr;
	int i = 0;
	bool flag = false;
	for (itr = listing_table.begin(); itr != listing_table.end(); itr++) {
		i++;
		if (flag) {
			errorInPass1 = true;
			unsigned int t = 0;
			for (t = 0; t < listing_table[i - 2].error.size(); t++) {
				file << "      ****Error: ";
				file << listing_table[i - 2].error.at(t);
				file << "\n";
			}
			flag = false;
		} else if (!listing_table[i - 1].error.empty()) {
			flag = true;
		}
		if (i < 10) {
			file << i;
			file << "        ";
		} else if (i < 100) {
			file << i;
			file << "       ";
		} else if (i < 1000) {
			file << i;
			file << "      ";
		}
		std::stringstream ss;
		ss << std::hex << itr->second.address; // int decimal_value
		std::string res(ss.str());

		int temp = 6 - res.length();
		while (temp > 0) {
			res = "0" + res;
			temp--;
		}
		file << getUpperVersion(res);
		file << "  ";
		file << itr->second.label;
		unsigned int spaces2 = 9 - itr->second.label.size();
		while (spaces2 > 0) {
			file << " ";
			spaces2--;
		}
		if (itr->second.isFormat4) {
			file << '+' << itr->second.mnemonic;
		} else {
			file << itr->second.mnemonic;
		}
		unsigned int spaces1 = 10 - itr->second.mnemonic.size();
		if (itr->second.isFormat4) {
			spaces1--;
		}
		while (spaces1 > 0) {
			file << " ";
			spaces1--;
		}

		file << itr->second.operand;
		unsigned int spaces = 17 - itr->second.operand.size();
		while (spaces > 0) {
			file << " ";
			spaces--;
		}
		file << itr->second.comment;
		file << "\n";
	}
	if (flag) {
		errorInPass1 = true;
		unsigned int t = 0;
		for (t = 0; t < listing_table[i - 1].error.size(); t++) {
			file << "      ****Error: ";
			file << listing_table[i - 1].error.at(t);
			file << "\n";
		}
		flag = false;
	}
	file.close();
}

void pass1_Algorithm(string codePath) {
	build_listing_table(codePath);
	current_line_number = 0;

	//skip the comments
	while (listing_table[current_line_number].isAllComment) {
		current_line_number++;
	}

	current_line = listing_table[current_line_number];
	//check start addressing
	if (iequals(current_line.mnemonic, "START")) {
		starting_address = stoi(current_line.operand, 0, 16);
		listing_table[current_line_number].address = starting_address;
		current_line = listing_table[++current_line_number];
	} else {
		starting_address = 0;
	}
	LOCCTR = starting_address;

	//reading code loop
	while (!iequals(current_line.mnemonic, "END")) {
		//assign address to the line
		listing_table[current_line_number].address = LOCCTR;

		//process the line if not a comment
		if (!current_line.isAllComment) {
			//process the label field
			if (!current_line.label.empty()) {
				//save the label in symbol table in upper case form
				string label = getUpperVersion(current_line.label);
				if (symbol_table.find(label) != symbol_table.end()) {
					listing_table[current_line_number].error.push_back(
							"symbol '" + current_line.label
									+ "' is already defined");
				} else {
					symbol_table[label].address = LOCCTR;
				}
			}

			//process the mnemonic
			string mnemonic = getUpperVersion(current_line.mnemonic);

			if (opTable.find(mnemonic) != opTable.end()) {
				//not directive
				if (opTable[mnemonic].format == 3 && current_line.isFormat4) {
					LOCCTR += 4;
				} else if (opTable[mnemonic].format == 2
						&& current_line.isFormat4) {
					listing_table[current_line_number].error.push_back(
							"Can't use format 4 with mnemonic "
									+ current_line.mnemonic);
				} else {
					LOCCTR += opTable[mnemonic].format;
				}
			} else if (handleDirective(current_line)) {

			} else {
				listing_table[current_line_number].error.push_back(
						"Invalid operation code");
			}
		}				//end line process

		++current_line_number;
		if (listing_table.find(current_line_number) == listing_table.end()) {
			listing_table[current_line_number - 1].error.push_back(
					"There is no End directive");
			break;
		}
		current_line = listing_table[current_line_number];
		if (iequals(current_line.mnemonic, "END")
				&& !current_line.label.empty()) {
			listing_table[current_line_number].error.push_back(
					"Label field must be blank in END instruction !!");
		}
	}
	listing_table[current_line_number].address = LOCCTR;
	program_length = LOCCTR - starting_address;

}

void runPass1(string input) {
	loadOpTable("optable.txt");
	pass1_Algorithm(input);
	write_listing_file("ListingTable.txt");
	write_symbol_table();
}

//int main() {
//	//Enter "pass1 <input-file-name>" to start
//	//pass1 input.txt
//
//	loadOpTable("optable.txt");
//	bool error = true;
//	while(error){
//		cout << "Enter 'pass1 <input-file-name>' to start, Ex : pass1 input.txt" <<endl;
//		string input;
//		getline(cin, input);
//		smatch m;
//		regex r("^pass1\\s+(\\S+)$");
//		regex_search(input, m, r);
//		if (m.size() > 0) {
//			error = false;
//			pass1_Algorithm(m[1].str());
//			write_listing_file();
//		}else{
//			cout << "File name format is not correct" <<endl<<endl;
//		}
//	}
//	write_listing_file();
//	write_symbol_table();
//	return 0;
//}
<file_sep>#include<iostream>
#include"assemblerdata.h"
#include"utility.h"

using namespace std;

int base = -1;
map<string, string> registers;
string objectCode;

void loadRegisters() {
	registers["A"] = "0000";
	registers["X"] = "0001";
	registers["L"] = "0010";
	registers["B"] = "0011";
	registers["S"] = "0100";
	registers["T"] = "0101";
	registers["F"] = "0110";
	registers["PC"] = "1000";
	registers["SW"] = "1001";
}

bool handleFormat2(string mnemonic, string operand) {
	objectCode = hextobin(opTable[mnemonic].opcode);
	smatch m;
	regex r("^(\\w+)(\\,(\\w+))?$");
	regex_search(operand, m, r);
	if (m.size() > 0 && registers.find(m[1].str()) != registers.end()) {
		//register 1 exist
		objectCode.append(registers[m[1].str()]);
		if (m[3].str().empty()) {
			//no register 2
			objectCode.append("0000");
		} else {
			if (registers.find(m[3].str()) != registers.end()) {
				//register 2 exist
				objectCode.append(registers[m[3].str()]);
			} else {
				return false;
			}
		}
	} else {
		return false;
	}
	objectCode = bintohex(objectCode);
	return true;
}

bool isOperandToTargetAddress(string operand) {
	if (operand.empty()) {
		return false;
	} else if (symbol_table.find(operand) != symbol_table.end()) {
		address = symbol_table[operand].address;
	} else if (iequals("*", operand)) {
		address = LOCCTR;
	} else {
		if (isRelocatable(operand)) {
			return true;
		} else if (isAbsluteExp(operand)) {
			return true;
		}
		try {
			int z = stoi(operand);
			address = z;
		} catch (invalid_argument& e) {
			return false;
		}
	}
	return true;
}

//return false if there is an error in operand
bool instructionToObjectCode(unsigned int line_number) {
	objectCode.clear();
	loadRegisters();
	string operand = getUpperVersion(listing_table[line_number].operand);
	string mnemonic = getUpperVersion(listing_table[line_number].mnemonic);
	unsigned int format =
			listing_table[line_number].isFormat4 == true ?
					4 : opTable[mnemonic].format;
	if (format == 2) {
		if (handleFormat2(mnemonic, operand)) {
			return true;
		} else {
			listing_table[line_number].error.push_back(
					"Couldn't process format 2 !!");
			return false;
		}

	}
	objectCode = hextobin(opTable[mnemonic].opcode).substr(0, 6);
	//handle special case RSUB has no operand
	if (mnemonic == "RSUB") {
		objectCode = bintohex(objectCode.append("110000"));
		objectCode.append("000");
		if (format == 4) {
			objectCode.append("00");
		}
		return true;
	}
	string last2chars = "";
	last2chars.push_back(operand[operand.size() - 2]);
	last2chars.push_back(operand[operand.size() - 1]);
	if (iequals(last2chars, ",X")) {
		//indexing nix = 111
		objectCode.append("111");
		operand = operand.substr(0, operand.size() - 2);
	} else if (operand[0] == '#') {
		//immediate nix = 010
		objectCode.append("010");
		operand = operand.substr(1, operand.size() - 1);
		if (is_number(operand)) {
			//special case operand is #int ex: #3
			if (format == 4) {
				if (stoi(operand) < 0 || stoi(operand) > 1048575) {
					//1048575 dec = fffff hex
					listing_table[line_number].error.push_back(
							"Operand Can't be greater than 0XFFFFF or less than 0 in format 4 !!");
					return false;
				}
				//bpe = 001
				objectCode.append("001");
				objectCode.append(intToBinaryString(stoi(operand), 5));
				objectCode = bintohex(objectCode);
			} else {
				if (stoi(operand) < 0 || stoi(operand) > 4095) {
					//4095 dec = fff hex
					listing_table[line_number].error.push_back(
							"Operand Can't be greater than 0XFFF or less than 0 in format 3 !!");
					return false;
				}
				//bpe = 000
				objectCode.append("000");
				objectCode.append(intToBinaryString(stoi(operand), 3));
				objectCode = bintohex(objectCode);
			}
			return true;
		}
		//TODO evaluate expression
		//if(/*expression*/)
	} else if (operand[0] == '@') {
		//indirect nix = 100
		objectCode.append("100");
		operand = operand.substr(1, operand.size() - 1);
	} else {
		//simple addressing with no indexing nix = 110
		objectCode.append("110");
	}
	int TA;
	if (isOperandToTargetAddress(operand)) {
		TA = address;
	} else {
		listing_table[line_number].error.push_back("Invalid operand !!");
		return false;
	}
	if (format == 4) {
		//TODO modification record
		objectCode.append("001");
		objectCode.append(intToBinaryString(TA, 5));
		objectCode = bintohex(objectCode);
	} else {
		int disp = TA - (LOCCTR + format);
		if (-2048 <= disp && disp <= 2047) {
			//PC-relative bpe = 010
			objectCode.append("010");
		} else if (base >= 0) {
			//base available
			disp = TA - base;
			if (0 <= disp && disp <= 4095) {
				//base relative bpe = 100
				objectCode.append("100");
			} else {
				listing_table[line_number].error.push_back(
						"Can't Process the address!!");
				return false;
			}
		}
		objectCode.append(intToBinaryString(disp, 3));
		objectCode = bintohex(objectCode);

	}
	if (objectCode.length() != 6 && format == 3) {
		listing_table[line_number].error.push_back(
				"Error in operand in format 3 !!");
		return false;
	} else if (objectCode.length() != 8 && format == 4) {
		listing_table[line_number].error.push_back(
				"Error in operand in format 4 !!");
		return false;
	} else {
		return true;
	}

}
void pass2() {

	current_line_number = 0;

	//skip the comments
	while (listing_table[current_line_number].isAllComment) {
		current_line_number++;
	}

	current_line = listing_table[current_line_number];
	ofstream file;
	file.open("ObjectProgram.txt");
	file << "H^";

	//check start mnemonic (Program name)
	if (iequals(current_line.mnemonic, "START")) {
		if (current_line.label.size() > 6) {
			current_line.error.push_back(
					"Program name is more than 6 characters");
			file << current_line.label.substr(0, 6);
		} else {
			int spacesNum = 6 - current_line.label.size();
			file << current_line.label;
			for (int i = 0; i < spacesNum; ++i) {
				file << " ";
			}
		}
		current_line = listing_table[++current_line_number];
	} else {
		file << "      ";
	}
	file << "^";
	LOCCTR = starting_address;
	file << bintohex(intToBinaryString(starting_address, 6));
	file << "^";
	file << bintohex(intToBinaryString(program_length, 6));
	file << "\n";
	//max length of tRecord = 30 bytes (0x1E) = 60 hex digits
	int tRecordLength = 0;		//length by hex digits
	int tRecordStart = starting_address;
	vector<string> tRecords;
	string tempRecord;

	while (!iequals(current_line.mnemonic, "END")) {
		LOCCTR = current_line.address;
		if (tRecordStart == -1) {
			tRecordStart = LOCCTR;
		}
		if (!current_line.error.empty()) {
			current_line = listing_table[++current_line_number];
			continue;
		}

		//process the line if not a comment
		if (!current_line.isAllComment) {
			string mnemonic = getUpperVersion(current_line.mnemonic);
			if (opTable.find(mnemonic) != opTable.end()) {
				//not directive
				if (instructionToObjectCode(current_line_number)) {
					tRecordLength += objectCode.size();
					tRecords.push_back(objectCode);
					listing_table[current_line_number].objectCode = objectCode;
				}
			} else {
				//directive
				if (iequals(current_line.mnemonic, "NOBASE")) {
					base = -1;
				} else if (iequals(current_line.mnemonic, "BASE")) {
					if (!handleBasePass2(current_line_number)) {
						listing_table[current_line_number].error.push_back(
								"Error in BASE operand");
					}
				} else if (iequals(current_line.mnemonic, "WORD")) {
					objectCode = wordObCode(current_line_number);
					tRecordLength += objectCode.size();
					tRecords.push_back(objectCode);
					listing_table[current_line_number].objectCode = objectCode;
				} else if (iequals(current_line.mnemonic, "BYTE")) {
					objectCode = byteObCode(current_line_number);
					tRecordLength += objectCode.size();
					tRecords.push_back(objectCode);
					listing_table[current_line_number].objectCode = objectCode;
				}
			}
			if (tRecordLength > 60) {
				file << "T^";
				file << bintohex(intToBinaryString(tRecordStart, 6));
				file << "^";
				tempRecord = tRecords.back();
				tRecords.erase(tRecords.end() - 1);
				tRecordLength -= tempRecord.size();
				file << bintohex(intToBinaryString(tRecordLength / 2, 2));
				file << "^";
				int temp;
				for (unsigned int i = 0; i < tRecords.size() - 1; i++) {
					file << tRecords.at(i);
					file << "^";
					temp = i;
				}
				file << tRecords.at(temp + 1);
				file << "\n";
				tRecords.clear();
				tRecords.push_back(tempRecord);
				tRecordStart = LOCCTR;
				tRecordLength = tempRecord.size();
			} else if (iequals(current_line.mnemonic, "RESW")
					|| iequals(current_line.mnemonic, "RESB")
					|| iequals(current_line.mnemonic, "ORG")) {
				if (!tRecords.empty()) {
					file << "T^";
					file << bintohex(intToBinaryString(tRecordStart, 6));
					file << "^";
					file << bintohex(intToBinaryString(tRecordLength / 2, 2));
					file << "^";
					int temp;
					for (unsigned int i = 0; i < tRecords.size() - 1; i++) {
						file << tRecords.at(i);
						file << "^";
						temp = i;
					}
					file << tRecords.at(temp + 1);
					file << "\n";
					tRecords.clear();
					tRecordLength = 0;
				}
				//start from the next iteration
				tRecordStart = -1;
			}

		}
		current_line = listing_table[++current_line_number];
	}
	if (iequals(current_line.mnemonic, "END") && !tRecords.empty()) {
		file << "T^";
		file << bintohex(intToBinaryString(tRecordStart, 6));
		file << "^";
		file << bintohex(intToBinaryString(tRecordLength / 2, 2));
		file << "^";
		int temp;
		for (unsigned int i = 0; i < tRecords.size() - 1; i++) {
			file << tRecords.at(i);
			file << "^";
			temp = i;
		}
		file << tRecords.at(temp + 1);
		file << "\n";
	}
	if (iequals(current_line.mnemonic, "END")) {
		file << "E^";
		if (!current_line.operand.empty()) {
			if (isOperandToTargetAddress(current_line.operand)) {
				file << bintohex(intToBinaryString(address, 6));
			} else {
				listing_table[current_line_number].error.push_back(
						"Error in End operand !!");
			}
		} else {
			file << "000000";
		}
	}
	file.close();
}

int main() {
	//Enter "assemble <input-file-name>" to start
	//assemble input.txt

	string input;
	getline(cin, input);
	smatch m;
	regex r("^assemble\\s+(\\S+)$");
	regex_search(input, m, r);
	if (m.size() > 0) {
		runPass1(m[1].str());
		if(!errorInPass1){
			pass2();
			write_listing_file2("ObjectCode.txt");
		}
	}
}
<file_sep>#include"utility.h"

using namespace std;
//helping functions

bool is_number(const std::string& num) {
	string s = num[0] == '-' ? num.substr(1, num.length() - 1) : num;
	return !s.empty()
			&& std::find_if(s.begin(), s.end(),
					[](char c) {return !std::isdigit(c);}) == s.end();
}

//numOfHexDigits must be big enough to carry the whole int
std::string intToBinaryString(const int num, const int numOfHexDigits) {
	unsigned int x;
	if (num < 0) {
		x = -1 * num;
	} else {
		x = num;
	}
	std::string s;
	do {
		s.push_back('0' + (x & 1));
	} while (x >>= 1);
	std::reverse(s.begin(), s.end());
	int diff = numOfHexDigits * 4 - s.size();
	string temp = "";
	for(int  i = 0; i < diff; ++i) {
		temp.push_back('0');
	}
	s = temp.append(s);
	if (num < 0) {
		bool firstOnePassed = false;
		for (int j = s.size() - 1; j >= 0 ; --j) {
			 if(firstOnePassed){
				 s[j] = (s[j] == '1') ? '0': '1';
			 }
			 if(s[j] == '1'){
				 firstOnePassed = true;
			 }
		}
	}
	return s;
}

int binaryStringToInt(const string &binaryString) {
	int value = 0;
	int indexCounter = 0;
	for (int i = binaryString.length() - 1; i >= 0; i--) {
		if (binaryString[i] == '1') {
			value += pow(2, indexCounter);
		}
		indexCounter++;
	}
	return value;
}

string hextobin(const string &s) {
	string out;
	for (auto i : s) {
		uint8_t n;
		if (i <= '9' and i >= '0')
			n = i - '0';
		else
			n = 10 + i - 'A';
		for (int8_t j = 3; j >= 0; --j)
			out.push_back((n & (1 << j)) ? '1' : '0');
	}

	return out;
}

string bintohex(const string &s) {
	string out;
	for (unsigned int i = 0; i < s.size(); i += 4) {
		int8_t n = 0;
		for (unsigned int j = i; j < i + 4; ++j) {
			n <<= 1;
			if (s[j] == '1')
				n |= 1;
		}

		if (n <= 9)
			out.push_back('0' + n);
		else
			out.push_back('A' + n - 10);
	}

	return out;
}

bool exists_test0(const std::string& name) {
	ifstream f(name.c_str());
	return f.good();
}

string getUpperVersion(const string &x) {
	string temp;
	transform(x.begin(), x.end(), back_inserter(temp), ::toupper);
	return temp;
}

//iequals function check equality of two strings CASE-INSENSITIVE
struct iequal {
	bool operator()(int c1, int c2) const {
		return std::toupper(c1) == std::toupper(c2);
	}
};

bool iequals(const std::string& str1, const std::string& str2) {
	return (str1.size() == str2.size())
			&& std::equal(str1.begin(), str1.end(), str2.begin(), iequal());
}
//end iequals
<file_sep>#include<map>
#include<string>
#include<vector>
#include<regex>


using namespace std;

#ifndef ASSEMBLERDATA_H_
#define ASSEMBLERDATA_H_


struct struct_opcode {
	string opcode;
	unsigned int format;
};

struct listing_line {
	bool isAllComment;
	unsigned int address;
	bool isFormat4;
	string label;
	string mnemonic;
	string operand;
	string comment;
	vector<string> error;
	string objectCode;
};

struct symbol_struct{
	int address;
	char type;
	symbol_struct() : address(0), type('R') {}

};
extern map<string, struct_opcode> opTable;
extern map<unsigned int, listing_line> listing_table;
//key: label name ,  value: address
extern map<string, symbol_struct> symbol_table;

extern unsigned int starting_address;
extern unsigned int program_length;
extern unsigned int LOCCTR;
//if base is negative then NOBASE
extern int base;
extern int address;
extern unsigned int current_line_number;
extern listing_line current_line;
extern bool errorInPass1;


void runPass1(string input);
void write_listing_file(string fileName);
void write_listing_file2(string fileName);
void build_listing_table(string path);
bool handleDirective(listing_line x);
bool isDirective(string x);
bool isRelocatable(string exp);
bool isAbsluteExp(string exp);
bool handleBasePass2(unsigned int lineNumber);
string byteObCode(unsigned int lineNumber);
string wordObCode(unsigned int lineNumber);

#endif /* ASSEMBLERDATA_H_ */
