×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Can someone compile a C++ file for me? No compilers I can find will...

Can someone compile a C++ file for me? No compilers I can find will...

Can someone compile a C++ file for me? No compilers I can find will...

(OP)
Here is the code I need compiled. I have tried several compilers to no avail...

/*********************************************************************************************
*                                                                                             *                        
* Program Name:C2ASM,Ver 1.0,9th July,2003.                                                     *    
*                                                                                             *
* Category:Cross Compiler(From "C" to "Assembly Language").                                     *
*                                                                                             *
* Input:c_code.txt(Place the "C" code u want to convert into "ASSEMBLY" Language)             *
*                                                                                             *
* Output:asm_code.txt("ASSEMBLY" code for INPUT "C" program)                                 *
*                                                                                             *
* Requirements:Microsoft Windows(95/98/Me/2000/XP)/DOS.                                         *
*             Microsoft Visual C++(Ver 6.0)/Microsoft Visual C++ .NET                         *
*             Microsoft MASM(Ver 6.11)                                                         *    
*                                                                                             *
*        NOTE:All Names Mentioned in "Requirements" Section are Registered trade marks of     *
*             Microsoft Corporation.                                                             *
*                                                                                             *
* Programmed By:Muhammad Owais Khan Afridi.                                                     *
*              BS(Computer Science),8th Semester,Department Of Computer Science,                 *
*              Karachi University,Pakistan.                                                     *
*                                                                                             *
* Notes for Readers:                                                                         *
*    1)Sure to read documentation supplied with this code.It'll clear many confusions.         *
*    2)Reader Shld know programming in C,Assembly,Use of <Vectors> and <Stack> of STL(C++),     *
*      to understand this code.                                                                 *
*    3)This program doesn't use any Object Code Optimization,Register Allocation Algorithms.  *
*    4)It converts STANDARD "C",See Sample Programs supplied to get some idea.                 *
*    5)It doesn't Convert all the "C" statements like Switch-Case.It uses a Sub-Part of "C"   *
*      Language,See GRAMMAR,TOKEN SET of Language in Documentation Supplied to get idea abt it*
*                                                                                             *    
* Disclaimer:                                                                                 *
*            The Author of this PROGRAM shall not be liable in any event for incidental or    *
*            consequential damages in connection with,or arising out of,the furnishing,       *
*            performance,or use of this program.                                                 *
*********************************************************************************************/
#pragma warning (disable:4786)
#include<conio.h>
#include<string.h>
#include<iostream.h>
#include<fstream.h>
#include<vector.h>
#include<stack.h>
using namespace std;

#define LEXEME_SIZE 30            
#define FILE_READ "c_code.txt"    //This is the INPUT "C" file,which is to be converted into
                                //Assembly.

#define FILE_WRITE "asm_code.txt"  //This is the OUTPUT "ASSEMBLY" file For the input "C" file

//Globals Used By Lexical Box,Syntax Box,Code Generator.
vector<long> number_long;    //This vector will hold Long Constants occuring in the Program
vector<long> number_int;    //This vector will hold Int Constants occuring in the Program

//////////////////////////////
//
//Globals Used By Lexical Box.
//
/////////////////////////////

//This Vector is used to hold IDENTIFIER(s) for Lexical Box ONLY!
vector<string> lex_identifier;    

#define TOTAL_KEYWORDS 10
string keywrd[TOTAL_KEYWORDS]={"void","main","int","long","if","else","for","while","do","return"};

//This Vector will Pick Keywords from the above Array.
vector<string> keywords;

//Structure Of a Token
struct to{
    string clas;    //Stores Class part of Token
    int index;        //Stores Value part of Token
}tok;                //tok is used to PUSH values on "tokens" Vector.

//This Vector will hold ALL Tokens Generated by Lexical Box.
vector<to> tokens;

///////////////////////////////////
//
//Lexical Box Fucntion Declaration
//
///////////////////////////////////

//Lexemer will break input stream into LEXEMES using D.F.A approach as discussed in ULMAN's
//Compiler Construction Book
void lexemer(ifstream& input,int &line);

//If we follow a particular D.F.A to recognize input stream,In case that FAILS we need to check
//Some Other D.F.A,"lexemer_fail" will provide this fuctionality.
int lexemer_fail(ifstream& input,char& faulty_character,int& line,int& starting_state,streampos& lexeme_begining);

//If we're unable to identify a Lexeme as a particular TOKEN of Our Language,Then we need to
//Show some error message."lexemer_error" will do this.
void lexemer_error(char& faulty_character,int &line);

//It makes Token for a LEXEME
void tokenizer(char* lexeme_buffer,int& starting_state);

void syntax_box();        //Syntax Box Declaration
void code_generator();    //Code Generator Declaration

int main()
{

    //Loading KEYWORDS LIST.It's used in Differentiating Kewords From Identifiers.
    for(unsigned int i=0;i<TOTAL_KEYWORDS;i++)
        keywords.push_back(keywrd[i]);        
        
    char file_read='\0';
    int linecount=1;
    ifstream input(FILE_READ);

//Start Reading INPUT File.
while(input.get(file_read))
{
    if(file_read=='\n') linecount++;
    if(file_read!='\n'&&file_read!='\t'&&file_read!=' ')
    {
        input.seekg(-1,ios::cur);
        lexemer(input,linecount);    //Start Making Lexemes
    }//end of if
    
}//end reading file

    input.close();

    //If u wanna See Which TOKENs are generated,Remove Comments From the Following Code,It'll
    //Show u ALL TOKENs on CONSOLE.
    /*
    for(unsigned int i=0;i<tokens.size();i++)
    {
        cout<<"\n";
        cout<<tokens[i].clas;
        cout<<"\t"<<tokens[i].index;
    }
    */
    
    //Pushing An Error Token At the END of TOKEN STREAM.
    //So that we've an "End Marker"
        tok.clas="error";
        tok.index=-10;
        tokens.push_back(tok);

        //Start Parsing,Type Checking,Intermediate Code Generation
        syntax_box();
        
    //If u wanna See What Intermediate Code is generated,Remove Comments From the Following
    //Code,It'll Show u ALL ATOMS on CONSOLE.

/*        cout<<"\n\nFollowing Intermediate Code is Generated\n";

        cout<<"INDEX----DATATYPE----TABLE";
        for(i=0;i<atoms.size();i++)
            cout<<endl<<atoms[i].op<<" type="<<atoms[i].type
                <<"  arg1= "<<atoms[i].arg1.index <<" "<< atoms[i].arg1.datatype <<" "<< atoms[i].arg1.whichtable
                <<"  arg2= "<<atoms[i].arg2.index <<" "<< atoms[i].arg2.datatype <<" "<< atoms[i].arg2.whichtable
                <<"  result= "<<atoms[i].result.index <<" "<< atoms[i].result.datatype <<" "<< atoms[i].result.whichtable;
*/                

    //Start CODE GENERATION.
        code_generator();

        cout<<"\n\n\"C2ASM\" has sucessfully converted \"C\" code(c_code.txt)"
            <<endl<<"to \"ASSEMBLY\" code(asm_code.txt)";
        
    cout<<"\n";
    getch();
    return(0);
}


///**********************///
///**********************///
///                         ///
/// LEXICAL BOX STARTED. ///
///                         ///
///**********************///
///**********************///

void lexemer(ifstream& input,int& line)
{
    char character_read='\0';
    char lexeme_buffer[LEXEME_SIZE];
    memset(lexeme_buffer,'\0',LEXEME_SIZE);
    int counter=0;
    int current_state=0,starting_state=0;
    bool read_flag=true;
    streampos lexeme_begining=input.tellg();
    while(read_flag){
            switch(current_state)
            {
            //D.F.A for Identifier And Keyword
            case 0:input.get(character_read);
                if(isalpha(character_read)||character_read=='_') {current_state=1;lexeme_buffer[counter]=character_read;counter++;starting_state=0;}
                else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining);
                break;
            case 1:input.get(character_read);
                if(isalpha(character_read)||character_read=='_'||isdigit(character_read)) {current_state=1;lexeme_buffer[counter]=character_read;counter++;}
                else current_state=2;
                break;
            case 2:
                input.seekg(-1,ios::cur);
                read_flag=false;
                break;
            //D.F.A for Relational And Assignment Operators
            case 3:input.get(character_read);
                if(character_read=='=') {current_state=4;lexeme_buffer[counter]=character_read;counter++;starting_state=3;}
                else if(character_read=='<') {current_state=7;lexeme_buffer[counter]=character_read;counter++;starting_state=3;}
                else if(character_read=='>') {current_state=11;lexeme_buffer[counter]=character_read;counter++;starting_state=3;}
                else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining);                
                break;
            case 4:input.get(character_read);
                if(character_read=='=') {current_state=5;lexeme_buffer[counter]=character_read;counter++;}
                else current_state=6;
                break;
            case 5:
                read_flag=false;
                break;
            case 6:
                input.seekg(-1,ios::cur);
                read_flag=false;
                break;
            case 7:input.get(character_read);
                if(character_read=='=') {current_state=8;lexeme_buffer[counter]=character_read;counter++;}
                else if(character_read=='>') {current_state=9;lexeme_buffer[counter]=character_read;counter++;}
                else current_state=10;
                break;
            case 8:
                read_flag=false;
                break;
            case 9:
                read_flag=false;
                break;
            case 10:
                input.seekg(-1,ios::cur);
                read_flag=false;
                break;
            case 11:input.get(character_read);
                if(character_read=='=') {current_state=12;lexeme_buffer[counter]=character_read;counter++;}
                else current_state=13;
                break;
            case 12:
                read_flag=false;
                break;
            case 13:
                input.seekg(-1,ios::cur);
                read_flag=false;
                break;
            //D.F.A for Arithmetic Operators
            case 14:
                //MAULA ALI!
                input.get(character_read);
                if(character_read=='+'|| character_read=='-'||character_read=='*'||character_read=='/'||character_read=='%')
                {current_state=15;lexeme_buffer[counter]=character_read;counter++;starting_state=14;}
                else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining);                
                break;
            case 15:
                read_flag=false;
                break;
            //D.F.A for Punctuations
            case 16:
                input.get(character_read);
                if(character_read=='('||character_read==')'||character_read=='{'||character_read=='}'||character_read==','||character_read==';'||character_read=='['||character_read==']')
                {current_state=17;lexeme_buffer[counter]=character_read;counter++;starting_state=16;}
                else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining);
                break;
            case 17:
                read_flag=false;                                
                break;
            //D.F.A for LONG Numbers
            case 18:
                input.get(character_read);
                if(isdigit(character_read)) {current_state=19;lexeme_buffer[counter]=character_read;counter++;starting_state=18;}
                else current_state=lexemer_fail(input,character_read,line,starting_state,lexeme_begining);
                break;
            case 19:
                input.get(character_read);
                if(isdigit(character_read)) {current_state=19;lexeme_buffer[counter]=character_read;counter++;}
                else if(character_read=='L'||character_read=='l') {current_state=20;lexeme_buffer[counter]=character_read;counter++;}
                else current_state=21;                
                break;
            case 20:
                read_flag=false;                                
                break;
            case 21:
                input.seekg(-1,ios::cur);
                read_flag=false;                                
                break;
            //Error TOKEN
            case 100:
                input.get(character_read);
                {current_state=100;lexeme_buffer[counter]=character_read;counter++;starting_state=100;}
                read_flag=false;    
                break;

            }//End of switch
                }//End Reading One LEXEME
        lexeme_buffer[counter]='\0';

        //A Lexeme Is Made Sucessfully,Call Tokenizer to Make It's Coresponding TOKEN
        tokenizer(lexeme_buffer,starting_state);
}

