mirror of
https://github.com/golang/go
synced 2024-11-25 13:27:57 -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:
parent
ea33ff4067
commit
8f4af6d205
@ -208,7 +208,7 @@ dowidth(Type *t)
|
||||
}
|
||||
|
||||
void
|
||||
typeinit(int lex)
|
||||
typeinit(void)
|
||||
{
|
||||
int i, etype, sameas;
|
||||
Type *t;
|
||||
@ -306,7 +306,7 @@ typeinit(int lex)
|
||||
types[TFUNC] = functype(N, N, N);
|
||||
|
||||
/* types used in front end */
|
||||
types[TNIL] = typ(TNIL);
|
||||
// types[TNIL] got set early in lexinit
|
||||
types[TIDEAL] = typ(TIDEAL);
|
||||
|
||||
/* simple aliases */
|
||||
@ -317,7 +317,6 @@ typeinit(int lex)
|
||||
/* pick up the backend typedefs */
|
||||
for(i=0; typedefs[i].name; i++) {
|
||||
s = lookup(typedefs[i].name);
|
||||
s->lexical = lex;
|
||||
|
||||
etype = typedefs[i].etype;
|
||||
if(etype < 0 || etype >= nelem(types))
|
||||
@ -340,7 +339,7 @@ typeinit(int lex)
|
||||
|
||||
dowidth(t);
|
||||
types[etype] = t;
|
||||
s->otype = t;
|
||||
s->def = typenod(t);
|
||||
}
|
||||
|
||||
Array_array = rnd(0, widthptr);
|
||||
|
213
src/cmd/gc/dcl.c
213
src/cmd/gc/dcl.c
@ -67,11 +67,11 @@ dodcltype(Type *n)
|
||||
// if n has been forward declared,
|
||||
// use the Type* created then
|
||||
s = n->sym;
|
||||
if(s->block == block && s->otype != T) {
|
||||
switch(s->otype->etype) {
|
||||
if(s->block == block && s->def != N && s->def->op == OTYPE) {
|
||||
switch(s->def->type->etype) {
|
||||
case TFORWSTRUCT:
|
||||
case TFORWINTER:
|
||||
n = s->otype;
|
||||
n = s->def->type;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
@ -95,7 +95,7 @@ updatetype(Type *n, Type *t)
|
||||
int local;
|
||||
|
||||
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);
|
||||
|
||||
switch(n->etype) {
|
||||
@ -132,7 +132,7 @@ updatetype(Type *n, Type *t)
|
||||
n->printed = 0;
|
||||
n->method = nil;
|
||||
n->vargen = 0;
|
||||
|
||||
n->nod = N;
|
||||
// catch declaration of incomplete type
|
||||
switch(n->etype) {
|
||||
case TFORWSTRUCT:
|
||||
@ -306,7 +306,7 @@ addmethod(Node *n, Type *t, int local)
|
||||
goto bad;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -383,7 +383,9 @@ funchdr(Node *n)
|
||||
Sym *s;
|
||||
|
||||
s = n->nname->sym;
|
||||
on = s->oname;
|
||||
on = s->def;
|
||||
if(on != N && (on->op != ONAME || on->builtin))
|
||||
on = N;
|
||||
|
||||
// check for same types
|
||||
if(on != N) {
|
||||
@ -748,7 +750,7 @@ loop:
|
||||
f->embedded = n->embedded;
|
||||
f->sym = f->nname->sym;
|
||||
if(pkgimportname != S && !exportname(f->sym->name))
|
||||
f->sym = pkglookup(f->sym->name, pkgcontext);
|
||||
f->sym = pkglookup(f->sym->name, structpkg);
|
||||
}
|
||||
|
||||
*t = f;
|
||||
@ -793,11 +795,8 @@ void
|
||||
dcopy(Sym *a, Sym *b)
|
||||
{
|
||||
a->name = b->name;
|
||||
a->oname = b->oname;
|
||||
a->otype = b->otype;
|
||||
a->oconst = b->oconst;
|
||||
a->def = b->def;
|
||||
a->package = b->package;
|
||||
a->lexical = b->lexical;
|
||||
a->undef = b->undef;
|
||||
a->vargen = b->vargen;
|
||||
a->block = b->block;
|
||||
@ -954,11 +953,8 @@ addvar(Node *n, Type *t, int ctxt)
|
||||
|
||||
redeclare("variable", s);
|
||||
s->vargen = gen;
|
||||
s->oname = n;
|
||||
s->def = n;
|
||||
s->offset = 0;
|
||||
s->oconst = nil;
|
||||
s->otype = nil;
|
||||
s->lexical = LNAME;
|
||||
|
||||
n->funcdepth = funcdepth;
|
||||
n->type = t;
|
||||
@ -1004,10 +1000,7 @@ addtyp(Type *n, int ctxt)
|
||||
}
|
||||
|
||||
redeclare("type", s);
|
||||
s->otype = n;
|
||||
s->oconst = nil;
|
||||
s->oname = nil;
|
||||
s->lexical = LATYPE;
|
||||
s->def = typenod(n);
|
||||
|
||||
d = dcl();
|
||||
d->dsym = s;
|
||||
@ -1041,7 +1034,7 @@ addconst(Node *n, Node *e, int ctxt)
|
||||
Sym *s;
|
||||
Dcl *r, *d;
|
||||
|
||||
if(n->op != ONAME)
|
||||
if(n->op != ONAME && n->op != ONONAME)
|
||||
fatal("addconst: not a name");
|
||||
|
||||
if(e->op != OLITERAL) {
|
||||
@ -1059,10 +1052,8 @@ addconst(Node *n, Node *e, int ctxt)
|
||||
}
|
||||
|
||||
redeclare("constant", s);
|
||||
s->oconst = e;
|
||||
s->otype = nil;
|
||||
s->oname = nil;
|
||||
s->lexical = LNAME;
|
||||
s->def = e;
|
||||
e->sym = s;
|
||||
|
||||
d = dcl();
|
||||
d->dsym = s;
|
||||
@ -1073,7 +1064,7 @@ addconst(Node *n, Node *e, int ctxt)
|
||||
r->back = d;
|
||||
|
||||
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*
|
||||
@ -1130,6 +1121,18 @@ newname(Sym *s)
|
||||
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
|
||||
* that has already been pushed on the
|
||||
@ -1142,15 +1145,7 @@ oldname(Sym *s)
|
||||
Node *n;
|
||||
Node *c;
|
||||
|
||||
if(s->oconst) {
|
||||
n = nod(OLITERAL, N, N);
|
||||
n->sym = s;
|
||||
n->val = s->oconst->val;
|
||||
n->type = s->oconst->type;
|
||||
return n;
|
||||
}
|
||||
|
||||
n = s->oname;
|
||||
n = s->def;
|
||||
if(n == N) {
|
||||
n = nod(ONONAME, N, N);
|
||||
n->sym = s;
|
||||
@ -1158,7 +1153,15 @@ oldname(Sym *s)
|
||||
n->addable = 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
|
||||
// in outer func.
|
||||
if(n->closure == N || n->closure->funcdepth != funcdepth) {
|
||||
@ -1200,9 +1203,19 @@ oldtype(Sym *s)
|
||||
{
|
||||
Type *t;
|
||||
|
||||
t = s->otype;
|
||||
if(t == T)
|
||||
fatal("%S not a type", s); // cant happen
|
||||
if(s->def == N || s->def->op != OTYPE) {
|
||||
yyerror("%S is not a type", s);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1219,9 +1232,9 @@ nametoanondcl(Node *na)
|
||||
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
|
||||
n->right = nametoanondcl(n->right);
|
||||
|
||||
t = n->sym->otype;
|
||||
if(t == T) {
|
||||
yyerror("%s is not a type", n->sym->name);
|
||||
n = n->sym->def;
|
||||
if(n == N || n->op != OTYPE || (t = n->type) == T) {
|
||||
yyerror("%S is not a type", n->sym);
|
||||
t = typ(TINT32);
|
||||
}
|
||||
n = nod(ODCLFIELD, N, N);
|
||||
@ -1261,33 +1274,95 @@ anondcl(Type *t)
|
||||
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
|
||||
*/
|
||||
void
|
||||
Node*
|
||||
checkarglist(Node *n)
|
||||
{
|
||||
if(n->op != OLIST)
|
||||
return;
|
||||
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;
|
||||
Node *r;
|
||||
Node **l;
|
||||
|
||||
mixed:
|
||||
yyerror("cannot mix anonymous and named function arguments");
|
||||
// check for all anonymous
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1325,7 +1400,7 @@ anyinit(Node *n)
|
||||
// is there an explicit init function
|
||||
snprint(namebuf, sizeof(namebuf), "init·%s", filename);
|
||||
s = lookup(namebuf);
|
||||
if(s->oname != N)
|
||||
if(s->def != N)
|
||||
return 1;
|
||||
|
||||
// are there any imported init functions
|
||||
@ -1333,7 +1408,7 @@ anyinit(Node *n)
|
||||
for(s = hash[h]; s != S; s = s->link) {
|
||||
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
|
||||
continue;
|
||||
if(s->oname == N)
|
||||
if(s->def == N)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
@ -1409,13 +1484,13 @@ fninit(Node *n)
|
||||
for(s = hash[h]; s != S; s = s->link) {
|
||||
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
|
||||
continue;
|
||||
if(s->oname == N)
|
||||
if(s->def == N)
|
||||
continue;
|
||||
if(s == initsym)
|
||||
continue;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -1426,8 +1501,8 @@ fninit(Node *n)
|
||||
// could check that it is fn of no args/returns
|
||||
snprint(namebuf, sizeof(namebuf), "init·%s", filename);
|
||||
s = lookup(namebuf);
|
||||
if(s->oname != N) {
|
||||
a = nod(OCALL, s->oname, N);
|
||||
if(s->def != N) {
|
||||
a = nod(OCALL, s->def, N);
|
||||
r = list(r, a);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ dumpexportconst(Sym *s)
|
||||
Node *n;
|
||||
Type *t;
|
||||
|
||||
n = s->oconst;
|
||||
n = s->def;
|
||||
if(n == N || n->op != OLITERAL)
|
||||
fatal("dumpexportconst: oconst nil: %S", s);
|
||||
|
||||
@ -141,7 +141,7 @@ dumpexportvar(Sym *s)
|
||||
Node *n;
|
||||
Type *t;
|
||||
|
||||
n = s->oname;
|
||||
n = s->def;
|
||||
if(n == N || n->type == T) {
|
||||
yyerror("variable exported but not defined: %S", s);
|
||||
return;
|
||||
@ -161,48 +161,53 @@ dumpexportvar(Sym *s)
|
||||
void
|
||||
dumpexporttype(Sym *s)
|
||||
{
|
||||
dumpprereq(s->otype);
|
||||
Type *t;
|
||||
|
||||
t = s->def->type;
|
||||
dumpprereq(t);
|
||||
Bprint(bout, "\t");
|
||||
switch (s->otype->etype) {
|
||||
switch (t->etype) {
|
||||
case TFORW:
|
||||
case TFORWSTRUCT:
|
||||
case TFORWINTER:
|
||||
yyerror("export of incomplete type %T", s->otype);
|
||||
yyerror("export of incomplete type %T", t);
|
||||
return;
|
||||
}
|
||||
Bprint(bout, "type %#T %l#T\n", s->otype, s->otype);
|
||||
Bprint(bout, "type %#T %l#T\n", t, t);
|
||||
}
|
||||
|
||||
void
|
||||
dumpsym(Sym *s)
|
||||
{
|
||||
Type *f;
|
||||
Type *f, *t;
|
||||
|
||||
if(s->exported != 0)
|
||||
return;
|
||||
s->exported = 1;
|
||||
|
||||
switch(s->lexical) {
|
||||
default:
|
||||
if(s->def == N) {
|
||||
yyerror("unknown export symbol: %S", s);
|
||||
return;
|
||||
}
|
||||
switch(s->def->op) {
|
||||
default:
|
||||
yyerror("unexpected export symbol: %O %S", s->def->op, s);
|
||||
break;
|
||||
case LPACK:
|
||||
yyerror("package export symbol: %S", s);
|
||||
case OLITERAL:
|
||||
dumpexportconst(s);
|
||||
break;
|
||||
case LATYPE:
|
||||
case OTYPE:
|
||||
t = s->def->type;
|
||||
// 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);
|
||||
|
||||
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",
|
||||
f->type->type->type, f->sym, f->type);
|
||||
break;
|
||||
case LNAME:
|
||||
if(s->oconst)
|
||||
dumpexportconst(s);
|
||||
else
|
||||
case ONAME:
|
||||
dumpexportvar(s);
|
||||
break;
|
||||
}
|
||||
@ -216,7 +221,7 @@ dumptype(Type *t)
|
||||
return;
|
||||
|
||||
// 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;
|
||||
|
||||
Bprint(bout, "type %#T %l#T\n", t, t);
|
||||
@ -256,43 +261,22 @@ dumpexport(void)
|
||||
* 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
|
||||
*/
|
||||
Sym*
|
||||
importsym(Node *ss, int lexical)
|
||||
importsym(Sym *s, int op)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
if(ss->op != OIMPORT)
|
||||
fatal("importsym: oops1 %N", ss);
|
||||
|
||||
s = pkgsym(ss->sym->name, ss->psym->name, lexical);
|
||||
/* TODO botch - need some diagnostic checking for the following assignment */
|
||||
if(exportname(ss->sym->name))
|
||||
if(s->def != N && s->def->op != op) {
|
||||
// Clumsy hack for
|
||||
// package parser
|
||||
// import "go/parser" // defines type parser
|
||||
if(s == lookup(package))
|
||||
s->def = N;
|
||||
else
|
||||
yyerror("redeclaration of %lS during import", s, s->def->op, op);
|
||||
}
|
||||
if(exportname(s->name))
|
||||
s->export = 1;
|
||||
else
|
||||
s->export = 2; // package scope
|
||||
@ -304,47 +288,36 @@ importsym(Node *ss, int lexical)
|
||||
* return the type pkg.name, forward declaring if needed
|
||||
*/
|
||||
Type*
|
||||
pkgtype(char *name, char *pkg)
|
||||
pkgtype(Sym *s)
|
||||
{
|
||||
Sym *s;
|
||||
Type *t;
|
||||
|
||||
// botch
|
||||
// s = pkgsym(name, pkg, LATYPE);
|
||||
Node *n;
|
||||
n = nod(OIMPORT, N, N);
|
||||
n->sym = lookup(name);
|
||||
n->psym = lookup(pkg);
|
||||
s = importsym(n, LATYPE);
|
||||
|
||||
if(s->otype == T) {
|
||||
importsym(s, OTYPE);
|
||||
if(s->def == N || s->def->op != OTYPE) {
|
||||
t = typ(TFORW);
|
||||
t->sym = s;
|
||||
s->otype = t;
|
||||
s->def = typenod(t);
|
||||
}
|
||||
return s->otype;
|
||||
return s->def->type;
|
||||
}
|
||||
|
||||
static int
|
||||
mypackage(Node *ss)
|
||||
mypackage(Sym *s)
|
||||
{
|
||||
// we import all definitions for sys.
|
||||
// lowercase ones can only be used by the compiler.
|
||||
return strcmp(ss->psym->name, package) == 0
|
||||
|| strcmp(ss->psym->name, "sys") == 0;
|
||||
return strcmp(s->package, package) == 0
|
||||
|| strcmp(s->package, "sys") == 0;
|
||||
}
|
||||
|
||||
void
|
||||
importconst(Node *ss, Type *t, Node *n)
|
||||
importconst(Sym *s, Type *t, Node *n)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
if(!exportname(ss->sym->name) && !mypackage(ss))
|
||||
if(!exportname(s->name) && !mypackage(s))
|
||||
return;
|
||||
|
||||
importsym(s, OLITERAL);
|
||||
convlit(n, t);
|
||||
s = importsym(ss, LNAME);
|
||||
if(s->oconst != N) {
|
||||
if(s->def != N) {
|
||||
// TODO: check if already the same.
|
||||
return;
|
||||
}
|
||||
@ -356,19 +329,17 @@ importconst(Node *ss, Type *t, Node *n)
|
||||
}
|
||||
|
||||
void
|
||||
importvar(Node *ss, Type *t, int ctxt)
|
||||
importvar(Sym *s, Type *t, int ctxt)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
if(!exportname(ss->sym->name) && !mypackage(ss))
|
||||
if(!exportname(s->name) && !mypackage(s))
|
||||
return;
|
||||
|
||||
s = importsym(ss, LNAME);
|
||||
if(s->oname != N) {
|
||||
if(cvttype(t, s->oname->type))
|
||||
importsym(s, ONAME);
|
||||
if(s->def != N && s->def->op == ONAME) {
|
||||
if(cvttype(t, s->def->type))
|
||||
return;
|
||||
warn("redeclare import var %S from %T to %T",
|
||||
s, s->oname->type, t);
|
||||
s, s->def->type, t);
|
||||
}
|
||||
checkwidth(t);
|
||||
addvar(newname(s), t, ctxt);
|
||||
@ -378,25 +349,34 @@ importvar(Node *ss, Type *t, int ctxt)
|
||||
}
|
||||
|
||||
void
|
||||
importtype(Node *ss, Type *t)
|
||||
importtype(Sym *s, Type *t)
|
||||
{
|
||||
Sym *s;
|
||||
Node *n;
|
||||
Type *tt;
|
||||
|
||||
s = importsym(ss, LATYPE);
|
||||
if(s->otype != T) {
|
||||
if(cvttype(t, s->otype))
|
||||
importsym(s, OTYPE);
|
||||
n = s->def;
|
||||
if(n != N && n->op == OTYPE) {
|
||||
if(cvttype(t, n->type))
|
||||
return;
|
||||
if(s->otype->etype != TFORW) {
|
||||
if(n->type->etype != TFORW) {
|
||||
warn("redeclare import type %S from %lT to %lT",
|
||||
s, s->otype, t);
|
||||
s->otype = typ(0);
|
||||
s, n->type, t);
|
||||
n = s->def = typenod(typ(0));
|
||||
}
|
||||
}
|
||||
if(s->otype == T)
|
||||
s->otype = typ(0);
|
||||
*s->otype = *t;
|
||||
s->otype->sym = s;
|
||||
checkwidth(s->otype);
|
||||
if(n == N || n->op != OTYPE) {
|
||||
tt = typ(0);
|
||||
tt->sym = s;
|
||||
n = typenod(tt);
|
||||
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'])
|
||||
print("import type %S %lT\n", s, t);
|
||||
@ -425,7 +405,9 @@ return;
|
||||
|
||||
for(h=0; h<NHASH; h++)
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
@ -145,6 +145,8 @@ struct Type
|
||||
uchar copyany;
|
||||
uchar local; // created in this file
|
||||
|
||||
Node* nod; // canonical OTYPE node
|
||||
|
||||
// TFUNCT
|
||||
uchar thistuple;
|
||||
uchar outtuple;
|
||||
@ -187,6 +189,7 @@ struct Node
|
||||
uchar diag; // already printed error about this
|
||||
uchar noescape; // ONAME never move to heap
|
||||
uchar funcdepth;
|
||||
uchar builtin; // built-in name, like len or close
|
||||
|
||||
// most nodes
|
||||
Node* left;
|
||||
@ -247,10 +250,7 @@ struct Sym
|
||||
|
||||
char* package; // package name
|
||||
char* name; // variable name
|
||||
Node* oname; // ONAME node if a var
|
||||
Type* otype; // TYPE node if a type
|
||||
Node* oconst; // OLITERAL node if a const
|
||||
char* opack; // package reference if lexical == LPACK
|
||||
Node* def; // definition: ONAME OTYPE OPACK or OLITERAL
|
||||
vlong offset; // stack location if automatic
|
||||
int32 lexical;
|
||||
int32 vargen; // unique variable number
|
||||
@ -298,9 +298,8 @@ enum
|
||||
{
|
||||
OXXX,
|
||||
|
||||
OTYPE, OVAR, OIMPORT,
|
||||
|
||||
ONAME, ONONAME, ODCL,
|
||||
ONAME, ONONAME, OTYPE, OPACK, OLITERAL,
|
||||
ODCL,
|
||||
ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
|
||||
ODCLFUNC, ODCLFIELD, ODCLARG,
|
||||
OLIST, OCMP, OPTR, OARRAY, ORANGE,
|
||||
@ -325,7 +324,7 @@ enum
|
||||
OCALL, OCALLMETH, OCALLINTER,
|
||||
OINDEX, OSLICE,
|
||||
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
|
||||
OLITERAL, OREGISTER, OINDREG,
|
||||
OREGISTER, OINDREG,
|
||||
OKEY, OPARAM,
|
||||
OCOMPOS, OCOMPSLICE, OCOMPMAP,
|
||||
OCONV,
|
||||
@ -573,6 +572,7 @@ EXTERN int importflag;
|
||||
EXTERN int inimportsys;
|
||||
EXTERN int initflag; // compiling the init fn
|
||||
EXTERN int statuniqgen; // name generator for static temps
|
||||
EXTERN int loophack;
|
||||
|
||||
EXTERN uint32 iota;
|
||||
EXTERN Node* lastconst;
|
||||
@ -595,8 +595,7 @@ EXTERN Node* fskel;
|
||||
EXTERN Node* addtop;
|
||||
EXTERN Node* typeswvar;
|
||||
|
||||
EXTERN char* context;
|
||||
EXTERN char* pkgcontext;
|
||||
EXTERN char* structpkg;
|
||||
extern int thechar;
|
||||
extern char* thestring;
|
||||
EXTERN char* hunk;
|
||||
@ -623,7 +622,7 @@ void importfile(Val*);
|
||||
void cannedimports(char*, char*);
|
||||
void unimportfile();
|
||||
int32 yylex(void);
|
||||
void typeinit(int lex);
|
||||
void typeinit(void);
|
||||
void lexinit(void);
|
||||
char* lexname(int);
|
||||
int32 getr(void);
|
||||
@ -731,7 +730,7 @@ int isnilinter(Type*);
|
||||
int isddd(Type*);
|
||||
Type* maptype(Type*, Type*);
|
||||
Type* methtype(Type*);
|
||||
Sym* signame(Type*);
|
||||
Node* signame(Type*);
|
||||
int eqtype(Type*, Type*);
|
||||
int cvttype(Type*, Type*);
|
||||
int eqtypenoname(Type*, Type*);
|
||||
@ -821,6 +820,7 @@ Node* renameinit(Node*);
|
||||
void funchdr(Node*);
|
||||
void funcargs(Type*);
|
||||
void funcbody(Node*);
|
||||
Node* typenod(Type*);
|
||||
Type* dostruct(Node*, int);
|
||||
Type** stotype(Node*, int, Type**);
|
||||
Type* sortinter(Type*);
|
||||
@ -844,7 +844,7 @@ void fninit(Node*);
|
||||
Node* nametoanondcl(Node*);
|
||||
Node* nametodcl(Node*, Type*);
|
||||
Node* anondcl(Type*);
|
||||
void checkarglist(Node*);
|
||||
Node* checkarglist(Node*);
|
||||
void checkwidth(Type*);
|
||||
void defercheckwidth(void);
|
||||
void resumecheckwidth(void);
|
||||
@ -887,12 +887,12 @@ void doimport6(Node*, Node*);
|
||||
void doimport7(Node*, Node*);
|
||||
void doimport8(Node*, Val*, 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 importtype(Node *ss, Type *t);
|
||||
void importvar(Node *ss, Type *t, int ctxt);
|
||||
void importtype(Sym *s, Type *t);
|
||||
void importvar(Sym *s, Type *t, int ctxt);
|
||||
void checkimports(void);
|
||||
Type* pkgtype(char*, char*);
|
||||
Type* pkgtype(Sym*);
|
||||
|
||||
/*
|
||||
* walk.c
|
||||
|
806
src/cmd/gc/go.y
806
src/cmd/gc/go.y
File diff suppressed because it is too large
Load Diff
233
src/cmd/gc/lex.c
233
src/cmd/gc/lex.c
@ -64,7 +64,7 @@ main(int argc, char *argv[])
|
||||
fatal("betypeinit failed");
|
||||
|
||||
lexinit();
|
||||
typeinit(LATYPE);
|
||||
typeinit();
|
||||
|
||||
lineno = 1;
|
||||
block = 1;
|
||||
@ -711,6 +711,40 @@ l0:
|
||||
}
|
||||
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:
|
||||
goto lx;
|
||||
}
|
||||
@ -764,15 +798,16 @@ talph:
|
||||
ungetc(c);
|
||||
|
||||
s = lookup(lexbuf);
|
||||
if(s->lexical == LIGNORE)
|
||||
switch(s->lexical) {
|
||||
case LIGNORE:
|
||||
goto l0;
|
||||
|
||||
if(context != nil) {
|
||||
s = pkglookup(s->name, context);
|
||||
if(s->lexical == LIGNORE)
|
||||
goto l0;
|
||||
if(!exportname(s->name) && strcmp(package, s->package) != 0)
|
||||
s = pkglookup(s->name, ".private");
|
||||
case LFOR:
|
||||
case LIF:
|
||||
case LSWITCH:
|
||||
case LSELECT:
|
||||
loophack = 1; // see comment about loophack above
|
||||
break;
|
||||
}
|
||||
|
||||
DBG("lex: %S %s\n", s, lexname(s->lexical));
|
||||
@ -1109,77 +1144,74 @@ static struct
|
||||
char* name;
|
||||
int lexical;
|
||||
int etype;
|
||||
int op;
|
||||
} syms[] =
|
||||
{
|
||||
/* name lexical etype
|
||||
/* name lexical etype op
|
||||
*/
|
||||
/* basic types */
|
||||
"int8", LATYPE, TINT8,
|
||||
"int16", LATYPE, TINT16,
|
||||
"int32", LATYPE, TINT32,
|
||||
"int64", LATYPE, TINT64,
|
||||
"int8", LNAME, TINT8, OXXX,
|
||||
"int16", LNAME, TINT16, OXXX,
|
||||
"int32", LNAME, TINT32, OXXX,
|
||||
"int64", LNAME, TINT64, OXXX,
|
||||
|
||||
"uint8", LATYPE, TUINT8,
|
||||
"uint16", LATYPE, TUINT16,
|
||||
"uint32", LATYPE, TUINT32,
|
||||
"uint64", LATYPE, TUINT64,
|
||||
"uint8", LNAME, TUINT8, OXXX,
|
||||
"uint16", LNAME, TUINT16, OXXX,
|
||||
"uint32", LNAME, TUINT32, OXXX,
|
||||
"uint64", LNAME, TUINT64, OXXX,
|
||||
|
||||
"float32", LATYPE, TFLOAT32,
|
||||
"float64", LATYPE, TFLOAT64,
|
||||
"float80", LATYPE, TFLOAT80,
|
||||
"float32", LNAME, TFLOAT32, OXXX,
|
||||
"float64", LNAME, TFLOAT64, OXXX,
|
||||
"float80", LNAME, TFLOAT80, OXXX,
|
||||
|
||||
"bool", LATYPE, TBOOL,
|
||||
"byte", LATYPE, TUINT8,
|
||||
"string", LATYPE, TSTRING,
|
||||
"bool", LNAME, TBOOL, OXXX,
|
||||
"byte", LNAME, TUINT8, OXXX,
|
||||
"string", LNAME, TSTRING, OXXX,
|
||||
|
||||
"any", LATYPE, TANY,
|
||||
"any", LNAME, TANY, OXXX,
|
||||
|
||||
"break", LBREAK, Txxx,
|
||||
"case", LCASE, Txxx,
|
||||
"chan", LCHAN, Txxx,
|
||||
"const", LCONST, Txxx,
|
||||
"continue", LCONTINUE, Txxx,
|
||||
"default", LDEFAULT, Txxx,
|
||||
"else", LELSE, Txxx,
|
||||
"defer", LDEFER, Txxx,
|
||||
"fallthrough", LFALL, Txxx,
|
||||
"false", LFALSE, Txxx,
|
||||
"for", LFOR, Txxx,
|
||||
"func", LFUNC, Txxx,
|
||||
"go", LGO, Txxx,
|
||||
"goto", LGOTO, Txxx,
|
||||
"if", LIF, Txxx,
|
||||
"import", LIMPORT, Txxx,
|
||||
"interface", LINTERFACE, Txxx,
|
||||
"iota", LIOTA, Txxx,
|
||||
"make", LMAKE, Txxx,
|
||||
"map", LMAP, Txxx,
|
||||
"new", LNEW, Txxx,
|
||||
"len", LLEN, Txxx,
|
||||
"cap", LCAP, Txxx,
|
||||
"nil", LNIL, Txxx,
|
||||
"package", LPACKAGE, Txxx,
|
||||
"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,
|
||||
"break", LBREAK, Txxx, OXXX,
|
||||
"case", LCASE, Txxx, OXXX,
|
||||
"chan", LCHAN, Txxx, OXXX,
|
||||
"const", LCONST, Txxx, OXXX,
|
||||
"continue", LCONTINUE, Txxx, OXXX,
|
||||
"default", LDEFAULT, Txxx, OXXX,
|
||||
"else", LELSE, Txxx, OXXX,
|
||||
"defer", LDEFER, Txxx, OXXX,
|
||||
"fallthrough", LFALL, Txxx, OXXX,
|
||||
"for", LFOR, Txxx, OXXX,
|
||||
"func", LFUNC, Txxx, OXXX,
|
||||
"go", LGO, Txxx, OXXX,
|
||||
"goto", LGOTO, Txxx, OXXX,
|
||||
"if", LIF, Txxx, OXXX,
|
||||
"import", LIMPORT, Txxx, OXXX,
|
||||
"interface", LINTERFACE, Txxx, OXXX,
|
||||
"map", LMAP, Txxx, OXXX,
|
||||
"package", LPACKAGE, Txxx, OXXX,
|
||||
"range", LRANGE, Txxx, OXXX,
|
||||
"return", LRETURN, Txxx, OXXX,
|
||||
"select", LSELECT, Txxx, OXXX,
|
||||
"struct", LSTRUCT, Txxx, OXXX,
|
||||
"switch", LSWITCH, Txxx, OXXX,
|
||||
"type", LTYPE, Txxx, OXXX,
|
||||
"var", LVAR, Txxx, OXXX,
|
||||
|
||||
"close", LCLOSE, Txxx,
|
||||
"closed", LCLOSED, Txxx,
|
||||
"cap", LNAME, Txxx, OCAP,
|
||||
"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,
|
||||
"thetruthofthematter", LIGNORE, Txxx,
|
||||
"despiteallobjections", LIGNORE, Txxx,
|
||||
"whereas", LIGNORE, Txxx,
|
||||
"insofaras", LIGNORE, Txxx,
|
||||
"notwithstanding", LIGNORE, Txxx, OXXX,
|
||||
"thetruthofthematter", LIGNORE, Txxx, OXXX,
|
||||
"despiteallobjections", LIGNORE, Txxx, OXXX,
|
||||
"whereas", LIGNORE, Txxx, OXXX,
|
||||
"insofaras", LIGNORE, Txxx, OXXX,
|
||||
};
|
||||
|
||||
void
|
||||
@ -1189,6 +1221,7 @@ lexinit(void)
|
||||
Sym *s;
|
||||
Type *t;
|
||||
int etype;
|
||||
Val v;
|
||||
|
||||
/*
|
||||
* initialize basic types array
|
||||
@ -1201,24 +1234,50 @@ lexinit(void)
|
||||
s->package = package;
|
||||
|
||||
etype = syms[i].etype;
|
||||
if(etype == Txxx)
|
||||
continue;
|
||||
|
||||
if(etype != Txxx) {
|
||||
if(etype < 0 || etype >= nelem(types))
|
||||
fatal("lexinit: %s bad etype", s->name);
|
||||
|
||||
t = types[etype];
|
||||
if(t != T) {
|
||||
s->otype = t;
|
||||
continue;
|
||||
}
|
||||
if(t == T) {
|
||||
t = typ(etype);
|
||||
t->sym = s;
|
||||
|
||||
dowidth(t);
|
||||
types[etype] = t;
|
||||
s->otype = t;
|
||||
}
|
||||
s->def = typenod(t);
|
||||
continue;
|
||||
}
|
||||
|
||||
etype = syms[i].op;
|
||||
if(etype != OXXX) {
|
||||
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.
|
||||
// types[TSTRING] is the named type string
|
||||
@ -1244,14 +1303,18 @@ struct
|
||||
LCONST, "CONST",
|
||||
LCONTINUE, "CONTINUE",
|
||||
LDEC, "DEC",
|
||||
LDEFER, "DEFER",
|
||||
LELSE, "ELSE",
|
||||
LEQ, "EQ",
|
||||
LFALL, "FALL",
|
||||
LFOR, "FOR",
|
||||
LFUNC, "FUNC",
|
||||
LGE, "GE",
|
||||
LGO, "GO",
|
||||
LGOTO, "GOTO",
|
||||
LGT, "GT",
|
||||
LIF, "IF",
|
||||
LIMPORT, "IMPORT",
|
||||
LINC, "INC",
|
||||
LINTERFACE, "INTERFACE",
|
||||
LLE, "LE",
|
||||
@ -1262,7 +1325,7 @@ struct
|
||||
LNAME, "NAME",
|
||||
LNE, "NE",
|
||||
LOROR, "OROR",
|
||||
LPACK, "PACK",
|
||||
LPACKAGE, "PACKAGE",
|
||||
LRANGE, "RANGE",
|
||||
LRETURN, "RETURN",
|
||||
LRSH, "RSH",
|
||||
@ -1270,16 +1333,6 @@ struct
|
||||
LSWITCH, "SWITCH",
|
||||
LTYPE, "TYPE",
|
||||
LVAR, "VAR",
|
||||
LFOR, "FOR",
|
||||
LNEW, "NEW",
|
||||
LLEN, "LEN",
|
||||
LFALL, "FALL",
|
||||
LIOTA, "IOTA",
|
||||
LPRINT, "PRINT",
|
||||
LPACKAGE, "PACKAGE",
|
||||
LIMPORT, "IMPORT",
|
||||
LDEFER, "DEFER",
|
||||
LPANIC, "PANIC",
|
||||
};
|
||||
|
||||
char*
|
||||
@ -1316,8 +1369,8 @@ mkpackage(char* pkg)
|
||||
|
||||
// declare this name as a package
|
||||
s = lookup(package);
|
||||
s->lexical = LPACK;
|
||||
s->opack = s->name;
|
||||
s->def = nod(OPACK, N, N);
|
||||
s->def->sym = s;
|
||||
|
||||
if(outfile == nil) {
|
||||
p = strrchr(infile, '/');
|
||||
|
@ -58,7 +58,7 @@ dumpglobls(void)
|
||||
continue;
|
||||
|
||||
dowidth(n->type);
|
||||
ggloblnod(s->oname, n->type->width);
|
||||
ggloblnod(s->def, n->type->width);
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,6 +393,7 @@ dumpsignatures(void)
|
||||
Dcl *d, *x;
|
||||
Type *t, *progt, *methodt, *ifacet, *rcvrt;
|
||||
Sym *s;
|
||||
Node *n;
|
||||
|
||||
// copy externdcl list to signatlist
|
||||
for(d=externdcl; d!=D; d=d->forw) {
|
||||
@ -403,9 +404,10 @@ dumpsignatures(void)
|
||||
if(t == T)
|
||||
continue;
|
||||
|
||||
s = signame(t);
|
||||
if(s == S)
|
||||
n = signame(t);
|
||||
if(n == N || n->sym == S)
|
||||
continue;
|
||||
s = n->sym;
|
||||
|
||||
x = mal(sizeof(*d));
|
||||
x->op = OTYPE;
|
||||
@ -425,10 +427,11 @@ dumpsignatures(void)
|
||||
continue;
|
||||
t = d->dtype;
|
||||
et = t->etype;
|
||||
s = signame(t);
|
||||
n = signame(t);
|
||||
//print("signame %S for %T\n", s, t);
|
||||
if(s == S)
|
||||
if(n == N || n->sym == S)
|
||||
continue;
|
||||
s = n->sym;
|
||||
|
||||
// only emit one
|
||||
if(s->siggen)
|
||||
|
@ -156,9 +156,9 @@ lookup(char *p)
|
||||
}
|
||||
|
||||
s = mal(sizeof(*s));
|
||||
s->lexical = LNAME;
|
||||
s->name = mal(strlen(p)+1);
|
||||
s->package = package;
|
||||
s->lexical = LNAME;
|
||||
|
||||
strcpy(s->name, p);
|
||||
|
||||
@ -186,7 +186,6 @@ pkglookup(char *p, char *k)
|
||||
}
|
||||
|
||||
s = mal(sizeof(*s));
|
||||
s->lexical = LNAME;
|
||||
s->name = mal(strlen(p)+1);
|
||||
strcpy(s->name, p);
|
||||
|
||||
@ -220,13 +219,11 @@ importdot(Sym *opkg)
|
||||
if(strcmp(s->package, opkg->name) != 0)
|
||||
continue;
|
||||
s1 = lookup(s->name);
|
||||
if(s1->oname != N || s1->otype != T) {
|
||||
if(s1->def != N) {
|
||||
yyerror("redeclaration of %S during import", s1);
|
||||
continue;
|
||||
}
|
||||
s1->lexical = s->lexical;
|
||||
s1->oname = s->oname;
|
||||
s1->otype = s->otype;
|
||||
s1->def = s->def;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -571,7 +568,7 @@ loop:
|
||||
break;
|
||||
|
||||
case OTYPE:
|
||||
print("%O-%E %lT\n", n->op, n->etype, n);
|
||||
print("%O %T\n", n->op, n->type);
|
||||
break;
|
||||
|
||||
case OIF:
|
||||
@ -696,7 +693,6 @@ opnames[] =
|
||||
[OGOTO] = "GOTO",
|
||||
[OGT] = "GT",
|
||||
[OIF] = "IF",
|
||||
[OIMPORT] = "IMPORT",
|
||||
[OINC] = "INC",
|
||||
[OINDEX] = "INDEX",
|
||||
[OINDREG] = "INDREG",
|
||||
@ -722,6 +718,7 @@ opnames[] =
|
||||
[OOR] = "OR",
|
||||
[OPANICN] = "PANICN",
|
||||
[OPANIC] = "PANIC",
|
||||
[OPACK] = "PACK",
|
||||
[OPARAM] = "PARAM",
|
||||
[OPLUS] = "PLUS",
|
||||
[OPRINTN] = "PRINTN",
|
||||
@ -741,7 +738,6 @@ opnames[] =
|
||||
[OTYPEOF] = "TYPEOF",
|
||||
[OTYPESW] = "TYPESW",
|
||||
[OTYPE] = "TYPE",
|
||||
[OVAR] = "VAR",
|
||||
[OXCASE] = "XCASE",
|
||||
[OXFALL] = "XFALL",
|
||||
[OXOR] = "XOR",
|
||||
@ -1044,8 +1040,11 @@ Tpretty(Fmt *fp, Type *t)
|
||||
fmtprint(fp, "%hS", s);
|
||||
else
|
||||
fmtprint(fp, "%lS", s);
|
||||
if(strcmp(s->package, package) == 0)
|
||||
if((s->otype != t || !s->export) && !s->imported) {
|
||||
if(strcmp(s->package, package) != 0)
|
||||
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);
|
||||
if(t->vargen)
|
||||
fmtprint(fp, "·%d", t->vargen);
|
||||
@ -1339,7 +1338,7 @@ Nconv(Fmt *fp)
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
if(n->sym != S) {
|
||||
@ -1581,7 +1580,7 @@ iscomposite(Type *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Sym*
|
||||
Node*
|
||||
signame(Type *t)
|
||||
{
|
||||
Sym *ss;
|
||||
@ -1611,10 +1610,10 @@ signame(Type *t)
|
||||
strcpy(buf, "dotdotdot");
|
||||
|
||||
ss = pkglookup(buf, e);
|
||||
if(ss->oname == N) {
|
||||
ss->oname = newname(ss);
|
||||
ss->oname->type = types[TUINT8];
|
||||
ss->oname->class = PEXTERN;
|
||||
if(ss->def == N) {
|
||||
ss->def = newname(ss);
|
||||
ss->def->type = types[TUINT8];
|
||||
ss->def->class = PEXTERN;
|
||||
}
|
||||
|
||||
//print("siggen %T %d\n", t, t->siggen);
|
||||
@ -1633,10 +1632,10 @@ signame(Type *t)
|
||||
}
|
||||
|
||||
out:
|
||||
return ss;
|
||||
return ss->def;
|
||||
|
||||
bad:
|
||||
return S;
|
||||
return N;
|
||||
}
|
||||
|
||||
int
|
||||
@ -1942,15 +1941,15 @@ syslook(char *name, int copy)
|
||||
Node *n;
|
||||
|
||||
s = pkglookup(name, "sys");
|
||||
if(s == S || s->oname == N)
|
||||
if(s == S || s->def == N)
|
||||
fatal("looksys: cant find sys.%s", name);
|
||||
|
||||
if(!copy)
|
||||
return s->oname;
|
||||
return s->def;
|
||||
|
||||
n = nod(0, N, N);
|
||||
*n = *s->oname;
|
||||
n->type = deep(s->oname->type);
|
||||
*n = *s->def;
|
||||
n->type = deep(s->def->type);
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -2073,7 +2072,7 @@ frame(int context)
|
||||
case OTYPE:
|
||||
if(flag)
|
||||
print("--- %s frame ---\n", p);
|
||||
print("%O %lT\n", d->op, d->dnode);
|
||||
print("%O %T\n", d->op, d->dnode);
|
||||
flag = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -123,8 +123,16 @@ loop:
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
switch(n->op) {
|
||||
|
||||
case OLIST:
|
||||
@ -248,6 +256,7 @@ loop:
|
||||
|
||||
switch(n->op) {
|
||||
default:
|
||||
dump("walk", n);
|
||||
fatal("walktype: switch 1 unknown op %N", n);
|
||||
goto ret;
|
||||
|
||||
@ -313,6 +322,9 @@ loop:
|
||||
if(n->type == T) {
|
||||
s = n->sym;
|
||||
if(s->undef == 0) {
|
||||
if(n->etype != 0)
|
||||
yyerror("walktype: %S must be called", s);
|
||||
else
|
||||
yyerror("walktype: %S undeclared", s);
|
||||
s->undef = 1;
|
||||
}
|
||||
@ -1030,19 +1042,27 @@ loop:
|
||||
case OMAKE:
|
||||
if(top != Erv)
|
||||
goto nottop;
|
||||
l = n->left;
|
||||
if(l == N) {
|
||||
yyerror("missing argument to make");
|
||||
goto ret;
|
||||
}
|
||||
indir(n, makecompat(n));
|
||||
goto ret;
|
||||
|
||||
case ONEW:
|
||||
if(top != Erv)
|
||||
goto nottop;
|
||||
if(n->left != N) {
|
||||
yyerror("cannot new(%T, expr)", t);
|
||||
goto ret;
|
||||
}
|
||||
t = n->type;
|
||||
if(t == T)
|
||||
goto ret;
|
||||
l = n->left;
|
||||
if(l == N)
|
||||
yyerror("missing argument to new");
|
||||
else if(n->right != N)
|
||||
yyerror("too many arguments to new");
|
||||
else if(l->op != OTYPE)
|
||||
yyerror("argument to new must be type");
|
||||
else if((t = l->type) == T)
|
||||
;
|
||||
else
|
||||
indir(n, callnew(t));
|
||||
goto ret;
|
||||
}
|
||||
@ -1927,12 +1947,12 @@ sigtype(Type *st)
|
||||
x = mal(sizeof(*x));
|
||||
x->op = OTYPE;
|
||||
x->dsym = s;
|
||||
x->dtype = s->otype;
|
||||
x->dtype = t;
|
||||
x->forw = signatlist;
|
||||
x->block = block;
|
||||
signatlist = x;
|
||||
|
||||
return s->otype;
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2350,8 +2370,22 @@ Node*
|
||||
makecompat(Node *n)
|
||||
{
|
||||
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)
|
||||
switch(t->etype) {
|
||||
@ -3045,9 +3079,8 @@ arrayop(Node *n, int top)
|
||||
|
||||
a = listfirst(&save, &n->left); // nel
|
||||
if(a == N) {
|
||||
if(t->bound < 0)
|
||||
yyerror("new open array must have size");
|
||||
a = nodintconst(t->bound);
|
||||
yyerror("new slice must have size");
|
||||
a = nodintconst(1);
|
||||
}
|
||||
a = nod(OCONV, a, N);
|
||||
a->type = types[TINT];
|
||||
@ -3193,7 +3226,6 @@ ifacecvt(Type *tl, Node *n, int et)
|
||||
{
|
||||
Type *tr;
|
||||
Node *r, *a, *on;
|
||||
Sym *s;
|
||||
|
||||
tr = n->type;
|
||||
|
||||
@ -3207,19 +3239,10 @@ ifacecvt(Type *tl, Node *n, int et)
|
||||
a = n; // elem
|
||||
r = a;
|
||||
|
||||
s = signame(tr); // sigt
|
||||
if(s == S)
|
||||
fatal("ifacecvt: signame-1 T2I: %lT", tr);
|
||||
a = s->oname;
|
||||
a = nod(OADDR, a, N);
|
||||
a = nod(OADDR, signame(tr), N); // sigt
|
||||
r = list(a, r);
|
||||
|
||||
s = signame(tl); // sigi
|
||||
if(s == S) {
|
||||
fatal("ifacecvt: signame-2 T2I: %lT", tl);
|
||||
}
|
||||
a = s->oname;
|
||||
a = nod(OADDR, a, N);
|
||||
a = nod(OADDR, signame(tl), N); // sigi
|
||||
r = list(a, r);
|
||||
|
||||
on = syslook("ifaceT2I", 1);
|
||||
@ -3240,11 +3263,7 @@ ifacecvt(Type *tl, Node *n, int et)
|
||||
a = n; // interface
|
||||
r = a;
|
||||
|
||||
s = signame(tl); // sigi or sigt
|
||||
if(s == S)
|
||||
fatal("ifacecvt: signame %d", et);
|
||||
a = s->oname;
|
||||
a = nod(OADDR, a, N);
|
||||
a = nod(OADDR, signame(tl), N); // sigi or sigt
|
||||
r = list(a, r);
|
||||
|
||||
on = syslook(ifacename[et], 1);
|
||||
@ -3268,11 +3287,7 @@ ifacecvt(Type *tl, Node *n, int et)
|
||||
a = n; // elem
|
||||
r = a;
|
||||
|
||||
s = signame(tr); // sigt
|
||||
if(s == S)
|
||||
fatal("ifacecvt: signame-1 T2E: %lT", tr);
|
||||
a = s->oname;
|
||||
a = nod(OADDR, a, N);
|
||||
a = nod(OADDR, signame(tr), N); // sigt
|
||||
r = list(a, r);
|
||||
|
||||
on = syslook("ifaceT2E", 1);
|
||||
@ -3394,7 +3409,9 @@ colasname(Node *n)
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
case ONONAME:
|
||||
case OPACK:
|
||||
break;
|
||||
case OTYPE:
|
||||
case OLITERAL:
|
||||
if(n->sym != S)
|
||||
break;
|
||||
@ -4248,9 +4265,7 @@ arraylit(Node *n, Node *var)
|
||||
|
||||
if(b < 0) {
|
||||
// slice
|
||||
a = nod(OMAKE, N, N);
|
||||
a->type = t;
|
||||
a->left = nodintconst(ninit);
|
||||
a = nod(OMAKE, nod(OLIST, typenod(t), nodintconst(ninit)), N);
|
||||
a = nod(OAS, var, a);
|
||||
addtop = list(addtop, a);
|
||||
} else {
|
||||
@ -4377,8 +4392,7 @@ maplit(Node *n, Node *var)
|
||||
tempname(var, t);
|
||||
}
|
||||
|
||||
a = nod(OMAKE, N, N);
|
||||
a->type = t;
|
||||
a = nod(OMAKE, typenod(t), N);
|
||||
a = nod(OAS, var, a);
|
||||
addtop = list(addtop, a);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user