//=====================================================================================================================
  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;
  }
Esempio n. 4
0
    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");
  }
Esempio n. 8
0
    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
    }
Esempio n. 9
0
    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;
      
    }
Esempio n. 10
0
    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
    }
Esempio n. 11
0
    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
    }