node *COPbinop (node *arg_node, info *arg_info) { DBUG_ENTER("COPbinop"); switch (BINOP_OP( arg_node)) { case BO_add: INFO_ADD( arg_info) = INFO_ADD( arg_info) + 1; break; case BO_sub: INFO_SUB( arg_info) = INFO_SUB( arg_info) + 1; break; case BO_mul: INFO_MUL( arg_info) = INFO_MUL( arg_info) + 1; break; case BO_div: INFO_DIV( arg_info) = INFO_DIV( arg_info) + 1; break; case BO_mod: INFO_MOD( arg_info) = INFO_MOD( arg_info) + 1; break; default: break; } /* * Extremely important: * we must continue to traverse the abstract syntax tree !! */ BINOP_LEFT( arg_node) = TRAVdo( BINOP_LEFT( arg_node), arg_info); BINOP_RIGHT( arg_node) = TRAVdo( BINOP_RIGHT( arg_node), arg_info); DBUG_RETURN( arg_node); }
/** <!--******************************************************************--> * * @fn CHKMbinop * * @brief Touched the node and its sons/attributes * * @param arg_node BinOp node to process * @param arg_info pointer to info structure * * @return processed node * ***************************************************************************/ node * CHKMbinop (node * arg_node, info * arg_info) { DBUG_ENTER ("CHKMbinop"); NODE_ERROR (arg_node) = CHKMTRAV (NODE_ERROR (arg_node), arg_info); BINOP_LEFT (arg_node) = CHKMTRAV (BINOP_LEFT (arg_node), arg_info); BINOP_RIGHT (arg_node) = CHKMTRAV (BINOP_RIGHT (arg_node), arg_info); DBUG_RETURN (arg_node); }
//check types of operands of binop and rewrite binop if neccessary node * CTbinop(node *arg_node, info *arg_info){ DBUG_ENTER("CTbinop"); node *leftexpr = BINOP_LEFT(arg_node); node *rightexpr = BINOP_RIGHT(arg_node); //compare types of operands BINOP_LEFT(arg_node) = TRAVdo(BINOP_LEFT(arg_node), arg_info); type typeleft = INFO_TYPE(arg_info); BINOP_RIGHT(arg_node) = TRAVdo(BINOP_RIGHT(arg_node), arg_info); type typeright = INFO_TYPE(arg_info); if(typeleft != typeright){ CTIerrorLine(NODE_LINE(arg_node), "Types of left and right expressions of the binop do not match"); } //check if the right type of operands are used with the right operators if((BINOP_OP(arg_node) == BO_and || BINOP_OP(arg_node) == BO_or)&&INFO_TYPE(arg_info)!=T_boolean){ CTIerrorLine(NODE_LINE(arg_node), "The used &&(and) or ||(or) operator can only compare two booleans"); } if((BINOP_OP(arg_node) == BO_lt || BINOP_OP(arg_node) == BO_le ||BINOP_OP(arg_node) == BO_gt || BINOP_OP(arg_node) == BO_ge) && INFO_TYPE(arg_info) == T_boolean){ CTIerrorLine(NODE_LINE(arg_node), "The used operator can only compare two integers or floats"); } if(BINOP_OP(arg_node) == BO_add ||BINOP_OP(arg_node) == BO_mul ||BINOP_OP(arg_node) == BO_sub ||BINOP_OP(arg_node) == BO_div || BINOP_OP(arg_node) == BO_mod ){ BINOP_OPTYPE(arg_node) = typeleft; } //set info_type to boolean if(BINOP_OP(arg_node) == BO_lt || BINOP_OP(arg_node) == BO_le ||BINOP_OP(arg_node) == BO_gt || BINOP_OP(arg_node) == BO_ge || BINOP_OP(arg_node) == BO_eq || BINOP_OP(arg_node) == BO_ne || BINOP_OP(arg_node) == BO_and || BINOP_OP(arg_node) == BO_or){ INFO_TYPE(arg_info) = T_boolean; BINOP_OPTYPE(arg_node) = typeleft; } else{ BINOP_OPTYPE(arg_node) = typeleft; } //rewrite and if(BINOP_OP(arg_node)==BO_and){ node *then = TBmakeBool(0); arg_node = TBmakeConditionexpr(leftexpr, then, rightexpr); } //rewrite or else if(BINOP_OP(arg_node) == BO_or){ node *orthen = TBmakeBool(1); arg_node = TBmakeConditionexpr(leftexpr, rightexpr, orthen); } DBUG_RETURN(arg_node); }
/** <!--******************************************************************--> * * @fn COPYbinop * * @brief Copies the node and its sons/attributes * * @param arg_node BinOp node to process * @param arg_info pointer to info structure * * @return processed node * ***************************************************************************/ node * COPYbinop (node * arg_node, info * arg_info) { node *result = TBmakeBinop (BO_unknown, NULL, NULL); DBUG_ENTER ("COPYbinop"); LUTinsertIntoLutP (INFO_LUT (arg_info), arg_node, result); /* Copy attributes */ BINOP_OP (result) = BINOP_OP (arg_node); /* Copy sons */ BINOP_LEFT (result) = COPYTRAV (BINOP_LEFT (arg_node), arg_info); BINOP_RIGHT (result) = COPYTRAV (BINOP_RIGHT (arg_node), arg_info); /* Return value */ DBUG_RETURN (result); }
node *OSbinop (node *arg_node, info *arg_info) { DBUG_ENTER("OSbinop"); /* * Extremely important: * we must continue to traverse the abstract syntax tree !! */ BINOP_LEFT( arg_node) = TRAVdo( BINOP_LEFT( arg_node), arg_info); BINOP_RIGHT( arg_node) = TRAVdo( BINOP_RIGHT( arg_node), arg_info); if (BINOP_OP( arg_node) == BO_sub) { if ((NODE_TYPE( BINOP_LEFT( arg_node)) == N_var) && (NODE_TYPE( BINOP_RIGHT( arg_node)) == N_var) && STReq( VAR_NAME( BINOP_LEFT( arg_node)), VAR_NAME( BINOP_RIGHT( arg_node)))) { arg_node = FREEdoFreeTree( arg_node); arg_node = TBmakeNum( 0); } else if ((NODE_TYPE( BINOP_LEFT( arg_node)) == N_num) && (NODE_TYPE( BINOP_RIGHT( arg_node)) == N_num) && (NUM_VALUE( BINOP_LEFT( arg_node)) == NUM_VALUE( BINOP_RIGHT( arg_node)))) { arg_node = FREEdoFreeTree( arg_node); arg_node = TBmakeNum( 0); } } DBUG_RETURN( arg_node); }
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 * PRTbinop (node * arg_node, info * arg_info) { char *tmp; DBUG_ENTER ("PRTbinop"); printf( "( "); BINOP_LEFT( arg_node) = TRAVdo( BINOP_LEFT( arg_node), arg_info); switch (BINOP_OP( arg_node)) { case BO_add: tmp = "+"; break; case BO_sub: tmp = "-"; break; case BO_mul: tmp = "*"; break; case BO_div: tmp = "/"; break; case BO_mod: tmp = "%"; break; case BO_lt: tmp = "<"; break; case BO_le: tmp = "<="; break; case BO_gt: tmp = ">"; break; case BO_ge: tmp = ">="; break; case BO_eq: tmp = "=="; break; case BO_ne: tmp = "!="; break; case BO_or: tmp = "||"; break; case BO_and: tmp = "&&"; break; case BO_unknown: DBUG_ASSERT( 0, "unknown binop detected!"); } printf( " %s ", tmp); BINOP_RIGHT( arg_node) = TRAVdo( BINOP_RIGHT( arg_node), arg_info); printf( ")"); DBUG_RETURN (arg_node); }