parse/specialize.c
/*
 * Fixes up nodes. This involves fixing up the
 * declaration identifiers once we specialize
 */
Fixes up nodes. This involves fixing up the
declaration identifiers once we specialize
Fixes up nodes . This involves fixing up the declaration identifiers once we specialize
static void fixup(Node *n)
{
    size_t i;
    Node *d;
    Stab *ns;
    if (!n)
        return;
    switch (n->type) {
        case Nfile:
        case Nuse:
            die("Node %s not allowed here\n", nodestr[n->type]);
            break;
        case Nexpr:
            fixup(n->expr.idx);
            for (i = 0; i < n->expr.nargs; i++)
                fixup(n->expr.args[i]);
            if (n->expr.op == Ovar) {
                ns = curstab();
                if (n->expr.args[0]->name.ns)
                    ns = getns(file, n->expr.args[0]->name.ns);
                if (!ns)
                    fatal(n, "No namespace %s\n", n->expr.args[0]->name.ns);
                d = getdcl(ns, n->expr.args[0]);
                if (!d)
                    die("Missing decl %s", namestr(n->expr.args[0]));
                if (d->decl.isgeneric)
                    d = specializedcl(d, n->expr.type, &n->expr.args[0]);
                n->expr.did = d->decl.did;
            }
            break;
        case Nlit:
            switch (n->lit.littype) {
                case Lfunc:     fixup(n->lit.fnval);          break;
                case Lchr: case Lint: case Lflt:
                case Lstr: case Llbl: case Lbool:
                    break;
            }
            break;
        case Nifstmt:
            fixup(n->ifstmt.cond);
            fixup(n->ifstmt.iftrue);
            fixup(n->ifstmt.iffalse);
            break;
        case Nloopstmt:
            pushstab(n->loopstmt.scope);
            fixup(n->loopstmt.init);
            fixup(n->loopstmt.cond);
            fixup(n->loopstmt.step);
            fixup(n->loopstmt.body);
            popstab();
            break;
        case Niterstmt:
            pushstab(n->iterstmt.body->block.scope);
            fixup(n->iterstmt.elt);
            popstab();
            fixup(n->iterstmt.seq);
            fixup(n->iterstmt.body);
            break;
        case Nmatchstmt:
            fixup(n->matchstmt.val);
            for (i = 0; i < n->matchstmt.nmatches; i++)
                fixup(n->matchstmt.matches[i]);
            break;
        case Nmatch:
            pushstab(n->match.block->block.scope);
            fixup(n->match.pat);
            popstab();
            fixup(n->match.block);
            break;
        case Nblock:
            pushstab(n->block.scope);
            for (i = 0; i < n->block.nstmts; i++)
                fixup(n->block.stmts[i]);
            popstab();
            break;
        case Ndecl:
            fixup(n->decl.init);
            break;
        case Nfunc:
            pushstab(n->func.scope);
            fixup(n->func.body);
            popstab();
            break;
        case Nnone: case Nname:
            break;
        case Nimpl:
            die("trait/impl not implemented");
            break;
    }
}
static void fixup ( Node * n ) { size_t i ; Node * d ; Stab * ns ; if ( ! n ) return ; switch ( n -> type ) { case Nfile : case Nuse : die ( " \n " , nodestr [ n -> type ] ) ; break ; case Nexpr : fixup ( n -> expr . idx ) ; for ( i = 0 ; i < n -> expr . nargs ; i ++ ) fixup ( n -> expr . args [ i ] ) ; if ( n -> expr . op == Ovar ) { ns = curstab ( ) ; if ( n -> expr . args [ 0 ] -> name . ns ) ns = getns ( file , n -> expr . args [ 0 ] -> name . ns ) ; if ( ! ns ) fatal ( n , " \n " , n -> expr . args [ 0 ] -> name . ns ) ; d = getdcl ( ns , n -> expr . args [ 0 ] ) ; if ( ! d ) die ( " " , namestr ( n -> expr . args [ 0 ] ) ) ; if ( d -> decl . isgeneric ) d = specializedcl ( d , n -> expr . type , & n -> expr . args [ 0 ] ) ; n -> expr . did = d -> decl . did ; } break ; case Nlit : switch ( n -> lit . littype ) { case Lfunc : fixup ( n -> lit . fnval ) ; break ; case Lchr : case Lint : case Lflt : case Lstr : case Llbl : case Lbool : break ; } break ; case Nifstmt : fixup ( n -> ifstmt . cond ) ; fixup ( n -> ifstmt . iftrue ) ; fixup ( n -> ifstmt . iffalse ) ; break ; case Nloopstmt : pushstab ( n -> loopstmt . scope ) ; fixup ( n -> loopstmt . init ) ; fixup ( n -> loopstmt . cond ) ; fixup ( n -> loopstmt . step ) ; fixup ( n -> loopstmt . body ) ; popstab ( ) ; break ; case Niterstmt : pushstab ( n -> iterstmt . body -> block . scope ) ; fixup ( n -> iterstmt . elt ) ; popstab ( ) ; fixup ( n -> iterstmt . seq ) ; fixup ( n -> iterstmt . body ) ; break ; case Nmatchstmt : fixup ( n -> matchstmt . val ) ; for ( i = 0 ; i < n -> matchstmt . nmatches ; i ++ ) fixup ( n -> matchstmt . matches [ i ] ) ; break ; case Nmatch : pushstab ( n -> match . block -> block . scope ) ; fixup ( n -> match . pat ) ; popstab ( ) ; fixup ( n -> match . block ) ; break ; case Nblock : pushstab ( n -> block . scope ) ; for ( i = 0 ; i < n -> block . nstmts ; i ++ ) fixup ( n -> block . stmts [ i ] ) ; popstab ( ) ; break ; case Ndecl : fixup ( n -> decl . init ) ; break ; case Nfunc : pushstab ( n -> func . scope ) ; fixup ( n -> func . body ) ; popstab ( ) ; break ; case Nnone : case Nname : break ; case Nimpl : die ( " " ) ; break ; } }
Fixes up nodes.
Fixes up nodes .
/* patterns are evaluated in their block's scope */