ast_result_t pass_flatten(ast_t** astp, pass_opt_t* options) { typecheck_t* t = &options->check; ast_t* ast = *astp; switch(ast_id(ast)) { case TK_NEW: { switch(ast_id(t->frame->type)) { case TK_CLASS: return flatten_constructor(ast); case TK_ACTOR: return flatten_async(ast); default: {} } break; } case TK_BE: return flatten_async(ast); case TK_UNIONTYPE: if(!flatten_union(astp)) return AST_ERROR; break; case TK_ISECTTYPE: if(!flatten_isect(astp)) return AST_ERROR; break; case TK_TUPLETYPE: case TK_ARROW: return flatten_noconstraint(t, ast); case TK_TYPEPARAMREF: return flatten_typeparamref(ast); default: {} } return AST_OK; }
ast_result_t pass_flatten(ast_t** astp, pass_opt_t* options) { ast_t* ast = *astp; switch(ast_id(ast)) { case TK_UNIONTYPE: return flatten_union(options, ast); case TK_ISECTTYPE: return flatten_isect(options, ast); case TK_NEW: { switch(ast_id(options->check.frame->type)) { case TK_CLASS: return flatten_constructor(options, ast); case TK_ACTOR: return flatten_async(options, ast); default: {} } break; } case TK_BE: return flatten_async(options, ast); case TK_ARROW: return flatten_arrow(options, astp); case TK_TYPEPARAMREF: return flatten_typeparamref(options, ast); case TK_EMBED: { // An embedded field must have a known, class type. AST_GET_CHILDREN(ast, id, type, init); bool ok = true; if(ast_id(type) != TK_NOMINAL) ok = false; ast_t* def = (ast_t*)ast_data(type); if(def == NULL) { ok = false; } else { switch(ast_id(def)) { case TK_STRUCT: case TK_CLASS: break; default: ok = false; break; } } if(!ok) { ast_error(options->check.errors, type, "embedded fields must be classes or structs"); return AST_ERROR; } if(cap_single(type) == TK_TAG) { ast_error(options->check.errors, type, "embedded fields cannot be tag"); return AST_ERROR; } return AST_OK; } case TK_ACTOR: case TK_CLASS: case TK_STRUCT: case TK_PRIMITIVE: case TK_TRAIT: case TK_INTERFACE: return flatten_provides_list(options, ast, 3); default: {} } return AST_OK; }