Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
65 kB
1
Indexable
/*
Function naming convention: <className>.<functionName> as is in 3ac

*/

#include <bits/stdc++.h>
#include <unistd.h>
#define PUSHQ "pushq\t"
#define MOVL "movl\t"
#define MOVQ "movq\t"
#define SUBQ "subq\t"
#define RBP "%rbp"
#define RSP "%rsp"
#define ADDQ "addq\t"
#define SUBQ "subq\t"
#define MULQ "imulq\t"
#define DIVQ "divq\t"
#define XORQ "xorq\t"
#define DEBUG 1
#define DBG if (DEBUG)
using namespace std;

string consOrVar(string);
int temporary_size; // hold the size of temporary variable used in a given fucntion
vector<char> ops = {'+', '-', '*', '/', '^', '&', '%'};
vector<string> relOps = {"<=", ">=", "==", "!=", ">", "<"};

map<string, int> sizes;

map<char, string> opConv;
map<string, vector<int>> var; // it keeps the data
                              //  its struct is map<var_name,{type,isarg,w1,w2,w3}>
map<string, string> relConv;

map<string, int> addressRegDes; // address descriptor
map<string, int> addressDes;    // describes the address relative to rbp for a given variable
map<string, bool> mem;          // whether value in memory is correct value of the variable
map<string, int> classSize;     // size of a class object assuming size of int as 8 bytes
map<string, string> objClass;   // keeps track of classes of object

string currClassName = ""; // current class being handled
string currFuncName = "";  // current function being dealt with in the code
string mainClassName = ""; // class having the main function

vector<int> genregs = {0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15};

vector<bool> islabel(2e5 + 1, false);

void beg_func(string x, vector<string> &funCode);
void func_call(vector<string> a, vector<string> &funcCode);
void ary_acc(string lex, int tp, string v1, string v2, string v3, string r, vector<string> &funCode);
void ary_ass(string lex, int tp, string v1, string v2, string v3, string val, vector<string> &funCode);
void call_malloc(string name, int tp, string s1, string s2, string s3, vector<string> &funCode);

void call_malloc(string name, int tp, string s1, string s2, string s3, vector<string> &funCode);
/************REG CLASS***********/
class reg
{
    int id;
    string regName;
    map<string, int> regDes; // register descriptor, as in slides, assuming a reg
public:
    reg(){};
    void init(int id, string regName);
    reg(int id, string regName);
    string getname();
    void addRegDes(string s);
    void rmRegDes(string s);
    bool getRegDes(string s);
    int getRegDesSize();
    bool isEmpty();
    vector<string> storeall();

} r[16];
string GetCurrentWorkingDir(void)
{
    char buff[FILENAME_MAX];
    getcwd(buff, FILENAME_MAX);
    std::string current_working_dir(buff);
    return current_working_dir;
}
void reg::init(int id, string regName)
{
    this->id = id;
    this->regName = regName;
}

std::string reg::getname()
{
    return regName;
}

int reg::getRegDesSize()
{
    int cnt = 0;
    for (auto it : regDes)
    {
        if (it.second == true)
            cnt++;
    }
    return cnt;
}

reg::reg(int id, string regName)
{
    this->id = id;
    this->regName = regName;
}

void declareRegs()
{
    // %rax, %rbx, %rcx, %rdx: 64 bit regs any purpose
    // %rax is used for 1st argument of syscall
    r[0].init(0, "%rax");
    r[1].init(1, "%rbx");
    r[2].init(2, "%rcx");
    r[3].init(3, "%rdx");
    r[4].init(4, "%rsi");
    r[5].init(5, "%rdi");
    r[6].init(6, "%rbp");
    r[7].init(7, "%rsp");
    r[8].init(8, "%r8");
    r[9].init(9, "%r9");
    r[10].init(10, "%r10");
    r[11].init(11, "%r11");
    r[12].init(12, "%r12");
    r[13].init(13, "%r13");
    r[14].init(14, "%r14");
    r[15].init(15, "%r15");
}

/************UTILITY FUNCTIONS***************/
bool is_number(const std::string &s)
{
    static const std::regex re("-?[0-9]+(\\.[0-9]*)?");
    return std::regex_match(s, re);
}

int countOccurrences(char c, string str)
{
    int count = 0;
    for (int i = 0; i < str.length(); i++)
    {
        if (str[i] == c)
        {
            count++;
        }
    }
    return count;
}

int getAddressDes(string varname)
{
    // if(varname.find('`') != string::npos) {
    //     varname = varname.substr(0, varname.find('`'));
    // }
    // // if(varname.find("this") != string::npos) {
    //     return addressDes[currClassName + "::::" + varname];
    // }
    cout << "looking for " << currClassName + "::" + currFuncName + "::" + varname << "\n";
    // for (auto it : addressDes)
    // {
    //     cout << it.first << " , ";
    // }

    if (addressDes.find(currClassName + "::" + currFuncName + "::" + varname) != addressDes.end())
        return addressDes[currClassName + "::" + currFuncName + "::" + varname];
    else if(addressDes.find(currClassName + "::::" + varname) != addressDes.end())
        return addressDes[currClassName + "::::" + varname];
    else {
        if(varname.find('`') != string::npos) {
            varname = varname.substr(0, varname.find('`'));
            return addressDes[currClassName + "::" + currFuncName + "::" + varname];
        }
        return addressDes[currClassName + "::::" + varname];
    }
}

vector<string> getArrayIndices(string s)
{
    vector<string> ans;
    string t1 = "", t2 = "", t3 = "";
    int numBrackets = countOccurrences('[', s);
    string t = s;
    if (numBrackets >= 1)
    {
        int startpos = t.find('[');
        int endpos = t.find(']');
        t1 = t.substr(startpos + 1, endpos - startpos - 1);
        cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$dim1 = " << t1 << "\n";
        t = t.substr(endpos+1);
    }
    if (numBrackets >= 2)
    {
        int startpos = t.find('[');
        int endpos = t.find(']');
        cout << "T = " << t << endl;
        cout << "issue2\n";
        cout << t.substr(startpos + 1, endpos - startpos - 1) << "\n";
        t2 = t.substr(startpos + 1, endpos - startpos - 1);
        t = t.substr(endpos+1);
    }
    if (numBrackets >= 3)
    {
        int startpos = t.find('[');
        int endpos = t.find(']');
        cout << "iss\n";
        t3 = t.substr(startpos + 1, endpos - startpos - 1);
        // t = t.substr();
    }
    if (is_number(t1))
        t1 = string("$") + t1;
    else
        t1 = to_string(getAddressDes(t1)) + "(%rbp)";
    if (is_number(t2))
        t2 = string("$") + t2;
    else
        t2 = to_string(getAddressDes(t2)) + "(%rbp)";
    if (is_number(t3))
        t3 = string("$") + t3;
    else
        t3 = to_string(getAddressDes(t3)) + "(%rbp)";

    ans.push_back(t1);
    ans.push_back(t2);
    ans.push_back(t3);
    return ans;
}

string trimInstr(string instr)
{
    if (instr.find(":") != string::npos)
    {
        return instr.substr(instr.find(":") + 1);
    }
    return instr;
}

string strip(string s)
{
    s.erase(0, s.find_first_not_of(" "));
    s.erase(s.find_last_not_of(" ") + 1);
    return s;
}

// get line no of 3ac instruction
int getLineNo(string instr)
{
    int i = 0;
    int lineNo = 0;
    while (i < instr.size() && isdigit(instr[i]))
    {
        lineNo = lineNo * 10 + (instr[i] - '0');
        i++;
    }
    return lineNo;
}