int lexemer_fail(ifstream& input,char& faulty_character,int& line,int& starting_state,streampos& lexeme_begining)
{
    switch(starting_state)
    {
    case 0:
    input.seekg(lexeme_begining);starting_state=3;break;
    case 3:
    input.seekg(lexeme_begining);starting_state=14;break;
    case 14:
    input.seekg(lexeme_begining);starting_state=16;break;
    case 16:
    input.seekg(lexeme_begining);starting_state=18;break;
    case 18:
    
    //We're Generating ERROR token for those things which are NOT part of OUR LANGUAGE.If U
    //wanna stop this ERROR code generation,Remove Comments From the Following Line and DO
    //COMMENT Line AFTER IT!.

    //input.seekg(lexeme_begining);lexemer_error(faulty_character,line);break;

    input.seekg(lexeme_begining);starting_state=100;break;
    //default:
    //    cout<<"\nNo More States";exit(-1);
    }
    return starting_state;
}

void lexemer_error(char& faulty_character,int &line)
{
    cout<<"\nSome Ir-Recoverable Error Occured in LEXICAL ANALYZER!---Possibly"
        <<"\nAn Invalid Lexeme Caused it,Which is Not Part Of Our Language"
        <<"The Starting SYMBOL Of Lexeme is "<<faulty_character<<" Line Number Is "<<line<<endl;
    getch();
    exit(-1);
}

void tokenizer(char* lexeme_buffer,int& starting_state)
{
    tok.clas=" ";
    tok.index=-10;

    string lexeme;
    lexeme.assign(lexeme_buffer);

    unsigned int j=0,k=0;
    

    long num;

    switch(starting_state)
    {
    //Lexeme is a KEYWORD/IDENTIFIER
    case 0:
        //If LEXEME is a KEYWORD
        for(k=0;k<keywords.size();k++)
        {
            if(lexeme==keywords[k])
            {
                if(lexeme=="int"||lexeme=="long")
                {
                    tok.clas="dt";
                    tok.index=(lexeme=="int")?0:1;
                }
                else{
                    tok.clas=lexeme;
                    tok.index=-10;
                }
            tokens.push_back(tok);
            return;
            }
        }
        
        //If LEXEME is an IDENTIFIER
        for(j=0;j<lex_identifier.size();j++)
            //If identifier is already THERE!        
            if(lex_identifier[j]==lexeme)
            {
            tok.clas="id";
            tok.index=j;
            tokens.push_back(tok);
            return;
            }

            //If Identifier is NOT THERE!
            if(lex_identifier.size()==0||lex_identifier.size()==j)
            {
            //Enter into IDENTIFIER SYMBOL TABLE!
            lex_identifier.push_back(lexeme);
            //Enter into TOKEN's TABLE!
            tok.clas="id";
            tok.index=j;
            tokens.push_back(tok);
            return;
            }
        break;
    
        //Lexeme is a RELATIONAL/ASSIGNMENT OPERATOR
    case 3:
        if(lexeme=="=")    //An Assignment Operator
            tok.clas="assignop";
        else    //A Relational Operator
            tok.clas="relop";
    
        if(lexeme=="==")
            tok.index=8;
        else if(lexeme=="<>")    
            tok.index=9;
        else if(lexeme==">=")    
        tok.index=10;
        else if(lexeme=="<=")    
        tok.index=11;
        else if(lexeme==">")    
        tok.index=12;
        else if(lexeme=="<")    
        tok.index=13;
        else if(lexeme=="=")    
        tok.index=14;

        //Enter into TOKEN's TABLE!
            tokens.push_back(tok);
        break;
    
    //Lexeme is an ARITHMENTIC OPERATOR
    case 14:

        tok.clas=(lexeme=="+" ||lexeme=="-") ? "add_sub" : "mul_div_mod";
        
        if(lexeme=="+")
        tok.index=15;
        else if(lexeme=="-")    
        tok.index=16;
        else if(lexeme=="*")    
        tok.index=17;
        else if(lexeme=="/")    
        tok.index=18;
        else if(lexeme=="%")    
        tok.index=19;
        //Enter into TOKEN's TABLE!
            tokens.push_back(tok);
        break;

    //Lexeme is a PUNCTUATION CHARACTIER
    case 16:
        if(lexeme=="{")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="braces_open";
            tok.index=2;
            tokens.push_back(tok);
        }
        
        else if(lexeme=="}")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="braces_close";
            tok.index=3;
            tokens.push_back(tok);
        }
    
        else if(lexeme=="(")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="parenthesis_open";
            tok.index=4;
            tokens.push_back(tok);
        }    

        else if(lexeme==")")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="parenthesis_close";
            tok.index=5;
            tokens.push_back(tok);
        }    
    
        else if(lexeme==",")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="comma";
            tok.index=6;
            tokens.push_back(tok);
        }    
            
        else if(lexeme==";")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="semicolon";
            tok.index=7;
            tokens.push_back(tok);
        }

        else if(lexeme=="[")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="square_open";
            tok.index=20;
            tokens.push_back(tok);
        }

        else if(lexeme=="]")
        {
            //Enter into TOKEN's TABLE!
            tok.clas="square_close";
            tok.index=21;
            tokens.push_back(tok);
        }
        break;

        //Lexeme is a NUMBER,It may be an INTEGER or a LONG
    case 18:
        
        //Checking Whehter the GIVEN NUM is a LONG?
        num=lexeme.find('L');
        if (num==-1) num=lexeme.find('l');
        
        //IF GIVEN NUM is a LONG!
        if(num!=-1)
        {
            //Convert String To LONG INTEGER!...
            lexeme.erase(num,1);    //Remove 'L' or 'l' from the END
            num=0;
            const char *temp=lexeme.c_str();
            num=atol(temp);

        for(unsigned int m=0;m<number_long.size();m++)
            //Number is already there!
            if(number_long[m]==num)
            {
            tok.clas="long_const";
            tok.index=m;
            tokens.push_back(tok);
            return;
            }
            //Number is NOT there!
            if(number_long.size()==0||number_long.size()==m)
            {
            //Enter into NUMBER's SYMBOL TABLE!
            number_long.push_back(num);
            //Enter into TOKEN's TABLE!
            tok.clas="long_const";
            tok.index=m;
            tokens.push_back(tok);
            return;
            }
        }
        //IF GIVEN NUM is an INTEGER!
        else
        {
            int num=0;
            num=atoi(lexeme_buffer);

        for(unsigned int m=0;m<number_int.size();m++)
            //Number is already there!
            if(number_int[m]==num)
            {
            tok.clas="int_const";
            tok.index=m;
            tokens.push_back(tok);
            return;
            }
            //Number is NOT there!
            if(number_int.size()==0||number_int.size()==m)
            {
            //Enter into NUMBER's SYMBOL TABLE!
            number_int.push_back(num);
            //Enter into TOKEN's TABLE!
            tok.clas="int_const";
            tok.index=m;
            tokens.push_back(tok);
            return;
            }
        }
        break;
        
        //Lexeme is an ERROR CHARACTIER
    case 100:
            //Enter into TOKEN's TABLE!
            tok.clas="error";
            tok.index=-10;
            tokens.push_back(tok);
            break;
    }//End Switch
}

///**********************///
///**********************///
///                         ///
/// SYNTAX BOX STARTED.     ///
///                         ///
///**********************///
///**********************///

//////////////////////
//
//Syntax Box's Globals
//
//////////////////////

to input;    //Used To read in Token Generated by LEXICAL BOX

//Structure Of Identifier Table,For Details Of FIELDs CONSULT the DOCUMETATION of C2ASM,
//Provided with it.

struct id{
    string name;
    int datatype;
    int scope;
    int binding;
    bool func_or_not;
    int type;
    int offset;
    int xtra;
}ident;

//This Vector will hold Main()/Fucntion/Temporary Variables and Function Names Also.
vector<id> syn_identifier;    

//This Vector will hold Fucntion's Parameters
vector<id> args_identifier;

int syn_index=0;    //Counter to Iterate through TOKEN's Vector

ofstream error("parser_log.txt");    //Parser Log File

int scopecount=-10;
stack <int> scopestack;        // Stack For Scope Handling

int func_index=-10;
bool main_func=false;
bool isreturn=false;

//Used in Making ATOMS or INTERMEDIATE CODE
struct expr{
    int index;
    int datatype;
    int whichtable;
}dump;

int table=-10;        // 0 for syn_identifier
                    // 1 for args_identifier

//Each ATOM has following structure.
struct atom{
    string op;
    int type;
    expr arg1;
    expr arg2;
    expr result;
}atm;

vector<atom> atoms;    //This Vector will hold All ATOMS or INTERMEDIATE CODE generated

vector<string> labels;    //This Vector will Hold all LABELS generated

long init_arg=-10,fin_arg=-10;

