int number_of_parameters() { switch(rel_type()) { case RT_VM: return 1; case RT_DLSYM: return 2; case RT_ENTRY_POINT: case RT_ENTRY_POINT_PIC: case RT_ENTRY_POINT_PIC_TAIL: case RT_LITERAL: case RT_HERE: case RT_UNTAGGED: case RT_THIS: case RT_MEGAMORPHIC_CACHE_HITS: case RT_CARDS_OFFSET: case RT_DECKS_OFFSET: case RT_EXCEPTION_HANDLER: return 0; default: critical_error("Bad rel type",rel_type()); return -1; /* Can't happen */ } }
PUBLIC type tc_expr(tree t, env e) #endif { switch (t->x_kind) { case REF: return ref_type((sym) t->x_tag, t->x_params, e, t); case INGEN: return ref_type((sym) t->x_tag, list2(t->x_param1, t->x_param2), e, t); case PREGEN: return ref_type((sym) t->x_tag, list1(t->x_param), e, t); case NUMBER: return nat_type; case SEXPR: { def d; frame params; if (! open_sref(t->x_ref, e, &d, ¶ms)) return err_type; if ((tok) t->x_ref->x_sref_decor != empty) { tc_error(t->x_loc, "Decoration ignored in schema reference"); tc_e_etc("Expression: %z", t); tc_e_end(); } if (t->x_ref->x_sref_renames != nil) { tc_error(t->x_loc, "Renaming ignored in schema reference"); tc_e_etc("Expression: %z", t); tc_e_end(); } if (! aflag && d->d_abbrev) return mk_power(mk_abbrev(d, params)); else return mk_power(seal(mk_sproduct(d->d_schema), params)); } case POWER: { type tt1, tt2; if (! anal_power(tt1 = tc_expr(t->x_arg, e), &tt2, t->x_arg)) { tc_error(t->x_loc, "Argument of \\power must be a set"); tc_e_etc("Expression: %z", t); tc_e_etc("Arg type: %t", tt1); tc_e_end(); } return mk_power(mk_power(tt2)); } case TUPLE : { type a[MAX_ARGS]; int n = 0; tree u; for (u = t->x_elements; u != nil; u = cdr(u)) { if (n >= MAX_ARGS) panic("tc_expr - tuple too big"); a[n++] = tc_expr(car(u), e); } return mk_cproduct(n, a); } case CROSS: { type a[MAX_ARGS]; type tt1, tt2; int n = 0; tree u; for (u = t->x_factors; u != nil; u = cdr(u)) { if (n >= MAX_ARGS) panic("tc_expr - product too big"); tt1 = tc_expr(car(u), e); if (! anal_power(tt1, &tt2, car(u))) { tc_error(t->x_loc, "Argument %d of \\cross must be a set", n+1); tc_e_etc("Expression: %z", t); tc_e_etc("Arg %d type: %t", n+1, tt1); tc_e_end(); } a[n++] = tt2; } return mk_power(mk_cproduct(n, a)); } case EXT: case SEQ: case BAG: { type elem_type; type tt; tree u; if (t->x_elements == nil) elem_type = new_typevar(t); else { elem_type = tc_expr(car(t->x_elements), e); for (u = cdr(t->x_elements); u != nil; u = cdr(u)) { if (unify(elem_type, tt = tc_expr(car(u), e))) elem_type = type_union(elem_type, arid, tt, arid); else { tc_error(t->x_loc, "Type mismatch in %s display", (t->x_kind == EXT ? "set" : t->x_kind == SEQ ? "sequence" : "bag")); tc_e_etc("Expression: %z", car(u)); tc_e_etc("Has type: %t", tt); tc_e_etc("Expected: %t", elem_type); tc_e_end(); } } } switch (t->x_kind) { case EXT: return mk_power(elem_type); case SEQ: return (aflag ? rel_type(num_type, elem_type) : mk_seq(elem_type)); case BAG: return (aflag ? rel_type(elem_type, num_type) : mk_bag(elem_type)); } } case THETA: return theta_type(t, e, (type) NULL, t); case BINDING: { tree u; env e1 = new_env(e); for (u = t->x_elements; u != nil; u = cdr(u)) add_def(VAR, (sym) car(u)->x_lhs, tc_expr(car(u)->x_rhs, e), e1); return mk_sproduct(mk_schema(e1)); } case SELECT: { type a = tc_expr(t->x_arg, e); if (type_kind(a) != SPRODUCT) { tc_error(t->x_loc, "Argument of selection must have schema type"); tc_e_etc("Expression: %z", t); tc_e_etc("Arg type: %t", a); tc_e_end(); mark_error(); return err_type; } switch (t->x_field->x_kind) { case IDENT: return (comp_type(a, (sym) t->x_field, t, t->x_loc)); case THETA: return (theta_type(t->x_field, e, a, t)); default: bad_tag("tc_expr.SELECT", t->x_field->x_kind); return (type) NULL; } } case APPLY: return tc_apply(APPLY, t, t->x_arg1, t->x_arg2, e); case INOP: return tc_apply(INOP, t, simply(t->x_op, t->x_loc), pair(t->x_rand1, t->x_rand2), e); case POSTOP: return tc_apply(POSTOP, t, simply(t->x_op, t->x_loc), t->x_rand, e); case LAMBDA: { env e1 = tc_schema(t->x_bvar, e); type dom = tc_expr(char_tuple(t->x_bvar), e1); type ran = tc_expr(t->x_body, e1); return (aflag ? rel_type(dom, ran) : mk_pfun(dom, ran)); } case COMP: case MU: { env e1 = tc_schema(t->x_bvar, e); type a = tc_expr(exists(t->x_body) ? the(t->x_body) : char_tuple(t->x_bvar), e1); return (t->x_kind == COMP ? mk_power(a) : a); } case LETEXPR: return tc_expr(t->x_body, tc_letdefs(t->x_defs, e)); case IF: { type a, b; tc_pred(t->x_if, e); a = tc_expr(t->x_then, e); b = tc_expr(t->x_else, e); if (unify(a, b)) return type_union(a, arid, b, arid); else { tc_error(t->x_loc, "Type mismatch in conditional expression"); tc_e_etc("Expression: %z", t); tc_e_etc("Then type: %t", a); tc_e_etc("Else type: %t", b); tc_e_end(); return err_type; } } default: bad_tag("tc_expr", t->x_kind); /* dummy */ return (type) NULL; } }