// check if the passed string is a constant or a variable
string consOrVar(string x)
{
    if (x.rfind("pushparam", 0) != 0)
    {
        cout << "Error the instruction not start with pushparam\n";
    }
    string temp;
    int f = 0;
    for (int j = 0; j < x.size(); j++)
    {
        if (x[j] == ' ')
        {
            f = 1;
        }
        else
        {
            if (f == 1)
            {
                temp.push_back(x[j]);
            }
        }
    }
    f = 0;
    for (int j = 0; j < temp.size(); j++)
    {

        if (!is_number(strip(temp)))
        {
            f = 1;
            break;
        }
    }
    string ans;
    if (f == 1)
    {
        cout << "******************x = " << temp << "\n";
        ans = to_string(getAddressDes(strip(temp))) + "(%rbp)";
    }
    else
    {
        ans = string("$") + strip(temp);
    }
    return ans;
}

vector<vector<string>> read_csv(string filename)
{
    vector<vector<string>> data;
    ifstream file;
    file.open(filename);
    if (!file)
    {
        cout << "RRRR-" << filename << "can'tbe opened\n";
    }
    string line;
    while (getline(file, line))
    {
        stringstream ss(line);
        vector<string> row;

        string cell;
        while (getline(ss, cell, ','))
        {
            row.push_back(cell);
        }

        data.push_back(row);
    }
    file.close();
    return data;
}

/*
General tips:
- %rsi and %rdi are used for passing function arguments



*/

// class for a register

// return move instruction
string genMove(string src, string dest)
{
    // check if src is a number
    cout << src << " in genMove\n";
    if (is_number(src))
    {
        // int val = stoi(src);
        src = string("$") + src;
    }
    else if (src[0] != '%')
    {
        src = to_string(getAddressDes(src)) + string("(%rbp)");
    }
    if (dest[0] != '%')
    {
        dest = to_string(getAddressDes(dest)) + string("(%rbp)");
    }

    // else {
    //     src = to_string(addressDes[src]) + string("(%rbp)");
    // }
    return MOVQ + src + ", " + dest;
}

string genArithmetic(string op, string src, string dest)
{
    if (op.size() == 0)
        return string("error");
    return opConv[op[0]] + src + ", " + dest;
}

vector<string> cmpOps = {"==", "<=", ">=", ">", "<", "!="};