/////////////////////////////////////
//
//Syntax Box's Fucntions Declaration
//
/////////////////////////////////////

//Helper Functions

///////////////////////////////
//
// Recursive Descend Functions
//
///////////////////////////////

//Used to Advance Like u see in Recursive Descend Method's Discussed in Compiler Books
void advanc();

//Used to Reject Like u see in Recursive Descend Method's Discussed in Compiler Books
void reject();

///////////////////////////////
//
// Type System's Functions
//
///////////////////////////////

//Used to Set the Datatype of Main()/Function's/Temporary Variables/Function's Return Type
void settype(int index,int type);

//Used to Set the Datatype of Function's Parameters
void settype_args(int index,int type);

//Generates New Temporary Variables
expr newtemp(int type);

//Generates New Temporary Variables Names Used by "newtemp"
string newtempname(void);

//Check whether an Identifier is DECLARED before it's used
long chk_ident(long index);

//Check whether Two Identifiers or Numbers are of same Type
bool chk_types(expr v1,expr v2);

//Makes ATOM of a Particular Type on the basis of it's Arguments
void setatom(int op,expr arg1,expr arg2,expr result);

//Generates New Labels
int newlabel(void);

//Check whether a Function is DECLARED before it's used
long chk_func(long index);

//Gived Arguments Info. of a Particular Function
void args_info(long index,long &init_arg,long &fin_arg);

//Calculates Paramters Offset,When they're on STACK
int calc_param_offset();

//Calculates Locals Offset,When they're on STACK
int calc_local_offset();

////////////////////
//
//Grammar Functions
//
////////////////////

//Read the Supplied Document For a Better Understanding

void program();
void data_or_function(int type);
void function_or_main();
void function_body();
void variable_declarations();
void variable_list(int type);
void argument_list();
void argument();
void compound_statement();
void statements();
void statement();
void optional_else();
void right_hand_side(expr &r);
void function_call(expr &f);
void optional_expression_list();
void expression_listf();
void expression_list_element();
void expression(expr &k);
void relational(expr &k,expr &t1);
void arithmetic(expr &p);
void subtract(expr p,expr &q);
void t(expr &p);
void add(expr p,expr &q);
void u(expr &p);
void multiply(expr p,expr &q);
void v(expr &p);
void divide(expr p,expr &q);
void w(expr &p);
void mod(expr p,expr &q);
void x(expr &p);


void advanc()
{    
    //Updating "parser_log.txt" File.
    error<<syn_index+1<<'\t'<<input.clas<<'\t'<<input.index<<'\t'<<scopestack.top()<<endl;

    //Picking Up Next Token
    if(syn_index!=(tokens.size()-1))
    {
    syn_index++;
    input=tokens[syn_index];
    }
}

void reject()
{
    //Updating "parser_log.txt" File.
    error<<syn_index+1<<'\t'<<input.clas<<'\t'<<input.index<<'\t'<<scopestack.top()<<endl;
    error.close();

    cout<<"\nParser Failed";
    cout<<"\nParser has parsed "<< syn_index+1 <<" Tokens\n";
    cout<<"See \"parser_log.txt\" For Details\n";
    getch();
    exit(-1);
}

void settype(int index,int type)
{
string name=lex_identifier[index];

for(unsigned int j=0;j<syn_identifier.size();j++)
{
    if(syn_identifier[j].name==name
        && syn_identifier[j].scope==scopestack.top())
            {
                cout<<"Variable name->"<< name<<" with scope "<< scopestack.top()<<" and datatype "<< type <<endl
                    <<"Already exists With name->"<< syn_identifier[j].name<<" ,scope "<<syn_identifier[j].scope <<" and datatype "<< syn_identifier[j].datatype<<endl;
                reject();            
            }
}
//Chk for the name clashing of FORMAL PARAMETERS and LOCAL VARIABLES.
if(func_index!=-10)
{
    for(unsigned int j=0;j<args_identifier.size();j++)
    {
    if(args_identifier[j].name==name
        && args_identifier[j].binding==func_index)
            {
            cout<<endl<<"Redifinition of formal parameter "<< name
                <<" in "<<syn_identifier[func_index].name;
            reject();            
            }
    }
}

ident.name=name;
ident.datatype=type;
ident.scope=scopestack.top();
ident.func_or_not=false;
ident.xtra=-10;

//It's a Global Variable
if(func_index==-10 && main_func==false)
{
ident.binding=-2;    //-2 for a global
ident.type=0;        //0 for a global
ident.offset=-10;    //No Need To calculate this
}
//It's a Main Variable
else if(func_index==-10 && main_func==true)
{
ident.binding=-1;    //-1 for a main
ident.type=1;        //1 for main
ident.offset=-10;    //No Need To calculate this
}
//It's a Local Variable
else if(func_index!=-10 && main_func==false)
{
ident.binding=func_index;    
ident.type=2;        //2 for Local
ident.offset=-10;    //WE'LL CALCULATE THIS AFTER SOMETIME!!!!
}

syn_identifier.push_back(ident);
}

//For Arguments
void settype_args(int index,int type)
{
string name=lex_identifier[index];
int binding=syn_identifier.size()-1;

for(unsigned int j=0;j<args_identifier.size();j++)
{
    if(args_identifier[j].name==name
        && args_identifier[j].binding==binding)
            {
                cout<<"Variable name->"<< name<<" with binding "<< binding <<" and datatype "<< type <<endl
                    <<"Already exists With name->"<< args_identifier[j].name<<" ,binding "
                    <<args_identifier[j].binding<<" and datatype "<< args_identifier[j].datatype<<endl;
                reject();            
            }
}
//Updating ARGUMENTS SYMBOL TABLE
ident.name=name;
ident.datatype=type;
ident.scope=-10;
ident.binding=binding;
ident.func_or_not=false;
ident.type=3;
ident.offset=-10;    //We'll Calculate this LATER on.
ident.xtra=-10;
args_identifier.push_back(ident);

}

expr newtemp(int type)
{
    if(type==23) type=0;
    if(type==24) type=1;

    expr temp;

    ident.name=newtempname();
    ident.datatype=type;
    ident.scope=scopestack.top();
    ident.func_or_not=false;
    ident.type=4;    //For Temporaries
    ident.offset=-10;    //Will CALCULATE afterwards
    ident.xtra=-10;
    
    //Deciding Whose Temporary is this! Main or an Ordinary Function
    if(main_func==true)
        ident.binding=-1;
    else
        ident.binding=func_index;

    syn_identifier.push_back(ident);
    
    temp.index=syn_identifier.size()-1;
    temp.datatype=type;
    temp.whichtable=0;
    
    return temp;
}

string newtempname(void)
{
    static long count=1;
    
    char name[10];
    char temp[5];

    ltoa(count,temp,10);
    strcpy(name,"t");
    strcat(name,temp);
    
    count++;
    return string(name);
    
}

long chk_ident(long index)
{
table=-10;
string name=lex_identifier[index];
unsigned int j=0;

//Check in Local Scope
for(j=0;j<syn_identifier.size();j++)
{
    if(syn_identifier[j].name==name
        && syn_identifier[j].scope==scopestack.top()
        && syn_identifier[j].func_or_not==false)
            {
            table=0;    //For syn_identifier
            return j;
            }
}

//Check in if it's a Formal Parameter
if(func_index!=10)
{
for(j=0;j<args_identifier.size();j++)
{
    if(args_identifier[j].name==name
        && args_identifier[j].binding==func_index)
            {
            table=1;    //For args_identifier
            return j;
            }
}

}

//Check in Global Scope
for(j=0;j<syn_identifier.size();j++)
{
    if(syn_identifier[j].name==name
        && syn_identifier[j].scope==0
        && syn_identifier[j].func_or_not==false)
            {
            table=0;    //For syn_identifier
            return j;
            }
}

return -10;
}

bool chk_types(expr v1,expr v2)
{
    v1.datatype=v1.datatype==23 ? 0 : v1.datatype;
    v1.datatype=v1.datatype==24 ? 1 : v1.datatype;

    v2.datatype=v2.datatype==23 ? 0 : v2.datatype;
    v2.datatype=v2.datatype==24 ? 1 : v2.datatype;

    return(v1.datatype==v2.datatype);
}

void setatom(int op,expr arg1,expr arg2,expr result)
{
    atm.type=op;
    atm.arg1=arg1;
    atm.arg2=arg2;
    atm.result=result;

    switch(op)
    {
    //Addition
    case 15:
        atm.op="ADD";
        break;

        //Subtraction
    case 16:
        atm.op="SUB";
        break;

        //Multiply
    case 17:
        atm.op="MUL";
        break;

        //Division
    case 18:
        atm.op="DIV";
        break;

        //Remainder
    case 19:
        atm.op="MOD";
        break;
        
        //Assign
    case 26:
        atm.op="ASSIGN";
        break;

        //Label
    case 25:
        atm.op="LABEL";
        break;

        //Conditional Jump
    case 27:
        atm.op="CONDJUMP";
        break;

        //Jump
    case 28:
        atm.op="JUMP";
        break;

        //Return
    case 29:
        atm.op="RETURN";
        break;

        //Param
    case 30:
        atm.op="PARAM";
        break;

            //CALL
    case 31:
        atm.op="CALL";
        break;
        
            //PROC_MARKER
    case 34:
        atm.op="PROC_MARKER";
        break;

            //JUMPF
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
        atm.op="JUMPF";
        break;

        //CMP
    case 108:
    case 109:
    case 110:
    case 111:
    case 112:
    case 113:
        atm.op="CMP";
        //atm.type=op-100;
        break;
    default:
        cout<<"\nNo Matching Found";
    }
    atoms.push_back(atm);
}

int newlabel(void)
{
    static long count=1;
    
    char name[10];
    char temp[5];

    ltoa(count,temp,10);
    strcpy(name,"L");
    strcat(name,temp);
    
    string s1=name;
    labels.push_back(s1);

    count++;
    return(labels.size()-1);
}

long chk_func(long index)
{
string name=lex_identifier[index];

for(unsigned int j=0;j<syn_identifier.size();j++)
{
    if(syn_identifier[j].name==name
        && syn_identifier[j].func_or_not==true)
            {
            table=0;
            return j;
            }
}
return -10;
}

