ast_t* viewpoint_type(ast_t* l_type, ast_t* r_type) { switch(ast_id(l_type)) { case TK_TUPLETYPE: case TK_UNIONTYPE: case TK_ISECTTYPE: { // Only occurs in codegen. return r_type; } case TK_NOMINAL: { if(ast_id(r_type) == TK_ARROW) return make_arrow_type(l_type, r_type); AST_GET_CHILDREN(l_type, pkg, id, typeargs, cap, eph); token_id tcap = ast_id(cap); if(tcap == TK_CAP_READ) return make_arrow_type(l_type, r_type); return viewpoint_cap(tcap, ast_id(eph), r_type); } case TK_TYPEPARAMREF: { if(ast_id(r_type) == TK_ARROW) return make_arrow_type(l_type, r_type); AST_GET_CHILDREN(l_type, id, cap, eph); token_id tcap = ast_id(cap); if(tcap == TK_CAP_READ) return make_arrow_type(l_type, r_type); return viewpoint_cap(tcap, ast_id(eph), r_type); } case TK_ARROW: case TK_BOXTYPE: case TK_THISTYPE: return make_arrow_type(l_type, r_type); default: {} } return NULL; }
ast_t* viewpoint_type(ast_t* l_type, ast_t* r_type) { switch(ast_id(l_type)) { case TK_TUPLETYPE: case TK_UNIONTYPE: case TK_ISECTTYPE: { // Only occurs in codegen. return r_type; } case TK_NOMINAL: { if(ast_id(r_type) == TK_ARROW) return make_arrow_type(l_type, r_type); AST_GET_CHILDREN(l_type, pkg, id, typeargs, cap, eph); return viewpoint_cap(ast_id(cap), ast_id(eph), r_type); } case TK_TYPEPARAMREF: { if(ast_id(r_type) == TK_ARROW) return make_arrow_type(l_type, r_type); // If the left side is a type parameter, return an arrow type if the // capability is box, otherwise adapt the type. AST_GET_CHILDREN(l_type, id, cap, eph); token_id tcap = ast_id(cap); if(tcap == TK_BOX_GENERIC) return make_arrow_type(l_type, r_type); return viewpoint_cap(tcap, ast_id(eph), r_type); } case TK_ARROW: case TK_BOXTYPE: case TK_THISTYPE: return make_arrow_type(l_type, r_type); default: {} } return NULL; }
static ast_t* make_arrow_type(ast_t* left, ast_t* right) { switch(ast_id(right)) { case TK_UNIONTYPE: case TK_ISECTTYPE: case TK_TUPLETYPE: { ast_t* type = ast_from(right, ast_id(right)); ast_t* child = ast_child(right); while(child != NULL) { ast_append(type, make_arrow_type(left, child)); child = ast_sibling(child); } return type; } case TK_NOMINAL: case TK_TYPEPARAMREF: { switch(cap_single(right)) { case TK_VAL: case TK_TAG: return right; default: {} } return make_single_arrow(left, right); } case TK_ARROW: return make_single_arrow(left, right); default: {} } assert(0); return NULL; }