vector<string> identifyInstr(string instr)
{
    /*


    assume nstruction starts immediately after colon
    */
    // string instr = lines[0];
    vector<string> ans;
    if (DEBUG)
        cout << "hey there\n";
    size_t colpos = instr.find(":");

    int line_num = getLineNo(instr);

    // put label if required
    if (islabel[line_num])
    {
        string ins = ".L" + to_string(line_num) + ":";
        ans.push_back(ins);
    }

    // consider instr only after colon, line no already dealt with
    instr = instr.substr(colpos + 1);
    DBG cout << "hey\n";
    size_t eqpos = instr.find('=');
    if (eqpos != string::npos && !(instr.find("!=") != string::npos) && !(instr.find("==") != string::npos) && !(instr.find(">=") != string::npos) && !(instr.find("<=") != string::npos))
    {
        //
        DBG cout << "hey here\n";
        string s = instr.substr(eqpos + 1);
        int flag = 0; // to check for arithmetic ops
        string x = instr.substr(0, eqpos);
        int dimx, dimy, dimz;
        dimx = countOccurrences('[', x);
        if (DEBUG)
            cout << "x != " << x << " " << instr << "\n";
        for (auto op : ops)
        {
            if (s.find(op) != string::npos)
            {
                string y = s.substr(0, s.find(op));
                string z = s.substr(s.find(op) + 1);
                int dimlhs = 0, dimrhs = 0;

                dimy = countOccurrences('[', y);
                dimz = countOccurrences('[', z);

                if (DEBUG)
                    cout << "y, z = " << y << ", " << z << "\n";
                // move to rbx and rcx
                // string ins1 = genMove(y, "%rbx");
                // string ins2 = genMove(z, "%rcx");
                if (dimy > 0)
                {
                    vector<string> ind = getArrayIndices(y);

                    ary_acc(y.substr(0, y.find('[')), dimy * 100, ind[0], ind[1], ind[2], "%rbx", ans);
                }
                else if (y.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(y);
                    cout << "yy = " << y << "\n";
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rax";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rax";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rax), %rbx";
                    ans.push_back(instr);
                }
                else
                {
                    ans.push_back(genMove(y, "%rbx"));
                    cout << "y = " << y << "\n";
                }
                if (dimz > 0)
                {
                    vector<string> ind = getArrayIndices(z);

                    ary_acc(z.substr(0, z.find('[')), dimz * 100, ind[0], ind[1], ind[2], "%rcx", ans);
                }
                else if (z.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(z);
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rax";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rax";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rax), %rbx";
                    ans.push_back(instr);
                }
                else
                {
                    ans.push_back(genMove(z, "%rcx"));
                }

                string ins3 = genArithmetic(s.substr(s.find(op), 1), "%rcx", "%rbx");
                string ins4 = genMove("%rbx", x);
                // ans.push_back(ins1);
                ans.push_back(ins3);
                if (x.find("this") == string::npos)
                {
                    if (dimx == 0)
                        ans.push_back(ins4);
                    else
                    {
                        vector<string> ind = getArrayIndices(x);
                        ary_ass(x.substr(0, x.find('[')), dimx * 100, ind[0], ind[1], ind[2], "%rcx", ans);
                    }
                }

                else
                {
                    int relpos = getAddressDes(x);
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rax";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rax";
                    ans.push_back(instr);
                    instr = MOVQ + string("%rcx, (%rax)");
                    ans.push_back(instr);
                }

                // add code
                // let x, y, x be st x = y + z
                flag = 1;
                break;
            }
        }
        if (flag == 0)
        {
            // copy instruction

            string s = instr.substr(eqpos + 1);   // rhs
            string var1 = instr.substr(0, eqpos); // lhs
            int dimlhs = countOccurrences('[', var1);
            int dimrhs = countOccurrences('[', s);
            if (s.substr(0, 7) == "new int")
            {
                vector<string> temp = getArrayIndices(s.substr(4));
                cout << temp[0] << " = temp"
                     << "\n";
                // for(int i = 0; i < dimrhs; i++) {
                //      if(is_number(temp[i])) {
                //         temp[i] = string("$") + temp[i];
                //      }
                //      else if(temp[i]!= "") {
                //         temp[i] = getAddressDes(temp[i]) + "(%rbp)";
                //      }
                // }
                cout << temp[0] << " = temp"
                     << "\n";
                call_malloc(var1, dimrhs * 100, temp[0], temp[1], temp[2], ans);
                return ans;
            }
            if (s.substr(0, 3) == "new")
            {
                // class constructor is being called

                string classname= s.substr(s.find(' ') + 1);

                call_malloc(var1,4*100,var1, to_string(classSize[classname]), "" , ans);
                string ins = string(MOVQ) + to_string(getAddressDes(var1)) + string("(%rbp), %rdi");

                ans.push_back(ins);
                // ins = "call\t" + objClass[var1] + "-" + objClass[var1];
                // ans.push_back(ins);
                return ans;
            }
            if (s.size() && is_number(s))
            {
                // rhs is a number
                // string var2 = instr.substr(0, eqpos);
                DBG cout << "getting address for " << var1 << " as " << getAddressDes(var1) << "\n";
                string ins = MOVQ + string("$") + s + string(", ") + to_string(getAddressDes(var1)) + string("(%rbp)");
                if (dimlhs == 0)
                    ans.push_back(ins);
                else if (var1.find("this") != string::npos)
                {
                    int relpos = getAddressDes(var1);
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rax";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rax";
                    ans.push_back(instr);
                    instr = MOVQ + string("$") + s + string(", (%rax)");
                    ans.push_back(instr);
                }
                else
                {
                    vector<string> ind = getArrayIndices(var1);
                    ary_ass(var1.substr(0, var1.find('[')), dimlhs * 100, ind[0], ind[1], ind[2], string("$") + s, ans);
                }
            }
            else
            {
                // rhs is a variable
                // move rhs to %rbx
                if (dimrhs > 0)
                {
                    vector<string> ind = getArrayIndices(s);
                    ary_acc(s.substr(0, s.find('[')), dimrhs * 100, ind[0], ind[1], ind[2], "%rbx", ans);
                }
                else if (s.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(s);
                    cout << "s = " << s <<'\n';
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rax";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rax";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rax), %rbx";
                    ans.push_back(instr);
                }

                else
                {
                    string ins = MOVQ + to_string(getAddressDes(s)) + string("(%rbp), %rbx");
                    ans.push_back(ins);
                }
                string ins = MOVQ + string("%rbx, ") + to_string(getAddressDes(var1)) + string("(%rbp)");
                if (dimlhs == 0)
                {
                    if (var1.find("this") != string::npos)
                    {
                        int relpos = getAddressDes(var1);
                        cout << "var1 = " << var1 << "\n";
                        cout << "relpos  = "<< relpos << "\n";
                        string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rax";
                        ans.push_back(instr);
                        instr = ADDQ + string("$") + to_string(relpos) + ", %rax";
                        ans.push_back(instr);
                        instr = MOVQ + string("%rbx, (%rax)");
                        ans.push_back(instr);
                    }
                    else
                    {
                        ans.push_back(ins);
                    }
                }
                else
                {
                    vector<string> ind = getArrayIndices(var1);
                    ary_ass(var1.substr(0, var1.find('[')), dimlhs * 100, ind[0], ind[1], ind[2], "%rbx", ans);
                }
            }
        }
    }
    else
    {
        // if then else, goto, call, pushparam, popparam

        if (instr.find("if") != string::npos)
        {
            cout << "if found\n";
            string t = instr.substr(instr.find("if"));
            string var1, var2, gotoloc;
            int gotopos = t.find("goto");

            int relpos = 0;
            for (auto ch : relOps)
            {
                if (t.find(ch) != string::npos)
                {
                    relpos = t.find(ch);
                    break;
                }
            }
            var1 = t.substr(3, relpos - 3);
            int relEnd = relpos;
            if (!isalnum(t[relpos + 1]))
                relEnd++;
            var2 = t.substr(relEnd + 1, gotopos - relEnd - 2);

            DBG cout << var1 << " var 1 " << var2 << "\n";
            int dimlhs = 0, dimrhs = 0;

                dimlhs = countOccurrences('[', var1);
                dimrhs = countOccurrences('[', var2);
                string y = var1, z = var2;
                int dimy = dimlhs, dimz = dimrhs;
                // if (DEBUG)
                //     cout << "y, z = " << y << ", " << z << "\n";
                // move to rbx and rcx
                // string ins1 = genMove(y, "%rbx");
                // string ins2 = genMove(z, "%rcx");
                if (dimlhs > 0)
                {
                    vector<string> ind = getArrayIndices(var1);

                    ary_acc(y.substr(0, y.find('[')), dimlhs * 100, ind[0], ind[1], ind[2], "%rax", ans);
                }
                else if (y.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(y);
                    cout << "yy = " << y << "\n";
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rbx";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rbx";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rbx), %rax";
                    ans.push_back(instr);
                }
                else
                {
                    ans.push_back(genMove(y, "%rax"));
                    cout << "y = " << y << "\n";
                }
                if (dimz > 0)
                {
                    vector<string> ind = getArrayIndices(z);

                    ary_acc(z.substr(0, z.find('[')), dimz * 100, ind[0], ind[1], ind[2], "%rcx", ans);
                }
                else if (z.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(z);
                    cout << "yy = " << z << "\n";
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rbx";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rbx";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rbx), %rcx";
                    ans.push_back(instr);
                }
                else
                {
                    ans.push_back(genMove(z, "%rcx"));
                }

            string ins = "cmpq\t%rcx, %rax";
            string ins_ = relConv[t.substr(relpos, relEnd - relpos + 1)] + " .L" + t.substr(gotopos + 5);
            DBG cout << ins_ << "\n";
            ans.push_back(".L" + to_string(line_num) + ":");

            // ans.push_back(ins1);
            // ans.push_back(ins2);
            ans.push_back(ins);
            ans.push_back(ins_);
            gotoloc = t.substr(gotopos + 5);
            cout << "use\n";
            int gotoval = stoi(gotoloc);
            islabel[gotoval] = true;
            return ans;
        }
        else if (instr.find("goto") != string::npos)
        {
            // pure goto instruction with no if
            cout << "use\n";
            int gotoval = stoi(instr.substr(5));
            islabel[gotoval] = true;
             
            string ins = string("jmp .L") + to_string(gotoval);
            ans.push_back((ins));
        }
        else if (instr.substr(0, 5) == "print")
        {
            string ins1 = MOVQ + string("$0, %rax");
            string varName = instr.substr(6);
            // cout << line << "\n";
            if (DEBUG)
                cout << varName << " heree var name\n";
            string t;
            t = to_string(getAddressDes(varName)) + string("(%rbp)");
            string ins2 = MOVQ + string("$printfmt, %rdi");
            string ins3 = MOVQ + t + string(", %rsi");
            
            // ans.push_back(ins3);
            int dimz = countOccurrences('[', varName);
            string z = varName;
            if (dimz > 0)
                {
                    vector<string> ind = getArrayIndices(varName);

                    ary_acc(z.substr(0, z.find('[')), dimz * 100, ind[0], ind[1], ind[2], "%rsi", ans);
                }
                else if (z.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(z);
                    cout << "yy = " << z << "\n";
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rbx";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rbx";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rbx), %rsi";
                    ans.push_back(instr);
                }
                else
                {
                    ans.push_back(genMove(z, "%rsi"));
                }
                ans.push_back(ins1);
                ans.push_back(ins2);
            ans.push_back("call printf");
            return ans;
        }
        else if (instr.substr(0, 6) == "return" && instr.length() > string("return").length())
        {
            // put return value in %rax since a value is being returned here

            string retvar = instr.substr(instr.find(' ') + 1);
            int dimz = countOccurrences('[', retvar);
            string z = retvar;
            if (dimz > 0)
                {
                    vector<string> ind = getArrayIndices(retvar);

                    ary_acc(z.substr(0, z.find('[')), dimz * 100, ind[0], ind[1], ind[2], "%rax", ans);
                }
                else if (z.find("this") != string::npos)
                {
                    // assumong to be of type this.simething
                    int relpos = getAddressDes(z);
                    cout << "yy = " << z << "\n";
                    string instr = MOVQ + to_string(getAddressDes("this")) + "(%rbp), %rbx";
                    ans.push_back(instr);
                    instr = ADDQ + string("$") + to_string(relpos) + ", %rbx";
                    ans.push_back(instr);
                    instr = string(MOVQ) + "(%rbx), %rax";
                    ans.push_back(instr);
                }
                else
                {
                    ans.push_back(genMove(z, "%rax"));
                }
                return ans;
                // ans.push_back(ins1);
                // ans.push_back(ins2);
            // ans.push_back("call printf");
            // string ins = genMove(retvar, "%rax");
            // ans.push_back(ins);
        }
    }
    return ans;
}

