Commit 35e5906f authored by Russ Cox's avatar Russ Cox

another baby step.

excluding import data,
no yacc node has type Type* anymore.

0 reduce/reduce conflicts.

R=ken
OCL=31793
CL=31795
parent 1593b1fc
...@@ -1306,6 +1306,7 @@ xanondcl(Node *nt) ...@@ -1306,6 +1306,7 @@ xanondcl(Node *nt)
Node *n; Node *n;
Type *t; Type *t;
walkexpr(nt, Etype, &nt->ninit);
t = nt->type; t = nt->type;
if(nt->op != OTYPE) { if(nt->op != OTYPE) {
yyerror("%S is not a type", nt->sym); yyerror("%S is not a type", nt->sym);
...@@ -1324,17 +1325,21 @@ namedcl(Node *nn, Node *nt) ...@@ -1324,17 +1325,21 @@ namedcl(Node *nn, Node *nt)
if(nn->op == OKEY) if(nn->op == OKEY)
nn = nn->left; nn = nn->left;
if(nn->op == OTYPE && nn->sym == S) { if(nn->sym == S) {
walkexpr(nn, Etype, &nn->ninit);
yyerror("cannot mix anonymous %T with named arguments", nn->type); yyerror("cannot mix anonymous %T with named arguments", nn->type);
return xanondcl(nn); return xanondcl(nn);
} }
t = types[TINT32]; t = types[TINT32];
if(nt == N) if(nt == N)
yyerror("missing type for argument %S", nn->sym); yyerror("missing type for argument %S", nn->sym);
else if(nt->op != OTYPE) else {
yyerror("%S is not a type", nt->sym); walkexpr(nt, Etype, &nt->ninit);
else if(nt->op != OTYPE)
t = nt->type; yyerror("%S is not a type", nt->sym);
else
t = nt->type;
}
n = nod(ODCLFIELD, newname(nn->sym), N); n = nod(ODCLFIELD, newname(nn->sym), N);
n->type = t; n->type = t;
return n; return n;
...@@ -1643,12 +1648,19 @@ embedded(Sym *s) ...@@ -1643,12 +1648,19 @@ embedded(Sym *s)
* new_name_list (type | [type] = expr_list) * new_name_list (type | [type] = expr_list)
*/ */
NodeList* NodeList*
variter(NodeList *vl, Type *t, NodeList *el) variter(NodeList *vl, Node *nt, NodeList *el)
{ {
int doexpr; int doexpr;
Node *v, *e, *a; Node *v, *e, *a;
Type *tv; Type *tv;
NodeList *r; NodeList *r;
Type *t;
t = T;
if(nt) {
walkexpr(nt, Etype, &nt->ninit);
t = nt->type;
}
r = nil; r = nil;
doexpr = el != nil; doexpr = el != nil;
......
...@@ -877,7 +877,7 @@ void checkwidth(Type*); ...@@ -877,7 +877,7 @@ void checkwidth(Type*);
void defercheckwidth(void); void defercheckwidth(void);
void resumecheckwidth(void); void resumecheckwidth(void);
Node* embedded(Sym*); Node* embedded(Sym*);
NodeList* variter(NodeList*, Type*, NodeList*); NodeList* variter(NodeList*, Node*, NodeList*);
NodeList* constiter(NodeList*, Node*, NodeList*); NodeList* constiter(NodeList*, Node*, NodeList*);
Node* funclit0(Node*); Node* funclit0(Node*);
......
...@@ -5,14 +5,6 @@ ...@@ -5,14 +5,6 @@
/* /*
* Go language grammar. * Go language grammar.
* *
* The grammar has 6 reduce/reduce conflicts, caused by
* input that can be parsed as either a type or an expression
* depending on context, like the t in t(1). The expressions
* have the more general syntax, so the grammar arranges
* that such input gets parsed as expressions and then is
* fixed up as a type later. In return for this extra work,
* the lexer need not distinguish type names from variable names.
*
* The Go semicolon rules are: * The Go semicolon rules are:
* *
* 1. all statements and declarations are terminated by semicolons * 1. all statements and declarations are terminated by semicolons
...@@ -63,7 +55,7 @@ ...@@ -63,7 +55,7 @@
%type <node> fndcl fnliteral %type <node> fndcl fnliteral
%type <node> for_body for_header for_stmt if_header if_stmt %type <node> for_body for_header for_stmt if_header if_stmt
%type <node> keyval labelname name %type <node> keyval labelname name
%type <node> name_or_type %type <node> name_or_type non_expr_type
%type <node> new_name dcl_name oexpr %type <node> new_name dcl_name oexpr
%type <node> onew_name %type <node> onew_name
%type <node> osimple_stmt pexpr %type <node> osimple_stmt pexpr
...@@ -78,9 +70,8 @@ ...@@ -78,9 +70,8 @@
%type <list> interfacedcl_list interfacedcl vardcl vardcl_list structdcl structdcl_list %type <list> interfacedcl_list interfacedcl vardcl vardcl_list structdcl structdcl_list
%type <list> common_dcl constdcl constdcl1 constdcl_list typedcl_list %type <list> common_dcl constdcl constdcl1 constdcl_list typedcl_list
%type <type> type
%type <node> convtype dotdotdot %type <node> convtype dotdotdot
%type <node> indcl interfacetype structtype %type <node> indcl interfacetype structtype ptrtype
%type <type> new_type typedclname %type <type> new_type typedclname
%type <node> chantype non_chan_type othertype non_fn_type fntype fnlitdcl %type <node> chantype non_chan_type othertype non_fn_type fntype fnlitdcl
...@@ -119,10 +110,8 @@ ...@@ -119,10 +110,8 @@
%left ')' %left ')'
%left PreferToRightParen %left PreferToRightParen
%left NotDot
%left '.' %left '.'
%left NotBrace
%left '{' %left '{'
%% %%
...@@ -367,17 +356,17 @@ varoptsemi: ...@@ -367,17 +356,17 @@ varoptsemi:
} }
vardcl: vardcl:
dcl_name_list type varoptsemi dcl_name_list ntype varoptsemi
{ {
$$ = variter($1, $2, nil); $$ = variter($1, $2, nil);
} }
| dcl_name_list type varoptsemi '=' expr_list | dcl_name_list ntype varoptsemi '=' expr_list
{ {
$$ = variter($1, $2, $5); $$ = variter($1, $2, $5);
} }
| dcl_name_list '=' expr_list | dcl_name_list '=' expr_list
{ {
$$ = variter($1, T, $3); $$ = variter($1, nil, $3);
} }
constdcl: constdcl:
...@@ -409,9 +398,10 @@ typedclname: ...@@ -409,9 +398,10 @@ typedclname:
} }
typedcl: typedcl:
typedclname type typedclname ntype
{ {
updatetype($1, $2); walkexpr($2, Etype, &$2->ninit);
updatetype($1, $2->type);
resumecheckwidth(); resumecheckwidth();
} }
| typedclname LSTRUCT | typedclname LSTRUCT
...@@ -471,7 +461,7 @@ simple_stmt: ...@@ -471,7 +461,7 @@ simple_stmt:
} }
case: case:
LCASE expr_list ':' LCASE expr_or_type_list ':'
{ {
int e; int e;
Node *n; Node *n;
...@@ -512,19 +502,6 @@ case: ...@@ -512,19 +502,6 @@ case:
} }
break; break;
} }
| LCASE type ':'
{
Node *n;
$$ = nod(OXCASE, N, N);
poptodcl();
if(typeswvar == N || typeswvar->right == N) {
yyerror("type case not in a type switch");
n = N;
} else
n = old2new(typeswvar->right, $2, &$$->ninit);
$$->list = list1(nod(OTYPESW, n, N));
}
| LCASE name '=' expr ':' | LCASE name '=' expr ':'
{ {
// will be converted to OCASE // will be converted to OCASE
...@@ -862,7 +839,7 @@ pexpr: ...@@ -862,7 +839,7 @@ pexpr:
{ {
$$ = nodlit($1); $$ = nodlit($1);
} }
| name %prec NotBrace | name
| pexpr '.' sym | pexpr '.' sym
{ {
if($1->op == OPACK) { if($1->op == OPACK) {
...@@ -923,14 +900,10 @@ pexpr: ...@@ -923,14 +900,10 @@ pexpr:
expr_or_type: expr_or_type:
expr expr
| ntype %prec PreferToRightParen | non_expr_type %prec PreferToRightParen
name_or_type: name_or_type:
dotname ntype
| type
{
$$ = typenod($1);
}
lbrace: lbrace:
LBODY LBODY
...@@ -975,7 +948,7 @@ sym: ...@@ -975,7 +948,7 @@ sym:
LNAME LNAME
name: name:
sym %prec NotDot sym
{ {
$$ = oldname($1); $$ = oldname($1);
} }
...@@ -1016,23 +989,26 @@ dotdotdot: ...@@ -1016,23 +989,26 @@ dotdotdot:
$$ = typenod(typ(TDDD)); $$ = typenod(typ(TDDD));
} }
type: ntype:
ntype chantype
| fntype
| othertype
| ptrtype
| dotname
| '(' ntype ')'
{ {
NodeList *init; $$ = $2;
init = nil;
walkexpr($1, Etype, &init);
// init can only be set if this was not a type; ignore
$$ = $1->type;
} }
ntype: non_expr_type:
chantype chantype
| fntype | fntype
| othertype | othertype
| '(' ntype ')' | '*' non_expr_type
{
$$ = nod(OIND, $2, N);
}
| '(' non_expr_type ')'
{ {
$$ = $2; $$ = $2;
} }
...@@ -1040,6 +1016,8 @@ ntype: ...@@ -1040,6 +1016,8 @@ ntype:
non_chan_type: non_chan_type:
fntype fntype
| othertype | othertype
| ptrtype
| dotname
| '(' ntype ')' | '(' ntype ')'
{ {
$$ = $2; $$ = $2;
...@@ -1048,9 +1026,11 @@ non_chan_type: ...@@ -1048,9 +1026,11 @@ non_chan_type:
non_fn_type: non_fn_type:
chantype chantype
| othertype | othertype
| ptrtype
| dotname
dotname: dotname:
name %prec NotDot name
| name '.' sym | name '.' sym
{ {
if($1->op == OPACK) { if($1->op == OPACK) {
...@@ -1064,9 +1044,9 @@ dotname: ...@@ -1064,9 +1044,9 @@ dotname:
} }
othertype: othertype:
'[' oexpr ']' type '[' oexpr ']' ntype
{ {
$$ = typenod(aindex($2, $4)); $$ = nod(OTARRAY, $2, $4);
} }
| LCOMM LCHAN ntype | LCOMM LCHAN ntype
{ {
...@@ -1082,13 +1062,14 @@ othertype: ...@@ -1082,13 +1062,14 @@ othertype:
{ {
$$ = nod(OTMAP, $3, $5); $$ = nod(OTMAP, $3, $5);
} }
| '*' ntype | structtype
| interfacetype
ptrtype:
'*' ntype
{ {
$$ = nod(OIND, $2, N); $$ = nod(OIND, $2, N);
} }
| structtype
| interfacetype
| dotname
chantype: chantype:
LCHAN ntype LCHAN ntype
...@@ -1152,12 +1133,18 @@ xfndcl: ...@@ -1152,12 +1133,18 @@ xfndcl:
fndcl: fndcl:
dcl_name '(' oarg_type_list ')' fnres dcl_name '(' oarg_type_list ')' fnres
{ {
Node *n;
b0stack = dclstack; // mark base for fn literals b0stack = dclstack; // mark base for fn literals
$$ = nod(ODCLFUNC, N, N); $$ = nod(ODCLFUNC, N, N);
$$->nname = $1; $$->nname = $1;
if($3 == nil && $5 == nil) if($3 == nil && $5 == nil)
$$->nname = renameinit($1); $$->nname = renameinit($1);
$$->type = functype(N, $3, $5); n = nod(OTFUNC, N, N);
n->list = $3;
n->rlist = $5;
walkexpr(n, Etype, &n->ninit);
$$->type = n->type;
funchdr($$); funchdr($$);
} }
| '(' oarg_type_list ')' new_name '(' oarg_type_list ')' fnres | '(' oarg_type_list ')' new_name '(' oarg_type_list ')' fnres
...@@ -1333,14 +1320,16 @@ interfacedcl: ...@@ -1333,14 +1320,16 @@ interfacedcl:
} }
| packname | packname
{ {
$$ = list1(nod(ODCLFIELD, N, typenod(oldtype($1)))); $$ = list1(nod(ODCLFIELD, N, oldname($1)));
} }
indcl: indcl:
'(' oarg_type_list ')' fnres '(' oarg_type_list ')' fnres
{ {
// without func keyword // without func keyword
$$ = typenod(functype(fakethis(), $2, $4)); $$ = nod(OTFUNC, fakethis(), N);
$$->list = $2;
$$->rlist = $4;
} }
/* /*
......
...@@ -415,6 +415,7 @@ reswitch: ...@@ -415,6 +415,7 @@ reswitch:
t->type = r->type; t->type = r->type;
n->op = OTYPE; n->op = OTYPE;
n->type = t; n->type = t;
checkwidth(t);
goto ret; goto ret;
case OTMAP: case OTMAP:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment