#include <bits/stdc++.h>
#include <fstream>
using namespace std;
void ad_insert(map<string, int> &m)
{
m.insert({"START", 1});
m.insert({"END", 2});
m.insert({"ORIGIN", 3});
m.insert({"EQU", 4});
m.insert({"LTORG", 5});
}
void dl_insert(map<string, int> &m)
{
m.insert({"DC", 1});
m.insert({"DS", 2});
}
void is_insert(map<string, int> &m)
{
m.insert({"STOP", 0});
m.insert({"ADD", 1});
m.insert({"SUB", 2});
m.insert({"MULT", 3});
m.insert({"MOVER", 4});
m.insert({"MOVEM", 5});
m.insert({"COMP", 6});
m.insert({"BC", 7});
m.insert({"DIV", 8});
m.insert({"READ", 9});
m.insert({"PRINT", 10});
}
// function to split a string into words and store in vector
void spltline(string s, vector<string> &v)
{
string temp = "";
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ' || s[i] == ')')
{
v.push_back(temp);
temp = "";
}
else
{
temp = temp + s[i];
}
}
if (temp != "" && temp != " ")
{
v.push_back(temp);
}
}
int main()
{
// cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
map<string, int> ad;
map<string, int> is;
map<string, int> dl;
map<string, int> st; // symbol table
map<string, int> lt; // literal table
queue<int> pool_table; //pool table
queue<string> litq; //temporary queue to store literals of one pool
vector<string> temp_st; //to access indexes of symbols
vector<string> temp_lt; //to access indexes of literals
// is,dl,ad tables are created
ad_insert(ad);
is_insert(is);
dl_insert(dl);
// creating file and writing program in it
fstream f, ff;
// f.open("prog_file.txt",ios::out);
string line;
// while(f)
// {
// cout<<"Enter a line of program: ";
// getline(cin,line);
// if(line=="-1")
//{
// break;
// }
// f<<line<<endl;
// }
// f.close();
// rendering program taken from user
f.open("prog_file.txt", ios::in);
// cout << "Our assembly program is: " << endl;
ff.open("output.txt", ios::out);
int lc = 0;
while (f)
{
getline(f, line);
if (f.eof())
{
break;
}
vector<string> g;
// split line into words
spltline(line, g);
string typ = "";
int ind;
if(ad.find(g[1])==ad.end())
{
ff << lc << " ";
}
else{
ff<<"--- ";
}
if (g[0] != "#")
{
st[g[0]] = lc;
temp_st.push_back(g[0]);
if (g[1] != "DS")
{
ff << "(S," << st.size() << ")";
}
}
if (g[1] != "#")
{
if (g[1] == "START")
{
lc = stoi(g[3]);
}
if(g[1]=="LTORG")
{
bool my=true;
while(!litq.empty())
{
if(my)
{
pool_table.push(lt.size()-litq.size()+1);
my=false;
}
lt[litq.front()]=lc;
// temp_lt.push_back(litq.front());
lc++;
litq.pop();
}
}
if (ad.find(g[1]) != ad.end())
{
typ = "AD";
ind = ad.find(g[1])->second;
lc--;
}
else if (is.find(g[1]) != is.end())
{
typ = "IS";
ind = is.find(g[1])->second;
}
else if (dl.find(g[1]) != dl.end())
{
typ = "DL";
if (dl.find(g[1])->second == 2)
{
lc += stoi(g[3]);
}
ind = dl.find(g[1])->second;
}
// cout << "(" << typ << " , " << ind << ")";
ff << "(" << typ << "," << ind << ")";
// if(g[1]=="START")
//{
// lc=999;
// }
}
if (g[2] != "#")
{
if (g[2] == "AREG")
{
// cout << "( REG , 1 )";
ff << "(REG,1)";
}
else if (g[2] == "BREG")
{
// cout << "( REG , 2 )";
ff << "(REG,2)";
}
else if (g[2] == "CREG")
{
// cout << "( REG , 3 )";
ff << "(REG,3)";
}
}
if (g[3] != "#")
{
if(st.find(g[3])!=st.end())
{
// cout<<"( S , "<<g[3]<<")";
ff<<"(S,"<<g[3]<<")";
}
else if (g[3] == "AREG")
{
// cout << " ( REG , 1 )";
ff << "(REG,1)";
}
else if (g[3] == "BREG")
{
// cout << " ( REG , 2 )";
ff << "(REG,2)";
}
else if (g[3] == "CREG")
{
// cout << " ( REG , 3 )";
ff << "(REG,3)";
}
else if (isdigit(g[3][0]))
{
// cout << " ( const, " << g[3] << " ) ";
ff << "(const," << g[3] << ")";
}
else
{
if(g[3][0]=='=')
{
lt[g[3]]=-1;
temp_lt.push_back(g[3]);
litq.push(g[3]);
ff<<"(L,"<<lt.size()<<")";
}
else if(st.find(g[3]) == st.end())
{
st[g[3]] = -1;
temp_st.push_back(g[3]);
// cout << "( S ," << st.size() << " )";
ff << "(S," << st.size() << ")";
}
}
}
// cout << endl;
ff << endl;
lc++;
if (f.eof())
{
break;
}
}
//if some literals occurs after last LTORG
bool my=true;
while(!litq.empty())
{
if(my)
{
pool_table.push(lt.size()-litq.size()+1);
my=false;
}
lt[litq.front()]=lc;
lc++;
litq.pop();
}
f.close();
ff.close();
cout << "Symbol table: " << endl;
for (auto it = st.begin(); it != st.end(); it++)
{
cout << it->first << " : " << it->second << endl;
}
cout<<"\nLiteral table: \n";
for (auto it = lt.begin(); it != lt.end(); it++)
{
cout << it->first << " : " << it->second << endl;
}
cout<<"\n Pool table: \n";
while(!pool_table.empty())
{
cout<<pool_table.front()<<endl;
pool_table.pop();
}
//-------------------------pass-2 starts from here---------------------------------
f.open("output.txt", ios::in);
ff.open("output2.txt", ios::out);
cout<<"temp_st: ";
for(int i=0;i<temp_st.size();i++)
{
cout<<temp_st[i]<<" ";
}cout<<endl;
cout<<"temp_lt: ";
for(int i=0;i<temp_lt.size();i++)
{
cout<<temp_lt[i]<<" ";
}cout<<endl;
while (f)
{
getline(f, line);
if (f.eof())
{
break;
}
vector<string> vec;
spltline(line, vec);
for(int i=0;i<vec.size();i++)
{
if(vec[i]=="---")
{
break;
}
if(i==0)
{
ff<<vec[i]<<" ";
}
if(vec[i][1]=='R' && vec[i][2]=='E' && vec[i][3]=='G')
{
ff<<" 0"<<vec[i][5];
}
else if((vec[i][1]=='I' && vec[i][2]=='S') || (vec[i][1]=='D' && vec[i][2]=='L') || (vec[i][1]=='A' && vec[i][2]=='D'))
{
ff<<" 0"<<vec[i][4];
}
else if(vec[i][1]=='c' && vec[i][2]=='o' && vec[i][3]=='n' )
{
ff<<vec[i][7]<<vec[i][8]<<vec[i][9];
}
else if(vec[i][1]=='S' )
{
int ind=int(vec[i][3])-'0';
string key;
for(int j=0;j<ind;j++)
{
key=temp_st[j];
}
int addr=st.find(key)->second;
ff<<addr;
}
else if(vec[i][1]=='L' )
{
int ind=int(vec[i][3])-'0';
string key;
for(int j=0;j<ind;j++)
{
key=temp_lt[j];
}
int addr=lt.find(key)->second;
ff<<addr;
}
ff<<" ";
}
ff<<endl;
}
return 0;
}