// generate the assembly code for a function
vector<string> genfunc(string funcName)
{
    // open the csv corresponding to the function name

    ifstream file2(GetCurrentWorkingDir() + "/temporary/" + currClassName + "_" + currFuncName + ".3ac");
    // vector<vector<string>> data;
    cout << currClassName + "_" + currFuncName + ".3ac"
         << "uuuuuuu\n";
    vector<string> funcCode;
    string y;
    if (funcName == "main")
    {
        y = "\n\n.globl main";
    }
    else
    {
        y = "\n\n.globl " + currClassName + "_" + funcName;
    }
    funcCode.push_back(y);
    string line;
    getline(file2, line);
    getline(file2, line);
    cout << "line: " << trimInstr(line) << "\n";
    beg_func(trimInstr(line), funcCode);

    if (!file2.is_open())
    {
        cout << "Error opening file" << endl;
        return funcCode;
    }

    // string line;
    cout << "file opened!\n";
    int linecnt = 0;
    int cnt = 0;
    while (getline(file2, line))
    {
        cnt++;
        cout << "cnt = " << cnt << "\n";
        if (DEBUG)
            cout << "line: " << line << "\n";
        vector<string> lines;
        int isfunc = 0;
        while (line.find("pushparam") != string::npos)
        {
            lines.push_back(trimInstr(line));
            if (islabel[getLineNo(line)])
            {
                string ins = ".L" + to_string(getLineNo(line)) + ":";
                funcCode.push_back(ins);
            }
            isfunc = 1;
            getline(file2, line);
            cout << "##################Line is : " << line << "\n";
            // lines.push_back(line);
        }

        if (isfunc)
        {
            getline(file2, line);
            cout << "##################Line is : " << line << "\n";
            // getline(file2, line);
            int isret = 0;
            if (trimInstr(line).find('=') != string::npos)
            {
                // function is returning
                string t = line.substr(line.find('=') + 1);
                lines.push_back(t);
                isret = 1;
            }
            else
                lines.push_back(trimInstr(line));
            // lines.push_back(trimInstr(line));
            cout << "##################Line is : " << line << "\n";
            if (line.find("call") != string::npos)
            {
                func_call(lines, funcCode);
            }
            if (line.find("new") != string::npos)
            {
                // possibly a constructor for a class
                lines.pop_back();
                string lhs = trimInstr(line).substr(0, trimInstr(line).find('='));
                string rhs = trimInstr(line).substr(trimInstr(line).find('=') + 1);
                string classname = rhs.substr(rhs.find(' ') + 1);
                // class constructor is being called
                call_malloc(lhs, 4 * 100, lhs, to_string(classSize[classname]), "", funcCode);
                string ins = string(MOVQ) + to_string(getAddressDes(lhs)) + string("(%rbp), %rdi");
                funcCode.push_back(ins);
                ins = "call " + classname;
                cout << "ins = " << ins << "\n";
                lines.push_back(ins);
                ins = string(MOVQ) + to_string(getAddressDes(lhs)) + "(%rbp), %rdi";
                funcCode.push_back(ins);
                func_call(lines, funcCode);
                isret = 0;
                // ans.push_back(ins);
                // return ans;
            }
            if (isret)
            {
                funcCode.push_back(genMove("%rax", trimInstr(line).substr(0, trimInstr(line).find('='))));
            }
            getline(file2, line);
            cout << "##################Line is : " << line << "\n";
            continue;
        }
        if (line.find("call") != string::npos)
        {
            if (islabel[getLineNo(line)])
            {
                string ins = ".L" + to_string(getLineNo(line)) + ":";
                funcCode.push_back(ins);
            }
            lines.push_back(line);
            func_call(lines, funcCode);
            continue;
        }

        // int numBrackets = 0;
        // if((numBrackets = countOccurrences('[', line)) > 0){
        //     if(numBrackets == 1) {

        //     }
        // }
        cout << trimInstr(line) << "\n";
        cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
        if (trimInstr(line).substr(0, 7) == "endfunc")
        {
            if (islabel[getLineNo(line)])
            {
                funcCode.push_back(".L" + to_string(getLineNo(line)) + ":");
            }
            funcCode.push_back("leave");
            funcCode.push_back("ret");
            currFuncName = "";
            file2.close();
            return funcCode;
        }

        vector<string> t = identifyInstr(line);
        cout << "identify called\n";
        for (auto it : t)
        {
            DBG cout << it << "\n";
        }
        if (t.size())
        {
            DBG cout << "ret\n";
            cout << "size is " << funcCode.size() << "\n";
            for (auto it : t)
            {
                funcCode.push_back(it);
            }
            DBG cout << "done\n";
            cout << "printing funccode\n";
            for (auto it : funcCode)
            {
                cout << it << "\n";
            }
        }
        cout << "funccode size: " << funcCode.size() << "\n";
    }

    // closing the function code

    file2.close();
    return funcCode;
    // Access the data by index
    // cout << data[0][0] << endl; // Print the first cell of the first row
}

void handleClassDec(string filename)
{
    string line;
    temporary_size = 0;
    ifstream fp(GetCurrentWorkingDir() + "/temporary/" + filename);
    getline(fp, line);
    line = trimInstr(line);
    if (strip(line.substr(0, 10)) == "beginclass")
    {
        currClassName = strip(line.substr(11));
        cout << "Curr class declared as: " << currClassName << "!\n";
        vector<vector<string>> data = read_csv(GetCurrentWorkingDir() + "/temporary/" + currClassName + ".csv");
        getline(fp, line);
        cout << "line = " << line << " " << (line.find("endclass") == string::npos) << "\n";

        while (line.find("endclass") == string::npos)
        {
            // getline(file2, line);
            // two things, integer variable or array declaration, or even class declaration
            // addressDes[currClassName + "::" + line.substr()]
            // assuming there is a csv file having variable info, type of variable and name of variable
            cout << "the hash is here\n";
            int pos = -8;
            classSize[currClassName] = 0;
            for (int i = 1; i < data.size(); i++)
            {
                string var = data[i][2];

                string typeName = data[i][3];
                objClass[var] = typeName;
                cout << "type = " << typeName << " " << var << "\n";
                if (sizes.find(typeName) != sizes.end())
                {
                    classSize[currClassName] += sizes[typeName];
                    addressDes[currClassName + "::" + currFuncName + "::" + var] = pos;
                    pos -= 8;
                    cout << "dec here :" << currClassName + "::" + currFuncName + "::" + var << classSize[currClassName] << "\n";
                }
                else if (classSize.find(data[i][2]) != classSize.end())
                {
                    classSize[currClassName] += classSize[data[i][3]];
                    addressDes[currClassName + "::" + var] = pos;
                    pos = pos - classSize[data[i][3]];
                }
                else
                {
                    // array type
                    int dim = 0;
                    int w1 = 0, w2 = 0, w3 = 0;
                    if (data[i][3].length() < 5)
                    {
                        cout << "symbol table type undefined\n";
                    }
                    else
                        dim++;
                    w1 = data[i][3][4] - '0';
                    if (data[i][3].length() > 7)
                    {
                        w2 = data[i][3][7] - '0';
                        dim++;
                    }
                    else {
                        //array type
                        // int dim = 0;
                        // int w1=0, w2=0, w3=0;
                        // if(data[i][3].length() < 5) {cout<< "symbol table type undefined\n";}
                        // else dim++;
                        // w1 = data[i][3][4] - '0';
                        // if(data[i][3].length() > 7) {w2 = data[i][3][7]- '0'; dim++;}
                        // if(data[i][3].length() > 10) {w3 = data[i][3][10] - '0'; dim++;}
                        // // only int arrays assumed of size 8 bytes
                        // addressDes[currClassName + "::" + data[i][2]] = pos;
                        // // if(dim == 1) {
                        // //     pos = pos - 8 * w1;
                        // // }
                        // // else if(dim == 2) {
                        // //     pos = pos - 8 * w1 * w2;
                        // // }
                        // // else {
                        // //     pos = pos - 8 * w1 * w2 * w3;
                        // // }
                    }
                }
            }
            getline(fp, line);
        }
    }
    // temporary_size += (max(1, classSize[currClassName]/8));
    fp.close();
}

