parse/specialize.c
/*
 * Takes a generic declaration, and creates a specialized
 * duplicate of it with type 'to'. It also generates
 * a name for this specialized node, and returns it in '*name'.
 */
Takes a generic declaration, and creates a specialized
duplicate of it with type 'to'. It also generates
a name for this specialized node, and returns it in '*name'.
Takes a generic declaration and creates a specialized duplicate of it with type ' to ' . It also generates a name for this specialized node and returns it in ' * name ' .
Node *specializedcl(Node *g, Type *to, Node **name)
{
    extern int stabstkoff;
    Node *d, *n;
    Htab *tsmap;
    Stab *st;
    assert(g->type == Ndecl);
    assert(g->decl.isgeneric);
    n = genericname(g, to);
    *name = n;
    if (n->name.ns)
        st = getns(file, n->name.ns);
    else
        st = file->file.globls;
    if (!st)
        fatal(n, "Can't find symbol table for %s.%s", n->name.ns, n->name.name);
    d = getdcl(st, n);
    if (debugopt['S'])
        printf("depth[%d] specializing [%d]%s => %s\n", stabstkoff, g->loc.line, namestr(g->decl.name), namestr(n));
    if (d)
        return d;
    if (g->decl.trait) {
        printf("%s\n", namestr(n));
        fatal(g, "No trait implemented for for %s:%s", namestr(g->decl.name), tystr(to));
    }
    if (n->name.ns)
        pushstab(st);
    tsmap = mkht(tyhash, tyeq);
    fillsubst(tsmap, to, g->decl.type);
    d = mkdecl(g->loc, n, tysubst(g->decl.type, tsmap));
    d->decl.isconst = g->decl.isconst;
    d->decl.isextern = g->decl.isextern;
    d->decl.isglobl = g->decl.isglobl;
    d->decl.init = specializenode(g->decl.init, tsmap);
    putdcl(st, d);
    fixup(d);
    lappend(&file->file.stmts, &file->file.nstmts, d);
    if (d->decl.name->name.ns)
        popstab();
    return d;
}
Node * specializedcl ( Node * g , Type * to , Node * * name ) { extern int stabstkoff ; Node * d , * n ; Htab * tsmap ; Stab * st ; assert ( g -> type == Ndecl ) ; assert ( g -> decl . isgeneric ) ; n = genericname ( g , to ) ; * name = n ; if ( n -> name . ns ) st = getns ( file , n -> name . ns ) ; else st = file -> file . globls ; if ( ! st ) fatal ( n , " " , n -> name . ns , n -> name . name ) ; d = getdcl ( st , n ) ; if ( debugopt [ ' ' ] ) printf ( " \n " , stabstkoff , g -> loc . line , namestr ( g -> decl . name ) , namestr ( n ) ) ; if ( d ) return d ; if ( g -> decl . trait ) { printf ( " \n " , namestr ( n ) ) ; fatal ( g , " " , namestr ( g -> decl . name ) , tystr ( to ) ) ; } if ( n -> name . ns ) pushstab ( st ) ; tsmap = mkht ( tyhash , tyeq ) ; fillsubst ( tsmap , to , g -> decl . type ) ; d = mkdecl ( g -> loc , n , tysubst ( g -> decl . type , tsmap ) ) ; d -> decl . isconst = g -> decl . isconst ; d -> decl . isextern = g -> decl . isextern ; d -> decl . isglobl = g -> decl . isglobl ; d -> decl . init = specializenode ( g -> decl . init , tsmap ) ; putdcl ( st , d ) ; fixup ( d ) ; lappend ( & file -> file . stmts , & file -> file . nstmts , d ) ; if ( d -> decl . name -> name . ns ) popstab ( ) ; return d ; }
Takes a generic declaration, and creates a specialized
 duplicate of it with type 'to'.
Takes a generic declaration and creates a specialized duplicate of it with type ' to ' .
/* namespaced names need to be looked up in their correct
     * context. */ /* specialize */