Logo Search packages:      
Sourcecode: fauhdlc version File versions

void ast::GenCode::visit ( CaseStat node  )  [private, virtual]

Visit a CaseStat

Parameters:
node CaseStat node that get's visited.

Reimplemented from ast::TopDownVisitor.

Definition at line 2578 of file GenCode.cpp.

References ast::AstNode::accept(), intermediate::CodeContainer::addCode(), ast::CaseStat::alternatives, assignExpression, ast::Expression::baseType, container, destRegs, intermediate::LabelFactory::getLabel(), ast::RegisterSet::getValue(), isTarget, processAlternative(), ast::CaseStat::select, and sourceRegs.

{
      // TODO: there are a number of restrictions on 
      //       select and alternatives, which aren't checked yet
      //       see lrm 8.8 for details.
      //       However these restrictions should be checked elsewhere.
      //
      // TODO 2: This is a pretty poor implementation, as all
      //       expression choices should be locally static.
      //       A good implementation would choose the best algorithm
      //       for the alternatives, including
      //       - a jump lookup table
      //       - if/then/else constructs (that's done here)
      //       - a combination thereof
      //       - ...

      assert(node.select != NULL);
      assert(node.alternatives != NULL);

      this->assignExpression = false;
      this->isTarget = false;
      this->sourceRegs = RegisterSet(*this->container);
      this->destRegs = RegisterSet(*this->container);

      switch (node.select->baseType) {
      case BASE_TYPE_RECORD:
      case BASE_TYPE_ARRAY:
            // FIXME not handled yet: this needs to 
            // 1) assign the result of the expression to a temporary
            // 2) compare the temporary with the choices
            assert(false);
            break;

      case BASE_TYPE_UNSET:
            assert(false);
            break;

      default:
            break;
      }

      node.select->accept(*this);
      Operand *cmpVal = this->sourceRegs.getValue(node.select->baseType);
      this->sourceRegs = RegisterSet(*this->container);
      
      Label *caseOut = LabelFactory::getLabel("case_out");

      // handle each alternative
      for (std::list<CaseAlternative *>::const_iterator i = 
            node.alternatives->begin();
            i != node.alternatives->end(); /* nothing */) {

            CaseAlternative *current = *i;
            Label *caseNext = caseOut;
            i++;

            // use caseOut as last next label.
            if (i != node.alternatives->end()) {
                  caseNext = LabelFactory::getLabel("case_next");
            }

            this->processAlternative(*current, cmpVal, caseNext, caseOut);

            if (i != node.alternatives->end()) {
                  this->container->addCode(caseNext);
            }
      }


      this->container->addCode(caseOut);
}


Generated by  Doxygen 1.6.0   Back to index