void finalCodeGen(vector<string> &funcCode, string otpt)
{
    ofstream fout;
    fout.open(otpt);
    if (!fout)
    {
        cout << "RRRR-"
             << "can't be opened\n";
    }
    fout << ".text\n";
    // fout << ".globl " + mainClassName + "-" + "main" + "\n";
    for (auto s : funcCode)
    {
        fout << s << "\n";
    }
    fout << "movq $60, %rax\n";
    fout << "xorq %rbx, %rbx\n";
    fout << "syscall\n";

    fout << "printfmt: \n";
    fout << ".string \"%d\"";
    fout.close();
    return;
}

string getfuncName(string x)
{
    if (x.rfind("call", 0) != 0 && x.find("new") == string::npos)
    {
        cout << "Error the instruction not start with call\n";
    }
    x = x.substr(x.find(' ') + 1);
    string temp = currClassName + "_" + x;
    if (x.find(".") != string::npos)
    {
        string var = x.substr(0, x.find('.'));
        string func = x.substr(x.find('.') + 1);
        cout << "var = " << var <<"\n";
        cout << "func = " << func << "\n";
        // a class object's function is being called
        // need to consult the symbol table for this current function, or class
        string filename = currClassName + "_" + currFuncName + ".csv";
        vector<vector<string>> data = read_csv(GetCurrentWorkingDir() + "/temporary/" + filename);
        for (int i = 1; i < data.size(); i++)
        {
            cout << "j=" << i << "\n";
            if (data[i][2] == var)
            {
                temp = data[i][3] + "_" + func;
                cout << "temp = " << temp;
            }
        }
        //std::cout << "temp =" << temp << "\n";
        std::cout << "var = " << var << '\n';
    }
    return temp;
}
string smplPush(string x)
{
    if (x.rfind("pushparam", 0) != 0)
    {
        cout << "Not a push instruction";
    }
    string ans;
    int f = 0;
    for (int j = 0; j < x.size(); j++)
    {
        if (x[j] == ' ')
        {
            f = 1;
        }
        else if (f == 1)
        {
            ans.push_back(x[j]);
        }
    }
    return ans;
}

void modify_var_arg(string s)
{
    cout << "called\n";
    cout << "s=" << s << "\n";
    s = currClassName + "::" + currFuncName + "::" + s;
    if (var.find(s) != var.end())
    {
        var[s][1] = 1;
        cout << "done\n";
    }
    else
    {
        cout << s << " not found\n";
    }
    cout << "returning\n";
    return;
}
vector<int> var_info(string x)
{
    // //string x;
    cout << "ar info\n";
    vector<int> ans;
    for (auto it : var)
    {
        cout << it.first << " ";
        if (it.first == x)
        {
            cout << "found\n";
        }
    }
    cout << "\n";
    x = currClassName + "::" + currFuncName + "::" + x;
    if (var.find(x) == var.end())
    {
        cout << "not f\n";
        return ans;
    }
    cout << "come\n";
    return var[x];
}
int sz_func()
{
    int ans = 0;
    vector<vector<string>> data = read_csv(GetCurrentWorkingDir() + "/temporary/" + currClassName + "_" + currFuncName + ".csv");
    for (int i = 1; i < data.size(); i++)
    {
    }
    ans += temporary_size * 8 + 8;

    return ans;
}
int string_to_int(string x)
{ // replacement for stoi
cout << "string to int\n";
    return stoi(x);
}
void fill_var_temp_sz(string x)
{
    ifstream file;
    cout << "x = " << x << "\n";
    file.open(GetCurrentWorkingDir() + "/temporary/" + currClassName + "_" + x + ".3ac");
    if (!file)
    {
        cout << "RRRR-file not opening\n";
    }
    cout << currClassName + "_" + x << "\n";
    string line;
    getline(file, line);
    file.close();
    cout << "the line is " << line << "\n";
    line = line.substr(line.find(',') + 1);

    temporary_size += string_to_int(line);
    vector<string> v;
    file.open(GetCurrentWorkingDir() + "/temporary/" + currClassName + "_" + x + ".csv");
    if (!file)
    {
        cout << "RRRR- file not openong\n";
    }
    getline(file, line);
    while (getline(file, line))
    {
        v.push_back(line);
    }
    file.close();
    var.clear();
    for (int j = 0; j < v.size(); j++)
    {
        int cnt = 0;
        int k = 0;
        for (k = 0; k < v[j].size(); k++)
        {
            if (v[j][k] == ',')
            {
                cnt++;
            }
            if (cnt == 2)
            {
                break;
            }
        }
        k++;
        string nm;
        for (; k < v[j].size(); k++)
        {
            if (v[j][k] == ',')
                break;
            nm.push_back(v[j][k]);
        }
        nm = currClassName + "::" + currFuncName + "::" + nm;
        vector<int> temp;
        k++;
        string tp;
        for (; k < v[j].size(); k++)
        {
            if (v[j][k] == ',')
                break;
            tp.push_back(v[j][k]);
        }
        if (tp == "int")
        {
            temp = {1, 0};
        }
        else
        {
            int w = 0;
            int cnt = 0;
            for (int k = 0; k < tp.size(); k++)
            {
                if (tp[k] == 'w')
                {
                    w = 1;
                }
                if (tp[k] == ']')
                {
                    cnt++;
                }
            }
            if (w == 1)
            {
                if (cnt == 1)
                {
                    temp = {100, 1};
                }
                if (cnt == 2)
                {
                    temp = {200, 1};
                }
                if (cnt == 3)
                {
                    temp = {300, 1};
                }
            }
            else
            {
                vector<int> u = {cnt * 100, 0};
                w = 0;
                string p;
                for (int k = 0; k < tp.size(); k++)
                {
                    if (tp[k] == '[')
                    {
                        w = 1;
                    }
                    else if (w == 1)
                    {
                        if (tp[k] == ']')
                        {
                            u.push_back(string_to_int(p));
                            w = 0;
                            p = "";
                        }
                        else
                        {
                            p.push_back(tp[k]);
                        }
                    }
                }
                temp = u;
            }
        }
        var[nm] = temp;
        cout << "Name = " << nm << "as\n";
    }
    cout << "fill var returned\n";
}