void args_info(long index,long &init_arg,long &fin_arg)
{
init_arg=-10;
fin_arg=-10;
vector<int> temp;
    for(unsigned int j=0;j<args_identifier.size();j++)
        if(args_identifier[j].binding==index)
            temp.push_back(j);
    if(temp.size()!=0)
    {
    init_arg=temp[0];
    fin_arg=temp[temp.size()-1];
    }
}

int calc_param_offset()
{
    int index=func_index;    //Get FUNCTION's INDEX
    bool flag=false;
    int counter=0;
    int k=args_identifier.size()-1;
    int tot_len=0;
    while(index==func_index)
    {
        //If It's the LAST parameter
        if(flag==false){
            counter=6;
            args_identifier[k].offset=counter;
            counter+=args_identifier[k].datatype==0 ? 2 : 4;
            tot_len+=args_identifier[k].datatype==0 ? 2 : 4;
            flag=true;
        }
        //If It's OTHER THAN last parameter
        else{
            args_identifier[k].offset=counter;
            counter+=args_identifier[k].datatype==0 ? 2 : 4;
            tot_len+=args_identifier[k].datatype==0 ? 2 : 4;
        }
        k--;
        //It sometimes Happens that even -ve INDICES also points
        //to some array element causing PROBLEMS
        if(k<0) break;    
        index=args_identifier[k].binding;
    }
    return tot_len;
}

int calc_local_offset()
{
    int counter=0;
    //Chk For LOCAL's which are BINDED to LATEST "func_index"
    for(unsigned int i=0;i<syn_identifier.size();i++)
        if(syn_identifier[i].binding==func_index)
        {
        counter+=syn_identifier[i].datatype==0 ? 2 : 4;
        syn_identifier[i].offset=counter;
        }
return counter;
}

void syntax_box()
{
    //Doing Initializations
    syn_index=0;
    input=tokens[syn_index];
    scopecount=0;
    scopestack.push(scopecount);
    dump.index=-10;
    dump.datatype=-10;
    dump.whichtable=-10;
    
    program();
    
    //Check whether we've got our End Of Marker
    //Yes,End Marker has Arrived,ACCEPT INPUT PROGRAM!
    if(input.clas=="error")
    {
    error<<syn_index+1<<'\t'<<input.clas<<'\t'<<input.index<<'\t'<<scopestack.top()<<endl;
    error.close();
    //cout<<"\nParser Succeeded";
    //cout<<"\nSee \"parser_log.txt\" For Details";
    }
    //No,End Marker hasn't Arrived,REJECT INPUT PROGRAM!
    else
    {
    error<<syn_index+1<<'\t'<<input.clas<<'\t'<<input.index<<'\t'<<scopestack.top()<<endl;
    error.close();
    cout<<"\nParser Failed";
    cout<<"\nParser has parsed "<< syn_index+1 <<" Tokens\n";
    cout<<"See \"parser_log.txt\" For Details\n";
    }
    
    //If u wanna See IDENTIFERs LIST with ALL details,Remove Comments from the following Lines
    /*
    cout<<"\n\nIDENTIFIERS";
    cout<<endl<<" name "<<" "<<"datatype"
        <<" "<<"scope"<<" "<<"binding"<<" "<<"f_or_not"
        <<" "<<"type"<<" "<<"offset ";
    for(unsigned int j=0;j<syn_identifier.size();j++)
    cout<<endl<<j<<" "<<syn_identifier[j].name<<'\t'
          <<syn_identifier[j].datatype
    <<'\t'<<syn_identifier[j].scope
    <<'\t'<<syn_identifier[j].binding
    <<'\t'<<syn_identifier[j].func_or_not
    <<'\t'<<syn_identifier[j].type
    <<'\t'<<syn_identifier[j].offset
    <<'\t'<<syn_identifier[j].xtra;
    */

    //If u wanna See What Paramters are Binded to Which Fucntion,Remove Comments from the
    //following Lines
    /*
    cout<<"\n\nBINDINGS";
    for(j=0;j<args_identifier.size();j++)
    cout<<endl<<j<<" "<<args_identifier[j].name<<'\t'
          <<args_identifier[j].datatype
    <<'\t'<<args_identifier[j].scope
    <<'\t'<<args_identifier[j].binding
    <<'\t'<<args_identifier[j].func_or_not
    <<'\t'<<args_identifier[j].type
    <<'\t'<<args_identifier[j].offset
    <<'\t'<<args_identifier[j].xtra;
    */
    
    
}

void program()
{
    if(input.clas=="dt")
    {
        int type=input.index;
        advanc();
        
        if(input.clas=="id")
        {
            int index=input.index;
            settype(index,type);
            advanc();
        }
        else reject();
        
        data_or_function(type);
        program();
    }
    else if(input.clas=="void")
    {
        advanc();
        function_or_main();
    }
    else reject();
}

void data_or_function(int type)
{
    if(input.clas=="comma")
    {
        advanc();
        if(input.clas=="id")
        {
            int index=input.index;
            settype(index,type);            
            advanc();
        }
        else reject();
        data_or_function(type);
    }
    else if(input.clas=="semicolon")
        advanc();
    else if(input.clas=="parenthesis_open")
    {
        /*Since This Fucntion Shld've a RETURN statement in it's
        body,Therefore Setting "isreturn=false",To LET IT BE TURNED
        to TRUE by a STATEMENT in Fucntion's body*/
        isreturn=false;

        advanc();
        argument_list();
        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        function_body();
    }
    else reject();
}

void function_or_main()
{
    if(input.clas=="main")
    {
        // Set FLAG to true,Since it's main STARTING
        main_func=true;

        advanc();
        if(input.clas=="parenthesis_open")
            advanc();
        else reject();
        
        if(input.clas=="void")
            advanc();
        else reject();

        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        function_body();
    }
    else if(input.clas=="id")
    {
        settype(input.index,22);
        advanc();

        if(input.clas=="parenthesis_open")
            advanc();
        else reject();

        argument_list();

        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        function_body();
        program();
    }
    else reject();
}

void function_body()
{
    int start_atom,end_atom,total;
    start_atom=end_atom=total=-10;

    if(input.clas=="braces_open")
    {
        //
        //Marking Begining Of Function
        //
        
        //Is it a main() function?
        if(main_func==true)
        {
        expr temp;
        temp.index=-1;        //-1 For main() OR func_index For others
        temp.datatype=1;    //1 Shows Starting,0 Shows Ending
        temp.whichtable=-10;

        setatom(34,temp,dump,dump);
        }
        //It's an ORDINARY function
        else
        {
        expr temp;
        temp.index=func_index;        //-1 For main() OR func_index For others
        temp.datatype=1;    //1 Shows Starting,0 Shows Ending
        temp.whichtable=-10;

        setatom(34,temp,dump,dump);
        start_atom=atoms.size()-1;    //Storing Index Of Starting ATOM
        }

        //Update scope_or_binding.
        scopecount++;
        scopestack.push(scopecount);

            advanc();
            
            variable_declarations();
            statements();
            
            if(input.clas=="braces_close")
            {
                if((scopestack.size()-1)>0)
                            scopestack.pop();
                else
                    reject();
            advanc();
            }
            else
            reject();

        //
        //Marking Ending Of Function
        //
        
        //Is it a main() function?
        if(main_func==true)
        {
        expr temp;
        temp.index=-1;        //-1 For main() OR func_index For others
        temp.datatype=0;    //1 Shows Starting,0 Shows Ending
        temp.whichtable=-10;
        
        setatom(34,temp,dump,dump);
        }
        //It's an ORDINARY function
        else
        {
        expr temp;
        temp.index=func_index;        //-1 For main() OR func_index For others
        temp.datatype=0;    //1 Shows Starting,0 Shows Ending
        temp.whichtable=-10;
                
        setatom(34,temp,dump,dump);
        end_atom=atoms.size()-1;    //Storing Index Of Ending ATOM
        }
        
        //Setting LOCAL VARIABLES+TEMPoRARIES' OFFSETS.
        if(func_index!=-10)
        {
            total=calc_local_offset();
            //Now,Saving The TOTAL LENGTH of OFFSETS into the Starting
            //and Ending PROC_MARKER ATOMS Of this Particular Fucntion
            atoms[start_atom].arg1.whichtable=total;
            atoms[end_atom].arg1.whichtable=total;
        }


        /*If this Fucntion has to return something,ASSURING that it
        has done this ATLEAST one time!*/
        if(func_index!=-10)
        {
            if(isreturn!=true&& syn_identifier[func_index].datatype!=22/*Shldn't Be void*/)
            {
                cout<<endl<<"Fucntion named "<< syn_identifier[func_index].name
                <<" Shld return "<< syn_identifier[func_index].datatype <<endl;
                reject();
            }
        }
    
        main_func=false;    //Main Fucntion Ended
        func_index=-10;    //De-Registering Fucntion if it was local
        isreturn=false;    //Re-Setting the Return Flag
    }
    else
        reject();
}

void variable_declarations()
{
    if(input.clas=="dt")
    {
        int type=input.index;
            advanc();
            
            if(input.clas=="id")
            {
                int index=input.index;
                settype(index,type);
                advanc();
            }
            else reject();
            
            variable_list(type);

            if(input.clas=="semicolon")
                advanc();
            else reject();

            variable_declarations();
    }
    else if(input.clas=="id" || input.clas=="braces_open" || input.clas=="while" ||
        input.clas=="for" || input.clas=="do" || input.clas=="return" ||
        input.clas=="if" || input.clas=="square_open" || input.clas=="braces_close" )
    {
    
    }
    else reject();
}

void variable_list(int type)
{
    if(input.clas=="comma")
    {
        advanc();
        
        if(input.clas=="id")
        {
            int index=input.index;
            settype(index,type);
            advanc();
        }
        else reject();

        variable_list(type);
    }
    else if(input.clas=="semicolon")
    {
    
    }
    else reject();
}

