int expr_is_constant(struct expr *e){ if(!e) return 1; //null is a constant expression if(expr_is_constant(e->left) == 0) return 0; if(expr_is_constant(e->right) == 0) return 0; if(e->kind == EXPR_IDENT) return 0; else return 1; }
int expr_is_constant(struct expr *e) { if (!e) return 1; if (e->kind == EXPR_VARIABLE || e->kind == EXPR_INCR || e->kind == EXPR_DECR || e->kind == EXPR_FUNCTION_CALL) return 0; return (expr_is_constant(e->left) && expr_is_constant(e->right)); }
/* Check for and simplify identities. Returns new number of expr terms. * Sets e->op = EXPR_IDENT if numterms ends up being 1. * Uses numterms parameter instead of e->numterms for basis of "new" number * of terms. * Assumes int_term is *only* integer term in e. * NOTE: Really designed to only be used by expr_level_op(). */ static int expr_simplify_identity(yasm_expr *e, int numterms, int *int_term, int simplify_reg_mul) { int i; int save_numterms; /* Don't do this step if it's 1*REG. Save and restore numterms so * yasm_expr__contains() works correctly. */ save_numterms = e->numterms; e->numterms = numterms; if (simplify_reg_mul || e->op != YASM_EXPR_MUL || !yasm_intnum_is_pos1(e->terms[*int_term].data.intn) || !yasm_expr__contains(e, YASM_EXPR_REG)) { /* Check for simple identities that delete the intnum. * Don't delete if the intnum is the only thing in the expn. */ if ((*int_term == 0 && numterms > 1 && expr_can_destroy_int_left(e->op, e->terms[0].data.intn)) || (*int_term > 0 && expr_can_destroy_int_right(e->op, e->terms[*int_term].data.intn))) { /* Delete the intnum */ yasm_intnum_destroy(e->terms[*int_term].data.intn); /* Slide everything to its right over by 1 */ if (*int_term != numterms-1) /* if it wasn't last.. */ memmove(&e->terms[*int_term], &e->terms[*int_term+1], (numterms-1-*int_term)*sizeof(yasm_expr__item)); /* Update numterms */ numterms--; *int_term = -1; /* no longer an int term */ } } e->numterms = save_numterms; /* Check for simple identites that delete everything BUT the intnum. * Don't bother if the intnum is the only thing in the expn. */ if (numterms > 1 && *int_term != -1 && expr_is_constant(e->op, e->terms[*int_term].data.intn)) { /* Loop through, deleting everything but the integer term */ for (i=0; i<e->numterms; i++) if (i != *int_term) expr_delete_term(&e->terms[i], 1); /* Move integer term to the first term (if not already there) */ if (*int_term != 0) e->terms[0] = e->terms[*int_term]; /* structure copy */ /* Set numterms to 1 */ numterms = 1; } /* Compute NOT, NEG, and LNOT on single intnum. */ if (numterms == 1 && *int_term == 0 && (e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG || e->op == YASM_EXPR_LNOT)) yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL); /* Change expression to IDENT if possible. */ if (numterms == 1) e->op = YASM_EXPR_IDENT; /* Return the updated numterms */ return numterms; }