diff options
| author | Ken Thompson <ken@golang.org> | 2009-09-07 17:36:47 -0700 |
|---|---|---|
| committer | Ken Thompson <ken@golang.org> | 2009-09-07 17:36:47 -0700 |
| commit | 0421cf072e275534a21790630081ff498e682016 (patch) | |
| tree | ca5f439685095f8ef7bb267e2a21039994837acc /src/cmd | |
| parent | a24a26c10727304cde89ad7b17f535bb4a2b3e46 (diff) | |
| download | go-0421cf072e275534a21790630081ff498e682016.tar.xz | |
maps in static initialization
R=rsc
OCL=34434
CL=34434
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/gc/walk.c | 127 |
1 files changed, 124 insertions, 3 deletions
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 061d8b966c..c3fbdb7f04 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -2158,10 +2158,13 @@ void maplit(Node *n, Node *var, NodeList **init) { Node *r, *a; - Node* hash[101]; NodeList *l; - int nerr; + int nerr, b; + Type *t, *tk, *tv, *t1; + Node *vstat, *index, *value; + Sym *syma, *symb; + // make the map var nerr = nerrors; a = nod(OMAKE, N, N); @@ -2171,9 +2174,127 @@ maplit(Node *n, Node *var, NodeList **init) walkexpr(&a, init); *init = list(*init, a); - memset(hash, 0, sizeof(hash)); + // count the initializers + b = 0; for(l=n->list; l; l=l->next) { r = l->n; + + if(r->op != OKEY) + fatal("slicelit: rhs not OKEY: %N", r); + index = r->left; + value = r->right; + + if(isliteral(index) && isliteral(value)) + b++; + } + + t = T; + if(b != 0) { + // build type [count]struct { a Tindex, b Tvalue } + t = n->type; + tk = t->down; + tv = t->type; + + symb = lookup("b"); + t = typ(TFIELD); + t->type = tv; + t->sym = symb; + + syma = lookup("a"); + t1 = t; + t = typ(TFIELD); + t->type = tk; + t->sym = syma; + t->down = t1; + + t1 = t; + t = typ(TSTRUCT); + t->type = t1; + + t1 = t; + t = typ(TARRAY); + t->bound = b; + t->type = t1; + + dowidth(t); + + // make and initialize static array + vstat = staticname(t); + b = 0; + for(l=n->list; l; l=l->next) { + r = l->n; + + if(r->op != OKEY) + fatal("slicelit: rhs not OKEY: %N", r); + index = r->left; + value = r->right; + + if(isliteral(index) && isliteral(value)) { + // build vstat[b].a = key; + a = nodintconst(b); + a = nod(OINDEX, vstat, a); + a = nod(ODOT, a, newname(syma)); + a = nod(OAS, a, index); + typecheck(&a, Etop); + walkexpr(&a, init); + a->dodata = 2; + *init = list(*init, a); + + // build vstat[b].b = value; + a = nodintconst(b); + a = nod(OINDEX, vstat, a); + a = nod(ODOT, a, newname(symb)); + a = nod(OAS, a, value); + typecheck(&a, Etop); + walkexpr(&a, init); + a->dodata = 2; + *init = list(*init, a); + + b++; + } + } + + // loop adding structure elements to map + // for i = 0; i < len(vstat); i++ { + // map[vstat[i].a] = vstat[i].b + // } + index = nod(OXXX, N, N); + tempname(index, types[TINT]); + + a = nod(OINDEX, vstat, index); + a = nod(ODOT, a, newname(symb)); + + r = nod(OINDEX, vstat, index); + r = nod(ODOT, r, newname(syma)); + r = nod(OINDEX, var, r); + + r = nod(OAS, r, a); + + a = nod(OFOR, N, N); + a->nbody = list1(r); + + a->ninit = list1(nod(OAS, index, nodintconst(0))); + a->ntest = nod(OLT, index, nodintconst(t->bound)); + a->nincr = nod(OASOP, index, nodintconst(1)); + a->nincr->etype = OADD; + + typecheck(&a, Etop); + walkstmt(&a); + *init = list(*init, a); + } + + // put in dynamic entries one-at-a-time + for(l=n->list; l; l=l->next) { + r = l->n; + + if(r->op != OKEY) + fatal("slicelit: rhs not OKEY: %N", r); + index = r->left; + value = r->right; + + if(isliteral(index) && isliteral(value)) + continue; + // build list of var[c] = expr a = nod(OINDEX, var, r->left); a = nod(OAS, a, r->right); |