void argument_list()
{
    if(input.clas=="void")
    {
        ident.name="void";
        ident.datatype=22;
        ident.scope=-10;
        ident.binding=syn_identifier.size()-1;
        ident.func_or_not=false;
        ident.type=3;    //For Parameters 3!.
        ident.offset=-10;    //We'll calculate it LATER
        ident.xtra=-10;

        args_identifier.push_back(ident);

        //Since we got argument list for our recently entered identifier,
        //therefore we need to recognize that as a FUNCTION NAME EXPLICITLY.
        //Updating IDENTIFIER SYMBOL TABLE
        int ind=syn_identifier.size()-1;
        ident=syn_identifier[ind];
        ident.func_or_not=true;
        syn_identifier[ind]=ident;

        //Registering This Fucntion's Start
        func_index=ind;

        advanc();
    }
    else if(input.clas=="dt")
    {
        int type=input.index;
        advanc();
        if(input.clas=="id")
        {
            int index=input.index;
            settype_args(index,type);
            advanc();
        }
        else reject();
        argument();

        //Since we got argument list for our recently entered identifier,
        //therefore we need to recognize that as a FUNCTION NAME EXPLICITLY.
        //Updating IDENTIFIER SYMBOL TABLE
        int ind=syn_identifier.size()-1;
        ident=syn_identifier[ind];
        ident.func_or_not=true;
        syn_identifier[ind]=ident;

        //Registering This Fucntion's Start
        func_index=ind;

        //Caculating Fucntion Parameter's Offsets
        int ret=calc_param_offset();

        //Storing the Total SIZE of PARAMETERS
        syn_identifier[ind].xtra=ret;
    }
    else reject();
}

void argument()
{
    if(input.clas=="comma")
    {
        int type;
        advanc();
        
        if(input.clas=="dt")
        {
            type=input.index;
            advanc();
        }
        else reject();

        if(input.clas=="id")
        {
            int index=input.index;
            settype_args(index,type);
            advanc();
        }
        else reject();

        argument();
    }
    else if(input.clas=="parenthesis_close")
    {
    
    }
    else reject();
}

void compound_statement()
{
    if(input.clas=="braces_open")
    {
        advanc();
        
        statements();
        
        if(input.clas=="braces_close")
            advanc();
        else reject();
    }
    else reject();
}

void statements()
{
    if(input.clas=="id"||input.clas=="braces_open"||input.clas=="while"||
        input.clas=="for"||input.clas=="do"||input.clas=="return"||
        input.clas=="if"||input.clas=="square_open")
    {
        statement();
        statements();
    }
    else if(input.clas=="braces_close")
    {
    
    }
    else reject();
}

void statement()
{
    if(input.clas=="id")
    {
        long ind=chk_ident(long(input.index));
        if(ind==-10)
        {
            cout<<"\nFailed in <Statement>-->id=<right_hand_side>;";
            cout<<"\nVariable Not Found ";
            reject();
        }
        expr t;
        t.index=ind;
        t.whichtable=table;
        if(table==0)
        t.datatype=syn_identifier[ind].datatype;
        else if(table==1)
        t.datatype=args_identifier[ind].datatype;

        advanc();

        if(input.clas=="assignop")
            advanc();
        else reject();
        
        expr r;
        right_hand_side(r);

        if(input.clas=="semicolon")
        advanc();
        else reject();
        
        if(chk_types(t,r)==true)
        {
        setatom(26,r,dump,t);
        }
        else
        {
                cout<<"\nType of id != <right_hand_side>";
                reject();
        }
    }
    else if(input.clas=="braces_open")
    {
        compound_statement();
    }
    else if(input.clas=="while")
    {
        expr temp;
        
        int start=newlabel();
        int end=newlabel();

        temp.datatype=25;
        temp.index=start;
        temp.whichtable=4;    // For Labels;

        setatom(25,dump,dump,temp);

        advanc();
        
        if(input.clas=="parenthesis_open")
            advanc();
        else reject();
        expr k;
        expression(k);
    
        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        temp.datatype=25;
        temp.index=end;
        temp.whichtable=4;

        expr temp1;
        temp1.datatype=0;
        temp1.index=-10;
        temp1.whichtable=-10;

        setatom(27,k,temp1,temp);

        statement();

        temp.datatype=25;
        temp.index=start;
        temp.whichtable=4;
        setatom(28,dump,dump,temp);

        temp.datatype=25;
        temp.index=end;
        temp.whichtable=4;

        setatom(25,dump,dump,temp);
    }
    else if(input.clas=="for")
    {
        int start=newlabel();
        int end=newlabel();
        int t_1=newlabel();
        int t_2=newlabel();
        
        expr i,e,s,i2,e2,ed,t1,t2,i4,e4;
        int r;

        s.index=start;
        s.datatype=25;
        s.whichtable=4;

        ed.index=end;
        ed.datatype=25;
        ed.whichtable=4;

        t1.index=t_1;
        t1.datatype=25;
        t1.whichtable=4;

        t2.index=t_2;
        t2.datatype=25;
        t2.whichtable=4;

        advanc();

        if(input.clas=="parenthesis_open")
            advanc();
        else reject();

        if(input.clas=="id")
        {
            long ind=chk_ident(long(input.index));
            if(ind==-10)
            {
            cout<<"\nFailed in <Statement>-->for(id=<expression>.......;";
            cout<<"\nVariable Not Found ";
            reject();
            }
            i.index=ind;
            i.whichtable=table;
            if(table==0)
            i.datatype=syn_identifier[ind].datatype;
            else if(table==1)
            i.datatype=args_identifier[ind].datatype;

            advanc();
        }
        else reject();

        if(input.clas=="assignop")
            advanc();
        else reject();
        
        expression(e);

        if(chk_types(i,e)==true)
            setatom(26,e,dump,i);
        else
        {
            cout<<"\nType of id!!!!!!!======<right_hand_side>";
            reject();
        }
                                
        if(input.clas=="semicolon")
            advanc();
        else reject();

        setatom(25,dump,dump,s);

        if(input.clas=="id")
        {
            long ind=chk_ident(long(input.index));
            if(ind==-10)
            {
            cout<<"\nFailed in <Statement>-->for(id=<expression>.......;";
            cout<<"\nVariable Not Found ";
            reject();
            }
            i2.index=ind;
            i2.whichtable=table;
            if(table==0)
            i2.datatype=syn_identifier[ind].datatype;
            else if(table==1)
            i2.datatype=args_identifier[ind].datatype;
            advanc();
        }
        else reject();

        if(input.clas=="relop")
        {
            r=input.index;
            advanc();
        }
        else reject();
        
        expression(e2);

        if(chk_types(i2,e2)!=true)
        {
                   cout<<"\nType of id!!!!!!!======<right_hand_side>";
                reject();
        }

        setatom(r,i2,e2,ed);
        setatom(28,dump,dump,t1);
        
        if(input.clas=="semicolon")
            advanc();
        else reject();

        setatom(25,dump,dump,t2);

        if(input.clas=="id")
        {
            long ind=chk_ident(long(input.index));
            if(ind==-10)
            {
            cout<<"\nFailed in <Statement>-->for(id=<expression>.......;";
            cout<<"\nVariable Not Found ";
            reject();
            }
            i4.index=ind;
            i4.whichtable=table;
            if(table==0)
            i4.datatype=syn_identifier[ind].datatype;
            else if(table==1)
            i4.datatype=args_identifier[ind].datatype;
            advanc();
        }
        else reject();

        if(input.clas=="assignop")
            advanc();
        else reject();

        expression(e4);

        if(chk_types(i4,e4)==true)
            setatom(26,e4,dump,i4);
        else
        {
            cout<<"\nType of id!!!!!!!======<right_hand_side>";
            reject();
        }

        setatom(28,dump,dump,s);

        if(input.clas=="parenthesis_close")
            advanc();
        else reject();
        
        setatom(25,dump,dump,t1);

        statement();

        setatom(28,dump,dump,t2);
        
        setatom(25,dump,dump,ed);
    }
    else if(input.clas=="do")
    {
        int start=newlabel();
        expr temp;

        temp.datatype=25;
        temp.index=start;
        temp.whichtable=4;
        
        setatom(25,dump,dump,temp);

        advanc();

        compound_statement();

        if(input.clas=="while")
            advanc();
        else reject();

        if(input.clas=="parenthesis_open")
            advanc();
        else reject();

        expr k; expression(k);

        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        if(input.clas=="semicolon")
            advanc();
        else reject();

        expr temp1;
        temp1.datatype=1;
        temp1.index=-10;
        temp1.whichtable=-10;

        setatom(27,k,temp1,temp);
    }
    else if(input.clas=="return")
    {
        /*Since This Fucntion Shld've a RETURN statement in it's
        body,Therefore Setting "isreturn=true",Since We Found a
        RETURN Statement*/
        isreturn=true;

        advanc();
        expr r;
        right_hand_side(r);
        
        //t takes the index of Function Name which is binded to this
        //particular return statement
        int t=args_identifier[args_identifier.size()-1].binding;
        
        expr temp;
        temp.datatype=syn_identifier[t].datatype;
        temp.index=t;        
        temp.whichtable=0;

        if(chk_types(temp,r)!=true)
        {
        if(func_index!=-10)
            cout<<"\nFunction "<<syn_identifier[t].name <<
                " is trying to Return mismatching datatype "<<
                r.datatype;
        else
            cout<<"\nFunction void main(void) is trying to Return a Value";
            reject();
        }
        
        if(input.clas=="semicolon")
            advanc();
        else reject();

        setatom(29,temp,dump,r);
    }
    else if(input.clas=="if")
    {
        int end=newlabel();
        int end2=newlabel();

        advanc();
        
        if(input.clas=="parenthesis_open")
            advanc();
        else reject();
        
        expr k; expression(k);

        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        expr temp1;
        temp1.datatype=0;
        temp1.index=-10;
        temp1.whichtable=-10;

        expr temp;
        temp.datatype=25;
        temp.index=end;
        temp.whichtable=4;

        setatom(27,k,temp1,temp);

        statement();

        temp.datatype=25;
        temp.index=end2;
        temp.whichtable=4;

        setatom(28,dump,dump,temp);

        temp.datatype=25;
        temp.index=end;
        temp.whichtable=4;

        setatom(25,dump,dump,temp);

        optional_else();

        temp.datatype=25;
        temp.index=end2;
        temp.whichtable=4;

        setatom(25,dump,dump,temp);

    }
    else if(input.clas=="square_open")
    {
        advanc();
        expr f;
        function_call(f);

        if(input.clas=="square_close")
            advanc();
        else reject();

        if(input.clas=="semicolon")
            advanc();
        else reject();
        //Chking Whether This Fucntion Can Return a Value or NOT?
        //Place an ERROR if it can RETURN a value other than Void
        if(f.datatype!=22)//If it's not void
        {
            cout<<endl<<"Fucntion named "<<syn_identifier[f.index].name
                <<" is returning a value,Which is Not being CAUGHT";
            reject();
        }
    }
    else reject();
}