void ary_ass(string lex, int tp, string v1, string v2, string v3, string val, vector<string> &funCode)
{
    // here lex is the array name , tp is type: 100 for 1d,200 for 2d..., v1,v2,v3 is the index you want to acess
    //  val is the valyue to be assigned send it as $const if it is const else send it the memory loc i.e. -8(%rbp)
    if (tp == 100)
    {
        // put val in rdx
        string instr = "movq " + val + ", %rdx";
        funCode.push_back(instr);
        // put index in rax
        instr = "movq " + v1 + ", %rax";
        funCode.push_back(instr);
        instr = "salq $3, %rax";
        funCode.push_back(instr);
        instr = "movq " + to_string(getAddressDes(lex)) + "(%rbp), %rdi";
        funCode.push_back(instr);
        instr = "addq %rax, %rdi";
        funCode.push_back(instr);
        // finally assignment
        instr = "movq %rdx, (%rdi)";
        funCode.push_back(instr);
    }
    if (tp == 200)
    {
        // put val in rdx
        string instr = "movq " + val + ", %rdx";
        funCode.push_back(instr);
        // put v1 in rax
        instr = "movq " + v1 + ", %rax";
        funCode.push_back(instr);
        // put v2 in rax
        instr = "movq " + v2 + ", %rdi";
        funCode.push_back(instr);
        // v1*w2+v2
        instr = "movq " + to_string(getAddressDes(lex + "_w2")) + "(%rbp), %rsi";
        funCode.push_back(instr);
        instr = "imulq %rsi, %rax";
        funCode.push_back(instr);
        instr = "addq %rsi, %rax";
        funCode.push_back(instr);
        // finally assignment
        instr = "salq $3, %rax";
        funCode.push_back(instr);
        instr = "movq " + to_string(getAddressDes(lex)) + "(%rbp), %rdi";
        funCode.push_back(instr);
        instr = "addq %rax, %rdi";
        funCode.push_back(instr);
        // finally assignment
        instr = "movq %rdx, (%rdi)";
        funCode.push_back(instr);
    }
    if (tp == 300)
    {
        // put val in rdx
        string instr = "movq " + val + ", %rdx";
        funCode.push_back(instr);
        // put v1 in rax
        instr = "movq " + v1 + ", %rax";
        funCode.push_back(instr);
        // put v2 in rdi
        instr = "movq " + v2 + ", %rdi";
        funCode.push_back(instr);
        // put v3 in r8
        instr = "movq " + v2 + ", %r8";
        funCode.push_back(instr);
        // put w2 in rsi
        instr = "movq " + to_string(getAddressDes(lex + "_w2")) + "(%rbp), %rsi";
        funCode.push_back(instr);

        // put w3 in r9
        instr = "movq " + to_string(getAddressDes(lex + "_w3")) + "(%rbp), %r9";
        funCode.push_back(instr);
        // v3+v1*w2*w3+v2*w3
        instr = "imulq %rsi, %rax";
        funCode.push_back(instr);
        instr = "imulq %r9, %rax";
        funCode.push_back(instr);
        instr = "imulq %r9, %rdi";
        funCode.push_back(instr);
        instr = "addq %rdi, %rax";
        funCode.push_back(instr);
        instr = "addq %r8, %rax";
        funCode.push_back(instr);
        // finally assignment
        instr = "salq $3, %rax";
        funCode.push_back(instr);
        instr = "movq " + to_string(getAddressDes(lex)) + "(%rbp), %rdi";
        funCode.push_back(instr);
        instr = "addq %rax, %rdi";
        funCode.push_back(instr);
        // finally assignment
        instr = "movq %rdx, (%rdi)";
        funCode.push_back(instr);
    }
}

void ary_acc(string lex, int tp, string v1, string v2, string v3, string r, vector<string> &funCode)
{
    // here lex is the array name , tp is type: 100 for 1d,200 for 2d..., v1,v2,v3 is the index you want to acess
    // here you will get your value in register r, send r as %rdx
    string instr;
    if (tp == 100)
    {
        // put index in rax
        instr = "movq " + v1 + ", %rax";
        funCode.push_back(instr);
        // finally acces
        instr = "salq $3, %rax";
        funCode.push_back(instr);
        instr = "movq " + to_string(getAddressDes(lex)) + "(%rbp), %rdi";
        funCode.push_back(instr);
        instr = "addq %rax, %rdi";
        funCode.push_back(instr);
        // finally assignment
        instr = "movq (%rdi), " + r;
        funCode.push_back(instr);
    }
    if (tp == 200)
    {
        // put v1 in rax
        instr = "movq " + v1 + ", %rax";
        funCode.push_back(instr);
        // put v2 in rax
        instr = "movq " + v2 + ", %rdi";
        funCode.push_back(instr);
        // v1*w2+v2
        instr = "movq " + to_string(getAddressDes(lex + "_w2")) + "(%rbp), %rsi";
        funCode.push_back(instr);
        instr = "imulq %rsi, %rax";
        funCode.push_back(instr);
        instr = "addq %rsi, %rax";
        funCode.push_back(instr);
        // finally assignment
        instr = "salq $3, %rax";
        funCode.push_back(instr);
        instr = "movq " + to_string(getAddressDes(lex)) + "(%rbp), %rdi";
        funCode.push_back(instr);
        instr = "addq %rax, %rdi";
        funCode.push_back(instr);
        // finally assignment
        instr = "movq (%rdi), " + r;
        funCode.push_back(instr);
    }
    if (tp == 300)
    {
        // put v1 in rax
        instr = "movq " + v1 + ", %rax";
        funCode.push_back(instr);
        // put v2 in rdi
        instr = "movq " + v2 + ", %rdi";
        funCode.push_back(instr);
        // put v3 in r8
        instr = "movq " + v2 + ", %r8";
        funCode.push_back(instr);
        // put w2 in rsi
        instr = "movq " + to_string(getAddressDes(lex + "_w2")) + "(%rbp), %rsi";
        funCode.push_back(instr);
        // put w3 in r9
        instr = "movq " + to_string(getAddressDes(lex + "_w3")) + "(%rbp), %r9";
        funCode.push_back(instr);
        // v3+v1*w2*w3+v2*w3
        instr = "imulq %rsi, %rax";
        funCode.push_back(instr);
        instr = "imulq %r9, %rax";
        funCode.push_back(instr);
        instr = "imulq %r9, %rdi";
        funCode.push_back(instr);
        instr = "addq %rdi, %rax";
        funCode.push_back(instr);
        instr = "addq %r8, %rax";
        funCode.push_back(instr);
        // finally assignment
        instr = "salq $3, %rax";
        funCode.push_back(instr);
        instr = "movq " + to_string(getAddressDes(lex)) + "(%rbp), %rdi";
        funCode.push_back(instr);
        instr = "addq %rax, %rdi";
        funCode.push_back(instr);
        // finally assignment
        instr = "movq (%rdi), " + r;
        funCode.push_back(instr);
    }
}
void insert_arg(vector<string> arg, vector<string> &funCode)
{
    int cnt = 0;
    DBG cout << "insert arg calleds\n";
    vector<string> arg_name;
    for (int j = 0; j < arg.size(); j++)
    {
        cout << "j=" << j << "\n";
        arg_name.push_back(arg[j]);
        cout << "hey]h\n";
        vector<int> info = var_info(arg[j]);

        if (info.size() == 0)
        {
            cout << "No such variable exist\n";
        }
        if (info[0] == 100)
        {
            arg_name.push_back(arg[j] + "_w1");
        }
        if (info[0] == 200)
        {
            arg_name.push_back(arg[j] + "_w1");
            arg_name.push_back(arg[j] + "_w2");
        }
        if (info[0] == 300)
        {
            arg_name.push_back(arg[j] + "_w1");
            arg_name.push_back(arg[j] + "_w2");
            arg_name.push_back(arg[j] + "_w3");
        }
    }
    cout << "reavched th\n";
    string instr = MOVQ + string("%rdi, ") + to_string(getAddressDes("this")) + "(%rbp)";
    funCode.push_back(instr);
    vector<string> rg = {"%rsi", "%rdx", "%rcx", "%r8", "%r9"};
    for (int j = 0; j < arg_name.size(); j++)
    {
        cnt++;

        if (cnt <= 5)
        {
            funCode.push_back("movq " + rg[cnt - 1] + ", " + to_string(getAddressDes(arg_name[j])) + "(%rbp)");
        }
        else
        {
            funCode.push_back("movq " + to_string(16 + ((arg_name.size() - 6) - (cnt - 6)) * 8) + "(%rbp)" + ", %rdx");
            funCode.push_back("movq %rdx, " + to_string(getAddressDes(arg_name[j])) + "(%rbp)");
        }
    }
    cout << "insert ags ret\n";
}
pair<int, int> declareLocalVars()
{
    // ifstream fp(currClassName + "-" + currFuncName + ".csv");
    cout << "Declaring local vars****************\n";
    vector<vector<string>> data = read_csv(GetCurrentWorkingDir() + "/temporary/" + currClassName + "_" + currFuncName + ".csv");
    cout << "read csv " << data.size() << "\n";
    int pos = -8;
    int sz = -8;

    for (int i = 1; i < data.size(); i++)
    {
        int dim1 = 1, dim2 = 1, dim3 = 1;
        cout << "i = " << i << "\n";
        int numBrackets = countOccurrences('[', data[i][3]);
        cout << "i = " << i << "\n";
        string t = data[i][3];
        cout << " t = " << data[i][3] << "!\n";
        if (t.substr(0, 3) != "int")
        {
            // not an int variable, look if its a class object
            // for(auto it: classSize) {
            //     cout << it.first << " " ;
            // }
            cout << "\n";
            if (classSize.find(t) != classSize.end())
            {
                string tt = currClassName + "::" + currFuncName + "::" + data[i][2];
                addressDes[tt] = pos;
                cout << "~~~~~~~~~~~~~~tt = " << tt << "\n";
                pos = pos - (classSize[t] != 0 ? classSize[t] : 8);
                sz = pos;
            }
            else
            {
                cout << "ERROR IN PROGRAM, CLASS NOT DECLARED\n";
            }
        }
        else
        {
            sz = sz - 8 * (numBrackets + 1);
        }
        string tt = currClassName + "::" + currFuncName + "::" + data[i][2];

        cout << "sz = " << sz << "\n";

        cout << "t=" << tt << endl;
        addressDes[tt] = pos;
        pos = pos - 8;
        // sz = pos;
        cout << "dec\n";

        if (numBrackets >= 1)
        {
            addressDes[tt + "_w1"] = pos;
            pos -= 8;
            sz -= 8;
        }
        if (numBrackets >= 2)
        {
            addressDes[tt + "_w2"] = pos;
            pos -= 8;
            sz -= 8;
        }
        if (numBrackets >= 3)
        {
            addressDes[tt + "_w3"] = pos;
            pos -= 8;
            sz -= 8;
        }
    }
    cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1tmp size = " << temporary_size << "\n";
    // sz -= 8 * temporary_size;
    for (int i = 0; i < temporary_size; i++)
    {
        string tempName = "_t" + to_string(i);
        string tt = currClassName + "::" + currFuncName + "::" + tempName;
        addressDes[tt] = pos;
        pos -= 8;
        // sz = pos;
    }
    addressDes[currClassName + "::" + currFuncName + "::this"] = pos;
    data = read_csv(GetCurrentWorkingDir() + "/temporary/" + currClassName + ".csv");
    int pp = 0;
    for (int i = 1; i < data.size(); i++)
    {
        addressDes[currClassName + "::" + currFuncName + "::this." + data[i][2]] = pp;
        pp += 8;
        cout << currClassName + "::" + currFuncName + "::this." + data[i][2] << "\n";
        

    }
    pos -= 8;
    sz -= 8;
    return {abs(pos), abs(pos)};
}

