]> Cypherpunks repositories - gostls13.git/commitdiff
gc: add delete(m, x) but leave in m[x] = 0, false.
authorRuss Cox <rsc@golang.org>
Tue, 18 Oct 2011 13:41:32 +0000 (09:41 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 18 Oct 2011 13:41:32 +0000 (09:41 -0400)
The old m[x] = 0, false syntax will be deleted
in a month or so, once people have had time to
change their code (there is a gofix in a separate CL).

R=ken2
CC=golang-dev
https://golang.org/cl/5265048

src/cmd/gc/builtin.c.boot
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/runtime.go
src/cmd/gc/subr.c
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c
src/pkg/runtime/hashmap.c

index 745791eb03f9851b4d6bf1073b01ed6b7332aab7..b2e9465c4761a0d0b4eaf2a1758dd9815c00ef81 100644 (file)
@@ -64,6 +64,7 @@ char *runtimeimport =
        "func @\"\".mapassign1 (mapType *uint8, hmap map[any] any, key any, val any)\n"
        "func @\"\".mapassign2 (mapType *uint8, hmap map[any] any, key any, val any, pres bool)\n"
        "func @\"\".mapiterinit (mapType *uint8, hmap map[any] any, hiter *any)\n"
+       "func @\"\".mapdelete (mapType *uint8, hmap map[any] any, key any)\n"
        "func @\"\".mapiternext (hiter *any)\n"
        "func @\"\".mapiter1 (hiter *any) any\n"
        "func @\"\".mapiter2 (hiter *any) (key any, val any)\n"
index 741d9527aa142afa098f5c3b1c87739b96dfa286..5c2de998e515186e34cbd2ac2433c926e6abc324 100644 (file)
@@ -425,7 +425,8 @@ enum
        OAPPEND,
        OARRAYBYTESTR, OARRAYRUNESTR,
        OSTRARRAYBYTE, OSTRARRAYRUNE,
-       OAS, OAS2, OAS2MAPW, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE, OASOP,
+       OAS, OAS2, OAS2MAPW, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE,
+       OASOP,
        OBAD,
        OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
        OCAP,
@@ -436,6 +437,7 @@ enum
        OCONV, OCONVIFACE, OCONVNOP,
        OCOPY,
        ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
+       ODELETE,
        ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
        ODOTTYPE,
        ODOTTYPE2,
index 54970dc8f4869ac86df80ed5d8fabbbfe96ca4ee..8328b38a3156434979e7827f848bebb6a094533a 100644 (file)
@@ -1624,6 +1624,7 @@ static    struct
        "close",        LNAME,          Txxx,           OCLOSE,
        "complex",      LNAME,          Txxx,           OCOMPLEX,
        "copy",         LNAME,          Txxx,           OCOPY,
+       "delete",               LNAME,          Txxx,           ODELETE,
        "imag",         LNAME,          Txxx,           OIMAG,
        "len",          LNAME,          Txxx,           OLEN,
        "make",         LNAME,          Txxx,           OMAKE,
index d45542b7293dd2d9d0fa14a434fd190a253154e0..b190e50a7aa0ddbc9decf866f0ddeb919dd616d0 100644 (file)
@@ -87,6 +87,7 @@ func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
 func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
 func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
 func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
+func mapdelete(mapType *byte, hmap map[any]any, key any)
 func mapiternext(hiter *any)
 func mapiter1(hiter *any) (key any)
 func mapiter2(hiter *any) (key any, val any)
index bf83dd8fa646577ddbd9084964762ee2b5d1dc39..c0e22c2be8ebc3a8a8aaf28d8299f6f4b33f5c66 100644 (file)
@@ -923,6 +923,7 @@ goopnames[] =
        [OCOPY]         = "copy",
        [ODEC]          = "--",
        [ODEFER]        = "defer",
+       [ODELETE]       = "delete",
        [ODIV]          = "/",
        [OEQ]           = "==",
        [OFALL]         = "fallthrough",
index 0b2e6f0ca603ba2fbfb343ff72cd76df56ffe2f3..20411a1a0ec57d65724bf2f78868c8a2fa764a88 100644 (file)
@@ -991,6 +991,31 @@ reswitch:
                ok |= Etop;
                goto ret;
 
+       case ODELETE:
+               args = n->list;
+               if(args == nil) {
+                       yyerror("missing arguments to delete");
+                       goto error;
+               }
+               if(args->next == nil) {
+                       yyerror("missing second (key) argument to delete");
+                       goto error;
+               }
+               if(args->next->next != nil) {
+                       yyerror("too many arguments to delete");
+                       goto error;
+               }
+               ok |= Etop;
+               typechecklist(args, Erv);
+               l = args->n;
+               r = args->next->n;
+               if(l->type != T && l->type->etype != TMAP) {
+                       yyerror("first argument to delete must be map; have %lT", l->type);
+                       goto error;
+               }
+               args->next->n = assignconv(r, l->type->down, "delete");
+               goto ret;
+
        case OAPPEND:
                ok |= Erv;
                args = n->list;
@@ -2284,7 +2309,7 @@ typecheckas2(Node *n)
 {
        int cl, cr;
        NodeList *ll, *lr;
-       Node *l, *r;
+       Node *l, *r, *rr;
        Iter s;
        Type *t;
 
@@ -2325,8 +2350,14 @@ typecheckas2(Node *n)
                        goto out;
                n->op = OAS2MAPW;
                n->rlist->n = assignconv(r, l->type, "assignment");
-               r = n->rlist->next->n;
-               n->rlist->next->n = assignconv(r, types[TBOOL], "assignment");
+               rr = n->rlist->next->n;
+               n->rlist->next->n = assignconv(rr, types[TBOOL], "assignment");
+               if(isconst(rr, CTBOOL) && !rr->val.u.bval) {
+                       n->op = ODELETE;
+                       n->list = list(list1(l->left), l->right);
+                       n->right = n->rlist->n;
+                       n->rlist = nil;
+               }
                goto out;
        }
 
index de7004e3e9bd008b650bb8dca47da4af93f898bd..9d06f1b7f595aec8d0dae7759336b228480e8f2a 100644 (file)
@@ -9,6 +9,7 @@
 static Node*   walkprint(Node*, NodeList**, int);
 static Node*   conv(Node*, Type*);
 static Node*   mapfn(char*, Type*);
+static Node*   mapfndel(char*, Type*);
 static Node*   makenewvar(Type*, NodeList**, Node**);
 static Node*   ascompatee1(int, Node*, Node*, NodeList**);
 static NodeList*       ascompatee(int, NodeList*, NodeList*, NodeList**);
@@ -173,6 +174,7 @@ walkstmt(Node **np)
        case OCALLINTER:
        case OCALL:
        case OCALLFUNC:
+       case ODELETE:
        case OSEND:
        case ORECV:
        case OPRINT:
@@ -610,6 +612,21 @@ walkexpr(Node **np, NodeList **init)
                n->op = OAS2FUNC;
                goto as2func;
 
+       case ODELETE:
+               *init = concat(*init, n->ninit);
+               n->ninit = nil;
+               l = n->list->n;
+               r = n->list->next->n;
+               if(n->right != N) {
+                       // TODO: Remove once two-element map assigment is gone.
+                       l = safeexpr(l, init);
+                       r = safeexpr(r, init);
+                       safeexpr(n->right, init);  // cause side effects from n->right
+               }
+               t = l->type;
+               n = mkcall1(mapfndel("mapdelete", t), t->down, init, typename(t), l, r);
+               goto ret;
+
        case OAS2MAPW:
                // map[] = a,b - mapassign2
                // a,b = m[i];
@@ -2254,6 +2271,20 @@ mapfn(char *name, Type *t)
        return fn;
 }
 
