1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:04:44 -07:00

gc: grammar cleanup:

* no longer distinguishes const, var, type, package names.
  * all the predefined names are not tokens anymore.

R=ken
OCL=29326
CL=29985
This commit is contained in:
Russ Cox 2009-06-06 12:46:38 -07:00
parent ea33ff4067
commit 8f4af6d205
9 changed files with 827 additions and 858 deletions

View File

@ -208,7 +208,7 @@ dowidth(Type *t)
} }
void void
typeinit(int lex) typeinit(void)
{ {
int i, etype, sameas; int i, etype, sameas;
Type *t; Type *t;
@ -306,7 +306,7 @@ typeinit(int lex)
types[TFUNC] = functype(N, N, N); types[TFUNC] = functype(N, N, N);
/* types used in front end */ /* types used in front end */
types[TNIL] = typ(TNIL); // types[TNIL] got set early in lexinit
types[TIDEAL] = typ(TIDEAL); types[TIDEAL] = typ(TIDEAL);
/* simple aliases */ /* simple aliases */
@ -317,7 +317,6 @@ typeinit(int lex)
/* pick up the backend typedefs */ /* pick up the backend typedefs */
for(i=0; typedefs[i].name; i++) { for(i=0; typedefs[i].name; i++) {
s = lookup(typedefs[i].name); s = lookup(typedefs[i].name);
s->lexical = lex;
etype = typedefs[i].etype; etype = typedefs[i].etype;
if(etype < 0 || etype >= nelem(types)) if(etype < 0 || etype >= nelem(types))
@ -340,7 +339,7 @@ typeinit(int lex)
dowidth(t); dowidth(t);
types[etype] = t; types[etype] = t;
s->otype = t; s->def = typenod(t);
} }
Array_array = rnd(0, widthptr); Array_array = rnd(0, widthptr);

View File

@ -67,11 +67,11 @@ dodcltype(Type *n)
// if n has been forward declared, // if n has been forward declared,
// use the Type* created then // use the Type* created then
s = n->sym; s = n->sym;
if(s->block == block && s->otype != T) { if(s->block == block && s->def != N && s->def->op == OTYPE) {
switch(s->otype->etype) { switch(s->def->type->etype) {
case TFORWSTRUCT: case TFORWSTRUCT:
case TFORWINTER: case TFORWINTER:
n = s->otype; n = s->def->type;
goto found; goto found;
} }
} }
@ -95,7 +95,7 @@ updatetype(Type *n, Type *t)
int local; int local;
s = n->sym; s = n->sym;
if(s == S || s->otype != n) if(s == S || s->def == N || s->def->op != OTYPE || s->def->type != n)
fatal("updatetype %T = %T", n, t); fatal("updatetype %T = %T", n, t);
switch(n->etype) { switch(n->etype) {
@ -132,7 +132,7 @@ updatetype(Type *n, Type *t)
n->printed = 0; n->printed = 0;
n->method = nil; n->method = nil;
n->vargen = 0; n->vargen = 0;
n->nod = N;
// catch declaration of incomplete type // catch declaration of incomplete type
switch(n->etype) { switch(n->etype) {
case TFORWSTRUCT: case TFORWSTRUCT:
@ -306,7 +306,7 @@ addmethod(Node *n, Type *t, int local)
goto bad; goto bad;
if(local && !f->local) { if(local && !f->local) {
yyerror("cannot define methods on non-local type %T", t); yyerror("cannot define methods on non-local type %T", f);
return; return;
} }
@ -383,7 +383,9 @@ funchdr(Node *n)
Sym *s; Sym *s;
s = n->nname->sym; s = n->nname->sym;
on = s->oname; on = s->def;
if(on != N && (on->op != ONAME || on->builtin))
on = N;
// check for same types // check for same types
if(on != N) { if(on != N) {
@ -748,7 +750,7 @@ loop:
f->embedded = n->embedded; f->embedded = n->embedded;
f->sym = f->nname->sym; f->sym = f->nname->sym;
if(pkgimportname != S && !exportname(f->sym->name)) if(pkgimportname != S && !exportname(f->sym->name))
f->sym = pkglookup(f->sym->name, pkgcontext); f->sym = pkglookup(f->sym->name, structpkg);
} }
*t = f; *t = f;
@ -793,11 +795,8 @@ void
dcopy(Sym *a, Sym *b) dcopy(Sym *a, Sym *b)
{ {
a->name = b->name; a->name = b->name;
a->oname = b->oname; a->def = b->def;
a->otype = b->otype;
a->oconst = b->oconst;
a->package = b->package; a->package = b->package;
a->lexical = b->lexical;
a->undef = b->undef; a->undef = b->undef;
a->vargen = b->vargen; a->vargen = b->vargen;
a->block = b->block; a->block = b->block;
@ -954,11 +953,8 @@ addvar(Node *n, Type *t, int ctxt)
redeclare("variable", s); redeclare("variable", s);
s->vargen = gen; s->vargen = gen;
s->oname = n; s->def = n;
s->offset = 0; s->offset = 0;
s->oconst = nil;
s->otype = nil;
s->lexical = LNAME;
n->funcdepth = funcdepth; n->funcdepth = funcdepth;
n->type = t; n->type = t;
@ -1004,10 +1000,7 @@ addtyp(Type *n, int ctxt)
} }
redeclare("type", s); redeclare("type", s);
s->otype = n; s->def = typenod(n);
s->oconst = nil;
s->oname = nil;
s->lexical = LATYPE;
d = dcl(); d = dcl();
d->dsym = s; d->dsym = s;
@ -1041,7 +1034,7 @@ addconst(Node *n, Node *e, int ctxt)
Sym *s; Sym *s;
Dcl *r, *d; Dcl *r, *d;
if(n->op != ONAME) if(n->op != ONAME && n->op != ONONAME)
fatal("addconst: not a name"); fatal("addconst: not a name");
if(e->op != OLITERAL) { if(e->op != OLITERAL) {
@ -1059,10 +1052,8 @@ addconst(Node *n, Node *e, int ctxt)
} }
redeclare("constant", s); redeclare("constant", s);
s->oconst = e; s->def = e;
s->otype = nil; e->sym = s;
s->oname = nil;
s->lexical = LNAME;
d = dcl(); d = dcl();
d->dsym = s; d->dsym = s;
@ -1073,7 +1064,7 @@ addconst(Node *n, Node *e, int ctxt)
r->back = d; r->back = d;
if(dflag()) if(dflag())
print("const-dcl %S %N\n", n->sym, n->sym->oconst); print("const-dcl %S %N\n", n->sym, n->sym->def);
} }
Node* Node*
@ -1130,6 +1121,18 @@ newname(Sym *s)
return n; return n;
} }
Node*
typenod(Type *t)
{
if(t->nod == N) {
t->nod = nod(OTYPE, N, N);
t->nod->type = t;
t->nod->sym = t->sym;
}
return t->nod;
}
/* /*
* this will return an old name * this will return an old name
* that has already been pushed on the * that has already been pushed on the
@ -1142,15 +1145,7 @@ oldname(Sym *s)
Node *n; Node *n;
Node *c; Node *c;
if(s->oconst) { n = s->def;
n = nod(OLITERAL, N, N);
n->sym = s;
n->val = s->oconst->val;
n->type = s->oconst->type;
return n;
}
n = s->oname;
if(n == N) { if(n == N) {
n = nod(ONONAME, N, N); n = nod(ONONAME, N, N);
n->sym = s; n->sym = s;
@ -1158,7 +1153,15 @@ oldname(Sym *s)
n->addable = 1; n->addable = 1;
n->ullman = 1; n->ullman = 1;
} }
if(n->funcdepth > 0 && n->funcdepth != funcdepth) { if(n->op == OLITERAL) {
c = nod(OLITERAL, N, N);
c->sym = s;
c->val = n->val;
c->type = n->type;
c->iota = n->iota;
return c;
}
if(n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
// inner func is referring to var // inner func is referring to var
// in outer func. // in outer func.
if(n->closure == N || n->closure->funcdepth != funcdepth) { if(n->closure == N || n->closure->funcdepth != funcdepth) {
@ -1200,9 +1203,19 @@ oldtype(Sym *s)
{ {
Type *t; Type *t;
t = s->otype; if(s->def == N || s->def->op != OTYPE) {
if(t == T) yyerror("%S is not a type", s);
fatal("%S not a type", s); // cant happen return T;
}
t = s->def->type;
/*
* If t is lowercase and not in our package
* and this isn't a reference during the parsing
* of import data, complain.
*/
if(pkgimportname == S && !exportname(s->name) && strcmp(s->package, package) != 0)
yyerror("cannot use type %T", t);
return t; return t;
} }
@ -1219,9 +1232,9 @@ nametoanondcl(Node *na)
for(l=&na; (n=*l)->op == OLIST; l=&n->left) for(l=&na; (n=*l)->op == OLIST; l=&n->left)
n->right = nametoanondcl(n->right); n->right = nametoanondcl(n->right);
t = n->sym->otype; n = n->sym->def;
if(t == T) { if(n == N || n->op != OTYPE || (t = n->type) == T) {
yyerror("%s is not a type", n->sym->name); yyerror("%S is not a type", n->sym);
t = typ(TINT32); t = typ(TINT32);
} }
n = nod(ODCLFIELD, N, N); n = nod(ODCLFIELD, N, N);
@ -1261,33 +1274,95 @@ anondcl(Type *t)
return n; return n;
} }
static Node*
findtype(Node *n)
{
Node *r;
for(r=n; r->op==OLIST; r=r->right)
if(r->left->op == OKEY)
return r->left->right;
if(r->op == OKEY)
return r->right;
if(n->op == OLIST)
n = n->left;
return N;
}
static Node*
xanondcl(Node *nt, int dddok)
{
Node *n;
Type *t;
t = nt->type;
if(nt->op != OTYPE) {
yyerror("%N is not a type", nt);
t = types[TINT32];
}
n = nod(ODCLFIELD, N, N);
n->type = t;
if(!dddok && t->etype == TDDD)
yyerror("only last argument can have type ...");
return n;
}
static Node*
namedcl(Node *nn, Node *nt, int dddok)
{
Node *n;
Type *t;
if(nn->op == OKEY)
nn = nn->left;
if(nn->op == OTYPE && nn->sym == S) {
yyerror("cannot mix anonymous %T with named arguments", nn->type);
return xanondcl(nn, dddok);
}
t = types[TINT32];
if(nt == N)
yyerror("missing type for argument %S", nn->sym);
else if(nt->op != OTYPE)
yyerror("%S is not a type", nt->sym);
else
t = nt->type;
n = nod(ODCLFIELD, newname(nn->sym), N);
n->type = t;
if(!dddok && t->etype == TDDD)
yyerror("only last argument can have type ...");
return n;
}
/* /*
* check that the list of declarations is either all anonymous or all named * check that the list of declarations is either all anonymous or all named
*/ */
void Node*
checkarglist(Node *n) checkarglist(Node *n)
{ {
if(n->op != OLIST) Node *r;
return; Node **l;
if(n->left->op != ODCLFIELD)
fatal("checkarglist");
if(n->left->left != N) {
for(n=n->right; n->op == OLIST; n=n->right)
if(n->left->left == N)
goto mixed;
if(n->left == N)
goto mixed;
} else {
for(n=n->right; n->op == OLIST; n=n->right)
if(n->left->left != N)
goto mixed;
if(n->left != N)
goto mixed;
}
return;
mixed: // check for all anonymous
yyerror("cannot mix anonymous and named function arguments"); for(r=n; r->op==OLIST; r=r->right)
if(r->left->op == OKEY)
goto named;
if(r->op == OKEY)
goto named;
// all anonymous - add names
for(l=&n; (r=*l)->op==OLIST; l=&r->right)
r->left = xanondcl(r->left, 0);
*l = xanondcl(r, 1);
return n;
named:
// otherwise, each run of names ends in a type.
// add a type to each one that needs one.
for(l=&n; (r=*l)->op==OLIST; l=&r->right)
r->left = namedcl(r->left, findtype(r), 0);
*l = namedcl(r, findtype(r), 1);
return n;
} }
/* /*
@ -1296,7 +1371,7 @@ mixed:
* func Init·<file>() (2) * func Init·<file>() (2)
* if initdone·<file> { (3) * if initdone·<file> { (3)
* if initdone·<file> == 2 (4) * if initdone·<file> == 2 (4)
* return * return
* throw(); (5) * throw(); (5)
* } * }
* initdone.<file>++; (6) * initdone.<file>++; (6)
@ -1325,7 +1400,7 @@ anyinit(Node *n)
// is there an explicit init function // is there an explicit init function
snprint(namebuf, sizeof(namebuf), "init·%s", filename); snprint(namebuf, sizeof(namebuf), "init·%s", filename);
s = lookup(namebuf); s = lookup(namebuf);
if(s->oname != N) if(s->def != N)
return 1; return 1;
// are there any imported init functions // are there any imported init functions
@ -1333,7 +1408,7 @@ anyinit(Node *n)
for(s = hash[h]; s != S; s = s->link) { for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0) if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
continue; continue;
if(s->oname == N) if(s->def == N)
continue; continue;
return 1; return 1;
} }
@ -1409,13 +1484,13 @@ fninit(Node *n)
for(s = hash[h]; s != S; s = s->link) { for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0) if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
continue; continue;
if(s->oname == N) if(s->def == N)
continue; continue;
if(s == initsym) if(s == initsym)
continue; continue;
// could check that it is fn of no args/returns // could check that it is fn of no args/returns
a = nod(OCALL, s->oname, N); a = nod(OCALL, s->def, N);
r = list(r, a); r = list(r, a);
} }
@ -1426,8 +1501,8 @@ fninit(Node *n)
// could check that it is fn of no args/returns // could check that it is fn of no args/returns
snprint(namebuf, sizeof(namebuf), "init·%s", filename); snprint(namebuf, sizeof(namebuf), "init·%s", filename);
s = lookup(namebuf); s = lookup(namebuf);
if(s->oname != N) { if(s->def != N) {
a = nod(OCALL, s->oname, N); a = nod(OCALL, s->def, N);
r = list(r, a); r = list(r, a);
} }

View File

@ -100,7 +100,7 @@ dumpexportconst(Sym *s)
Node *n; Node *n;
Type *t; Type *t;
n = s->oconst; n = s->def;
if(n == N || n->op != OLITERAL) if(n == N || n->op != OLITERAL)
fatal("dumpexportconst: oconst nil: %S", s); fatal("dumpexportconst: oconst nil: %S", s);
@ -141,7 +141,7 @@ dumpexportvar(Sym *s)
Node *n; Node *n;
Type *t; Type *t;
n = s->oname; n = s->def;
if(n == N || n->type == T) { if(n == N || n->type == T) {
yyerror("variable exported but not defined: %S", s); yyerror("variable exported but not defined: %S", s);
return; return;
@ -161,49 +161,54 @@ dumpexportvar(Sym *s)
void void
dumpexporttype(Sym *s) dumpexporttype(Sym *s)
{ {
dumpprereq(s->otype); Type *t;
t = s->def->type;
dumpprereq(t);
Bprint(bout, "\t"); Bprint(bout, "\t");
switch (s->otype->etype) { switch (t->etype) {
case TFORW: case TFORW:
case TFORWSTRUCT: case TFORWSTRUCT:
case TFORWINTER: case TFORWINTER:
yyerror("export of incomplete type %T", s->otype); yyerror("export of incomplete type %T", t);
return; return;
} }
Bprint(bout, "type %#T %l#T\n", s->otype, s->otype); Bprint(bout, "type %#T %l#T\n", t, t);
} }
void void
dumpsym(Sym *s) dumpsym(Sym *s)
{ {
Type *f; Type *f, *t;
if(s->exported != 0) if(s->exported != 0)
return; return;
s->exported = 1; s->exported = 1;
switch(s->lexical) { if(s->def == N) {
default:
yyerror("unknown export symbol: %S", s); yyerror("unknown export symbol: %S", s);
return;
}
switch(s->def->op) {
default:
yyerror("unexpected export symbol: %O %S", s->def->op, s);
break; break;
case LPACK: case OLITERAL:
yyerror("package export symbol: %S", s); dumpexportconst(s);
break; break;
case LATYPE: case OTYPE:
t = s->def->type;
// TODO(rsc): sort methods by name // TODO(rsc): sort methods by name
for(f=s->otype->method; f!=T; f=f->down) for(f=t->method; f!=T; f=f->down)
dumpprereq(f); dumpprereq(f);
dumpexporttype(s); dumpexporttype(s);
for(f=s->otype->method; f!=T; f=f->down) for(f=t->method; f!=T; f=f->down)
Bprint(bout, "\tfunc (%#T) %hS %#hhT\n", Bprint(bout, "\tfunc (%#T) %hS %#hhT\n",
f->type->type->type, f->sym, f->type); f->type->type->type, f->sym, f->type);
break; break;
case LNAME: case ONAME:
if(s->oconst) dumpexportvar(s);
dumpexportconst(s);
else
dumpexportvar(s);
break; break;
} }
} }
@ -216,7 +221,7 @@ dumptype(Type *t)
return; return;
// no need to dump type if it's not ours (was imported) // no need to dump type if it's not ours (was imported)
if(t->sym != S && t->sym->otype == t && !t->local) if(t->sym != S && t->sym->def == typenod(t) && !t->local)
return; return;
Bprint(bout, "type %#T %l#T\n", t, t); Bprint(bout, "type %#T %l#T\n", t, t);
@ -256,43 +261,22 @@ dumpexport(void)
* import * import
*/ */
/*
* look up and maybe declare pkg.name, which should match lexical
*/
Sym*
pkgsym(char *name, char *pkg, int lexical)
{
Sym *s;
s = pkglookup(name, pkg);
switch(lexical) {
case LATYPE:
if(s->oname)
yyerror("%s.%s is not a type", name, pkg);
break;
case LNAME:
if(s->otype)
yyerror("%s.%s is not a name", name, pkg);
break;
}
s->lexical = lexical;
return s;
}
/* /*
* return the sym for ss, which should match lexical * return the sym for ss, which should match lexical
*/ */
Sym* Sym*
importsym(Node *ss, int lexical) importsym(Sym *s, int op)
{ {
Sym *s; if(s->def != N && s->def->op != op) {
// Clumsy hack for
if(ss->op != OIMPORT) // package parser
fatal("importsym: oops1 %N", ss); // import "go/parser" // defines type parser
if(s == lookup(package))
s = pkgsym(ss->sym->name, ss->psym->name, lexical); s->def = N;
/* TODO botch - need some diagnostic checking for the following assignment */ else
if(exportname(ss->sym->name)) yyerror("redeclaration of %lS during import", s, s->def->op, op);
}
if(exportname(s->name))
s->export = 1; s->export = 1;
else else
s->export = 2; // package scope s->export = 2; // package scope
@ -304,47 +288,36 @@ importsym(Node *ss, int lexical)
* return the type pkg.name, forward declaring if needed * return the type pkg.name, forward declaring if needed
*/ */
Type* Type*
pkgtype(char *name, char *pkg) pkgtype(Sym *s)
{ {
Sym *s;
Type *t; Type *t;
// botch importsym(s, OTYPE);
// s = pkgsym(name, pkg, LATYPE); if(s->def == N || s->def->op != OTYPE) {
Node *n;
n = nod(OIMPORT, N, N);
n->sym = lookup(name);
n->psym = lookup(pkg);
s = importsym(n, LATYPE);
if(s->otype == T) {
t = typ(TFORW); t = typ(TFORW);
t->sym = s; t->sym = s;
s->otype = t; s->def = typenod(t);
} }
return s->otype; return s->def->type;
} }
static int static int
mypackage(Node *ss) mypackage(Sym *s)
{ {
// we import all definitions for sys. // we import all definitions for sys.
// lowercase ones can only be used by the compiler. // lowercase ones can only be used by the compiler.
return strcmp(ss->psym->name, package) == 0 return strcmp(s->package, package) == 0
|| strcmp(ss->psym->name, "sys") == 0; || strcmp(s->package, "sys") == 0;
} }
void void
importconst(Node *ss, Type *t, Node *n) importconst(Sym *s, Type *t, Node *n)
{ {
Sym *s; if(!exportname(s->name) && !mypackage(s))
if(!exportname(ss->sym->name) && !mypackage(ss))
return; return;
importsym(s, OLITERAL);
convlit(n, t); convlit(n, t);
s = importsym(ss, LNAME); if(s->def != N) {
if(s->oconst != N) {
// TODO: check if already the same. // TODO: check if already the same.
return; return;
} }
@ -356,19 +329,17 @@ importconst(Node *ss, Type *t, Node *n)
} }
void void
importvar(Node *ss, Type *t, int ctxt) importvar(Sym *s, Type *t, int ctxt)
{ {
Sym *s; if(!exportname(s->name) && !mypackage(s))
if(!exportname(ss->sym->name) && !mypackage(ss))
return; return;
s = importsym(ss, LNAME); importsym(s, ONAME);
if(s->oname != N) { if(s->def != N && s->def->op == ONAME) {
if(cvttype(t, s->oname->type)) if(cvttype(t, s->def->type))
return; return;
warn("redeclare import var %S from %T to %T", warn("redeclare import var %S from %T to %T",
s, s->oname->type, t); s, s->def->type, t);
} }
checkwidth(t); checkwidth(t);
addvar(newname(s), t, ctxt); addvar(newname(s), t, ctxt);
@ -378,25 +349,34 @@ importvar(Node *ss, Type *t, int ctxt)
} }
void void
importtype(Node *ss, Type *t) importtype(Sym *s, Type *t)
{ {
Sym *s; Node *n;
Type *tt;
s = importsym(ss, LATYPE); importsym(s, OTYPE);
if(s->otype != T) { n = s->def;
if(cvttype(t, s->otype)) if(n != N && n->op == OTYPE) {
if(cvttype(t, n->type))
return; return;
if(s->otype->etype != TFORW) { if(n->type->etype != TFORW) {
warn("redeclare import type %S from %lT to %lT", warn("redeclare import type %S from %lT to %lT",
s, s->otype, t); s, n->type, t);
s->otype = typ(0); n = s->def = typenod(typ(0));
} }
} }
if(s->otype == T) if(n == N || n->op != OTYPE) {
s->otype = typ(0); tt = typ(0);
*s->otype = *t; tt->sym = s;
s->otype->sym = s; n = typenod(tt);
checkwidth(s->otype); s->def = n;
}
if(n->type == T)
n->type = typ(0);
*n->type = *t;
n->type->sym = s;
n->type->nod = n;
checkwidth(n->type);
if(debug['E']) if(debug['E'])
print("import type %S %lT\n", s, t); print("import type %S %lT\n", s, t);
@ -425,7 +405,9 @@ return;
for(h=0; h<NHASH; h++) for(h=0; h<NHASH; h++)
for(s = hash[h]; s != S; s = s->link) { for(s = hash[h]; s != S; s = s->link) {
t = s->otype; if(s->def == N || s->def->op != OTYPE)
continue;
t = s->def->type;
if(t == T) if(t == T)
continue; continue;

View File

@ -145,6 +145,8 @@ struct Type
uchar copyany; uchar copyany;
uchar local; // created in this file uchar local; // created in this file
Node* nod; // canonical OTYPE node
// TFUNCT // TFUNCT
uchar thistuple; uchar thistuple;
uchar outtuple; uchar outtuple;
@ -187,6 +189,7 @@ struct Node
uchar diag; // already printed error about this uchar diag; // already printed error about this
uchar noescape; // ONAME never move to heap uchar noescape; // ONAME never move to heap
uchar funcdepth; uchar funcdepth;
uchar builtin; // built-in name, like len or close
// most nodes // most nodes
Node* left; Node* left;
@ -247,10 +250,7 @@ struct Sym
char* package; // package name char* package; // package name
char* name; // variable name char* name; // variable name
Node* oname; // ONAME node if a var Node* def; // definition: ONAME OTYPE OPACK or OLITERAL
Type* otype; // TYPE node if a type
Node* oconst; // OLITERAL node if a const
char* opack; // package reference if lexical == LPACK
vlong offset; // stack location if automatic vlong offset; // stack location if automatic
int32 lexical; int32 lexical;
int32 vargen; // unique variable number int32 vargen; // unique variable number
@ -298,9 +298,8 @@ enum
{ {
OXXX, OXXX,
OTYPE, OVAR, OIMPORT, ONAME, ONONAME, OTYPE, OPACK, OLITERAL,
ODCL,
ONAME, ONONAME, ODCL,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODCLFUNC, ODCLFIELD, ODCLARG, ODCLFUNC, ODCLFIELD, ODCLARG,
OLIST, OCMP, OPTR, OARRAY, ORANGE, OLIST, OCMP, OPTR, OARRAY, ORANGE,
@ -325,7 +324,7 @@ enum
OCALL, OCALLMETH, OCALLINTER, OCALL, OCALLMETH, OCALLINTER,
OINDEX, OSLICE, OINDEX, OSLICE,
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV, ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
OLITERAL, OREGISTER, OINDREG, OREGISTER, OINDREG,
OKEY, OPARAM, OKEY, OPARAM,
OCOMPOS, OCOMPSLICE, OCOMPMAP, OCOMPOS, OCOMPSLICE, OCOMPMAP,
OCONV, OCONV,
@ -573,6 +572,7 @@ EXTERN int importflag;
EXTERN int inimportsys; EXTERN int inimportsys;
EXTERN int initflag; // compiling the init fn EXTERN int initflag; // compiling the init fn
EXTERN int statuniqgen; // name generator for static temps EXTERN int statuniqgen; // name generator for static temps
EXTERN int loophack;
EXTERN uint32 iota; EXTERN uint32 iota;
EXTERN Node* lastconst; EXTERN Node* lastconst;
@ -595,8 +595,7 @@ EXTERN Node* fskel;
EXTERN Node* addtop; EXTERN Node* addtop;
EXTERN Node* typeswvar; EXTERN Node* typeswvar;
EXTERN char* context; EXTERN char* structpkg;
EXTERN char* pkgcontext;
extern int thechar; extern int thechar;
extern char* thestring; extern char* thestring;
EXTERN char* hunk; EXTERN char* hunk;
@ -623,7 +622,7 @@ void importfile(Val*);
void cannedimports(char*, char*); void cannedimports(char*, char*);
void unimportfile(); void unimportfile();
int32 yylex(void); int32 yylex(void);
void typeinit(int lex); void typeinit(void);
void lexinit(void); void lexinit(void);
char* lexname(int); char* lexname(int);
int32 getr(void); int32 getr(void);
@ -731,7 +730,7 @@ int isnilinter(Type*);
int isddd(Type*); int isddd(Type*);
Type* maptype(Type*, Type*); Type* maptype(Type*, Type*);
Type* methtype(Type*); Type* methtype(Type*);
Sym* signame(Type*); Node* signame(Type*);
int eqtype(Type*, Type*); int eqtype(Type*, Type*);
int cvttype(Type*, Type*); int cvttype(Type*, Type*);
int eqtypenoname(Type*, Type*); int eqtypenoname(Type*, Type*);
@ -821,6 +820,7 @@ Node* renameinit(Node*);
void funchdr(Node*); void funchdr(Node*);
void funcargs(Type*); void funcargs(Type*);
void funcbody(Node*); void funcbody(Node*);
Node* typenod(Type*);
Type* dostruct(Node*, int); Type* dostruct(Node*, int);
Type** stotype(Node*, int, Type**); Type** stotype(Node*, int, Type**);
Type* sortinter(Type*); Type* sortinter(Type*);
@ -844,7 +844,7 @@ void fninit(Node*);
Node* nametoanondcl(Node*); Node* nametoanondcl(Node*);
Node* nametodcl(Node*, Type*); Node* nametodcl(Node*, Type*);
Node* anondcl(Type*); Node* anondcl(Type*);
void checkarglist(Node*); Node* checkarglist(Node*);
void checkwidth(Type*); void checkwidth(Type*);
void defercheckwidth(void); void defercheckwidth(void);
void resumecheckwidth(void); void resumecheckwidth(void);
@ -887,12 +887,12 @@ void doimport6(Node*, Node*);
void doimport7(Node*, Node*); void doimport7(Node*, Node*);
void doimport8(Node*, Val*, Node*); void doimport8(Node*, Val*, Node*);
void doimport9(Sym*, Node*); void doimport9(Sym*, Node*);
void importconst(Node *ss, Type *t, Node *v); void importconst(Sym *s, Type *t, Node *v);
void importmethod(Sym *s, Type *t); void importmethod(Sym *s, Type *t);
void importtype(Node *ss, Type *t); void importtype(Sym *s, Type *t);
void importvar(Node *ss, Type *t, int ctxt); void importvar(Sym *s, Type *t, int ctxt);
void checkimports(void); void checkimports(void);
Type* pkgtype(char*, char*); Type* pkgtype(Sym*);
/* /*
* walk.c * walk.c

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ main(int argc, char *argv[])
fatal("betypeinit failed"); fatal("betypeinit failed");
lexinit(); lexinit();
typeinit(LATYPE); typeinit();
lineno = 1; lineno = 1;
block = 1; block = 1;
@ -711,6 +711,40 @@ l0:
} }
break; break;
/*
* clumsy dance:
* to implement rule that disallows
* if T{1}[0] { ... }
* but allows
* if (T{1}[0]) { ... }
* the block bodies for if/for/switch/select
* begin with an LBODY token, not '{'.
*
* when we see the keyword, the next
* non-parenthesized '{' becomes an LBODY.
* loophack is normally 0.
* a keyword makes it go up to 1.
* parens increment and decrement when loophack > 0.
* a '{' with loophack == 1 becomes LBODY and disables loophack.
*
* i said it was clumsy.
*/
case '(':
if(loophack > 0)
loophack++;
goto lx;
case ')':
if(loophack > 0)
loophack--;
goto lx;
case '{':
if(loophack == 1) {
DBG("%L lex: LBODY\n", lineno);
loophack = 0;
return LBODY;
}
goto lx;
default: default:
goto lx; goto lx;
} }
@ -764,15 +798,16 @@ talph:
ungetc(c); ungetc(c);
s = lookup(lexbuf); s = lookup(lexbuf);
if(s->lexical == LIGNORE) switch(s->lexical) {
case LIGNORE:
goto l0; goto l0;
if(context != nil) { case LFOR:
s = pkglookup(s->name, context); case LIF:
if(s->lexical == LIGNORE) case LSWITCH:
goto l0; case LSELECT:
if(!exportname(s->name) && strcmp(package, s->package) != 0) loophack = 1; // see comment about loophack above
s = pkglookup(s->name, ".private"); break;
} }
DBG("lex: %S %s\n", s, lexname(s->lexical)); DBG("lex: %S %s\n", s, lexname(s->lexical));
@ -1109,77 +1144,74 @@ static struct
char* name; char* name;
int lexical; int lexical;
int etype; int etype;
int op;
} syms[] = } syms[] =
{ {
/* name lexical etype /* name lexical etype op
*/ */
/* basic types */ /* basic types */
"int8", LATYPE, TINT8, "int8", LNAME, TINT8, OXXX,
"int16", LATYPE, TINT16, "int16", LNAME, TINT16, OXXX,
"int32", LATYPE, TINT32, "int32", LNAME, TINT32, OXXX,
"int64", LATYPE, TINT64, "int64", LNAME, TINT64, OXXX,
"uint8", LATYPE, TUINT8, "uint8", LNAME, TUINT8, OXXX,
"uint16", LATYPE, TUINT16, "uint16", LNAME, TUINT16, OXXX,
"uint32", LATYPE, TUINT32, "uint32", LNAME, TUINT32, OXXX,
"uint64", LATYPE, TUINT64, "uint64", LNAME, TUINT64, OXXX,
"float32", LATYPE, TFLOAT32, "float32", LNAME, TFLOAT32, OXXX,
"float64", LATYPE, TFLOAT64, "float64", LNAME, TFLOAT64, OXXX,
"float80", LATYPE, TFLOAT80, "float80", LNAME, TFLOAT80, OXXX,
"bool", LATYPE, TBOOL, "bool", LNAME, TBOOL, OXXX,
"byte", LATYPE, TUINT8, "byte", LNAME, TUINT8, OXXX,
"string", LATYPE, TSTRING, "string", LNAME, TSTRING, OXXX,
"any", LATYPE, TANY, "any", LNAME, TANY, OXXX,
"break", LBREAK, Txxx, "break", LBREAK, Txxx, OXXX,
"case", LCASE, Txxx, "case", LCASE, Txxx, OXXX,
"chan", LCHAN, Txxx, "chan", LCHAN, Txxx, OXXX,
"const", LCONST, Txxx, "const", LCONST, Txxx, OXXX,
"continue", LCONTINUE, Txxx, "continue", LCONTINUE, Txxx, OXXX,
"default", LDEFAULT, Txxx, "default", LDEFAULT, Txxx, OXXX,
"else", LELSE, Txxx, "else", LELSE, Txxx, OXXX,
"defer", LDEFER, Txxx, "defer", LDEFER, Txxx, OXXX,
"fallthrough", LFALL, Txxx, "fallthrough", LFALL, Txxx, OXXX,
"false", LFALSE, Txxx, "for", LFOR, Txxx, OXXX,
"for", LFOR, Txxx, "func", LFUNC, Txxx, OXXX,
"func", LFUNC, Txxx, "go", LGO, Txxx, OXXX,
"go", LGO, Txxx, "goto", LGOTO, Txxx, OXXX,
"goto", LGOTO, Txxx, "if", LIF, Txxx, OXXX,
"if", LIF, Txxx, "import", LIMPORT, Txxx, OXXX,
"import", LIMPORT, Txxx, "interface", LINTERFACE, Txxx, OXXX,
"interface", LINTERFACE, Txxx, "map", LMAP, Txxx, OXXX,
"iota", LIOTA, Txxx, "package", LPACKAGE, Txxx, OXXX,
"make", LMAKE, Txxx, "range", LRANGE, Txxx, OXXX,
"map", LMAP, Txxx, "return", LRETURN, Txxx, OXXX,
"new", LNEW, Txxx, "select", LSELECT, Txxx, OXXX,
"len", LLEN, Txxx, "struct", LSTRUCT, Txxx, OXXX,
"cap", LCAP, Txxx, "switch", LSWITCH, Txxx, OXXX,
"nil", LNIL, Txxx, "type", LTYPE, Txxx, OXXX,
"package", LPACKAGE, Txxx, "var", LVAR, Txxx, OXXX,
"panic", LPANIC, Txxx,
"panicln", LPANICN, Txxx,
"print", LPRINT, Txxx,
"println", LPRINTN, Txxx,
"range", LRANGE, Txxx,
"return", LRETURN, Txxx,
"select", LSELECT, Txxx,
"struct", LSTRUCT, Txxx,
"switch", LSWITCH, Txxx,
"true", LTRUE, Txxx,
"type", LTYPE, Txxx,
"var", LVAR, Txxx,
"close", LCLOSE, Txxx, "cap", LNAME, Txxx, OCAP,
"closed", LCLOSED, Txxx, "close", LNAME, Txxx, OCLOSE,
"closed", LNAME, Txxx, OCLOSED,
"len", LNAME, Txxx, OLEN,
"make", LNAME, Txxx, OMAKE,
"new", LNAME, Txxx, ONEW,
"panic", LNAME, Txxx, OPANIC,
"panicln", LNAME, Txxx, OPANICN,
"print", LNAME, Txxx, OPRINT,
"println", LNAME, Txxx, OPRINTN,
"notwithstanding", LIGNORE, Txxx, "notwithstanding", LIGNORE, Txxx, OXXX,
"thetruthofthematter", LIGNORE, Txxx, "thetruthofthematter", LIGNORE, Txxx, OXXX,
"despiteallobjections", LIGNORE, Txxx, "despiteallobjections", LIGNORE, Txxx, OXXX,
"whereas", LIGNORE, Txxx, "whereas", LIGNORE, Txxx, OXXX,
"insofaras", LIGNORE, Txxx, "insofaras", LIGNORE, Txxx, OXXX,
}; };
void void
@ -1189,6 +1221,7 @@ lexinit(void)
Sym *s; Sym *s;
Type *t; Type *t;
int etype; int etype;
Val v;
/* /*
* initialize basic types array * initialize basic types array
@ -1201,25 +1234,51 @@ lexinit(void)
s->package = package; s->package = package;
etype = syms[i].etype; etype = syms[i].etype;
if(etype == Txxx) if(etype != Txxx) {
continue; if(etype < 0 || etype >= nelem(types))
fatal("lexinit: %s bad etype", s->name);
t = types[etype];
if(t == T) {
t = typ(etype);
t->sym = s;
if(etype < 0 || etype >= nelem(types)) dowidth(t);
fatal("lexinit: %s bad etype", s->name); types[etype] = t;
}
t = types[etype]; s->def = typenod(t);
if(t != T) {
s->otype = t;
continue; continue;
} }
t = typ(etype);
t->sym = s;
dowidth(t); etype = syms[i].op;
types[etype] = t; if(etype != OXXX) {
s->otype = t; s->def = nod(ONAME, N, N);
s->def->sym = s;
s->def->etype = etype;
s->def->builtin = 1;
continue;
}
} }
// there's only so much table-driven we can handle.
// these are special cases.
types[TNIL] = typ(TNIL);
s = lookup("nil");
v.ctype = CTNIL;
s->def = nodlit(v);
s->def->sym = s;
s = lookup("true");
s->def = nodbool(1);
s->def->sym = s;
s = lookup("false");
s->def = nodbool(0);
s->def->sym = s;
s = lookup("iota");
s->def = nodintconst(iota);
s->def->iota = 1; // flag to reevaluate on copy
// logically, the type of a string literal. // logically, the type of a string literal.
// types[TSTRING] is the named type string // types[TSTRING] is the named type string
// (the type of x in var x string or var x = "hello"). // (the type of x in var x string or var x = "hello").
@ -1244,14 +1303,18 @@ struct
LCONST, "CONST", LCONST, "CONST",
LCONTINUE, "CONTINUE", LCONTINUE, "CONTINUE",
LDEC, "DEC", LDEC, "DEC",
LDEFER, "DEFER",
LELSE, "ELSE", LELSE, "ELSE",
LEQ, "EQ", LEQ, "EQ",
LFALL, "FALL",
LFOR, "FOR",
LFUNC, "FUNC", LFUNC, "FUNC",
LGE, "GE", LGE, "GE",
LGO, "GO", LGO, "GO",
LGOTO, "GOTO", LGOTO, "GOTO",
LGT, "GT", LGT, "GT",
LIF, "IF", LIF, "IF",
LIMPORT, "IMPORT",
LINC, "INC", LINC, "INC",
LINTERFACE, "INTERFACE", LINTERFACE, "INTERFACE",
LLE, "LE", LLE, "LE",
@ -1262,7 +1325,7 @@ struct
LNAME, "NAME", LNAME, "NAME",
LNE, "NE", LNE, "NE",
LOROR, "OROR", LOROR, "OROR",
LPACK, "PACK", LPACKAGE, "PACKAGE",
LRANGE, "RANGE", LRANGE, "RANGE",
LRETURN, "RETURN", LRETURN, "RETURN",
LRSH, "RSH", LRSH, "RSH",
@ -1270,16 +1333,6 @@ struct
LSWITCH, "SWITCH", LSWITCH, "SWITCH",
LTYPE, "TYPE", LTYPE, "TYPE",
LVAR, "VAR", LVAR, "VAR",
LFOR, "FOR",
LNEW, "NEW",
LLEN, "LEN",
LFALL, "FALL",
LIOTA, "IOTA",
LPRINT, "PRINT",
LPACKAGE, "PACKAGE",
LIMPORT, "IMPORT",
LDEFER, "DEFER",
LPANIC, "PANIC",
}; };
char* char*
@ -1316,8 +1369,8 @@ mkpackage(char* pkg)
// declare this name as a package // declare this name as a package
s = lookup(package); s = lookup(package);
s->lexical = LPACK; s->def = nod(OPACK, N, N);
s->opack = s->name; s->def->sym = s;
if(outfile == nil) { if(outfile == nil) {
p = strrchr(infile, '/'); p = strrchr(infile, '/');

View File

@ -58,7 +58,7 @@ dumpglobls(void)
continue; continue;
dowidth(n->type); dowidth(n->type);
ggloblnod(s->oname, n->type->width); ggloblnod(s->def, n->type->width);
} }
} }
@ -393,6 +393,7 @@ dumpsignatures(void)
Dcl *d, *x; Dcl *d, *x;
Type *t, *progt, *methodt, *ifacet, *rcvrt; Type *t, *progt, *methodt, *ifacet, *rcvrt;
Sym *s; Sym *s;
Node *n;
// copy externdcl list to signatlist // copy externdcl list to signatlist
for(d=externdcl; d!=D; d=d->forw) { for(d=externdcl; d!=D; d=d->forw) {
@ -403,9 +404,10 @@ dumpsignatures(void)
if(t == T) if(t == T)
continue; continue;
s = signame(t); n = signame(t);
if(s == S) if(n == N || n->sym == S)
continue; continue;
s = n->sym;
x = mal(sizeof(*d)); x = mal(sizeof(*d));
x->op = OTYPE; x->op = OTYPE;
@ -425,10 +427,11 @@ dumpsignatures(void)
continue; continue;
t = d->dtype; t = d->dtype;
et = t->etype; et = t->etype;
s = signame(t); n = signame(t);
//print("signame %S for %T\n", s, t); //print("signame %S for %T\n", s, t);
if(s == S) if(n == N || n->sym == S)
continue; continue;
s = n->sym;
// only emit one // only emit one
if(s->siggen) if(s->siggen)

View File

@ -156,9 +156,9 @@ lookup(char *p)
} }
s = mal(sizeof(*s)); s = mal(sizeof(*s));
s->lexical = LNAME;
s->name = mal(strlen(p)+1); s->name = mal(strlen(p)+1);
s->package = package; s->package = package;
s->lexical = LNAME;
strcpy(s->name, p); strcpy(s->name, p);
@ -186,7 +186,6 @@ pkglookup(char *p, char *k)
} }
s = mal(sizeof(*s)); s = mal(sizeof(*s));
s->lexical = LNAME;
s->name = mal(strlen(p)+1); s->name = mal(strlen(p)+1);
strcpy(s->name, p); strcpy(s->name, p);
@ -220,13 +219,11 @@ importdot(Sym *opkg)
if(strcmp(s->package, opkg->name) != 0) if(strcmp(s->package, opkg->name) != 0)
continue; continue;
s1 = lookup(s->name); s1 = lookup(s->name);
if(s1->oname != N || s1->otype != T) { if(s1->def != N) {
yyerror("redeclaration of %S during import", s1); yyerror("redeclaration of %S during import", s1);
continue; continue;
} }
s1->lexical = s->lexical; s1->def = s->def;
s1->oname = s->oname;
s1->otype = s->otype;
} }
} }
} }
@ -571,7 +568,7 @@ loop:
break; break;
case OTYPE: case OTYPE:
print("%O-%E %lT\n", n->op, n->etype, n); print("%O %T\n", n->op, n->type);
break; break;
case OIF: case OIF:
@ -696,7 +693,6 @@ opnames[] =
[OGOTO] = "GOTO", [OGOTO] = "GOTO",
[OGT] = "GT", [OGT] = "GT",
[OIF] = "IF", [OIF] = "IF",
[OIMPORT] = "IMPORT",
[OINC] = "INC", [OINC] = "INC",
[OINDEX] = "INDEX", [OINDEX] = "INDEX",
[OINDREG] = "INDREG", [OINDREG] = "INDREG",
@ -722,6 +718,7 @@ opnames[] =
[OOR] = "OR", [OOR] = "OR",
[OPANICN] = "PANICN", [OPANICN] = "PANICN",
[OPANIC] = "PANIC", [OPANIC] = "PANIC",
[OPACK] = "PACK",
[OPARAM] = "PARAM", [OPARAM] = "PARAM",
[OPLUS] = "PLUS", [OPLUS] = "PLUS",
[OPRINTN] = "PRINTN", [OPRINTN] = "PRINTN",
@ -741,7 +738,6 @@ opnames[] =
[OTYPEOF] = "TYPEOF", [OTYPEOF] = "TYPEOF",
[OTYPESW] = "TYPESW", [OTYPESW] = "TYPESW",
[OTYPE] = "TYPE", [OTYPE] = "TYPE",
[OVAR] = "VAR",
[OXCASE] = "XCASE", [OXCASE] = "XCASE",
[OXFALL] = "XFALL", [OXFALL] = "XFALL",
[OXOR] = "XOR", [OXOR] = "XOR",
@ -1044,8 +1040,11 @@ Tpretty(Fmt *fp, Type *t)
fmtprint(fp, "%hS", s); fmtprint(fp, "%hS", s);
else else
fmtprint(fp, "%lS", s); fmtprint(fp, "%lS", s);
if(strcmp(s->package, package) == 0) if(strcmp(s->package, package) != 0)
if((s->otype != t || !s->export) && !s->imported) { return 0;
if(s->imported)
return 0;
if(s->def == N || s->def->op != OTYPE || s->def->type != t || !s->export) {
fmtprint(fp, "·%s", filename); fmtprint(fp, "·%s", filename);
if(t->vargen) if(t->vargen)
fmtprint(fp, "·%d", t->vargen); fmtprint(fp, "·%d", t->vargen);
@ -1339,7 +1338,7 @@ Nconv(Fmt *fp)
break; break;
case OTYPE: case OTYPE:
snprint(buf, sizeof(buf), "%O-%E%J", n->op, n->etype, n); snprint(buf, sizeof(buf), "%O %T", n->op, n->type);
break; break;
} }
if(n->sym != S) { if(n->sym != S) {
@ -1581,7 +1580,7 @@ iscomposite(Type *t)
return 0; return 0;
} }
Sym* Node*
signame(Type *t) signame(Type *t)
{ {
Sym *ss; Sym *ss;
@ -1611,10 +1610,10 @@ signame(Type *t)
strcpy(buf, "dotdotdot"); strcpy(buf, "dotdotdot");
ss = pkglookup(buf, e); ss = pkglookup(buf, e);
if(ss->oname == N) { if(ss->def == N) {
ss->oname = newname(ss); ss->def = newname(ss);
ss->oname->type = types[TUINT8]; ss->def->type = types[TUINT8];
ss->oname->class = PEXTERN; ss->def->class = PEXTERN;
} }
//print("siggen %T %d\n", t, t->siggen); //print("siggen %T %d\n", t, t->siggen);
@ -1633,10 +1632,10 @@ signame(Type *t)
} }
out: out:
return ss; return ss->def;
bad: bad:
return S; return N;
} }
int int
@ -1942,15 +1941,15 @@ syslook(char *name, int copy)
Node *n; Node *n;
s = pkglookup(name, "sys"); s = pkglookup(name, "sys");
if(s == S || s->oname == N) if(s == S || s->def == N)
fatal("looksys: cant find sys.%s", name); fatal("looksys: cant find sys.%s", name);
if(!copy) if(!copy)
return s->oname; return s->def;
n = nod(0, N, N); n = nod(0, N, N);
*n = *s->oname; *n = *s->def;
n->type = deep(s->oname->type); n->type = deep(s->def->type);
return n; return n;
} }
@ -2073,7 +2072,7 @@ frame(int context)
case OTYPE: case OTYPE:
if(flag) if(flag)
print("--- %s frame ---\n", p); print("--- %s frame ---\n", p);
print("%O %lT\n", d->op, d->dnode); print("%O %T\n", d->op, d->dnode);
flag = 0; flag = 0;
break; break;
} }

View File

@ -123,8 +123,16 @@ loop:
return; return;
more = N; more = N;
if(n->op != ONAME) switch(n->op) {
case ONAME: // one only; lineno isn't right for right now
case OPACK:
case OTYPE:
case OLITERAL:
break;
default:
lineno = n->lineno; lineno = n->lineno;
}
switch(n->op) { switch(n->op) {
case OLIST: case OLIST:
@ -248,6 +256,7 @@ loop:
switch(n->op) { switch(n->op) {
default: default:
dump("walk", n);
fatal("walktype: switch 1 unknown op %N", n); fatal("walktype: switch 1 unknown op %N", n);
goto ret; goto ret;
@ -313,7 +322,10 @@ loop:
if(n->type == T) { if(n->type == T) {
s = n->sym; s = n->sym;
if(s->undef == 0) { if(s->undef == 0) {
yyerror("walktype: %S undeclared", s); if(n->etype != 0)
yyerror("walktype: %S must be called", s);
else
yyerror("walktype: %S undeclared", s);
s->undef = 1; s->undef = 1;
} }
} }
@ -1030,20 +1042,28 @@ loop:
case OMAKE: case OMAKE:
if(top != Erv) if(top != Erv)
goto nottop; goto nottop;
l = n->left;
if(l == N) {
yyerror("missing argument to make");
goto ret;
}
indir(n, makecompat(n)); indir(n, makecompat(n));
goto ret; goto ret;
case ONEW: case ONEW:
if(top != Erv) if(top != Erv)
goto nottop; goto nottop;
if(n->left != N) { l = n->left;
yyerror("cannot new(%T, expr)", t); if(l == N)
goto ret; yyerror("missing argument to new");
} else if(n->right != N)
t = n->type; yyerror("too many arguments to new");
if(t == T) else if(l->op != OTYPE)
goto ret; yyerror("argument to new must be type");
indir(n, callnew(t)); else if((t = l->type) == T)
;
else
indir(n, callnew(t));
goto ret; goto ret;
} }
@ -1927,12 +1947,12 @@ sigtype(Type *st)
x = mal(sizeof(*x)); x = mal(sizeof(*x));
x->op = OTYPE; x->op = OTYPE;
x->dsym = s; x->dsym = s;
x->dtype = s->otype; x->dtype = t;
x->forw = signatlist; x->forw = signatlist;
x->block = block; x->block = block;
signatlist = x; signatlist = x;
return s->otype; return t;
} }
/* /*
@ -2350,8 +2370,22 @@ Node*
makecompat(Node *n) makecompat(Node *n)
{ {
Type *t; Type *t;
Node *l, *r;
t = n->type; l = n->left;
r = N;
if(l->op == OLIST) {
r = l->right;
l = l->left;
}
if(l->op != OTYPE) {
yyerror("cannot make(expr)");
return n;
}
t = l->type;
n->type = t;
n->left = r;
n->right = N;
if(t != T) if(t != T)
switch(t->etype) { switch(t->etype) {
@ -3045,9 +3079,8 @@ arrayop(Node *n, int top)
a = listfirst(&save, &n->left); // nel a = listfirst(&save, &n->left); // nel
if(a == N) { if(a == N) {
if(t->bound < 0) yyerror("new slice must have size");
yyerror("new open array must have size"); a = nodintconst(1);
a = nodintconst(t->bound);
} }
a = nod(OCONV, a, N); a = nod(OCONV, a, N);
a->type = types[TINT]; a->type = types[TINT];
@ -3193,7 +3226,6 @@ ifacecvt(Type *tl, Node *n, int et)
{ {
Type *tr; Type *tr;
Node *r, *a, *on; Node *r, *a, *on;
Sym *s;
tr = n->type; tr = n->type;
@ -3207,19 +3239,10 @@ ifacecvt(Type *tl, Node *n, int et)
a = n; // elem a = n; // elem
r = a; r = a;
s = signame(tr); // sigt a = nod(OADDR, signame(tr), N); // sigt
if(s == S)
fatal("ifacecvt: signame-1 T2I: %lT", tr);
a = s->oname;
a = nod(OADDR, a, N);
r = list(a, r); r = list(a, r);
s = signame(tl); // sigi a = nod(OADDR, signame(tl), N); // sigi
if(s == S) {
fatal("ifacecvt: signame-2 T2I: %lT", tl);
}
a = s->oname;
a = nod(OADDR, a, N);
r = list(a, r); r = list(a, r);
on = syslook("ifaceT2I", 1); on = syslook("ifaceT2I", 1);
@ -3240,11 +3263,7 @@ ifacecvt(Type *tl, Node *n, int et)
a = n; // interface a = n; // interface
r = a; r = a;
s = signame(tl); // sigi or sigt a = nod(OADDR, signame(tl), N); // sigi or sigt
if(s == S)
fatal("ifacecvt: signame %d", et);
a = s->oname;
a = nod(OADDR, a, N);
r = list(a, r); r = list(a, r);
on = syslook(ifacename[et], 1); on = syslook(ifacename[et], 1);
@ -3268,11 +3287,7 @@ ifacecvt(Type *tl, Node *n, int et)
a = n; // elem a = n; // elem
r = a; r = a;
s = signame(tr); // sigt a = nod(OADDR, signame(tr), N); // sigt
if(s == S)
fatal("ifacecvt: signame-1 T2E: %lT", tr);
a = s->oname;
a = nod(OADDR, a, N);
r = list(a, r); r = list(a, r);
on = syslook("ifaceT2E", 1); on = syslook("ifaceT2E", 1);
@ -3394,7 +3409,9 @@ colasname(Node *n)
switch(n->op) { switch(n->op) {
case ONAME: case ONAME:
case ONONAME: case ONONAME:
case OPACK:
break; break;
case OTYPE:
case OLITERAL: case OLITERAL:
if(n->sym != S) if(n->sym != S)
break; break;
@ -4248,9 +4265,7 @@ arraylit(Node *n, Node *var)
if(b < 0) { if(b < 0) {
// slice // slice
a = nod(OMAKE, N, N); a = nod(OMAKE, nod(OLIST, typenod(t), nodintconst(ninit)), N);
a->type = t;
a->left = nodintconst(ninit);
a = nod(OAS, var, a); a = nod(OAS, var, a);
addtop = list(addtop, a); addtop = list(addtop, a);
} else { } else {
@ -4377,8 +4392,7 @@ maplit(Node *n, Node *var)
tempname(var, t); tempname(var, t);
} }
a = nod(OMAKE, N, N); a = nod(OMAKE, typenod(t), N);
a->type = t;
a = nod(OAS, var, a); a = nod(OAS, var, a);
addtop = list(addtop, a); addtop = list(addtop, a);