"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"
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,
OCONV, OCONVIFACE, OCONVNOP,
OCOPY,
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
+ ODELETE,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
ODOTTYPE,
ODOTTYPE2,
"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,
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)
[OCOPY] = "copy",
[ODEC] = "--",
[ODEFER] = "defer",
+ [ODELETE] = "delete",
[ODIV] = "/",
[OEQ] = "==",
[OFALL] = "fallthrough",
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;
{
int cl, cr;
NodeList *ll, *lr;
- Node *l, *r;
+ Node *l, *r, *rr;
Iter s;
Type *t;
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;
}
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**);
case OCALLINTER:
case OCALL:
case OCALLFUNC:
+ case ODELETE:
case OSEND:
case ORECV:
case OPRINT:
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];
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)
{
}
}
+// 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: