OLIST, OCMP, OPTR, OARRAY, ORANGE,
ORETURN, OFOR, OIF, OSWITCH,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
- OGOTO, OPROC, ONEW, OEMPTY, OSELECT,
+ OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT,
OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF,
OOROR,
Node* prcompat(Node*, int);
Node* nodpanic(int32);
Node* newcompat(Node*);
+Node* makecompat(Node*);
Node* stringop(Node*, int);
Type* fixmap(Type*);
Node* mapop(Node*, int);
%token <sym> LPACKAGE LIMPORT LEXPORT
%token <sym> LMAP LCHAN LINTERFACE LFUNC LSTRUCT
%token <sym> LCOLAS LFALL LRETURN LDDD
-%token <sym> LNEW LLEN LCAP LTYPEOF LPANIC LPANICN LPRINT LPRINTN
-%token <sym> LVAR LTYPE LCONST LCONVERT LSELECT
+%token <sym> LLEN LCAP LTYPEOF LPANIC LPANICN LPRINT LPRINTN
+%token <sym> LVAR LTYPE LCONST LCONVERT LSELECT LMAKE LNEW
%token <sym> LFOR LIF LELSE LSWITCH LCASE LDEFAULT
%token <sym> LBREAK LCONTINUE LGO LGOTO LRANGE
%token <sym> LNIL LTRUE LFALSE LIOTA
$$ = nod(ONEW, $5, N);
$$->type = $3;
}
+| LMAKE '(' type ')'
+ {
+ $$ = nod(OMAKE, N, N);
+ $$->type = $3;
+ }
+| LMAKE '(' type ',' expr_list ')'
+ {
+ $$ = nod(OMAKE, $5, N);
+ $$->type = $3;
+ }
| latype '(' expr ')'
{
$$ = nod(OCONV, $3, N);
| LPRINT
| LPRINTN
| LNEW
+| LMAKE
| LBASETYPE
| LTYPEOF
}
}
- // convert dynamic to static generated by ONEW
+ // convert dynamic to static generated by ONEW/OMAKE
if(issarray(t) && isdarray(l->type))
goto ret;
nvar = nod(0, N, N);
tempname(nvar, t);
- nnew = nod(ONEW, N, N);
+ nnew = nod(OMAKE, N, N);
nnew->type = t;
nnew = newcompat(nnew);
n->type = t->type;
goto ret;
+ case OMAKE:
+ if(top != Erv)
+ goto nottop;
+ indir(n, makecompat(n));
+ goto ret;
+
case ONEW:
if(top != Erv)
goto nottop;
}
Node*
-newcompat(Node *n)
+makecompat(Node *n)
{
Node *r, *on;
Type *t, *t0;
if(t0->etype == TARRAY)
return arrayop(n, Erv);
- if(!isptr[t0->etype] || t0->type == T)
+ if(!isptr[t0->etype])
goto bad;
t = t0->type;
+ if(t == T)
+ goto bad;
+
switch(t->etype) {
case TSTRING:
goto bad;
- // the call looks like new(map[int]int)
+ // the call looks like new(MAP[int]int)
// but internally we see new(*MAP[int]int)
case TMAP:
r = mapop(n, Erv);
break;
- // the call looks like new(chan int)
+ // the call looks like new(CHAN int)
// but internally we see new(*CHAN int)
case TCHAN:
r = chanop(n, Erv);
default:
if(n->left != N)
- yyerror("cannot new(%T, expr)", t0);
+ yyerror("cannot make(%T, expr)", t0);
+ dowidth(t);
+ on = syslook("mal", 1);
+ argtype(on, t);
+ r = nodintconst(t->width);
+ r = nod(OCALL, on, r);
+ walktype(r, Erv);
+ break;
+ }
+
+ return r;
+
+bad:
+ yyerror("cannot make(%T)", t0);
+ return n;
+}
+
+Node*
+newcompat(Node *n)
+{
+ Node *r, *on;
+ Type *t, *t0;
+
+ t = n->type;
+ if(t == T)
+ goto bad;
+
+ switch(t->etype) {
+ case TSTRING:
+ case TMAP:
+ case TCHAN:
+ goto bad;
+
+ default:
+ if(n->left != N)
+ yyerror("cannot new(%T, expr)", t);
dowidth(t);
on = syslook("mal", 1);
argtype(on, t);
return r;
bad:
- yyerror("cannot new(%T)", t0);
+ yyerror("cannot new(%T)", t);
return n;
}
default:
fatal("mapop: unknown op %O", n->op);
- case ONEW:
+ case OMAKE:
if(top != Erv)
goto nottop;
default:
fatal("chanop: unknown op %O", n->op);
- case ONEW:
+ case OMAKE:
// newchan(elemsize int, elemalg int,
// hint int) (hmap *chan[any-1]);
n->right = r;
return n;
- case ONEW:
+ case OMAKE:
// newarray(nel int, max int, width int) (ary []any)
t = fixarray(n->type);
if(t == T)
var = nod(OXXX, N, N);
tempname(var, t);
- nnew = nod(ONEW, N, N);
+ nnew = nod(OMAKE, N, N);
nnew->type = t;
nas = nod(OAS, var, nnew);
var = nod(OXXX, N, N);
tempname(var, t);
- a = nod(ONEW, N, N);
+ a = nod(OMAKE, N, N);
a->type = t;
a = nod(OAS, var, a);
addtop = list(addtop, a);