void optional_else()
{
    if(input.clas=="else")
    {
        advanc();
        statement();
    }
    else if(input.clas=="id"||input.clas=="while"||input.clas=="braces_open"||
        input.clas=="for"||input.clas=="do"||input.clas=="return"||
        input.clas=="if"||input.clas=="braces_close"||input.clas=="square_open")
    {

    }
    else reject();
}

void right_hand_side(expr &r)
{
    if(input.clas=="parenthesis_open" ||input.clas=="id" ||input.clas=="int_const"
        || input.clas=="long_const")
    {
         expression(r);
    }
    else if(input.clas=="square_open")
    {
        advanc();
        function_call(r);
        if(input.clas=="square_close")
            advanc();
        else reject();
        //Assuring that a function with void as return type
        //doesn't appear as RIGHT HAND SIDE.
        if(r.datatype!=22)    
        {
            /*Locating the 1st RETURN statement of this particular
            function and assigning that return value to r*/
            for(unsigned int i=0;i<atoms.size();i++)
                if(atoms[i].type==29 && atoms[i].arg1.index==r.index)
                {
                    r=atoms[i].result;
                    break;
                }
        }
        else{
            cout<<endl<<"Fucntion named "<<syn_identifier[r.index].name
                <<"is returning a void,Therefore It can't APPEAR as an R.H.S";
            reject();
        }
    }
    else reject();
}

void function_call(expr &f)
{
    if(input.clas=="id")
    {
        expr temp;
        long indx=chk_func(input.index);
        int no_args=-10;
        if(indx==-10)
        {
            cout<<"\nFailed in <function_call>-->id=(<optional_expression_list>)";
            cout<<"\nUsing Undefined Fuction--> "<< lex_identifier[input.index];
            reject();
        }
        f.index=indx;
        f.datatype=syn_identifier[indx].datatype;
        f.whichtable=table;

        args_info(indx,init_arg,fin_arg);
        
        /*If the Fucntion is expecting a VOID type then SET No. Of
          Arguments to 0*/
        if(args_identifier[init_arg].datatype!=22)
            no_args=(fin_arg-init_arg)+1;
        else
            no_args=0;
        //cout<<"\nArguments "<<no_args << init_arg<< fin_arg;
        temp.datatype=-10;
        temp.index=no_args;
        temp.whichtable=-10;

        advanc();
        
        if(input.clas=="parenthesis_open")
            advanc();
        else reject();

        optional_expression_list();

        if(input.clas=="parenthesis_close")
            advanc();
        else reject();

        /*If the Fucntion is expecting a VOID type then SKIP
        Argument PASSING STEPS*/
        if(args_identifier[init_arg].datatype!=22)
        {
            if(init_arg <= fin_arg)
            {
            cout<<"\nLess arguments are passed to function "
                << syn_identifier[indx].name;
            reject();
            }
            if((init_arg-1) > fin_arg)
            {
            cout<<"\nMore arguments are passed to function "
                << syn_identifier[indx].name;
            reject();
            }
        }
        setatom(31,temp,dump,f);
    }
    else reject();
}

void optional_expression_list()
{
    if(input.clas=="parenthesis_close")
    {

    }
    else if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" ||
        input.clas=="long_const" ||    input.clas=="square_open" )
    {
        expression_list_element();
        expression_listf();
    }
    else reject();
}

void expression_listf()
{
    if(input.clas=="comma")
    {
        advanc();
        expression_list_element();
        expression_listf();
    }
    else if(input.clas=="parenthesis_close")
    {
    
    }
    else reject();
}

void expression_list_element()
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" ||
        input.clas=="long_const")
    {
        expr k;
        expr temp;
            temp.index=init_arg;
            temp.datatype=args_identifier[init_arg].datatype;
            temp.whichtable=1;
    
            expression(k);
            
            //if((init_arg-1) > fin_arg) //OLD one
            if(init_arg > fin_arg)
            {
                cout<<"\nvoid expression_list_element() More arguments are passed to function "
                    << syn_identifier[args_identifier[fin_arg].binding].name;
                    reject();
            }

            if(chk_types(k,temp)==true)
                {
                setatom(30,dump,dump,k);
                //cout<<"\nArgument List "<<k.index;
                }
            else
                {
                cout<<"Type mismatched in passing arguments to Fucntion "
                    << syn_identifier[args_identifier[fin_arg].binding].name;
                reject();
                }
        init_arg++;
    }
    else if(input.clas=="square_open")
    {
        advanc();
        expr f;
        function_call(f);
        if(input.clas=="square_close")
            advanc();
        else reject();
    }
    else reject();
}

void expression(expr &k)
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" ||
        input.clas=="long_const")
    {
        expr t1;
        arithmetic(t1);
        relational(k,t1);
    }
    else reject();
}

void relational(expr &k,expr &t1)
{
    if(input.clas=="relop")
    {
        int op=input.index;
        advanc();
        expr t2;
        arithmetic(t2);
        if(chk_types(t1,t2)==true)
        {
        k=newtemp(t2.datatype);
        setatom(op+100,t1,t2,k);
        }
        else
        {
        cout<<"\nFailed in <Relational>--->.... "<<t1.index <<" is different from "<<t2.index;
        reject();
        }
    }
    else if(input.clas=="parenthesis_close" ||input.clas=="semicolon" ||input.clas=="comma")
    {
        k=t1;
    }
    else reject();
}

void arithmetic(expr &p)
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const"
      || input.clas=="long_const")
    {
        expr p1;
        t(p1);
        subtract(p1,p);
    }
    else reject();
}

void subtract(expr p,expr &q)
{
    if(input.clas=="add_sub"
        && input.index==16)
    {
        advanc();
        expr q1;
        t(q1);
        if(chk_types(p,q1)==true)
        {
        expr r1=newtemp(p.datatype);
        setatom(16,p,q1,r1);
        subtract(r1,q);
        }
        else
        {
            cout<<"\nFailed in <Subract>--->"<< p.index<<" is different from "<<q1.index;
            reject();
        }
    }
    else if(input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" ||
        input.clas=="comma")
    {
    q=p;
    }
    else reject();
}

void t(expr &p)
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" ||
        input.clas=="long_const" )
    {
        expr p1;
        u(p1);
        add(p1,p);
    }
    else reject();
}

void add(expr p,expr &q)
{
    if(input.clas=="add_sub"
        && input.index==15)
    {
        advanc();
        expr q1;
        u(q1);
        if(chk_types(p,q1)==true)
        {
        expr r1=newtemp(p.datatype);
        setatom(15,p,q1,r1);
        add(r1,q);
        }
        else
        {
        cout<<"\nFailed in <Add>--->"<< p.index<<" is different from "<<q1.index;
        reject();
        }
    }
    else if(input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" ||
        input.clas=="comma")
    {
        q=p;
    }
    else reject();
}

void u(expr &p)
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" ||
            input.clas=="long_const" )
    {
        expr p1;
        v(p1);
        multiply(p1,p);
    }
    else reject();
}

void multiply(expr p,expr &q)
{
    if(input.clas=="mul_div_mod"
        && input.index==17 )
    {
        advanc();
        expr q1;
        v(q1);
        if(chk_types(p,q1)==true)
        {
        expr r1=newtemp(p.datatype);
        setatom(17,p,q1,r1);
        multiply(r1,q);
        }
        else
        {
        cout<<"\nFailed in <Multiply>--->"<<p.index<<" is different from "<<q1.index;
        reject();
        }
    }
    else if(input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" || input.clas=="parenthesis_close" ||
        input.clas=="semicolon" || input.clas=="comma" )
    {
        q=p;
    }
    else reject();
}

void v(expr &p)
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const")
    {
        expr p1;
        w(p1);
        divide(p1,p);
    }
    else reject();
}

