string CBackendx86::Operand(const CTac *op)
{
  string operand;
  // TODO
  // return a string representing op
  // hint: take special care of references (op of type CTacReference)
  std::stringstream buffer ;
  buffer << op ;
  
  CScope *cs = GetScope();
  CSymtab *st = cs->GetSymbolTable();
  vector<CSymbol*> slist = st->GetSymbols();
 
  vector< CSymbol * > symbols = st->GetSymbols() ;
  //CTacName
  if (st->FindSymbol(buffer.str()) != NULL){
      operand =  buffer.str() ;
  }   
  //CTacConstant
  else if (buffer.str()[0] > 47 && buffer.str()[0] < 58){
       operand =  Imm(atoi(buffer.str().c_str())) ;
  }
      
  //CTacReference
  
  else {
      
  }
  
  
  return operand ;
}
void CBackendx86::EmitInstruction(CTacInstr *i)
{
  assert(i != NULL);

  ostringstream cmt;
  string mnm;
  cmt << i;

  EOperation op = i->GetOperation();
  CScope* sc = GetScope() ;
  const CSymbol* symbol ; 
  int size ;
  
  switch (op) {
      
    // binary operators
    // dst = src1 op src2
    // TODO
      case opAdd :
      //case opSub :
      case opMul :
      //case opDiv :
      //case opAnd :
      //case opOr :          
          EmitInstruction("movl", Operand(i->GetSrc(1)) + ", %eax", cmt.str());         
          EmitInstruction("movl", Operand(i->GetSrc(2)) + ", %ebx");
          
          if (op == opAdd)
             EmitInstruction("addl", "%ebx, %eax");  
          else if (op == opMul)
             EmitInstruction("imull", "%ebx");  
          
          symbol = sc->GetSymbolTable()->FindSymbol(Operand(i->GetSrc(1)));
          
          size = symbol->GetOffset() ; 
          cmt.str("");
          cmt << size ;
          EmitInstruction("movl", "%eax, -" + cmt.str() + "(%ebp)"  );
          
          break ;              
 
    // unary operators
    // dst = op src1
    // TODO
    case opNeg :
    //case opPos :
    //case opNot :
        symbol = sc->GetSymbolTable()->FindSymbol(Operand(i->GetSrc(1)));
        if (symbol != NULL){
            EmitInstruction("movl", Operand(i->GetSrc(1)) + ", %eax", cmt.str());
            EmitInstruction("negl", "%eax");
            size = symbol->GetOffset() ;cmt.str("");
            cmt << size ;
            EmitInstruction("movl", "%eax, -" + cmt.str() + "(%ebp)"  );
            
        } 
        else {
            EmitInstruction("movl", Operand(i->GetSrc(1)) + ", %eax", cmt.str());
            EmitInstruction("negl", "%eax");
        }
        
        break ;
    // memory operations
    // dst = src1
    // TODO
      case opAssign :
          if (false) {
              
          }else {
              //cmt << " assign\t" + Operand(i->GetDest()) + "  <-  " << i->GetSrc(1) ;
              Load(i->GetSrc(1), "%eax", cmt.str() ) ;
              Store(i->GetDest(), 'a', "") ;  
          }
       break ;
    // pointer operations
    // dst = &src1
    // TODO
    // dst = *src1
    case opDeref:
      // opDeref not generated for now
      EmitInstruction("# opDeref", "not implemented", cmt.str());
      break;


    // unconditional branching
    // goto dst
    // TODO

    // conditional branching
    // if src1 relOp src2 then goto dst
    // TODO
      

    // function call-related operations
    // TODO

    // special
    case opLabel:
      _out << Label(dynamic_cast<CTacLabel*>(i)) << ":" << endl;
      break;

    case opNop:
      EmitInstruction("nop", "", cmt.str());
      break;


    default:
      EmitInstruction("# ???", "not implemented", cmt.str());
  }
}