+static Node*
+mapfndel(char *name, Type *t)
+{
+       Node *fn;
+
+       if(t->etype != TMAP)
+               fatal("mapfn %T", t);
+       fn = syslook(name, 1);
+       argtype(fn, t->down);
+       argtype(fn, t->type);
+       argtype(fn, t->down);
+       return fn;
+}
+
 static Node*
 addstr(Node *n, NodeList **init)
 {
index f904bd32757e115e705e645555b61d6fad690f7d..b88cc3564119701678433cc3a5579e93fa807b06 100644 (file)
@@ -1028,6 +1028,28 @@ runtime·mapassign2(MapType *t, Hmap *h, ...)
        }
 }
 
+// mapdelete(mapType *type, hmap *map[any]any, key any)
+#pragma textflag 7
+void
+runtime·mapdelete(MapType *t, Hmap *h, ...)
+{
+       byte *ak;
+
+       if(h == nil)
+               runtime·panicstring("deletion of entry in nil map");
+
+       ak = (byte*)&h + h->ko2;
+       runtime·mapassign(t, h, ak, nil);
+
+       if(debug) {
+               runtime·prints("mapdelete: map=");
+               runtime·printpointer(h);
+               runtime·prints("; key=");
+               h->keyalg->print(h->keysize, ak);
+               runtime·prints("\n");
+       }
+}
+
 // For reflect:
 //     func mapassign(t type h map, key, val iword, pres bool)
 // where an iword is the same word an interface value would use: