optional semicolons
SVN=121604
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index c3af22b..1598a8e 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -530,6 +530,7 @@
Node* stringop(Node*);
Node* convas(Node*);
Node* reorder(Node*);
+void arrayconv(Type*, Node*);
/*
* const.c
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index a3f8e98..cfd4cc0 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -30,12 +30,14 @@
%type <lint> chandir
%type <node> xdcl xdcl_list_r oxdcl_list common_dcl
%type <node> oarg_type_list arg_type_list_r arg_type
-%type <node> stmt empty_stmt else_stmt
-%type <node> complex_stmt compound_stmt stmt_list_r ostmt_list
+%type <node> else_stmt1 else_stmt2
+%type <node> complex_stmt compound_stmt ostmt_list
+%type <node> stmt_list_r Astmt_list_r Bstmt_list_r
+%type <node> Astmt Bstmt Cstmt
%type <node> for_stmt for_body for_header
%type <node> if_stmt if_body if_header
%type <node> range_header range_body range_stmt
-%type <node> simple_stmt osimple_stmt
+%type <node> simple_stmt osimple_stmt semi_stmt
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
%type <node> name name_name new_name new_name_list_r
%type <node> vardcl_list_r vardcl
@@ -48,7 +50,7 @@
%type <node> fnres fnliteral xfndcl fndcl
%type <node> keyval_list_r keyval
-%type <type> type fntypeh fntype fnlitdcl intype new_type
+%type <type> type fntypeh fntype fnlitdcl intype new_type typeconv
%left LOROR
%left LANDAND
@@ -206,40 +208,16 @@
dodcltype($1, $2);
}
-/*
- * statements
- */
-stmt:
- error ';'
+else_stmt1:
+ complex_stmt
+| compound_stmt
+
+else_stmt2:
+ simple_stmt
+| semi_stmt
+| ';'
{
$$ = N;
- context = nil;
- }
-| common_dcl ';'
- {
- $$ = $1;
- }
-| simple_stmt ';'
-| complex_stmt
-| compound_stmt
-| empty_stmt
-
-empty_stmt:
- ';'
- {
- $$ = nod(OEMPTY, N, N);
- }
-
-else_stmt:
- stmt
- {
- $$ = $1;
- switch($$->op) {
- case OLABEL:
- case OXCASE:
- case OXFALL:
- yyerror("statement cannot be labeled");
- }
}
simple_stmt:
@@ -295,7 +273,7 @@
popdcl("if/switch");
$$ = $2;
}
-| LIF if_stmt LELSE else_stmt
+| LIF if_stmt LELSE else_stmt1
{
popdcl("if/switch");
$$ = $2;
@@ -306,10 +284,6 @@
popdcl("range");
$$ = $2;
}
-| LRETURN oexpr_list ';'
- {
- $$ = nod(ORETURN, $2, N);
- }
| LCASE expr_list ':'
{
// will be converted to OCASE
@@ -323,38 +297,50 @@
poptodcl();
$$ = nod(OXCASE, N, N);
}
-| LFALL ';'
+| new_name ':'
+ {
+ $$ = nod(OLABEL, $1, N);
+ }
+
+semi_stmt:
+ LFALL
{
// will be converted to OFALL
$$ = nod(OXFALL, N, N);
}
-| LBREAK oexpr ';'
+| LBREAK oexpr
{
$$ = nod(OBREAK, $2, N);
}
-| LCONTINUE oexpr ';'
+| LCONTINUE oexpr
{
$$ = nod(OCONTINUE, $2, N);
}
-| LGO pexpr '(' oexpr_list ')' ';'
+| LGO pexpr '(' oexpr_list ')'
{
$$ = nod(OPROC, $2, $4);
}
-| LPRINT expr_list ';'
+| LPRINT expr_list
{
$$ = nod(OPRINT, $2, N);
}
-| LPANIC oexpr_list ';'
+| LPANIC oexpr_list
{
$$ = nod(OPANIC, $2, N);
}
-| LGOTO new_name ';'
+| LGOTO new_name
{
$$ = nod(OGOTO, $2, N);
}
-| new_name ':'
+| LRETURN oexpr_list
{
- $$ = nod(OLABEL, $1, N);
+ $$ = nod(ORETURN, $2, N);
+ }
+| LIF if_stmt LELSE else_stmt2
+ {
+ popdcl("if/switch");
+ $$ = $2;
+ $$->nelse = $4;
}
compound_stmt:
@@ -657,11 +643,11 @@
// map literal
$$ = N;
}
-| latype '(' oexpr_list ')'
+| typeconv '(' oexpr_list ')'
{
// struct literal and conversions
$$ = nod(OCONV, $3, N);
- $$->type = $1->otype;
+ $$->type = $1;
}
| LCONVERT '(' type ',' expr ')'
{
@@ -738,6 +724,32 @@
$$ = oldname($1);
}
+typeconv:
+ latype
+ {
+ $$ = oldtype($1);
+ }
+| '[' ']' typeconv
+ {
+ $$ = aindex(N, $3);
+ }
+| LCHAN chandir typeconv
+ {
+ $$ = typ(TCHAN);
+ $$->type = $3;
+ $$->chan = $2;
+ }
+| LMAP '[' typeconv ']' typeconv
+ {
+ $$ = typ(TMAP);
+ $$->down = $3;
+ $$->type = $5;
+ }
+| LANY
+ {
+ $$ = typ(TANY);
+ }
+
type:
latype
{
@@ -1046,15 +1058,48 @@
$$ = nod(OLIST, $1, $3);
}
-stmt_list_r:
- stmt
- {
- $$ = $1;
- }
-| stmt_list_r stmt
+Astmt:
+ complex_stmt
+
+Bstmt:
+ semi_stmt
+| common_dcl
+
+Cstmt:
+ simple_stmt
+
+Astmt_list_r:
+ Astmt
+| Astmt_list_r Astmt
{
$$ = nod(OLIST, $1, $2);
}
+| Bstmt_list_r ';'
+| Astmt_list_r ';'
+| ';'
+ {
+ $$ = N;
+ }
+
+Bstmt_list_r:
+ Bstmt
+| Cstmt
+| Bstmt_list_r Bstmt
+ {
+ $$ = nod(OLIST, $1, $2);
+ }
+| Astmt_list_r Cstmt
+ {
+ $$ = nod(OLIST, $1, $2);
+ }
+| Astmt_list_r Bstmt
+ {
+ $$ = nod(OLIST, $1, $2);
+ }
+
+stmt_list_r:
+ Astmt_list_r
+| Bstmt_list_r
expr_list_r:
expr
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 995c641..1aeca1a 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -264,6 +264,7 @@
}
// simple fix-float
+ if(n->left->type != T)
if(isint[n->left->type->etype] || isfloat[n->left->type->etype])
if(isint[n->type->etype] || isfloat[n->type->etype]) {
evconst(n);
@@ -283,6 +284,11 @@
}
}
+ if(n->type->etype == TARRAY) {
+ arrayconv(n->type, n->left);
+ goto ret;
+ }
+
badtype(n->op, n->left->type, n->type);
goto ret;
@@ -1276,3 +1282,31 @@
{
return n;
}
+
+void
+arrayconv(Type *t, Node *n)
+{
+ int c;
+ Iter save;
+ Node *l;
+
+ l = listfirst(&save, &n);
+ c = 0;
+
+loop:
+ if(l == N) {
+ if(t->bound == 0)
+ t->bound = c;
+ if(t->bound == 0 || t->bound < c)
+ yyerror("error with array convert bounds");
+ return;
+ }
+
+ c++;
+ walktype(l, 0);
+ convlit(l, t->type);
+ if(!ascompat(l->type, t->type))
+ badtype(OARRAY, l->type, t->type);
+ l = listnext(&save);
+ goto loop;
+}