//===================================================================================================================== void visitClassImpl(ClassImpl *p) { fprintf(m_outputfile, "############ CLASS\n"); // Set current class name for function labels currClassName = dynamic_cast<ClassIDImpl*>(p->m_classid_1)->m_classname->spelling(); // Create this class's classnode and insert into class table ClassNode* node = new ClassNode(); node->name = new ClassName(currClassName); node->superClass = NULL; node->scope = new SymScope(); // only used for holding methods node->p = p; if(p->m_classid_2!=NULL) { const char* superclass = dynamic_cast<ClassIDImpl*>(p->m_classid_2)->m_classname->spelling(); assert(m_classtable->exist(superclass)); node->superClass = new ClassName(superclass); m_classtable->lookup(superclass)->offset->copyTo(node->offset); } currClassOffset = node->offset; m_classtable->insert(node->name->spelling(), node); inMethod = false; // Visit the children p->visit_children(this); fprintf(m_outputfile, "############\n\n"); }
//===================================================================================================================== void visitMethodCall(MethodCall *p) { fprintf(m_outputfile, "#### METHC\n"); // Visit variable and method name p->m_methodid->accept(this); p->m_variableid->accept(this); // Grab variable's classname (for jump label) from offset table OffsetTable* table = currMethodOffset; bool inClass=false; const char* varname = dynamic_cast<VariableIDImpl*>(p->m_variableid)->m_symname->spelling(); if(!table->exist(varname)) {table = currClassOffset; inClass=true;} assert(table->exist(varname)); CompoundType type = table->get_type(varname); const char* name; name = type.classID; // Visit parameters in reverse order, so their results will end up on the stack in x86 convention order int numparams = 0; list<Expression_ptr> *l = p->m_expression_list; list<Expression_ptr>::iterator it; Expression* exp; Expression_ptr ptr; for(it=l->end(); it!=l->begin();) { --it; ptr = (Expression_ptr)*it; exp = dynamic_cast<Expression*> (ptr); exp->accept(this); numparams++; } // Push referenced object's pointer to stack as final parameter if(!inClass) { fprintf( m_outputfile, " pushl %i(%%ebp)\n", table->get_offset(varname)); } else { fprintf( m_outputfile, " movl 8(%%ebp), %%ebx\n"); fprintf( m_outputfile, " pushl %i(%%ebx)\n", table->get_offset(varname)); } numparams++; // Find class/superclass that contains the function const char* funcname = dynamic_cast<MethodIDImpl*>(p->m_methodid)->m_symname->spelling(); ClassNode* node = m_classtable->lookup(name); assert(node!=NULL); while(!(node->scope->exist(funcname))) { assert(node->superClass != NULL); node = m_classtable->lookup(node->superClass); } // Call the function fprintf(m_outputfile, " call %s_%s\n", node->name->spelling(), funcname); // Clean up parameters fprintf(m_outputfile, " addl $%i, %%esp\n", numparams*4); // Push return value fprintf(m_outputfile, " pushl %%ebx\n"); fprintf(m_outputfile, "####\n"); }
//===================================================================================================================== void visitMethodImpl(MethodImpl *p) { inMethod = true; fprintf(m_outputfile, "######## METHOD\n"); // Create function label from class name and method name const char* funcname = dynamic_cast<MethodIDImpl*>(p->m_methodid)->m_symname->spelling(); fprintf(m_outputfile, "%s_%s:\n", currClassName, funcname); // Prologue - Push old ebp to stack, update ebp to current stack pointer fprintf(m_outputfile, " pushl %%ebp\n"); fprintf(m_outputfile, " movl %%esp, %%ebp\n"); // Set offset tables assert(m_classtable->exist(currClassName)); ClassNode* node = m_classtable->lookup(currClassName); currClassOffset = node->offset; currMethodOffset = new OffsetTable(); currMethodOffset->setTotalSize(4); // make space in table for %ebp // Add function to classnode's scope node->scope->insert(funcname, new Symbol()); assert(node->scope->exist(funcname)); // Iterate through parameters, saving to offset table list<Parameter_ptr> *l = p->m_parameter_list; list<Parameter_ptr>::iterator it; OffsetTable* table = currMethodOffset; ParameterImpl* param; Parameter_ptr ptr; int varSize = 4; int curroffset = 12; // leave space for return address and the 'this object' pointer for(it=l->begin(); it!=l->end(); ++it) { ptr = (Parameter_ptr)*it; param = dynamic_cast<ParameterImpl*> (ptr); table->insert(dynamic_cast<VariableIDImpl*>(param->m_variableid)->m_symname->spelling(), curroffset, varSize, param->m_type->m_attribute.m_type.classType); curroffset += varSize; } // Visit the children p->visit_children(this); // Epilogue - deallocate locals, set ebp to old ebp, return curroffset = currMethodOffset->getTotalSize(); fprintf(m_outputfile, " addl $%i, %%esp\n", curroffset-4); // everything but old ebp fprintf( m_outputfile," leave\n"); fprintf( m_outputfile," ret\n"); fprintf(m_outputfile, "########\n"); // Dereference the local offset table currMethodOffset == NULL; inMethod = false; }
void visitClassImpl(ClassImpl *p) { int stop; m_symboltable->open_scope(); Symbol * symPtr = new Symbol; // = new ClassNode; Symbol * symp;// = new Symbol; ClassIDImpl * ClassIdP = dynamic_cast<ClassIDImpl*>(p->m_classid_1); ClassIDImpl * ClassIdP2 = dynamic_cast<ClassIDImpl*>(p->m_classid_2); char * key1 = strdup(ClassIdP->m_classname->spelling()); symPtr->classType.classID = ClassIdP->m_classname->spelling(); char * progFinder = strdup("Program"); ClassName * nm = new ClassName(key1); if(progger == true){ t_error(no_program, p->m_attribute); } if(std::string(key1) == std::string(progFinder)){ progger = true; } //char * key2 = strdup(ClassIdP2->m_classname->spelling()); if(m_classtable->exist(key1)){ t_error(dup_ident_name, p->m_attribute); } else{ if(ClassIdP2->m_classname != NULL){ char * key2 = strdup(ClassIdP2->m_classname->spelling()); ClassName * nm2 = new ClassName(key2); // cout<<"inserted class: " <<key1 <<" from :"<<key2 <<endl; m_classtable->insert(nm, nm2, p, m_symboltable->get_scope()); ClassNode * clasp = m_classtable->getParentOf(key2); // cout<<"Class: " <<key1 <<", Super class: "<<clasp->name->spelling()<<endl; } else{ // cout<< "instered this in class table: "<< key1 <<endl; m_classtable->insert(nm, NULL, p, m_symboltable->get_scope()); } } m_symboltable->insert((char *)"xxx", symPtr); p->visit_children(this); m_symboltable->close_scope(); //WRITE ME }
//===================================================================================================================== void visitProgramImpl(ProgramImpl *p) { init(); // Visit the children p->visit_children(this); start(m_classtable->lookup("Program")->offset->getTotalSize()); }
//===================================================================================================================== void visitSelfCall(SelfCall *p) { fprintf(m_outputfile, "#### SELFC\n"); // Visit method name p->m_methodid->accept(this); // Visit parameters in reverse order, so their results will end up on the stack in x86 convention order int numparams = 0; list<Expression_ptr> *l = p->m_expression_list; list<Expression_ptr>::iterator it; Expression* exp; Expression_ptr ptr; for(it=l->end(); it!=l->begin();) { --it; ptr = (Expression_ptr)*it; exp = dynamic_cast<Expression*> (ptr); exp->accept(this); numparams++; } // Push current object's pointer to stack as final parameter fprintf( m_outputfile, " pushl 8(%%ebp)\n"); numparams++; // Find class/superclass that contains the function const char* funcname = dynamic_cast<MethodIDImpl*>(p->m_methodid)->m_symname->spelling(); ClassNode* node = m_classtable->lookup(currClassName); assert(node!=NULL); while(!(node->scope->exist(funcname))) { assert(node->superClass != NULL); node = m_classtable->lookup(node->superClass); } // Call the function fprintf(m_outputfile, " call %s_%s\n", node->name->spelling(), funcname); // Clean up parameters fprintf(m_outputfile, " addl $%i, %%esp\n", numparams*4); // Push return value fprintf(m_outputfile, " pushl %%ebx\n"); fprintf(m_outputfile, "####\n"); }
//===================================================================================================================== void visitDeclarationImpl(DeclarationImpl *p) { fprintf(m_outputfile, "#### DECLARATION\n"); // Visit the children p->visit_children(this); // Get type and decide on allocated size Basetype type = p->m_type->m_attribute.m_type.baseType; assert(type == bt_boolean || type == bt_integer || type == bt_object); int varSize = 4; // Iterate through list of variables, allocating and inserting into offset table list<VariableID_ptr> *l = p->m_variableid_list; list<VariableID_ptr>::iterator it; OffsetTable* table; bool isClassDec; int offsetDir; if(inMethod) { table = currMethodOffset; isClassDec = false; offsetDir = -1; } else{ table = currClassOffset; isClassDec = true; offsetDir = 1; } VariableIDImpl* var; VariableID_ptr ptr; int curroffset; for(it=l->begin(); it!=l->end(); ++it) { ptr = (VariableID_ptr)*it; var = dynamic_cast<VariableIDImpl*> (ptr); // Allocate space in stack/heap if not a class declaration if(type == bt_object && !isClassDec) { const char* c = p->m_type->m_attribute.m_type.classType.classID; assert(c != ""); assert(m_classtable->exist(c)); ClassNode* node = m_classtable->lookup(c); fprintf( m_outputfile, " pushl %s\n",heapTop); // push current heap top to stack as pointer to obj fprintf( m_outputfile, " addl $%d, %s\n",node->offset->getTotalSize(),heapTop); // allocate in heap } else if(!isClassDec) { fprintf(m_outputfile, " subl $%i, %%esp\n", varSize); } // Insert into and update offset table curroffset = table->getTotalSize(); table->insert(var->m_symname->spelling(), offsetDir*curroffset, varSize, p->m_type->m_attribute.m_type.classType); //fprintf( m_outputfile, "%i, %i, %i, %i\n", inMethod, offsetDir, curroffset, varSize); table->setTotalSize(offsetDir*(offsetDir*curroffset+offsetDir*varSize)); } fprintf(m_outputfile, "####\n"); }
void visitTObject(TObject *p) { p->m_attribute.m_type.baseType = bt_object; p->visit_children(this); ClassIDImpl * ClassIdP = dynamic_cast<ClassIDImpl*>(p->m_classid); char *name = strdup(ClassIdP->m_classname->spelling()); p->m_attribute.m_type.classType.classID = name; ClassNode * classptr; if(!m_classtable->exist(name)){ t_error(sym_name_undef, p->m_attribute); } //WRITE ME }
Symbol * InScope(char* key){// before calling this function make sure there is a parent scope Symbol * symbP; SymScope *sync; ClassNode * parent; ClassNode * clasp; char* parentName; bool found; string pName; int i =0; // cout<<" the key is "<<key<<endl; symbP = m_symboltable->lookup(key); if(!m_symboltable->exist(key)){ symbP = m_symboltable->lookup((const char *)"xxx"); char * Cname = strdup(symbP->classType.classID); parent = m_classtable->lookup(Cname); // cout<<"parent: "<<parent->name->spelling()<<endl; sync = parent->scope; symbP = sync->lookup(key); found = sync->exist(key); while(found == false){ ClassName * classGreat = new ClassName(Cname); ClassNode* pNode = m_classtable->getParentOf(classGreat); Cname = strdup(pNode->name->spelling()); std::string pName(pNode->name->spelling()); // cout<<"the parent name: "<<Cname<<endl; if( pName == "TopClass"){ return NULL; } sync = pNode->scope; found = sync->exist(key); symbP = sync->lookup(key); i++; } } return symbP; }
void visitProgramImpl(ProgramImpl *p) { p->visit_children(this); string x = "Program"; char* a = strdup("Program"); ClassName * cName = new ClassName(a); if(!m_classtable->exist(cName)){ t_error(no_program, p->m_attribute); } ClassNode* classnode = m_classtable->lookup(cName); SymScope * sync = classnode->scope; char * s = strdup("start"); // char * methodName = (s); Symbol * f= sync->lookup(s); if((f == NULL) || (f->methodType.returnType.baseType != 16)){ t_error(no_start, p->m_attribute); } if(f->methodType.argsType.size() != 0){ t_error(start_args_err, p->m_attribute); } printSymTab(); //WRITE ME }
void visitMethodCall(MethodCall *p) { p->visit_children(this); Symbol* symp; ClassNode * clasp; Basetype bargs; int i =0; Symbol * test; VariableIDImpl * VarIdP = dynamic_cast<VariableIDImpl*>(p->m_variableid); MethodIDImpl * MethIdP = dynamic_cast<MethodIDImpl*>(p->m_methodid); char * meth = strdup(MethIdP->m_symname->spelling()); test = m_symboltable->lookup(meth); // Basetype bargs; char * var = strdup(VarIdP->m_symname->spelling()); // cout<<"the var : "<<var<<endl; if( !m_symboltable->exist(var)){//if symbol not defined within class t_error(sym_name_undef, p->m_attribute); } symp = InScope(var) ;//~!~!~!~!~!~!~!~ place here if(symp->baseType != 8){ t_error(sym_type_mismatch,p->m_attribute); } char *name = strdup(symp->classType.classID); clasp = m_classtable->lookup(name); // cout<<name<<endl; if(!m_classtable->exist(name)){ t_error(sym_name_undef,p->m_attribute); } // SymScope *sync = clasp->scope; char * className= strdup(symp->classType.classID); ClassNode* classnode = m_classtable->lookup(className); SymScope * sync = classnode->scope; symp= sync->lookup(meth); //symp = InScope(meth);//~!~!~!~!~!~!~!~ place here if(symp == NULL){ t_error(no_class_method, p->m_attribute); } if(p->m_expression_list->size()!= symp->methodType.argsType.size() ) t_error(call_args_mismatch,p->m_attribute); typename std::list<Expression_ptr>::iterator it = p->m_expression_list->begin(); for( ; it != p->m_expression_list->end(); ++it) { Expression * Expoin = dynamic_cast<Expression *> (*it); bargs = symp->methodType.argsType[i].baseType; if(bargs != Expoin->m_attribute.m_type.baseType) t_error(call_args_mismatch, p->m_attribute); i++; } p->m_attribute.m_type.baseType = symp->methodType.returnType.baseType; p->m_attribute.m_type.methodType.returnType.baseType = symp->methodType.returnType.baseType; //WRITE ME }