/** * Return clast_expr corresponding to the variable "level" (1 based) in * the given constraint. */ struct clast_expr *cloog_constraint_variable_expr(CloogConstraint *constraint, int level, CloogNames *names) { struct cloog_isl_dim dim; const char *name; assert(constraint); dim = constraint_cloog_dim_to_isl_dim(constraint, level - 1); if (dim.type == isl_dim_div) return div_expr(constraint, dim.pos, names); if (dim.type == isl_dim_set) name = cloog_names_name_at_level(names, level); else name = names->parameters[dim.pos]; return &new_clast_name(name)->expr; }
void eval_expr(expr *in, expr *out, symtab *table) { switch (in->type) { case NOTHING: break; case INTEGER: case REAL: case STRING: out->type = in->type; out->val = in->val; return; case INT_VAR: { int n; if (lookup_int(in->val.string, table, &n)) { out->type = INTEGER; out->val.integer = n; return; } else { fprintf(stderr, "undefined integer variable '%s'\n", in->val.string); exit(1); } } break; case REAL_VAR: { double d; if (lookup_real(in->val.string, table, &d)) { out->type = REAL; out->val.real = d; return; } else { fprintf(stderr, "undefined real variable '%s'\n", in->val.string); exit(1); } } break; case STR_VAR: { char *s = (char *)malloc(MAX_LINE); if (lookup_str(in->val.string, table, &s)) { out->type = STRING; out->val.string = s; return; } else { fprintf(stderr, "undefined string variable '%s'\n", in->val.string); exit(1); } } break; } switch (in->op) { case NOTHING: fprintf(stderr, "No operation for non-constant expression\n"); exit(1); case ADD: add_expr(in, out, table); break; case SUB: sub_expr(in, out, table); break; case EXPT: pow_expr(in, out, table); break; case MUL: mul_expr(in, out, table); break; case DIV: div_expr(in, out, table); break; case LT: eval_expr(in->arg1, out->arg1, table); eval_expr(in->arg2, out->arg2, table); out->type = INTEGER; out->val.integer = compare(out->arg1, out->arg2, LT); break; case LE: eval_expr(in->arg1, out->arg1, table); eval_expr(in->arg2, out->arg2, table); out->type = INTEGER; out->val.integer = compare(out->arg1, out->arg2, LE); break; case EQ: eval_expr(in->arg1, out->arg1, table); eval_expr(in->arg2, out->arg2, table); out->type = INTEGER; out->val.integer = compare(out->arg1, out->arg2, EQ); break; case GE: eval_expr(in->arg1, out->arg1, table); eval_expr(in->arg2, out->arg2, table); out->type = INTEGER; out->val.integer = compare(out->arg1, out->arg2, GE); break; case GT: eval_expr(in->arg1, out->arg1, table); eval_expr(in->arg2, out->arg2, table); out->type = INTEGER; out->val.integer = compare(out->arg1, out->arg2, GT); break; case NE: eval_expr(in->arg1, out->arg1, table); eval_expr(in->arg2, out->arg2, table); out->type = INTEGER; out->val.integer = compare(out->arg1, out->arg2, NE); break; /* Numerical functions */ case RAND: { expr arg; eval_expr(in->arg1, &arg, table); out->type = INTEGER; out->val.integer = rand() % arg.val.integer; } break; case SQRT: { expr arg; eval_expr(in->arg1, &arg, table); out->type = REAL; out->val.real = sqrt(arg.type == REAL ? arg.val.real : (double)arg.val.integer); } break; /* Casting */ case CEIL: { expr arg; eval_expr(in->arg1, &arg, table); out->type = INTEGER; out->val.integer = (int)ceil(arg.val.real); } break; case FLOOR: { expr arg; eval_expr(in->arg1, &arg, table); out->type = INTEGER; out->val.integer = (int)floor(arg.val.real); } break; case REAL_CAST: { expr arg; eval_expr(in->arg1, &arg, table); out->type = REAL; out->val.real = (double)arg.val.integer; } break; case ROUND: { expr arg; eval_expr(in->arg1, &arg, table); out->type = INTEGER; out->val.integer = (int)round(arg.val.real); } break; default: fprintf(stderr, "unrecognised operation\n"); exit(1); } }