// handles starting code of function, initialize stack space etc
void beg_func(string x, vector<string> &funCode)
{
    if (x.rfind("beginfunc", 0) != 0)
    {
        cout << "Not a start of the function\n";
    }
    int f = 0;
    string xx = x.substr(x.find(' ') + 1);
    string func_nm = xx.substr(0, xx.find(' '));

    currFuncName = func_nm;
    fill_var_temp_sz(func_nm);
    vector<string> arg_name;
    string temp;
    int pos = string("beginfunc").length() + 1 + func_nm.length() + 1;
    cout << "pos = " << pos << "\n";
    for (int j = pos; j < x.size(); j++)
    {
        if (x[j] == ',')
        {
            arg_name.push_back(temp);
            temp = "";
        }
        else
        {
            temp.push_back(x[j]);
        }
    }
    if (temp.length() > 0)
        arg_name.push_back(temp);

    string instr = currClassName + "_" + func_nm + ":";
    if (func_nm == "main")
    {
        instr = "main:";
    }
    funCode.push_back(instr);
    pair<int, int> p = declareLocalVars();
    instr = "pushq %rbp";
    funCode.push_back(instr);
    instr = "movq %rsp, %rbp";
    funCode.push_back(instr);
    instr = "subq $" + to_string(p.first) + ", %rsp";
    funCode.push_back(instr);
    insert_arg(arg_name, funCode);
}
void func_call(vector<string> a, vector<string> &funcCode)
{
    vector<string> ans_reg; // keep all the register instruction
    vector<string> ans_st;  // keep all the pushq instruction
    vector<pair<string, int>> things;
    cout << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2num of arguments = " << a.size() - 1 << "\n";
    for (int j = a.size() - 2; j >= 0; j--)
    {
        string y = consOrVar(a[j]);
        if (y[0] == '$')
        {
            things.push_back({y, 0});
        }
        else
        {
            // string x=currClassName + "::" + currFuncName + "::" + smplPush(a[j]);
            string x = smplPush(a[j]);
            cout << "x = " << x << "\n";
            if (var_info(x).size() == 0)
            {
                cout << "No such variable exist\n";
                if (x[0] == '_')
                {
                    things.push_back({y, 0});
                }
            }
            else
            {
                vector<int> info = var_info(x);
                if (info[0] == 1)
                { // int
                    things.push_back({y, 0});
                }
                if (info[0] >= 100)
                {                                                                  // array
                    things.push_back({to_string(getAddressDes(x)) + "(%rbp)", 1}); // for this array we have width in stack
                    if (info[0] == 100)
                    { // 1darray
                        things.push_back({to_string(getAddressDes(x + "_w1")) + "(%rbp)", 0});
                    }
                    if (info[0] == 200)
                    { // 2darray
                        things.push_back({to_string(getAddressDes(x + "_w1")) + "(%rbp)", 0});
                        things.push_back({to_string(getAddressDes(x + "_w2")) + "(%rbp)", 0});
                    }
                    if (info[0] == 300)
                    { // 3darray
                        things.push_back({to_string(getAddressDes(x + "_w1")) + "(%rbp)", 0});
                        things.push_back({to_string(getAddressDes(x + "_w2")) + "(%rbp)", 0});
                        things.push_back({to_string(getAddressDes(x + "_w3")) + "(%rbp)", 0});
                    }
                }
            }
        }
    }
    vector<string> rg = {"%rsi", "%rdx", "%rcx", "%r8", "%r9"};
    for (int j = 0; j < things.size(); j++)
    {
        if (j < 5)
        {
            if (things[j].second == 0)
                ans_reg.push_back("movq  " + things[j].first + ", " + rg[j]);
            else
                ans_reg.push_back("movq  " + things[j].first + ", " + rg[j]);
        }
        else
        {
            if (things[j].second == 0)
                ans_st.push_back("movq  " + things[j].first + ", %rdx");
            else
                ans_st.push_back("movq  " + things[j].first + ", " + rg[j]);
            ans_st.push_back("pushq  %rdx");
        }
    }
    string instr;
    instr = "call " + getfuncName(a[a.size() - 1]);
    ans_reg.push_back(instr);
    int lineNum = getLineNo(a[0]);
    if (islabel[lineNum])
    {
        string ins = ".L" + to_string(lineNum) + ":";
        funcCode.push_back(ins);
    }
    for (auto y : ans_st)
    {
        funcCode.push_back(y);
    }
    for (auto y : ans_reg)
    {
        funcCode.push_back(y);
    }
}
void call_malloc(string name, int tp, string s1, string s2, string s3, vector<string> &funCode)
{
    // s is the registeer or the memory where sie is present send it as (%rbp) or $5
    // except rdi
    string instr;
    cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!tp = " << tp << "\n";
    if (tp == 100)
    {
        instr = "movq " + s1 + ",%rdi";
        funCode.push_back(instr);
        instr = "salq $3,%rdi";
        funCode.push_back(instr);
        instr = "movq " + s1 + ",%r8";
        funCode.push_back(instr);
        instr = "movq %r8," + to_string(getAddressDes(name + "_w1")) + "(%rbp)";
        cout << "the name is " << name << "\n";
        funCode.push_back(instr);
    }
    if (tp == 200)
    {
        instr = "movq " + s1 + ",%rdi";
        funCode.push_back(instr);
        instr = "imulq " + s2 + ",%rdi";
        funCode.push_back(instr);
        instr = "salq $3,%rdi";
        funCode.push_back(instr);
        instr = "movq " + s1 + ",%r8";
        funCode.push_back(instr);
        instr = "movq %r8," + to_string(getAddressDes(name + "_w1")) + "(%rbp)";
        funCode.push_back(instr);
        instr = "movq " + s2 + ",%r8";
        funCode.push_back(instr);
        instr = "movq %r8," + to_string(getAddressDes(name + "_w2")) + "(%rbp)";
        funCode.push_back(instr);
    }
    if (tp == 300)
    {
        instr = "movq " + s1 + ",%rdi";
        funCode.push_back(instr);
        instr = "imulq " + s2 + ",%rdi";
        funCode.push_back(instr);
        instr = "imulq " + s3 + ",%rdi";
        funCode.push_back(instr);
        instr = "salq $3,%rdi";
        funCode.push_back(instr);
        instr = "movq " + s1 + ",%r8";
        funCode.push_back(instr);
        instr = "movq %r8," + to_string(getAddressDes(name + "_w1")) + "(%rbp)";

        funCode.push_back(instr);
        instr = "movq " + s2 + ",%r8";
        funCode.push_back(instr);
        instr = "movq %r8," + to_string(getAddressDes(name + "_w2")) + "(%rbp)";
        funCode.push_back(instr);
        instr = "movq " + s3 + ",%r8";
        funCode.push_back(instr);
        instr = "movq %r8," + to_string(getAddressDes(name + "_w3")) + "(%rbp)";
        funCode.push_back(instr);
    }
    if (tp == 400)
    {
        instr = string(MOVQ) + string("$") + s2 + string(", %rdi");
        funCode.push_back(instr);
    }
    instr = "call\tmalloc";
    funCode.push_back(instr);

    cout << "S1 = " << s1 << " " << objClass[s1] << " \n";
    instr = string(MOVQ) + string("%rax, ") + to_string(getAddressDes(name)) + string("(%rbp)");
    funCode.push_back(instr);
}

