node* CALCCONSTmonop(node *arg_node, info *arg_info){ DBUG_ENTER ("CALCCONSTmonop"); node * ret; MONOP_EXPR( arg_node) = TRAVopt( MONOP_EXPR( arg_node), NULL); nodetype nt = NODE_TYPE(MONOP_EXPR( arg_node)); if(MONOP_OP(arg_node) == MO_not && nt == N_bool){ ret = TBmakeBool(! BOOL_VALUE(MONOP_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret); }else if(MONOP_OP(arg_node) == MO_neg){ if(nt == N_int){ ret = TBmakeInt(-INT_VALUE(MONOP_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret); }else if(nt == N_float){ ret = TBmakeFloat(-FLOAT_VALUE(MONOP_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret); }else{ DBUG_RETURN (arg_node); } }else{ DBUG_RETURN (arg_node); } }
//rewrite cast and set info_type to cast type node *CTcast(node *arg_node, info *arg_info){ DBUG_ENTER("CTcast"); extern node *CTbinop( node *arg_node, info *arg_info); extern node *CTfunbody( node *arg_node, info *arg_info); CAST_EXPRESSION(arg_node) = TRAVdo(CAST_EXPRESSION(arg_node), arg_info); type exprType = INFO_TYPE(arg_info); type castType = CAST_TYPE(arg_node); //set info type to cast type INFO_TYPE(arg_info) = CAST_TYPE(arg_node); //rewrite cast if(exprType == T_boolean && castType == T_int){ node *expr = CAST_EXPRESSION(arg_node); node *then = TBmakeNum(1); node *other = TBmakeNum(0); node *condexpr = TBmakeConditionexpr(expr, other, then); arg_node = condexpr; } else if(exprType == T_boolean && castType == T_float){ node *expr = CAST_EXPRESSION(arg_node); node *then = TBmakeFloat(1.0); node *other = TBmakeFloat(0.0); node *condexpr = TBmakeConditionexpr(expr, then, other); arg_node = condexpr; } else if(exprType == T_int && castType == T_boolean){ node *expr = TBmakeBinop(BO_gt, CAST_EXPRESSION(arg_node), TBmakeNum(0)); BINOP_OPTYPE(expr) = T_int; node *then = TBmakeBool(true); node *other = TBmakeBool(false); node *condexpr = TBmakeConditionexpr(expr, other, then); arg_node = condexpr; } else if(exprType == T_float && castType == T_boolean){ node *expr = TBmakeBinop(BO_gt, CAST_EXPRESSION(arg_node), TBmakeFloat(0.0)); BINOP_OPTYPE(expr) = T_float; node *then = TBmakeBool(true); node *other = TBmakeBool(false); node *condexpr = TBmakeConditionexpr(expr, other, then); arg_node = condexpr; } DBUG_RETURN(arg_node); }
/** <!--******************************************************************--> * * @fn COPYfloat * * @brief Copies the node and its sons/attributes * * @param arg_node Float node to process * @param arg_info pointer to info structure * * @return processed node * ***************************************************************************/ node * COPYfloat (node * arg_node, info * arg_info) { node *result = TBmakeFloat (0.0); DBUG_ENTER ("COPYfloat"); LUTinsertIntoLutP (INFO_LUT (arg_info), arg_node, result); /* Copy attributes */ FLOAT_VALUE (result) = FLOAT_VALUE (arg_node); /* Return value */ DBUG_RETURN (result); }
node* CALCCONSTbinop(node *arg_node, info *arg_info){ DBUG_ENTER ("CALCCONSTbinop"); node * ret; BINOP_LEFT( arg_node) = TRAVopt( BINOP_LEFT( arg_node), NULL); BINOP_RIGHT( arg_node) = TRAVopt( BINOP_RIGHT( arg_node), NULL); nodetype ntr = NODE_TYPE(BINOP_RIGHT( arg_node)); nodetype ntl = NODE_TYPE(BINOP_LEFT( arg_node)); if(ntr!= ntl || !(ntl==N_int || ntl==N_bool || ntl==N_float )) DBUG_RETURN (arg_node); if(ntl == N_bool){ bool l = BOOL_VALUE(BINOP_LEFT( arg_node)); bool r = BOOL_VALUE(BINOP_RIGHT( arg_node)); switch(BINOP_OP(arg_node)){ case BO_and: DBISNS(TBmakeBool(r&&l)); break; case BO_or: DBISNS(TBmakeBool(r||l)); break; case BO_ne: DBISNS(TBmakeBool(r != l)); break; case BO_eq: DBISNS(TBmakeBool(r==l)); break; case BO_add: DBISNS(TBmakeBool(r | l)); break; case BO_mul: DBISNS(TBmakeBool(r & l)); break; default: DBUG_RETURN(arg_node); break; } }else if(ntl == N_int){ int l = INT_VALUE(BINOP_LEFT( arg_node)); int r = INT_VALUE(BINOP_RIGHT( arg_node)); switch(BINOP_OP(arg_node)){ case BO_add: DBISNS(TBmakeInt(r+l)); break; case BO_sub: DBISNS(TBmakeInt(r-l)); break; case BO_mul: DBISNS(TBmakeInt(r*l)); break; case BO_div: if (r != 0) { DBISNS(TBmakeInt(l/r)); } break; case BO_mod: DBISNS(TBmakeInt(l % r)); break; case BO_lt: DBISNS(TBmakeBool(l < r)); break; case BO_le: DBISNS(TBmakeBool(l<=r)); break; case BO_gt: DBISNS(TBmakeBool(l>r)); break; case BO_ge: DBISNS(TBmakeBool(l>=r)); break; case BO_eq: DBISNS(TBmakeBool(l==r)); break; case BO_ne: DBISNS(TBmakeBool(l != r)); break; default: DBUG_RETURN (arg_node); break; } }else if(ntl == N_float){ float l = FLOAT_VALUE(BINOP_LEFT( arg_node)); float r = FLOAT_VALUE(BINOP_RIGHT( arg_node)); switch(BINOP_OP(arg_node)){ case BO_add: DBISNS(TBmakeFloat(r+l)); break; case BO_sub: DBISNS(TBmakeFloat(r-l)); break; case BO_mul: DBISNS(TBmakeFloat(r*l)); break; case BO_div: if (r != 0.0f) { DBISNS(TBmakeFloat(l/r)); } break; case BO_lt: DBISNS(TBmakeBool(l < r)); break; case BO_le: DBISNS(TBmakeBool(l<=r)); break; case BO_gt: DBISNS(TBmakeBool(l>r)); break; case BO_ge: DBISNS(TBmakeBool(l>=r)); break; case BO_eq: DBISNS(TBmakeBool(l==r)); break; case BO_ne: DBISNS(TBmakeBool(l != r)); break; default: DBUG_RETURN (arg_node); break; } } DBUG_RETURN (arg_node); }
node* CALCCONSTcast(node *arg_node, info *arg_info){ DBUG_ENTER ("CALCCONSTcast"); CAST_EXPR( arg_node) = TRAVopt( CAST_EXPR( arg_node), NULL); node * ret; switch(NODE_TYPE(CAST_EXPR( arg_node))){ case N_bool: switch(CAST_TYPE(arg_node)){ case VT_bool: //no cast needed ret = CAST_EXPR( arg_node); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; case VT_int: //FREEcast(arg_node); ret = TBmakeInt((int)BOOL_VALUE(CAST_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; case VT_float: //FREEcast(arg_node); ret = TBmakeFloat((float)BOOL_VALUE(CAST_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; default: DBUG_RETURN(arg_node); } break; case N_int: switch(CAST_TYPE(arg_node)){ case VT_bool: ret =TBmakeBool(INT_VALUE(CAST_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; case VT_int: //no cast needed ret = CAST_EXPR( arg_node); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; case VT_float: ret =TBmakeFloat((float)INT_VALUE(CAST_EXPR( arg_node) )); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; default: DBUG_RETURN(arg_node); } break; case N_float: switch(CAST_TYPE(arg_node)){ case VT_bool: ret =TBmakeBool(FLOAT_VALUE(CAST_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; case VT_int: ret =TBmakeInt(FLOAT_VALUE(CAST_EXPR( arg_node))); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; case VT_float: //no cast needed ret = CAST_EXPR( arg_node); FREEdoFreeNode(arg_node); DBUG_RETURN(ret ); break; default: DBUG_RETURN(arg_node); } break; default: DBUG_RETURN(arg_node); } }