ExpressionValue SemanticEval::evaluateExpr(ExpressionValue& ev, RefPortugolAST unary_op) { ExpressionValue nulo; //não permitir TIPO_ALL em expressões binarias if(ev.primitiveType() == TIPO_ALL) { stringstream msg; msg << "Função interna não pode participar de expressão"; ErrorHandler::self()->add(msg.str(), unary_op->getLine()); return nulo; } switch(unary_op->getType()) { //operadores unarios para expressões numéricas (retorna o tipo da expressão 'expr') case SemanticWalkerTokenTypes::TI_UN_POS://+ case SemanticWalkerTokenTypes::TI_UN_NEG://- if(!ev.isNumeric()) { stringstream msg; msg << "Operador unário \"" << unary_op->getText() << "\" deve ser usado em termos numéricos"; ErrorHandler::self()->add(msg.str(), unary_op->getLine()); return nulo; } else { return ev; } break; case SemanticWalkerTokenTypes::TI_UN_BNOT://~ if(!ev.isNumeric(true)) { stringstream msg; msg << "Operador unário \"" << unary_op->getText() << "\" deve ser usado em termos numéricos inteiros e compatíveis"; ErrorHandler::self()->add(msg.str(), unary_op->getLine()); return nulo; } else { return ev; } break; //operador "not", para todos os tipos. Retorna TIPO_LOGICO case SemanticWalkerTokenTypes::TI_UN_NOT: ev.setPrimitiveType(TIPO_LOGICO); return ev; break; } stringstream msg; msg << "Erro interno: operador não suportado: " << unary_op->getText() << ""; ErrorHandler::self()->add(msg.str(), unary_op->getLine()); return nulo; }
void SemanticEval::evaluateNumericExpr(ExpressionValue& ev, int line) { if(!ev.isPrimitive() || !ev.isNumeric()) { stringstream err; err << "Esperando uma expressão numérica. Encontrado expressão \"" << ev.toString() << "\""; ErrorHandler::self()->add(err.str(), line); } }
ExpressionValue SemanticEval::evaluateNumTypes(ExpressionValue& left, ExpressionValue& right) { ExpressionValue ret; if(!left.isNumeric() || !right.isNumeric()) return ret; //a ordem eh importante. Primeiro o tipo mais forte. if((left.primitiveType() == TIPO_REAL) || (right.primitiveType() == TIPO_REAL)) { ret.setPrimitiveType(TIPO_REAL); //promoted to real } else if((left.primitiveType() == TIPO_INTEIRO) || (right.primitiveType() == TIPO_INTEIRO)) { ret.setPrimitiveType(TIPO_INTEIRO); //promoted to int } else if((left.primitiveType() == TIPO_CARACTERE) || (right.primitiveType() == TIPO_CARACTERE)) { ret.setPrimitiveType(TIPO_CARACTERE); //promoted to char } else if((left.primitiveType() == TIPO_LOGICO) || (right.primitiveType() == TIPO_LOGICO)) { ret.setPrimitiveType(TIPO_LOGICO); //promoted to bool } return ret; //no number here... }