int main(int argc, char *argv[])
{

    // if(argc < 2) {
    //     cout << "Wrong input format\n";
    //     return 0;
    // }

    declareRegs();
    opConv['+'] = ADDQ;
    opConv['-'] = SUBQ;
    opConv['*'] = MULQ;
    opConv['/'] = DIVQ;
    opConv['^'] = XORQ;
    relConv["<"] = "jl";
    relConv[">"] = "jg";
    relConv[">="] = "jge";
    relConv["<="] = "jle";
    relConv["!="] = "jne";
    relConv["=="] = "je";
    sizes["int"] = sizes["byte"] = sizes["short"] = sizes["long"] = 8;
    string otpt;
    vector<string> inp;
    if (argc == 2)
    {
        if (argv[1][0] == '-' && argv[1][1] == '-' && argv[1][2] == 'h' && argv[1][3] == 'e' && argv[1][4] == 'l' && argv[1][5] == 'p' && argv[1][6] == '\0')
        {
            cout << "Usage: ./asmgen --input=<input_filename> --output=<output_filename>\noptions: --help\n";
            return 0;
        }
        else
        {
            cout << "Invalid argument. Use --help for usage.\n";
            return 0;
        }
    }
    else if (argc == 1)
    {
        cout << "No file specified. Use --help for usage.\n";
        return 0;
    }
    else if (argc == 3)
    {
        vector<string> y;
        y.push_back(argv[1]);
        y.push_back(argv[2]);
        sort(y.begin(), y.end());
        if (y[0].rfind("--input", 0) == 0 && y[1].rfind("--output=", 0) == 0)
        {
            string temp;
            for (int i = 8; i < y[0].size(); i++)
            {
                temp = temp + y[0][i];
            }
            ifstream file;
            file.open(GetCurrentWorkingDir() + "/temporary/" + temp);
            if (!file)
            {
                cout << "hello\n";
                cout << "RRRR- file not openong\n";
            }
            string line;
            while (getline(file, line))
            {
                inp.push_back(line);
            }
            file.close();
            for (int i = 9; i < y[1].size(); i++)
            {
                otpt = otpt + y[1][i];
            }
        }
        else
        {
            cout << "Invalid argument. Use --help for usage.\n";
            return 0;
        }
    }
    vector<string> classes;
    map<string, vector<string>> funcs;
    if (inp.size() == 0)
    {
        cout << "File can't be open\n";
    }
    else
    {
        string currclass = "";
        for (auto it : inp)
        {
            string ins = trimInstr(it);
            if (ins.rfind("beginclass", 0) == 0)
            {
                string temp;
                int f = 0;
                for (int j = 0; j < ins.size(); j++)
                {
                    if (ins[j] == ' ')
                    {
                        f = 1;
                    }
                    else if (f == 1)
                    {
                        temp.push_back(ins[j]);
                    }
                }
                classes.push_back(temp);
                currclass = temp;
            }
            if (ins.rfind("beginfunc", 0) == 0)
            {
                string temp;
                int f = 0;
                for (int j = 0; j < ins.size(); j++)
                {
                    if (f == 1 && ins[j] == ' ')
                        break;
                    if (ins[j] == ' ')
                    {
                        f = 1;
                    }
                    else if (f == 1)
                    {
                        temp.push_back(ins[j]);
                    }
                }
                funcs[currclass].push_back(temp);
            }
        }
    }
    vector<string> code;
    for (auto it : classes)
    {
        cout << "---" << it << "\n";
        handleClassDec(it + ".3ac");
        for (auto it : funcs[it])
        {
            currFuncName = it;
            cout << "it = " << it << "\n";
            vector<string> t = genfunc(it);
            for (auto it : t)
            {
                code.push_back(it);
            }
            // cout << "printing code till fnow\n";
            // for(auto it: code) {
            //     cout  << it << "\n";
            // }
        }
    }
    if (otpt.size() == 0)
    {
        otpt = "asm.s";
    }
    finalCodeGen(code, otpt);
}