void divide(expr p,expr &q)
{
    if(input.clas=="mul_div_mod"
        && input.index==18)
    {
        advanc();
        expr q1;
        w(q1);
        if(chk_types(p,q1)==true)
        {
        expr r1=newtemp(p.datatype);
        setatom(18,p,q1,r1);
        divide(r1,q);
        }
        else
        {
        cout<<"\nFailed in <Divide>--->"<<p.index<<" is different from "<<q1.index;
        reject();
        }
    }
    else if(input.clas=="mul_div_mod" || input.clas=="add_sub" || input.clas=="add_sub" || input.clas=="relop" ||
        input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma")
    {
    q=p;
    }
    else reject();
}

void w(expr &p)
{
    if(input.clas=="parenthesis_open" || input.clas=="id" || input.clas=="int_const" || input.clas=="long_const")
    {
        expr p1;
        x(p1);
        mod(p1,p);
    }
    else reject();
            
}

void mod(expr p,expr &q)
{
    if(input.clas=="mul_div_mod"
        && input.index==19)
    {
        advanc();
        expr q1;
        x(q1);
        if(chk_types(p,q1)==true)
        {
        expr r1=newtemp(p.datatype);
        setatom(19,p,q1,r1);
        mod(r1,q);
        }
        else
        {
        cout<<"\nFailed in <Mod>---> "<< p.index<<"is different from "<< q1.index;
        reject();
        }
    }
    else if(input.clas=="mul_div_mod" || input.clas=="mul_div_mod" || input.clas=="add_sub" || input.clas=="add_sub" ||
        input.clas=="relop" || input.clas=="parenthesis_close" || input.clas=="semicolon" || input.clas=="comma")
    {
        q=p;
    }
    else reject();
}

void x(expr &p)
{
    if(input.clas=="parenthesis_open")
    {
        advanc();
        expression(p);
        if(input.clas=="parenthesis_close")
            advanc();
        else reject();
    }
    else if(input.clas=="id")
    {    
        long indx=chk_ident(input.index);
        if(indx!=-10)
        {
            p.index=indx;
            p.whichtable=table;
            if(table==0)
            p.datatype=syn_identifier[indx].datatype;
            else if(table==1)
            p.datatype=args_identifier[indx].datatype;
        }
        else
        {
            cout<<"\nFailed in <X>-->...."
                <<" Variable "<<lex_identifier[input.index]<<" Not Found ";
            reject();
        }
        advanc();
    }
    else if(input.clas=="int_const")
    {
        p.datatype=23;
        p.index=input.index;
        p.whichtable=3;

        advanc();
    }
    else if(input.clas=="long_const")
    {
        p.datatype=24;
        p.index=input.index;
        p.whichtable=2;
        advanc();
    }
    else reject();
}

///**********************///
///**********************///
///                         ///
///   CODE GENERATOR     ///
///         STARTED         ///    
///**********************///
///**********************///


//
//Code Generator's Globals
//
ofstream code(FILE_WRITE);
//ofstream code("C2ASM.txt");
bool collect_ebx=false;

///////////////////////////////////////////////
//
//Code Generator's Helper Fucntion Declarations
//
///////////////////////////////////////////////

//Used to ATTACH "g" to Global Variables.So,that they don't CLASH with Main()'s variables,Since
//I used to PUT all the Global And Main() Variables in .Data Segment of Assembly
void mangle_globals();

//If a Variable Appears inside some User Defined Function.It must be addressed by using [BP+..]
//In Short These and other situations,Where Name_Resolving is IMPORTANT this Function is called
string name_resolve(expr& e);

//It places All Global/Main() Variables in the Data Segment of Assembly Code.
void putvariables();

//It Converts a Long Number into String Object
string number2string(long count);

//It returns correct Jump condition for a Particular Relational Operator.
//Used By "CMP" ATOM only
string jcond4cmps(int& indx);

//It returns correct Jump condition for a Particular Relational Operator.
//Used By "JUMPF" ATOM only
string jcond4jumpf(int& indx);

//Following Functions are respective Mappings of ATOMS into Functions.
//Each of them get Called whenever ATOM of their respective type is seen.

void proc_marker(atom& atm);
void adds(atom& atm);
void assign(atom& atm);
void subs(atom& atm);
void mul(atom& atm);
void divs(atom& atm);
void label(atom& atm);
void jump(atom& atm);
void cmps(atom& atm);
void condjump(atom& atm);
void jumpf(atom& atm);
void call(atom& atm);
void param(atom& atm);
void returns(atom& atm);

//
//Code Generator's Helper Fucntion Definitions
//
void mangle_globals()
{
    for(unsigned int i=0;i<syn_identifier.size();i++)
        //Find only GLOBAL VARIABLES
        if(syn_identifier[i].binding==-2 &&
            syn_identifier[i].func_or_not==false)
        {
            syn_identifier[i].name="g"+syn_identifier[i].name;
        }
}

void putvariables()
{
    for(unsigned int i=0;i<syn_identifier.size();i++)
        //OUTPUT only GLOBAL AND MAIN VARIABLES + Temporaries
    if((syn_identifier[i].binding==-2 || syn_identifier[i].binding==-1)
        && syn_identifier[i].func_or_not==false)
        {
        //Deciding Whether it's a LONG or an INTEGER?
        if(syn_identifier[i].datatype==0 ||syn_identifier[i].datatype==23)
        //An INTEGER
            code<<syn_identifier[i].name<<" dw "<<0<<endl;
        else
            //A LONG
            code<<syn_identifier[i].name<<" dd "<<0<<endl;
        }
}

void proc_marker(atom& atm)
{
    switch(atm.arg1.datatype)
    {
    
    //For Start Of Fucntion
    case 1:
        {
            switch(atm.arg1.index)
            {
                //It's main()
                case -1:
                    code<<"main proc"<<endl
                        <<"mov eax,@data"<<endl
                        <<"mov ds,ax"<<endl;
                    break;
                
                //It's an Ordinary Function
                default:
                    code<<syn_identifier[atm.arg1.index].name
                        <<" proc"<<endl
                        <<"push bp"<<endl
                        <<"mov bp,sp"<<endl
                        <<"sub sp,"<<atm.arg1.whichtable<<endl;
            }
        }
        break;

    //For End Of Fucntion
    case 0:
        {
            switch(atm.arg1.index)
            {
                //It's main()
                case -1:
                    code<<"mov ax,4c00h"<<endl
                        <<"int 21h"<<endl
                        <<"main endp"<<endl;
                    break;
                
                //It's an Ordinary Function
                default:
                    code<<"add sp,"<<atm.arg1.whichtable<<endl
                        <<"pop bp"<<endl
                        <<"ret"<<endl
                        <<syn_identifier[atm.arg1.index].name
                        <<" endp"<<endl;
            }
        }
        break;
    default:
        cout<<endl<<"Error in Fucntion Tagging";
        exit(-1);
    }

}

string name_resolve(expr& e)
{
    string name;
    switch(e.whichtable)
    {
    //Belongs to number_long
    case 2:
        name+=number2string(number_long[e.index]);
        break;

    //Belongs to number_int
    case 3:
        name+=number2string(number_int[e.index]);
        break;

    //Belongs to syn_identifier
    case 0:
        //If it Belongs to an Ordinary Fucntion
        if(syn_identifier[e.index].offset!=-10)
        {
            name+="[bp-";
            name+=number2string(syn_identifier[e.index].offset);
            name+="]";
        }
        //else it Belongs to a main() or a global variable
        else
            name=syn_identifier[e.index].name;    
        break;

        //Belongs to args_identifier
    case 1:
            name+="[bp+";
            name+=number2string(args_identifier[e.index].offset);
            name+="]";
            break;
    }
    return name;
}

string number2string(long count)
{    
    char name[40];
    char temp[40];

    ltoa(count,temp,10);
    strcpy(name,temp);

    return string(name);
}

void adds(atom& atm)
{
    //If its an INTEGER ADDITION use 16-Bit Registers
    if(atm.result.datatype==0)
    {
        code<<"push cx"<<endl
            <<"mov cx,0"<<endl
            <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
            <<"add cx,word ptr "<<name_resolve(atm.arg2)<<endl
            <<"mov "<<name_resolve(atm.result)<<",cx"<<endl
            <<"pop cx"<<endl;
    }
    //If its a LONG ADDITION use 32-Bit Registers
    else
    {
        code<<"push ecx"<<endl
            <<"mov ecx,0"<<endl
            <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
            <<"add ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
            <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
            <<"pop ecx"<<endl;
    }
}
void assign(atom& atm)
{
    //If its an INTEGER ASSIGNMENT use 16-Bit Registers
    if(atm.result.datatype==0)
    {
        /*If The assignment is taking PLACE immediately after FUNCTION
        call,Then USE BX register from where data is to be copied*/
        if(collect_ebx==true)
        {
            code<<"mov "<<name_resolve(atm.result)<<",bx"<<endl;
            collect_ebx=false;
        }
        else
        {
        code<<"push cx"<<endl
            <<"mov cx,0"<<endl
            <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
            <<"mov "<<name_resolve(atm.result)<<",cx"<<endl
            <<"pop cx"<<endl;
        }
    }
    //If its a LONG ASSIGNMENT use 32-Bit Registers
    else
    {
        /*If The assignment is taking PLACE immediately after FUNCTION
        call,Then USE EBX register from where data is to be copied*/
        if(collect_ebx==true)
        {
            code<<"mov "<<name_resolve(atm.result)<<",ebx"<<endl;
            collect_ebx=false;
        }
        else
        {
        code<<"push ecx"<<endl
            <<"mov ecx,0"<<endl
            <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
            <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
            <<"pop ecx"<<endl;
        }
    }
}

void subs(atom& atm)
{
    //If its an INTEGER SUBTRACTION use 16-Bit Registers
    if(atm.result.datatype==0)
    {
        code<<"push cx"<<endl
            <<"mov cx,0"<<endl
            <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
            <<"sub cx,word ptr "<<name_resolve(atm.arg2)<<endl
            <<"mov "<<name_resolve(atm.result)<<",cx"<<endl
            <<"pop cx"<<endl;
    }
    //If its a LONG SUBTRACTION use 32-Bit Registers
    else
    {
        code<<"push ecx"<<endl
            <<"mov ecx,0"<<endl
            <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
            <<"sub ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
            <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
            <<"pop ecx"<<endl;
    }
}

void mul(atom& atm)
{
    //If its an INTEGER MULTIPLICATION use 16-Bit Registers
    if(atm.result.datatype==0)
    {
    code<<"push cx"<<endl
        <<"mov cx,0"<<endl
        <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
        <<"mov "<<name_resolve(atm.result)<<",cx"<<endl
        <<"mov cx,"<<name_resolve(atm.arg2)<<endl
        <<"imul cx,word ptr "<<name_resolve(atm.result)<<endl
        <<"mov "<<name_resolve(atm.result)<<",cx"<<endl
        <<"pop cx"<<endl;
    }
    //If its a LONG MULTIPLICATION use 32-Bit Registers
    else
    {
    code<<"push ecx"<<endl
        <<"mov ecx,0"<<endl
        <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
        <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
        <<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
        <<"imul ecx,"<<name_resolve(atm.result)<<endl
        <<"mov "<<name_resolve(atm.result)<<",ecx"<<endl
        <<"pop ecx"<<endl;
    }
}

void divs(atom& atm)
{
    //If its an INTEGER DIVISION use 16-Bit Registers
    if(atm.result.datatype==0)
    {
    code<<"push ax"<<endl
        <<"push cx"<<endl
        <<"push dx"<<endl
        <<"mov ax,0"<<endl
        <<"mov cx,0"<<endl
        <<"mov dx,0"<<endl
        <<"mov ax,word ptr "<<name_resolve(atm.arg1)<<endl
        <<"mov cx,word ptr "<<name_resolve(atm.arg2)<<endl
        <<"div cx"<<endl
        <<"mov "<<name_resolve(atm.result)<<",ax"<<endl
        <<"pop dx"<<endl
        <<"pop cx"<<endl
        <<"pop ax"<<endl;
    }
    //If its a LONG DIVISION use 32-Bit Registers
    else
    {
    code<<";Warning: Long Division is LOGICALLY FLAWED due to EAX"<<endl
        <<"push eax"<<endl
        <<"push ecx"<<endl
        <<"push edx"<<endl
        <<"mov eax,0"<<endl
        <<"mov ecx,0"<<endl
        <<"mov edx,0"<<endl
        <<"mov eax,dword ptr "<<name_resolve(atm.arg1)<<endl
        <<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
        <<"div ecx"<<endl
        <<"mov "<<name_resolve(atm.result)<<",eax"<<endl
        <<"pop edx"<<endl
        <<"pop ecx"<<endl
        <<"pop eax"<<endl;
    }
}

void mods(atom& atm)
{
    //If its an INTEGER MOD use 16-Bit Registers
    if(atm.result.datatype==0)
    {
    code<<"push ax"<<endl
        <<"push cx"<<endl
        <<"push dx"<<endl
        <<"mov ax,0"<<endl
        <<"mov cx,0"<<endl
        <<"mov dx,0"<<endl
        <<"mov ax,word ptr "<<name_resolve(atm.arg1)<<endl
        <<"mov cx,word ptr "<<name_resolve(atm.arg2)<<endl
        <<"div cx"<<endl
        <<"mov "<<name_resolve(atm.result)<<",dx"<<endl
        <<"pop dx"<<endl
        <<"pop cx"<<endl
        <<"pop ax"<<endl;
    }
    //If its a LONG MOD use 32-Bit Registers
    else
    {
    code<<";Warning: Long MOD is LOGICALLY FLAWED due to EAX"<<endl
        <<"push eax"<<endl
        <<"push ecx"<<endl
        <<"push edx"<<endl
        <<"mov eax,0"<<endl
        <<"mov ecx,0"<<endl
        <<"mov edx,0"<<endl
        <<"mov eax,dword ptr "<<name_resolve(atm.arg1)<<endl
        <<"mov ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
        <<"div ecx"<<endl
        <<"mov "<<name_resolve(atm.result)<<",edx"<<endl
        <<"pop edx"<<endl
        <<"pop ecx"<<endl
        <<"pop eax"<<endl;
    }
}

void label(atom& atm)
{
    code<<labels[atm.result.index]<<":"<<'\t'<<";It's a Label"<<endl;
}

void jump(atom& atm)
{
    code<<"jmp "<<labels[atm.result.index]<<endl;
}

void cmps(atom& atm)
{
    //Generate 2 Labels
    int i=newlabel();
    string set=labels[i];
    i=newlabel();
    string notset=labels[i];

    //Decides Which Operator To USE.
    string jcond=jcond4cmps(atm.type);

    //If its an INTEGER COMPARISION use 16-Bit Registers
    if(atm.result.datatype==0)
    {
    code<<"push cx"<<endl
        <<"mov cx,0"<<endl
        <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
        <<"cmp cx,word ptr "<<name_resolve(atm.arg2)<<endl
        <<jcond<<" "<<set<<endl
        <<"mov "<<name_resolve(atm.result)<<",word ptr 0"<<endl
        <<"jmp "<<notset<<endl
        <<set<<":"<<endl
        <<"mov "<<name_resolve(atm.result)<<",word ptr 1"<<endl
        <<notset<<":"<<endl
        <<"pop cx"<<endl;
    }
    //If its a LONG COMPARISION use 32-Bit Registers
    else
    {
    code<<"push ecx"<<endl
        <<"mov ecx,0"<<endl
        <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
        <<"cmp ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
        <<jcond<<" "<<set<<endl
        <<"mov "<<name_resolve(atm.result)<<",dword ptr 0"<<endl
        <<"jmp "<<notset<<endl
        <<set<<":"<<endl
        <<"mov "<<name_resolve(atm.result)<<",dword ptr 1"<<endl
        <<notset<<":"<<endl
        <<"pop ecx"<<endl;
    }
}

string jcond4cmps(int& indx)
{
    string op;
    switch(indx)
    {
    case 8:
        op="je";
        break;        
        
    case 9:
        op="jne";
        break;

    case 10:
        op="jge";
        break;
        
    case 11:
        op="jle";
        break;
        
    case 12:
        op="jg";
        break;

    case 13:
        op="jl";
        break;
    }
    return op;
}

void condjump(atom& atm)
{
    //If It's an INTEGER COMPARISION
    if(atm.arg1.datatype==0)
    code<<"cmp "<<name_resolve(atm.arg1)<<",word ptr "<<atm.arg2.datatype<<endl
        <<"je "<<labels[atm.result.index]<<endl;
    else
    //If It's a LONG COMPARISION
    code<<"cmp "<<name_resolve(atm.arg1)<<",dword ptr "<<atm.arg2.datatype<<endl
        <<"je "<<labels[atm.result.index]<<endl;
}

void jumpf(atom& atm)
{
    //Decides Which Operator To USE.
    string jcond=jcond4jumpf(atm.type);

    //If its a INT COMPARISION use 16-Bit Registers
    if(atm.arg1.datatype==0)
    {
    code<<"mov cx,0"<<endl
        <<"mov cx,word ptr "<<name_resolve(atm.arg1)<<endl
        <<"cmp cx,word ptr "<<name_resolve(atm.arg2)<<endl
        <<jcond<<" "<<labels[atm.result.index]<<endl;
    }
    //If its a LONG COMPARISION use 32-Bit Registers
    else
    {
    code<<"mov ecx,0"<<endl
        <<"mov ecx,dword ptr "<<name_resolve(atm.arg1)<<endl
        <<"cmp ecx,dword ptr "<<name_resolve(atm.arg2)<<endl
        <<jcond<<" "<<labels[atm.result.index]<<endl;
    }
}

string jcond4jumpf(int& indx)
{
    string op;
    switch(indx)
    {
    case 8:
        op="jne";
        break;        
        
    case 9:
        op="je";
        break;

    case 10:
        op="jnge";
        break;
        
    case 11:
        op="jnle";
        break;
        
    case 12:
        op="jng";
        break;

    case 13:
        op="jnl";
        break;
    }
    return op;
}

void call(atom& atm)
{
    int data_type=atm.result.datatype;
    int pushed_values=syn_identifier[atm.result.index].xtra;

    code<<"call "<<syn_identifier[atm.result.index].name<<endl;

    //If Function has PUSHED PARAMETERS on STACK,Then Remove THEM!
    if(pushed_values!=-10)
    {
    for(int i=0;i<pushed_values;i+=2)
        code<<"pop ax"<<endl;
    }

    /*If Function has a return value,Then MAKE AN ANNOUNCEMENT that
    RETURN VALUE must be collected from bx or ebx.Since,If the function
    has a return value,it must appear on the R.H.S and ASSINGMENT
    immediately takes place after fuction's execution.
        It can be seen that "assign(atoms& atm)" takes advantage of this
    ANNOUNCEMENT*/

    if(data_type!=22)
        collect_ebx=true;
}

void param(atom& atm)
{
    switch(atm.result.datatype)
    {
    //It can be an INTEGER VARIABLE or an INTEGER CONSTANT use CX
    case 0:
    case 23:
            code<<"mov cx,word ptr "<<name_resolve(atm.result)<<endl
                <<"push cx"<<endl;
            
            break;
    
    //It can be an LONG VARIABLE or an LONG CONSTANT use ECX
    case 1:
    case 24:
            code<<"mov ecx,dword ptr "<<name_resolve(atm.result)<<endl
                <<"push ecx"<<endl;
            break;
    }
}

void returns(atom& atm)
{
    switch(atm.result.datatype)
    {
    //It can be an INTEGER VARIABLE or an INTEGER CONSTANT use BX
    case 0:
    case 23:
            code<<"mov bx,word ptr "<<name_resolve(atm.result)<<endl;    
            break;
    
    //It can be an LONG VARIABLE or an LONG CONSTANT use EBX
    case 1:
    case 24:
            code<<"mov ebx,dword ptr "<<name_resolve(atm.result)<<endl;
            break;
    }
}

//Code Generator
void code_generator()
{
    int atmtype;

    //Doing NAME MANGLING of GLOBAL VARIABLES only
    mangle_globals();
    //Placing INITIAL STARTUP CODE
    code<<"page ,"<<132<<endl
        <<"TITLE *** Assembly Generated By C2ASM *** "<<endl
        <<".model medium"<<endl
        <<".stack 200h"<<endl
        <<".386"<<endl
        <<".code"<<endl;

    //Start Processing ATOMS.
    for(unsigned int k=0;k<atoms.size();k++)
    {
        atmtype=atoms[k].type;
        
        switch(atmtype)
        {
        //PROC_MARKER
        case 34:
                 proc_marker(atoms[k]);
                 break;
        
        //ADD
        case 15:
            
                adds(atoms[k]);                
                break;
        
        //ASSIGN
        case 26:
                assign(atoms[k]);
                break;
        
        //SUB
        case 16:
                subs(atoms[k]);
                break;
        
        //MUL
        case 17:
                mul(atoms[k]);
                break;
        
        //DIV
        case 18:
                divs(atoms[k]);
                break;

        //DIV
        case 19:
                mods(atoms[k]);
                break;

        //LABEL
        case 25:
                label(atoms[k]);
                break;

        //JUMP
        case 28:
                jump(atoms[k]);
                break;

            //CMP
        case 108:
        case 109:
        case 110:
        case 111:
        case 112:
        case 113:
            atoms[k].type=atoms[k].type-100;    //Restore Orignal Index
            cmps(atoms[k]);
            break;

        //CONDJUMP
        case 27:
            condjump(atoms[k]);
            break;

        //JUMPF
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
            jumpf(atoms[k]);
            break;

        //CALL
        case 31:
            call(atoms[k]);
            break;

        //PARAM
        case 30:
            param(atoms[k]);
            break;

        //RETURN
        case 29:
            returns(atoms[k]);
            break;
        }//End Switch
    
    }//End Processing ATOMS.

    //Placing FINAL CLOSING CODE
    code<<".data"<<endl;
    putvariables();
    code<<"end main"<<endl;
    code.close();
}

RE: Can someone compile a C++ file for me? No compilers I can find will...

(OP)
The reason I've placed this in the ASM forum and not the C++ forum, btw, is because this translates C++ to ASM, and I figured that this would be useful to those who are here.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login


Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close