//=====================================================================================================================
  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 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");
  }