Commit d364d281 authored by Russ Cox's avatar Russ Cox

implement new semicolon rules:

 *  1. all statements and declarations are terminated by semicolons
 *  2. semicolons can be omitted at top level.
 *  3. semicolons can be omitted before and after the closing ) or }
 *	on a list of statements or declarations.

now that semicolons are in, uncomment forward declaration
	of interfaces

R=ken
DELTA=285  (124 added, 114 deleted, 47 changed)
OCL=16638
CL=16646
parent 983f06bd
...@@ -28,14 +28,28 @@ ...@@ -28,14 +28,28 @@
%token LLSH LRSH LINC LDEC LCOMM %token LLSH LRSH LINC LDEC LCOMM
%token LIGNORE %token LIGNORE
/*
* the go semicolon rules are:
*
* 1. all statements and declarations are terminated by semicolons
* 2. semicolons can be omitted at top level.
* 3. semicolons can be omitted before and after the closing ) or }
* on a list of statements or declarations.
*
* thus the grammar must distinguish productions that
* can omit the semicolon terminator and those that can't.
* names like Astmt, Avardcl, etc. can drop the semicolon.
* names like Bstmt, Bvardcl, etc. can't.
*/
%type <sym> sym sym1 sym2 keyword laconst lname latype lpackatype %type <sym> sym sym1 sym2 keyword laconst lname latype lpackatype
%type <node> xdcl xdcl_list_r oxdcl_list %type <node> xdcl xdcl_list_r oxdcl_list
%type <node> common_dcl Acommon_dcl Bcommon_dcl %type <node> common_dcl Acommon_dcl Bcommon_dcl
%type <node> oarg_type_list arg_type_list_r arg_chunk arg_chunk_list_r arg_type_list %type <node> oarg_type_list arg_type_list_r arg_chunk arg_chunk_list_r arg_type_list
%type <node> else_stmt1 else_stmt2 inc_stmt noninc_stmt %type <node> Aelse_stmt Belse_stmt
%type <node> complex_stmt compound_stmt ostmt_list %type <node> complex_stmt compound_stmt ostmt_list
%type <node> stmt_list_r Astmt_list_r Bstmt_list_r %type <node> stmt_list_r Astmt_list_r Bstmt_list_r
%type <node> Astmt Bstmt Cstmt Dstmt %type <node> Astmt Bstmt
%type <node> for_stmt for_body for_header %type <node> for_stmt for_body for_header
%type <node> if_stmt if_body if_header %type <node> if_stmt if_body if_header
%type <node> range_header range_body range_stmt select_stmt %type <node> range_header range_body range_stmt select_stmt
...@@ -47,14 +61,16 @@ ...@@ -47,14 +61,16 @@
%type <node> structdcl_list_r structdcl %type <node> structdcl_list_r structdcl
%type <node> fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody %type <node> fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
%type <node> keyexpr_list keyval_list_r keyval %type <node> keyexpr_list keyval_list_r keyval
%type <node> typedcl Atypedcl Btypedcl
%type <type> typedclname
%type <type> fntype fnlitdcl Afntype Bfntype fullAtype %type <type> typedclname new_type
%type <type> non_name_Atype non_name_type %type <type> type Atype Btype
%type <type> type Atype Btype indcl new_type fullBtype %type <type> othertype Aothertype Bothertype
%type <type> structtype interfacetype convtype %type <type> chantype Achantype Bchantype
%type <type> Achantype Bchantype %type <type> fntype Afntype Bfntype
%type <type> nametype structtype interfacetype convtype
%type <type> non_name_type Anon_fn_type Bnon_fn_type
%type <type> Anon_chan_type Bnon_chan_type
%type <type> indcl fnlitdcl
%type <val> hidden_constant %type <val> hidden_constant
%type <node> hidden_dcl %type <node> hidden_dcl
...@@ -249,7 +265,7 @@ vardcl: ...@@ -249,7 +265,7 @@ vardcl:
| Bvardcl | Bvardcl
Avardcl: Avardcl:
new_name_list_r fullAtype new_name_list_r Atype
{ {
$$ = rev($1); $$ = rev($1);
dodclvar($$, $2); dodclvar($$, $2);
...@@ -258,7 +274,7 @@ Avardcl: ...@@ -258,7 +274,7 @@ Avardcl:
} }
Bvardcl: Bvardcl:
new_name_list_r fullBtype new_name_list_r Btype
{ {
$$ = rev($1); $$ = rev($1);
dodclvar($$, $2); dodclvar($$, $2);
...@@ -323,10 +339,6 @@ constdcl1: ...@@ -323,10 +339,6 @@ constdcl1:
iota += 1; iota += 1;
} }
typedcl:
Atypedcl
| Btypedcl
typedclname: typedclname:
new_type new_type
{ {
...@@ -334,8 +346,19 @@ typedclname: ...@@ -334,8 +346,19 @@ typedclname:
defercheckwidth(); defercheckwidth();
} }
typedcl:
Atypedcl
| Btypedcl
Atypedcl: Atypedcl:
typedclname fullAtype typedclname Atype
{
updatetype($1, $2);
resumecheckwidth();
}
Btypedcl:
typedclname Btype
{ {
updatetype($1, $2); updatetype($1, $2);
resumecheckwidth(); resumecheckwidth();
...@@ -345,26 +368,17 @@ Atypedcl: ...@@ -345,26 +368,17 @@ Atypedcl:
updatetype($1, typ(TFORWSTRUCT)); updatetype($1, typ(TFORWSTRUCT));
resumecheckwidth(); resumecheckwidth();
} }
/*
| typedclname LINTERFACE | typedclname LINTERFACE
{ {
updatetype($1, typ(TFORWINTER)); updatetype($1, typ(TFORWINTER));
resumecheckwidth(); resumecheckwidth();
} }
*/
Btypedcl:
typedclname fullBtype
{
updatetype($1, $2);
resumecheckwidth();
}
else_stmt1: Aelse_stmt:
complex_stmt complex_stmt
| compound_stmt | compound_stmt
else_stmt2: Belse_stmt:
simple_stmt simple_stmt
| semi_stmt | semi_stmt
| ';' | ';'
...@@ -373,10 +387,6 @@ else_stmt2: ...@@ -373,10 +387,6 @@ else_stmt2:
} }
simple_stmt: simple_stmt:
inc_stmt
| noninc_stmt
noninc_stmt:
expr expr
{ {
$$ = $1; $$ = $1;
...@@ -411,9 +421,7 @@ noninc_stmt: ...@@ -411,9 +421,7 @@ noninc_stmt:
{ {
$$ = nod(OPANICN, $3, N); $$ = nod(OPANICN, $3, N);
} }
| expr LINC
inc_stmt:
expr LINC
{ {
$$ = nod(OASOP, $1, literal(1)); $$ = nod(OASOP, $1, literal(1));
$$->etype = OADD; $$->etype = OADD;
...@@ -441,7 +449,7 @@ complex_stmt: ...@@ -441,7 +449,7 @@ complex_stmt:
popdcl(); popdcl();
$$ = $2; $$ = $2;
} }
| LIF if_stmt LELSE else_stmt1 | LIF if_stmt LELSE Aelse_stmt
{ {
popdcl(); popdcl();
$$ = $2; $$ = $2;
...@@ -516,7 +524,7 @@ semi_stmt: ...@@ -516,7 +524,7 @@ semi_stmt:
{ {
$$ = nod(ORETURN, $2, N); $$ = nod(ORETURN, $2, N);
} }
| LIF if_stmt LELSE else_stmt2 | LIF if_stmt LELSE Belse_stmt
{ {
popdcl(); popdcl();
$$ = $2; $$ = $2;
...@@ -974,119 +982,157 @@ convtype: ...@@ -974,119 +982,157 @@ convtype:
} }
| structtype | structtype
/*
* to avoid parsing conflicts, type is split into
* named types
* channel types
* function types
* any other type
*
* (and also into A/B as described above).
*
* the type system makes additional restrictions,
* but those are not implemented in the grammar.
*/
type: type:
fullAtype Atype
| fullBtype | Btype
non_name_type: Atype:
non_name_Atype Achantype
| Afntype | Afntype
| Achantype | Aothertype
| fullBtype
Atype: Btype:
nametype
| Bchantype
| Bfntype
| Bothertype
non_name_type:
chantype
| fntype
| othertype
Anon_chan_type:
Afntype
| Aothertype
Bnon_chan_type:
nametype
| Bfntype
| Bothertype
Anon_fn_type:
Achantype
| Aothertype
Bnon_fn_type:
nametype
| Bchantype
| Bothertype
nametype:
LATYPE LATYPE
{ {
$$ = oldtype($1); $$ = oldtype($1);
} }
| non_name_Atype
non_name_Atype: othertype:
lpackatype Aothertype
{ | Bothertype
$$ = oldtype($1);
} Aothertype:
| '[' oexpr ']' fullAtype '[' oexpr ']' Atype
{ {
$$ = aindex($2, $4); $$ = aindex($2, $4);
} }
| LCOMM LCHAN fullAtype | LCOMM LCHAN Atype
{ {
$$ = typ(TCHAN); $$ = typ(TCHAN);
$$->type = $3; $$->type = $3;
$$->chan = Crecv; $$->chan = Crecv;
} }
| LCHAN LCOMM Atype /* not full Atype */ | LCHAN LCOMM Anon_chan_type
{ {
$$ = typ(TCHAN); $$ = typ(TCHAN);
$$->type = $3; $$->type = $3;
$$->chan = Csend; $$->chan = Csend;
} }
| LMAP '[' type ']' fullAtype | LMAP '[' type ']' Atype
{ {
$$ = typ(TMAP); $$ = typ(TMAP);
$$->down = $3; $$->down = $3;
$$->type = $5; $$->type = $5;
} }
| structtype | '*' Atype
| interfacetype
| '*' fullAtype
{ {
$$ = ptrto($2); $$ = ptrto($2);
} }
| structtype
| interfacetype
Achantype: Bothertype:
LCHAN fullAtype lpackatype
{ {
$$ = typ(TCHAN); $$ = oldtype($1);
$$->type = $2;
$$->chan = Cboth;
} }
| '*' lname /* TODO(rsc): yank */
{
Type *t;
fullAtype: t = dodcltype(newtype($2));
Atype updatetype(t, typ(TFORWSTRUCT));
| Afntype $$ = ptrto(t);
| Achantype }
| '[' oexpr ']' Btype
Btype:
'[' oexpr ']' fullBtype
{ {
$$ = aindex($2, $4); $$ = aindex($2, $4);
} }
| LCOMM LCHAN fullBtype | LCOMM LCHAN Btype
{ {
$$ = typ(TCHAN); $$ = typ(TCHAN);
$$->type = $3; $$->type = $3;
$$->chan = Crecv; $$->chan = Crecv;
} }
| LCHAN LCOMM Btype // not full Btype | LCHAN LCOMM Bnon_chan_type
{ {
$$ = typ(TCHAN); $$ = typ(TCHAN);
$$->type = $3; $$->type = $3;
$$->chan = Csend; $$->chan = Csend;
} }
| LMAP '[' type ']' fullBtype | LMAP '[' type ']' Btype
{ {
$$ = typ(TMAP); $$ = typ(TMAP);
$$->down = $3; $$->down = $3;
$$->type = $5; $$->type = $5;
} }
| '*' fullBtype | '*' Btype
{ {
$$ = ptrto($2); $$ = ptrto($2);
} }
| '*' lname
{
Type *t;
t = dodcltype(newtype($2)); chantype:
updatetype(t, typ(TFORWSTRUCT)); Achantype
$$ = ptrto(t); | Bchantype
Achantype:
LCHAN Atype
{
$$ = typ(TCHAN);
$$->type = $2;
$$->chan = Cboth;
} }
Bchantype: Bchantype:
LCHAN fullBtype LCHAN Btype
{ {
$$ = typ(TCHAN); $$ = typ(TCHAN);
$$->type = $2; $$->type = $2;
$$->chan = Cboth; $$->chan = Cboth;
} }
fullBtype:
Btype
| Bfntype
| Bchantype
structtype: structtype:
LSTRUCT '{' structdcl_list_r osemi '}' LSTRUCT '{' structdcl_list_r osemi '}'
{ {
...@@ -1224,27 +1270,27 @@ fnres: ...@@ -1224,27 +1270,27 @@ fnres:
| Bfnres | Bfnres
Afnres: Afnres:
Atype Anon_fn_type
{ {
$$ = nod(ODCLFIELD, N, N); $$ = nod(ODCLFIELD, N, N);
$$->type = $1; $$->type = $1;
$$ = cleanidlist($$); $$ = cleanidlist($$);
} }
| '(' oarg_type_list ')'
{
$$ = $2;
}
Bfnres: Bfnres:
{ {
$$ = N; $$ = N;
} }
| Btype | Bnon_fn_type
{ {
$$ = nod(ODCLFIELD, N, N); $$ = nod(ODCLFIELD, N, N);
$$->type = $1; $$->type = $1;
$$ = cleanidlist($$); $$ = cleanidlist($$);
} }
| '(' oarg_type_list ')'
{
$$ = $2;
}
/* /*
* lists of things * lists of things
...@@ -1403,8 +1449,7 @@ arg_type_list: ...@@ -1403,8 +1449,7 @@ arg_type_list:
} }
/* /*
* need semi in front NO * statement that doesn't need semicolon terminator
* need semi in back NO
*/ */
Astmt: Astmt:
complex_stmt complex_stmt
...@@ -1418,74 +1463,39 @@ Astmt: ...@@ -1418,74 +1463,39 @@ Astmt:
{ {
$$ = N; $$ = N;
} }
| new_name ':'
{
$$ = nod(OLABEL, $1, N);
}
| Bstmt ';'
/* /*
* need semi in front NO * statement that does
* need semi in back YES
*/ */
Bstmt: Bstmt:
semi_stmt semi_stmt
| Bcommon_dcl | Bcommon_dcl
| error Bstmt | simple_stmt
{
$$ = N;
}
/*
* need semi in front YES
* need semi in back YES
*/
Cstmt:
noninc_stmt
/*
* need semi in front YES
* need semi in back NO
*/
Dstmt:
inc_stmt
| new_name ':'
{
$$ = nod(OLABEL, $1, N);
}
/* /*
* statement list that ends AorD * statement list that doesn't need semicolon terminator
*/ */
Astmt_list_r: Astmt_list_r:
Astmt Astmt
| Dstmt
| Astmt_list_r Astmt | Astmt_list_r Astmt
{ {
$$ = list($1, $2); $$ = list($1, $2);
} }
| Astmt_list_r Dstmt
{
$$ = list($1, $2);
}
| Bstmt_list_r Astmt
{
$$ = list($1, $2);
}
/* /*
* statement list that ends BorC * statement list that needs semicolon terminator
*/ */
Bstmt_list_r: Bstmt_list_r:
Bstmt Bstmt
| Cstmt
| Astmt_list_r Bstmt | Astmt_list_r Bstmt
{ {
$$ = list($1, $2); $$ = list($1, $2);
} }
| Astmt_list_r Cstmt
{
$$ = list($1, $2);
}
| Bstmt_list_r Bstmt
{
$$ = list($1, $2);
}
stmt_list_r: stmt_list_r:
Astmt_list_r Astmt_list_r
......
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