Exemplo n.º 1
0
void SemanticEval::evaluateReturnCmd(ExpressionValue& ev, int line) {
  if(currentScope == SymbolTable::GlobalScope) {
    //tentando retornar no bloco principal
    ErrorHandler::self()->add("Bloco principal não deve ter retorno", line);
  } else {
    //currentScope eh o nome da funcao atual
    try {
      SymbolType sctype = stable.getSymbol(SymbolTable::GlobalScope, currentScope).type;
      
      if(!ev.isCompatibleWidth(sctype)) {
          stringstream msg;
          msg << "Expressão de retorno deve ser compatível com o tipo \"" 
            << sctype.toString() <<  "\"";
          ErrorHandler::self()->add(msg.str(), line);
      } //else ok!
    } catch(SymbolTableException& e) {
      cerr << "Erro interno: SemanticEval::evaluateReturnCmd exception\n";
    }
  } 
}
Exemplo n.º 2
0
void SemanticEval::evaluateAttribution(ExpressionValue&  lv, ExpressionValue& rv, int line) {
//lvalue e rvalue devem ter tipos compativeis
//  -numericos (inteiro, logico, real, caractere) sao compativeis entre si.

  stringstream msg;

  if(!lv.isPrimitive()) {
    msg << "Apenas variáveis de tipos primitivos podem receber valores";
    ErrorHandler::self()->add(msg.str(), line);
    return;
  }

  if(rv.primitiveType() == TIPO_NULO) {
    msg << "Expressão não retorna resultado para variável";  
    ErrorHandler::self()->add(msg.str(), line);
  } else  if(!lv.isCompatibleWidth(rv)) {
    msg << "Variável não pode receber valores do tipo '"
        << rv.toString() << "'";      
    ErrorHandler::self()->add(msg.str(), line);
  }
}
Exemplo n.º 3
0
ExpressionValue SemanticEval::evaluateExpr(ExpressionValue& left, ExpressionValue& right, RefPortugolAST op) {
  //analisa expressoes binarias

  ExpressionValue ret, nulo;

  //operadores suportam apenas primitivos
//   if(!left.isPrimitive() || !right.isPrimitive()) {
//     return ret;
//   }

  //não permitir TIPO_ALL em expressões binarias
  if((left.primitiveType() == TIPO_ALL) || (right.primitiveType() == TIPO_ALL)) {
    stringstream msg;
    msg << "Função interna não pode participar de expressão";
    ErrorHandler::self()->add(msg.str(), op->getLine());
    return nulo;
  }

  switch(op->getType()) {
    //qualquer tipo, contanto que left e right sejam compativeis
    case SemanticWalkerTokenTypes::T_IGUAL:
    case SemanticWalkerTokenTypes::T_DIFERENTE:

    //nota sobre literais:
    // operacoes aplicadas sobre o length() do literal
    case SemanticWalkerTokenTypes::T_MAIOR:
    case SemanticWalkerTokenTypes::T_MENOR:
    case SemanticWalkerTokenTypes::T_MAIOR_EQ:
    case SemanticWalkerTokenTypes::T_MENOR_EQ:

    case SemanticWalkerTokenTypes::T_KW_OU:
    case SemanticWalkerTokenTypes::T_KW_E:
      if(left.isCompatibleWidth(right)) {
        ret.setPrimitiveType(TIPO_LOGICO);
        return ret;
      } else {
        stringstream msg;
        msg << "Operador \"" << op->getText() << "\" não pode ser usado em expressões no formato " 
            << "'" << left.toString() 
            << " " << op->getText() 
            << " " << right.toString() << "'";
            ErrorHandler::self()->add(msg.str(), op->getLine());
            return nulo;
      }   
      break;

    //qualquer numerico não-real (inteiro, caractere, lógico)
    case SemanticWalkerTokenTypes::T_BIT_OU:
    case SemanticWalkerTokenTypes::T_BIT_XOU:
    case SemanticWalkerTokenTypes::T_BIT_E:
      ret = evaluateNumTypes(left, right);
      if((ret.primitiveType() == TIPO_REAL) || (ret.primitiveType() == TIPO_NULO)) {
        stringstream msg;
        msg << "Operador \"" << op->getText() << "\" só pode ser usado com termos númericos não-reais";
            ErrorHandler::self()->add(msg.str(), op->getLine());
         return nulo;
      } else {
        return ret;
      }
      break;

    //qualquer numérico
    case SemanticWalkerTokenTypes::T_MAIS:
    case SemanticWalkerTokenTypes::T_MENOS:
    case SemanticWalkerTokenTypes::T_DIV:
    case SemanticWalkerTokenTypes::T_MULTIP:    
      ret = evaluateNumTypes(left, right);
      if(!ret.isNumeric()) {
        stringstream msg;
        msg << "Operador \"" << op->getText() << "\" só pode ser usado com termos numéricos";
            ErrorHandler::self()->add(msg.str(), op->getLine());          
            return nulo;
      } else {
        return ret;
      }      
      break;
    case SemanticWalkerTokenTypes::T_MOD:
      ret = evaluateNumTypes(left, right);
      if(!ret.isNumeric(true)) {
        stringstream msg;
        msg << "Operador \"" << op->getText() << "\" não pode ser usado com termos "
            << "numéricos inteiros e compatíveis";
            ErrorHandler::self()->add(msg.str(), op->getLine());          
            return nulo;
      } else {
        return ret;
      }      
      break;
  }

  stringstream msg;
  msg << "Erro interno: operador não suportado: " << op->getText();
  ErrorHandler::self()->add(msg.str(), op->getLine());
  return nulo;
}