static bool names_typealias(pass_opt_t* opt, ast_t** astp, ast_t* def) { ast_t* ast = *astp; AST_GET_CHILDREN(ast, pkg, id, typeargs, cap, eph); // Make sure the alias is resolved, AST_GET_CHILDREN(def, alias_id, typeparams, def_cap, provides); ast_t* alias = ast_child(provides); if(!names_resolvealias(opt, def, &alias)) return false; // Reify the alias. ast_t* r_alias = reify(typeparams, alias, typeparams, typeargs); if(r_alias == NULL) return false; // Apply our cap and ephemeral to the result. if(!names_applycap(r_alias, cap, eph)) { ast_free_unattached(r_alias); return false; } // Maintain the position info of the original reference to aid error // reporting. ast_setpos(r_alias, ast_line(ast), ast_pos(ast)); // Replace this with the alias. ast_replace(astp, r_alias); return true; }
static void setup_type_fields(gentype_t* g) { assert(ast_id(g->ast) == TK_NOMINAL); g->field_count = 0; g->fields = NULL; g->field_keys = NULL; ast_t* def = (ast_t*)ast_data(g->ast); if(ast_id(def) == TK_PRIMITIVE) return; ast_t* typeargs = ast_childidx(g->ast, 2); ast_t* typeparams = ast_childidx(def, 1); ast_t* members = ast_childidx(def, 4); ast_t* member = ast_child(members); while(member != NULL) { switch(ast_id(member)) { case TK_FVAR: case TK_FLET: case TK_EMBED: { g->field_count++; break; } default: {} } member = ast_sibling(member); } if(g->field_count == 0) return; g->fields = (ast_t**)calloc(g->field_count, sizeof(ast_t*)); g->field_keys = (token_id*)calloc(g->field_count, sizeof(token_id)); member = ast_child(members); size_t index = 0; while(member != NULL) { switch(ast_id(member)) { case TK_FVAR: case TK_FLET: case TK_EMBED: { AST_GET_CHILDREN(member, name, type, init); g->fields[index] = reify(ast_type(member), typeparams, typeargs); // TODO: Are we sure the AST source file is correct? ast_setpos(g->fields[index], NULL, ast_line(name), ast_pos(name)); g->field_keys[index] = ast_id(member); index++; break; } default: {} } member = ast_sibling(member); } }
static void add_fields(reach_t* r, reach_type_t* t, pass_opt_t* opt) { ast_t* def = (ast_t*)ast_data(t->ast); ast_t* typeargs = ast_childidx(t->ast, 2); ast_t* typeparams = ast_childidx(def, 1); ast_t* members = ast_childidx(def, 4); ast_t* member = ast_child(members); while(member != NULL) { switch(ast_id(member)) { case TK_FVAR: case TK_FLET: case TK_EMBED: { t->field_count++; break; } default: {} } member = ast_sibling(member); } if(t->field_count == 0) return; t->fields = (reach_field_t*)calloc(t->field_count, sizeof(reach_field_t)); member = ast_child(members); size_t index = 0; while(member != NULL) { switch(ast_id(member)) { case TK_FVAR: case TK_FLET: case TK_EMBED: { ast_t* r_member = lookup(NULL, NULL, t->ast, ast_name(ast_child(member))); assert(r_member != NULL); AST_GET_CHILDREN(r_member, name, type, init); t->fields[index].embed = ast_id(member) == TK_EMBED; t->fields[index].ast = reify(ast_type(member), typeparams, typeargs, opt, true); ast_setpos(t->fields[index].ast, NULL, ast_line(name), ast_pos(name)); t->fields[index].type = add_type(r, type, opt); if(r_member != member) ast_free_unattached(r_member); index++; break; } default: {} } member = ast_sibling(member); } }