github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/cmd/compile/internal/gc/go.y (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6   * Go language grammar.
     7   *
     8   * The Go semicolon rules are:
     9   *
    10   *  1. all statements and declarations are terminated by semicolons.
    11   *  2. semicolons can be omitted before a closing ) or }.
    12   *  3. semicolons are inserted by the lexer before a newline
    13   *      following a specific list of tokens.
    14   *
    15   * Rules #1 and #2 are accomplished by writing the lists as
    16   * semicolon-separated lists with an optional trailing semicolon.
    17   * Rule #3 is implemented in yylex.
    18   */
    19  
    20  %{
    21  package gc
    22  
    23  import (
    24  	"fmt"
    25  	"strings"
    26  )
    27  %}
    28  %union	{
    29  	node *Node
    30  	list *NodeList
    31  	typ *Type
    32  	sym *Sym
    33  	val Val
    34  	i int
    35  }
    36  
    37  // |sed 's/.*	//' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx		/'
    38  
    39  %token	<val>	LLITERAL
    40  %token	<i>	LASOP LCOLAS
    41  %token	<sym>	LBREAK LCASE LCHAN LCONST LCONTINUE LDDD
    42  %token	<sym>	LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO
    43  %token	<sym>	LIF LIMPORT LINTERFACE LMAP LNAME
    44  %token	<sym>	LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH
    45  %token	<sym>	LTYPE LVAR
    46  
    47  %token		LANDAND LANDNOT LBODY LCOMM LDEC LEQ LGE LGT
    48  %token		LIGNORE LINC LLE LLSH LLT LNE LOROR LRSH
    49  
    50  %type	<i>	lbrace import_here
    51  %type	<sym>	sym packname
    52  %type	<val>	oliteral
    53  
    54  %type	<node>	stmt ntype
    55  %type	<node>	arg_type
    56  %type	<node>	case caseblock
    57  %type	<node>	compound_stmt dotname embed expr complitexpr bare_complitexpr
    58  %type	<node>	expr_or_type
    59  %type	<node>	fndcl hidden_fndcl fnliteral
    60  %type	<node>	for_body for_header for_stmt if_header if_stmt non_dcl_stmt
    61  %type	<node>	interfacedcl keyval labelname name
    62  %type	<node>	name_or_type non_expr_type
    63  %type	<node>	new_name dcl_name oexpr typedclname
    64  %type	<node>	onew_name
    65  %type	<node>	osimple_stmt pexpr pexpr_no_paren
    66  %type	<node>	pseudocall range_stmt select_stmt
    67  %type	<node>	simple_stmt
    68  %type	<node>	switch_stmt uexpr
    69  %type	<node>	xfndcl typedcl start_complit
    70  
    71  %type	<list>	xdcl fnbody fnres loop_body dcl_name_list
    72  %type	<list>	new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
    73  %type	<list>	oexpr_list caseblock_list elseif elseif_list else stmt_list oarg_type_list_ocomma arg_type_list
    74  %type	<list>	interfacedcl_list vardcl vardcl_list structdcl structdcl_list
    75  %type	<list>	common_dcl constdcl constdcl1 constdcl_list typedcl_list
    76  
    77  %type	<node>	convtype comptype dotdotdot
    78  %type	<node>	indcl interfacetype structtype ptrtype
    79  %type	<node>	recvchantype non_recvchantype othertype fnret_type fntype
    80  
    81  %type	<sym>	hidden_importsym hidden_pkg_importsym
    82  
    83  %type	<node>	hidden_constant hidden_literal hidden_funarg
    84  %type	<node>	hidden_interfacedcl hidden_structdcl
    85  
    86  %type	<list>	hidden_funres
    87  %type	<list>	ohidden_funres
    88  %type	<list>	hidden_funarg_list ohidden_funarg_list
    89  %type	<list>	hidden_interfacedcl_list ohidden_interfacedcl_list
    90  %type	<list>	hidden_structdcl_list ohidden_structdcl_list
    91  
    92  %type	<typ>	hidden_type hidden_type_misc hidden_pkgtype
    93  %type	<typ>	hidden_type_func
    94  %type	<typ>	hidden_type_recv_chan hidden_type_non_recv_chan
    95  
    96  %left		LCOMM	/* outside the usual hierarchy; here for good error messages */
    97  
    98  %left		LOROR
    99  %left		LANDAND
   100  %left		LEQ LNE LLE LGE LLT LGT
   101  %left		'+' '-' '|' '^'
   102  %left		'*' '/' '%' '&' LLSH LRSH LANDNOT
   103  
   104  /*
   105   * manual override of shift/reduce conflicts.
   106   * the general form is that we assign a precedence
   107   * to the token being shifted and then introduce
   108   * NotToken with lower precedence or PreferToToken with higher
   109   * and annotate the reducing rule accordingly.
   110   */
   111  %left		NotPackage
   112  %left		LPACKAGE
   113  
   114  %left		NotParen
   115  %left		'('
   116  
   117  %left		')'
   118  %left		PreferToRightParen
   119  
   120  %error loadsys package LIMPORT '(' LLITERAL import_package import_there ',':
   121  	"unexpected comma during import block"
   122  
   123  %error loadsys package LIMPORT LNAME ';':
   124  	"missing import path; require quoted string"
   125  
   126  %error loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header ';':
   127  	"missing { after if clause"
   128  
   129  %error loadsys package imports LFUNC LNAME '(' ')' '{' LSWITCH if_header ';':
   130  	"missing { after switch clause"
   131  
   132  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFOR for_header ';':
   133  	"missing { after for clause"
   134  
   135  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFOR ';' LBODY:
   136  	"missing { after for clause"
   137  
   138  %error loadsys package imports LFUNC LNAME '(' ')' ';' '{':
   139  	"unexpected semicolon or newline before {"
   140  
   141  %error loadsys package imports LTYPE LNAME ';':
   142  	"unexpected semicolon or newline in type declaration"
   143  
   144  %error loadsys package imports LCHAN '}':
   145  	"unexpected } in channel type"
   146  
   147  %error loadsys package imports LCHAN ')':
   148  	"unexpected ) in channel type"
   149  
   150  %error loadsys package imports LCHAN ',':
   151  	"unexpected comma in channel type"
   152  
   153  %error loadsys package imports LFUNC LNAME '(' ')' '{' if_stmt ';' LELSE:
   154  	"unexpected semicolon or newline before else"
   155  
   156  %error loadsys package imports LTYPE LNAME LINTERFACE '{' LNAME ',' LNAME:
   157  	"name list not allowed in interface type"
   158  
   159  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFOR LVAR LNAME '=' LNAME:
   160  	"var declaration not allowed in for initializer"
   161  
   162  %error loadsys package imports LVAR LNAME '[' ']' LNAME '{':
   163  	"unexpected { at end of statement"
   164  
   165  %error loadsys package imports LFUNC LNAME '(' ')' '{' LVAR LNAME '[' ']' LNAME '{':
   166  	"unexpected { at end of statement"
   167  
   168  %error loadsys package imports LFUNC LNAME '(' ')' '{' LDEFER LNAME ';':
   169  	"argument to go/defer must be function call"
   170  
   171  %error loadsys package imports LVAR LNAME '=' LNAME '{' LNAME ';':
   172  	"need trailing comma before newline in composite literal"
   173  
   174  %error loadsys package imports LVAR LNAME '=' comptype '{' LNAME ';':
   175  	"need trailing comma before newline in composite literal"
   176  
   177  %error loadsys package imports LFUNC LNAME '(' ')' '{' LFUNC LNAME:
   178  	"nested func not allowed"
   179  
   180  %error loadsys package imports LFUNC LNAME '(' ')' '{' LIF if_header loop_body LELSE ';':
   181  	"else must be followed by if or statement block"
   182  
   183  %%
   184  file:
   185  	loadsys
   186  	package
   187  	imports
   188  	xdcl_list
   189  	{
   190  		xtop = concat(xtop, $4);
   191  	}
   192  
   193  package:
   194  	%prec NotPackage
   195  	{
   196  		prevlineno = lineno;
   197  		Yyerror("package statement must be first");
   198  		errorexit();
   199  	}
   200  |	LPACKAGE sym ';'
   201  	{
   202  		mkpackage($2.Name);
   203  	}
   204  
   205  /*
   206   * this loads the definitions for the low-level runtime functions,
   207   * so that the compiler can generate calls to them,
   208   * but does not make the name "runtime" visible as a package.
   209   */
   210  loadsys:
   211  	{
   212  		importpkg = Runtimepkg;
   213  
   214  		if Debug['A'] != 0 {
   215  			cannedimports("runtime.Builtin", "package runtime\n\n$$\n\n");
   216  		} else {
   217  			cannedimports("runtime.Builtin", runtimeimport);
   218  		}
   219  		curio.importsafe = true
   220  	}
   221  	import_package
   222  	import_there
   223  	{
   224  		importpkg = nil;
   225  	}
   226  
   227  imports:
   228  |	imports import ';'
   229  
   230  import:
   231  	LIMPORT import_stmt
   232  |	LIMPORT '(' import_stmt_list osemi ')'
   233  |	LIMPORT '(' ')'
   234  
   235  import_stmt:
   236  	import_here import_package import_there
   237  	{
   238  		ipkg := importpkg;
   239  		my := importmyname;
   240  		importpkg = nil;
   241  		importmyname = nil;
   242  
   243  		if my == nil {
   244  			my = Lookup(ipkg.Name);
   245  		}
   246  
   247  		pack := Nod(OPACK, nil, nil);
   248  		pack.Sym = my;
   249  		pack.Name.Pkg = ipkg;
   250  		pack.Lineno = int32($1);
   251  
   252  		if strings.HasPrefix(my.Name, ".") {
   253  			importdot(ipkg, pack);
   254  			break;
   255  		}
   256  		if my.Name == "init" {
   257  			lineno = int32($1)
   258  			Yyerror("cannot import package as init - init must be a func");
   259  			break;
   260  		}
   261  		if my.Name == "_" {
   262  			break;
   263  		}
   264  		if my.Def != nil {
   265  			lineno = int32($1);
   266  			redeclare(my, "as imported package name");
   267  		}
   268  		my.Def = pack;
   269  		my.Lastlineno = int32($1);
   270  		my.Block = 1;	// at top level
   271  	}
   272  |	import_here import_there
   273  	{
   274  		// When an invalid import path is passed to importfile,
   275  		// it calls Yyerror and then sets up a fake import with
   276  		// no package statement. This allows us to test more
   277  		// than one invalid import statement in a single file.
   278  		if nerrors == 0 {
   279  			Fatalf("phase error in import");
   280  		}
   281  	}
   282  
   283  import_stmt_list:
   284  	import_stmt
   285  |	import_stmt_list ';' import_stmt
   286  
   287  import_here:
   288  	LLITERAL
   289  	{
   290  		// import with original name
   291  		$$ = parserline();
   292  		importmyname = nil;
   293  		importfile(&$1, $$);
   294  	}
   295  |	sym LLITERAL
   296  	{
   297  		// import with given name
   298  		$$ = parserline();
   299  		importmyname = $1;
   300  		importfile(&$2, $$);
   301  	}
   302  |	'.' LLITERAL
   303  	{
   304  		// import into my name space
   305  		$$ = parserline();
   306  		importmyname = Lookup(".");
   307  		importfile(&$2, $$);
   308  	}
   309  
   310  import_package:
   311  	LPACKAGE LNAME import_safety ';'
   312  	{
   313  		if importpkg.Name == "" {
   314  			importpkg.Name = $2.Name;
   315  			numImport[$2.Name]++
   316  		} else if importpkg.Name != $2.Name {
   317  			Yyerror("conflicting names %s and %s for package %q", importpkg.Name, $2.Name, importpkg.Path);
   318  		}
   319  		importpkg.Direct = true;
   320  		importpkg.Safe = curio.importsafe
   321  
   322  		if safemode != 0 && !curio.importsafe {
   323  			Yyerror("cannot import unsafe package %q", importpkg.Path);
   324  		}
   325  	}
   326  
   327  import_safety:
   328  |	LNAME
   329  	{
   330  		if $1.Name == "safe" {
   331  			curio.importsafe = true
   332  		}
   333  	}
   334  
   335  import_there:
   336  	{
   337  		defercheckwidth();
   338  	}
   339  	hidden_import_list '$' '$'
   340  	{
   341  		resumecheckwidth();
   342  		unimportfile();
   343  	}
   344  
   345  /*
   346   * declarations
   347   */
   348  xdcl:
   349  	{
   350  		Yyerror("empty top-level declaration");
   351  		$$ = nil;
   352  	}
   353  |	common_dcl
   354  |	xfndcl
   355  	{
   356  		$$ = list1($1);
   357  	}
   358  |	non_dcl_stmt
   359  	{
   360  		Yyerror("non-declaration statement outside function body");
   361  		$$ = nil;
   362  	}
   363  |	error
   364  	{
   365  		$$ = nil;
   366  	}
   367  
   368  common_dcl:
   369  	LVAR vardcl
   370  	{
   371  		$$ = $2;
   372  	}
   373  |	LVAR '(' vardcl_list osemi ')'
   374  	{
   375  		$$ = $3;
   376  	}
   377  |	LVAR '(' ')'
   378  	{
   379  		$$ = nil;
   380  	}
   381  |	lconst constdcl
   382  	{
   383  		$$ = $2;
   384  		iota_ = -100000;
   385  		lastconst = nil;
   386  	}
   387  |	lconst '(' constdcl osemi ')'
   388  	{
   389  		$$ = $3;
   390  		iota_ = -100000;
   391  		lastconst = nil;
   392  	}
   393  |	lconst '(' constdcl ';' constdcl_list osemi ')'
   394  	{
   395  		$$ = concat($3, $5);
   396  		iota_ = -100000;
   397  		lastconst = nil;
   398  	}
   399  |	lconst '(' ')'
   400  	{
   401  		$$ = nil;
   402  		iota_ = -100000;
   403  	}
   404  |	LTYPE typedcl
   405  	{
   406  		$$ = list1($2);
   407  	}
   408  |	LTYPE '(' typedcl_list osemi ')'
   409  	{
   410  		$$ = $3;
   411  	}
   412  |	LTYPE '(' ')'
   413  	{
   414  		$$ = nil;
   415  	}
   416  
   417  lconst:
   418  	LCONST
   419  	{
   420  		iota_ = 0;
   421  	}
   422  
   423  vardcl:
   424  	dcl_name_list ntype
   425  	{
   426  		$$ = variter($1, $2, nil);
   427  	}
   428  |	dcl_name_list ntype '=' expr_list
   429  	{
   430  		$$ = variter($1, $2, $4);
   431  	}
   432  |	dcl_name_list '=' expr_list
   433  	{
   434  		$$ = variter($1, nil, $3);
   435  	}
   436  
   437  constdcl:
   438  	dcl_name_list ntype '=' expr_list
   439  	{
   440  		$$ = constiter($1, $2, $4);
   441  	}
   442  |	dcl_name_list '=' expr_list
   443  	{
   444  		$$ = constiter($1, nil, $3);
   445  	}
   446  
   447  constdcl1:
   448  	constdcl
   449  |	dcl_name_list ntype
   450  	{
   451  		$$ = constiter($1, $2, nil);
   452  	}
   453  |	dcl_name_list
   454  	{
   455  		$$ = constiter($1, nil, nil);
   456  	}
   457  
   458  typedclname:
   459  	sym
   460  	{
   461  		// different from dclname because the name
   462  		// becomes visible right here, not at the end
   463  		// of the declaration.
   464  		$$ = typedcl0($1);
   465  	}
   466  
   467  typedcl:
   468  	typedclname ntype
   469  	{
   470  		$$ = typedcl1($1, $2, true);
   471  	}
   472  
   473  simple_stmt:
   474  	expr
   475  	{
   476  		$$ = $1;
   477  
   478  		// These nodes do not carry line numbers.
   479  		// Since a bare name used as an expression is an error,
   480  		// introduce a wrapper node to give the correct line.
   481  		switch($$.Op) {
   482  		case ONAME, ONONAME, OTYPE, OPACK, OLITERAL:
   483  			$$ = Nod(OPAREN, $$, nil);
   484  			$$.Implicit = true;
   485  			break;
   486  		}
   487  	}
   488  |	expr LASOP expr
   489  	{
   490  		$$ = Nod(OASOP, $1, $3);
   491  		$$.Etype = EType($2);			// rathole to pass opcode
   492  	}
   493  |	expr_list '=' expr_list
   494  	{
   495  		if $1.Next == nil && $3.Next == nil {
   496  			// simple
   497  			$$ = Nod(OAS, $1.N, $3.N);
   498  			break;
   499  		}
   500  		// multiple
   501  		$$ = Nod(OAS2, nil, nil);
   502  		$$.List = $1;
   503  		$$.Rlist = $3;
   504  	}
   505  |	expr_list LCOLAS expr_list
   506  	{
   507  		if $3.N.Op == OTYPESW {
   508  			$$ = Nod(OTYPESW, nil, $3.N.Right);
   509  			if $3.Next != nil {
   510  				Yyerror("expr.(type) must be alone in list");
   511  			}
   512  			if $1.Next != nil {
   513  				Yyerror("argument count mismatch: %d = %d", count($1), 1);
   514  			} else if ($1.N.Op != ONAME && $1.N.Op != OTYPE && $1.N.Op != ONONAME && ($1.N.Op != OLITERAL || $1.N.Name == nil)) || isblank($1.N) {
   515  				Yyerror("invalid variable name %s in type switch", $1.N);
   516  			} else {
   517  				$$.Left = dclname($1.N.Sym);
   518  			}  // it's a colas, so must not re-use an oldname.
   519  			break;
   520  		}
   521  		$$ = colas($1, $3, int32($2));
   522  	}
   523  |	expr LINC
   524  	{
   525  		$$ = Nod(OASOP, $1, Nodintconst(1));
   526  		$$.Implicit = true;
   527  		// TODO(marvin): Fix Node.EType type union.
   528  		$$.Etype = EType(OADD);
   529  	}
   530  |	expr LDEC
   531  	{
   532  		$$ = Nod(OASOP, $1, Nodintconst(1));
   533  		$$.Implicit = true;
   534  		// TODO(marvin): Fix Node.EType type union.
   535  		$$.Etype = EType(OSUB);
   536  	}
   537  
   538  case:
   539  	LCASE expr_or_type_list ':'
   540  	{
   541  		var n, nn *Node
   542  
   543  		// will be converted to OCASE
   544  		// right will point to next case
   545  		// done in casebody()
   546  		markdcl();
   547  		$$ = Nod(OXCASE, nil, nil);
   548  		$$.List = $2;
   549  		if typesw != nil && typesw.Right != nil {
   550  			n = typesw.Right.Left
   551  			if n != nil {
   552  				// type switch - declare variable
   553  				nn = newname(n.Sym);
   554  				declare(nn, dclcontext);
   555  				$$.Rlist = list1(nn);
   556  	
   557  				// keep track of the instances for reporting unused
   558  				nn.Name.Defn = typesw.Right;
   559  			}
   560  		}
   561  	}
   562  |	LCASE expr_or_type_list '=' expr ':'
   563  	{
   564  		var n *Node
   565  
   566  		// will be converted to OCASE
   567  		// right will point to next case
   568  		// done in casebody()
   569  		markdcl();
   570  		$$ = Nod(OXCASE, nil, nil);
   571  		if $2.Next == nil {
   572  			n = Nod(OAS, $2.N, $4);
   573  		} else {
   574  			n = Nod(OAS2, nil, nil);
   575  			n.List = $2;
   576  			n.Rlist = list1($4);
   577  		}
   578  		$$.List = list1(n);
   579  	}
   580  |	LCASE expr_or_type_list LCOLAS expr ':'
   581  	{
   582  		// will be converted to OCASE
   583  		// right will point to next case
   584  		// done in casebody()
   585  		markdcl();
   586  		$$ = Nod(OXCASE, nil, nil);
   587  		$$.List = list1(colas($2, list1($4), int32($3)));
   588  	}
   589  |	LDEFAULT ':'
   590  	{
   591  		var n, nn *Node
   592  
   593  		markdcl();
   594  		$$ = Nod(OXCASE, nil, nil);
   595  		if typesw != nil && typesw.Right != nil {
   596  			n = typesw.Right.Left
   597  			if n != nil {
   598  				// type switch - declare variable
   599  				nn = newname(n.Sym);
   600  				declare(nn, dclcontext);
   601  				$$.Rlist = list1(nn);
   602  	
   603  				// keep track of the instances for reporting unused
   604  				nn.Name.Defn = typesw.Right;
   605  			}
   606  		}
   607  	}
   608  
   609  compound_stmt:
   610  	'{'
   611  	{
   612  		markdcl();
   613  	}
   614  	stmt_list '}'
   615  	{
   616  		if $3 == nil {
   617  			$$ = Nod(OEMPTY, nil, nil);
   618  		} else {
   619  			$$ = liststmt($3);
   620  		}
   621  		popdcl();
   622  	}
   623  
   624  caseblock:
   625  	case
   626  	{
   627  		// If the last token read by the lexer was consumed
   628  		// as part of the case, clear it (parser has cleared yychar).
   629  		// If the last token read by the lexer was the lookahead
   630  		// leave it alone (parser has it cached in yychar).
   631  		// This is so that the stmt_list action doesn't look at
   632  		// the case tokens if the stmt_list is empty.
   633  		yylast = yychar;
   634  		$1.Xoffset = int64(block);
   635  	}
   636  	stmt_list
   637  	{
   638  		// This is the only place in the language where a statement
   639  		// list is not allowed to drop the final semicolon, because
   640  		// it's the only place where a statement list is not followed 
   641  		// by a closing brace.  Handle the error for pedantry.
   642  
   643  		// Find the final token of the statement list.
   644  		// yylast is lookahead; yyprev is last of stmt_list
   645  		last := yyprev;
   646  
   647  		if last > 0 && last != ';' && yychar != '}' {
   648  			Yyerror("missing statement after label");
   649  		}
   650  		$$ = $1;
   651  		$$.Nbody = $3;
   652  		popdcl();
   653  	}
   654  
   655  caseblock_list:
   656  	{
   657  		$$ = nil;
   658  	}
   659  |	caseblock_list caseblock
   660  	{
   661  		$$ = list($1, $2);
   662  	}
   663  
   664  loop_body:
   665  	LBODY
   666  	{
   667  		markdcl();
   668  	}
   669  	stmt_list '}'
   670  	{
   671  		$$ = $3;
   672  		popdcl();
   673  	}
   674  
   675  range_stmt:
   676  	expr_list '=' LRANGE expr
   677  	{
   678  		$$ = Nod(ORANGE, nil, $4);
   679  		$$.List = $1;
   680  		$$.Etype = 0;	// := flag
   681  	}
   682  |	expr_list LCOLAS LRANGE expr
   683  	{
   684  		$$ = Nod(ORANGE, nil, $4);
   685  		$$.List = $1;
   686  		$$.Colas = true;
   687  		colasdefn($1, $$);
   688  	}
   689  |	LRANGE expr
   690  	{
   691  		$$ = Nod(ORANGE, nil, $2);
   692  		$$.Etype = 0; // := flag
   693  	}
   694  
   695  for_header:
   696  	osimple_stmt ';' osimple_stmt ';' osimple_stmt
   697  	{
   698  		// init ; test ; incr
   699  		if $5 != nil && $5.Colas {
   700  			Yyerror("cannot declare in the for-increment");
   701  		}
   702  		$$ = Nod(OFOR, nil, nil);
   703  		if $1 != nil {
   704  			$$.Ninit = list1($1);
   705  		}
   706  		$$.Left = $3;
   707  		$$.Right = $5;
   708  	}
   709  |	osimple_stmt
   710  	{
   711  		// normal test
   712  		$$ = Nod(OFOR, nil, nil);
   713  		$$.Left = $1;
   714  	}
   715  |	range_stmt
   716  
   717  for_body:
   718  	for_header loop_body
   719  	{
   720  		$$ = $1;
   721  		$$.Nbody = concat($$.Nbody, $2);
   722  	}
   723  
   724  for_stmt:
   725  	LFOR
   726  	{
   727  		markdcl();
   728  	}
   729  	for_body
   730  	{
   731  		$$ = $3;
   732  		popdcl();
   733  	}
   734  
   735  if_header:
   736  	osimple_stmt
   737  	{
   738  		// test
   739  		$$ = Nod(OIF, nil, nil);
   740  		$$.Left = $1;
   741  	}
   742  |	osimple_stmt ';' osimple_stmt
   743  	{
   744  		// init ; test
   745  		$$ = Nod(OIF, nil, nil);
   746  		if $1 != nil {
   747  			$$.Ninit = list1($1);
   748  		}
   749  		$$.Left = $3;
   750  	}
   751  
   752  /* IF cond body (ELSE IF cond body)* (ELSE block)? */
   753  if_stmt:
   754  	LIF
   755  	{
   756  		markdcl();
   757  	}
   758  	if_header
   759  	{
   760  		if $3.Left == nil {
   761  			Yyerror("missing condition in if statement");
   762  		}
   763  	}
   764  	loop_body
   765  	{
   766  		$3.Nbody = $5;
   767  	}
   768  	elseif_list else
   769  	{
   770  		var n *Node
   771  		var nn *NodeList
   772  
   773  		$$ = $3;
   774  		n = $3;
   775  		popdcl();
   776  		for nn = concat($7, $8); nn != nil; nn = nn.Next {
   777  			if nn.N.Op == OIF {
   778  				popdcl();
   779  			}
   780  			n.Rlist = list1(nn.N);
   781  			n = nn.N;
   782  		}
   783  	}
   784  
   785  elseif:
   786  	LELSE LIF 
   787  	{
   788  		markdcl();
   789  	}
   790  	if_header loop_body
   791  	{
   792  		if $4.Left == nil {
   793  			Yyerror("missing condition in if statement");
   794  		}
   795  		$4.Nbody = $5;
   796  		$$ = list1($4);
   797  	}
   798  
   799  elseif_list:
   800  	{
   801  		$$ = nil;
   802  	}
   803  |	elseif_list elseif
   804  	{
   805  		$$ = concat($1, $2);
   806  	}
   807  
   808  else:
   809  	{
   810  		$$ = nil;
   811  	}
   812  |	LELSE compound_stmt
   813  	{
   814  		l := &NodeList{N: $2}
   815  		l.End = l
   816  		$$ = l;
   817  	}
   818  
   819  switch_stmt:
   820  	LSWITCH
   821  	{
   822  		markdcl();
   823  	}
   824  	if_header
   825  	{
   826  		var n *Node
   827  		n = $3.Left;
   828  		if n != nil && n.Op != OTYPESW {
   829  			n = nil;
   830  		}
   831  		typesw = Nod(OXXX, typesw, n);
   832  	}
   833  	LBODY caseblock_list '}'
   834  	{
   835  		$$ = $3;
   836  		$$.Op = OSWITCH;
   837  		$$.List = $6;
   838  		typesw = typesw.Left;
   839  		popdcl();
   840  	}
   841  
   842  select_stmt:
   843  	LSELECT
   844  	{
   845  		typesw = Nod(OXXX, typesw, nil);
   846  	}
   847  	LBODY caseblock_list '}'
   848  	{
   849  		$$ = Nod(OSELECT, nil, nil);
   850  		$$.Lineno = typesw.Lineno;
   851  		$$.List = $4;
   852  		typesw = typesw.Left;
   853  	}
   854  
   855  /*
   856   * expressions
   857   */
   858  expr:
   859  	uexpr
   860  |	expr LOROR expr
   861  	{
   862  		$$ = Nod(OOROR, $1, $3);
   863  	}
   864  |	expr LANDAND expr
   865  	{
   866  		$$ = Nod(OANDAND, $1, $3);
   867  	}
   868  |	expr LEQ expr
   869  	{
   870  		$$ = Nod(OEQ, $1, $3);
   871  	}
   872  |	expr LNE expr
   873  	{
   874  		$$ = Nod(ONE, $1, $3);
   875  	}
   876  |	expr LLT expr
   877  	{
   878  		$$ = Nod(OLT, $1, $3);
   879  	}
   880  |	expr LLE expr
   881  	{
   882  		$$ = Nod(OLE, $1, $3);
   883  	}
   884  |	expr LGE expr
   885  	{
   886  		$$ = Nod(OGE, $1, $3);
   887  	}
   888  |	expr LGT expr
   889  	{
   890  		$$ = Nod(OGT, $1, $3);
   891  	}
   892  |	expr '+' expr
   893  	{
   894  		$$ = Nod(OADD, $1, $3);
   895  	}
   896  |	expr '-' expr
   897  	{
   898  		$$ = Nod(OSUB, $1, $3);
   899  	}
   900  |	expr '|' expr
   901  	{
   902  		$$ = Nod(OOR, $1, $3);
   903  	}
   904  |	expr '^' expr
   905  	{
   906  		$$ = Nod(OXOR, $1, $3);
   907  	}
   908  |	expr '*' expr
   909  	{
   910  		$$ = Nod(OMUL, $1, $3);
   911  	}
   912  |	expr '/' expr
   913  	{
   914  		$$ = Nod(ODIV, $1, $3);
   915  	}
   916  |	expr '%' expr
   917  	{
   918  		$$ = Nod(OMOD, $1, $3);
   919  	}
   920  |	expr '&' expr
   921  	{
   922  		$$ = Nod(OAND, $1, $3);
   923  	}
   924  |	expr LANDNOT expr
   925  	{
   926  		$$ = Nod(OANDNOT, $1, $3);
   927  	}
   928  |	expr LLSH expr
   929  	{
   930  		$$ = Nod(OLSH, $1, $3);
   931  	}
   932  |	expr LRSH expr
   933  	{
   934  		$$ = Nod(ORSH, $1, $3);
   935  	}
   936  	/* not an expression anymore, but left in so we can give a good error */
   937  |	expr LCOMM expr
   938  	{
   939  		$$ = Nod(OSEND, $1, $3);
   940  	}
   941  
   942  uexpr:
   943  	pexpr
   944  |	'*' uexpr
   945  	{
   946  		$$ = Nod(OIND, $2, nil);
   947  	}
   948  |	'&' uexpr
   949  	{
   950  		if $2.Op == OCOMPLIT {
   951  			// Special case for &T{...}: turn into (*T){...}.
   952  			$$ = $2;
   953  			$$.Right = Nod(OIND, $$.Right, nil);
   954  			$$.Right.Implicit = true;
   955  		} else {
   956  			$$ = Nod(OADDR, $2, nil);
   957  		}
   958  	}
   959  |	'+' uexpr
   960  	{
   961  		$$ = Nod(OPLUS, $2, nil);
   962  	}
   963  |	'-' uexpr
   964  	{
   965  		$$ = Nod(OMINUS, $2, nil);
   966  	}
   967  |	'!' uexpr
   968  	{
   969  		$$ = Nod(ONOT, $2, nil);
   970  	}
   971  |	'~' uexpr
   972  	{
   973  		Yyerror("the bitwise complement operator is ^");
   974  		$$ = Nod(OCOM, $2, nil);
   975  	}
   976  |	'^' uexpr
   977  	{
   978  		$$ = Nod(OCOM, $2, nil);
   979  	}
   980  |	LCOMM uexpr
   981  	{
   982  		$$ = Nod(ORECV, $2, nil);
   983  	}
   984  
   985  /*
   986   * call-like statements that
   987   * can be preceded by 'defer' and 'go'
   988   */
   989  pseudocall:
   990  	pexpr '(' ')'
   991  	{
   992  		$$ = Nod(OCALL, $1, nil);
   993  	}
   994  |	pexpr '(' expr_or_type_list ocomma ')'
   995  	{
   996  		$$ = Nod(OCALL, $1, nil);
   997  		$$.List = $3;
   998  	}
   999  |	pexpr '(' expr_or_type_list LDDD ocomma ')'
  1000  	{
  1001  		$$ = Nod(OCALL, $1, nil);
  1002  		$$.List = $3;
  1003  		$$.Isddd = true;
  1004  	}
  1005  
  1006  pexpr_no_paren:
  1007  	LLITERAL
  1008  	{
  1009  		$$ = nodlit($1);
  1010  	}
  1011  |	name
  1012  |	pexpr '.' sym
  1013  	{
  1014  		if $1.Op == OPACK {
  1015  			var s *Sym
  1016  			s = restrictlookup($3.Name, $1.Name.Pkg);
  1017  			$1.Used = true;
  1018  			$$ = oldname(s);
  1019  			break;
  1020  		}
  1021  		$$ = Nod(OXDOT, $1, newname($3));
  1022  	}
  1023  |	pexpr '.' '(' expr_or_type ')'
  1024  	{
  1025  		$$ = Nod(ODOTTYPE, $1, $4);
  1026  	}
  1027  |	pexpr '.' '(' LTYPE ')'
  1028  	{
  1029  		$$ = Nod(OTYPESW, nil, $1);
  1030  	}
  1031  |	pexpr '[' expr ']'
  1032  	{
  1033  		$$ = Nod(OINDEX, $1, $3);
  1034  	}
  1035  |	pexpr '[' oexpr ':' oexpr ']'
  1036  	{
  1037  		$$ = Nod(OSLICE, $1, Nod(OKEY, $3, $5));
  1038  	}
  1039  |	pexpr '[' oexpr ':' oexpr ':' oexpr ']'
  1040  	{
  1041  		if $5 == nil {
  1042  			Yyerror("middle index required in 3-index slice");
  1043  		}
  1044  		if $7 == nil {
  1045  			Yyerror("final index required in 3-index slice");
  1046  		}
  1047  		$$ = Nod(OSLICE3, $1, Nod(OKEY, $3, Nod(OKEY, $5, $7)));
  1048  	}
  1049  |	pseudocall
  1050  |	convtype '(' expr ocomma ')'
  1051  	{
  1052  		// conversion
  1053  		$$ = Nod(OCALL, $1, nil);
  1054  		$$.List = list1($3);
  1055  	}
  1056  |	comptype lbrace start_complit braced_keyval_list '}'
  1057  	{
  1058  		$$ = $3;
  1059  		$$.Right = $1;
  1060  		$$.List = $4;
  1061  		fixlbrace($2);
  1062  	}
  1063  |	pexpr_no_paren '{' start_complit braced_keyval_list '}'
  1064  	{
  1065  		$$ = $3;
  1066  		$$.Right = $1;
  1067  		$$.List = $4;
  1068  	}
  1069  |	'(' expr_or_type ')' '{' start_complit braced_keyval_list '}'
  1070  	{
  1071  		Yyerror("cannot parenthesize type in composite literal");
  1072  		$$ = $5;
  1073  		$$.Right = $2;
  1074  		$$.List = $6;
  1075  	}
  1076  |	fnliteral
  1077  
  1078  start_complit:
  1079  	{
  1080  		// composite expression.
  1081  		// make node early so we get the right line number.
  1082  		$$ = Nod(OCOMPLIT, nil, nil);
  1083  	}
  1084  
  1085  keyval:
  1086  	complitexpr ':' complitexpr
  1087  	{
  1088  		$$ = Nod(OKEY, $1, $3);
  1089  	}
  1090  
  1091  bare_complitexpr:
  1092  	expr
  1093  	{
  1094  		// These nodes do not carry line numbers.
  1095  		// Since a composite literal commonly spans several lines,
  1096  		// the line number on errors may be misleading.
  1097  		// Introduce a wrapper node to give the correct line.
  1098  		$$ = $1;
  1099  		switch($$.Op) {
  1100  		case ONAME, ONONAME, OTYPE, OPACK, OLITERAL:
  1101  			$$ = Nod(OPAREN, $$, nil);
  1102  			$$.Implicit = true;
  1103  		}
  1104  	}
  1105  |	'{' start_complit braced_keyval_list '}'
  1106  	{
  1107  		$$ = $2;
  1108  		$$.List = $3;
  1109  	}
  1110  
  1111  complitexpr:
  1112  	expr
  1113  |	'{' start_complit braced_keyval_list '}'
  1114  	{
  1115  		$$ = $2;
  1116  		$$.List = $3;
  1117  	}
  1118  
  1119  pexpr:
  1120  	pexpr_no_paren
  1121  |	'(' expr_or_type ')'
  1122  	{
  1123  		$$ = $2;
  1124  		
  1125  		// Need to know on lhs of := whether there are ( ).
  1126  		// Don't bother with the OPAREN in other cases:
  1127  		// it's just a waste of memory and time.
  1128  		switch($$.Op) {
  1129  		case ONAME, ONONAME, OPACK, OTYPE, OLITERAL, OTYPESW:
  1130  			$$ = Nod(OPAREN, $$, nil);
  1131  		}
  1132  	}
  1133  
  1134  expr_or_type:
  1135  	expr
  1136  |	non_expr_type	%prec PreferToRightParen
  1137  
  1138  name_or_type:
  1139  	ntype
  1140  
  1141  lbrace:
  1142  	LBODY
  1143  	{
  1144  		$$ = LBODY;
  1145  	}
  1146  |	'{'
  1147  	{
  1148  		$$ = '{';
  1149  	}
  1150  
  1151  /*
  1152   * names and types
  1153   *	newname is used before declared
  1154   *	oldname is used after declared
  1155   */
  1156  new_name:
  1157  	sym
  1158  	{
  1159  		if $1 == nil {
  1160  			$$ = nil;
  1161  		} else {
  1162  			$$ = newname($1);
  1163  		}
  1164  	}
  1165  
  1166  dcl_name:
  1167  	sym
  1168  	{
  1169  		$$ = dclname($1);
  1170  	}
  1171  
  1172  onew_name:
  1173  	{
  1174  		$$ = nil;
  1175  	}
  1176  |	new_name
  1177  
  1178  sym:
  1179  	LNAME
  1180  	{
  1181  		$$ = $1;
  1182  		// during imports, unqualified non-exported identifiers are from builtinpkg
  1183  		if importpkg != nil && !exportname($1.Name) {
  1184  			$$ = Pkglookup($1.Name, builtinpkg);
  1185  		}
  1186  	}
  1187  |	hidden_importsym
  1188  |	'?'
  1189  	{
  1190  		$$ = nil;
  1191  	}
  1192  
  1193  hidden_importsym:
  1194  	'@' LLITERAL '.' LNAME
  1195  	{
  1196  		var p *Pkg
  1197  
  1198  		if $2.U.(string) == "" {
  1199  			p = importpkg;
  1200  		} else {
  1201  			if isbadimport($2.U.(string)) {
  1202  				errorexit();
  1203  			}
  1204  			p = mkpkg($2.U.(string));
  1205  		}
  1206  		$$ = Pkglookup($4.Name, p);
  1207  	}
  1208  |	'@' LLITERAL '.' '?'
  1209  	{
  1210  		var p *Pkg
  1211  
  1212  		if $2.U.(string) == "" {
  1213  			p = importpkg;
  1214  		} else {
  1215  			if isbadimport($2.U.(string)) {
  1216  				errorexit();
  1217  			}
  1218  			p = mkpkg($2.U.(string));
  1219  		}
  1220  		$$ = Pkglookup("?", p);
  1221  	}
  1222  
  1223  name:
  1224  	sym	%prec NotParen
  1225  	{
  1226  		$$ = oldname($1);
  1227  		if $$.Name != nil && $$.Name.Pack != nil {
  1228  			$$.Name.Pack.Used = true;
  1229  		}
  1230  	}
  1231  
  1232  labelname:
  1233  	new_name
  1234  
  1235  /*
  1236   * to avoid parsing conflicts, type is split into
  1237   *	channel types
  1238   *	function types
  1239   *	parenthesized types
  1240   *	any other type
  1241   * the type system makes additional restrictions,
  1242   * but those are not implemented in the grammar.
  1243   */
  1244  dotdotdot:
  1245  	LDDD
  1246  	{
  1247  		Yyerror("final argument in variadic function missing type");
  1248  		$$ = Nod(ODDD, typenod(typ(TINTER)), nil);
  1249  	}
  1250  |	LDDD ntype
  1251  	{
  1252  		$$ = Nod(ODDD, $2, nil);
  1253  	}
  1254  
  1255  ntype:
  1256  	recvchantype
  1257  |	fntype
  1258  |	othertype
  1259  |	ptrtype
  1260  |	dotname
  1261  |	'(' ntype ')'
  1262  	{
  1263  		$$ = $2;
  1264  	}
  1265  
  1266  non_expr_type:
  1267  	recvchantype
  1268  |	fntype
  1269  |	othertype
  1270  |	'*' non_expr_type
  1271  	{
  1272  		$$ = Nod(OIND, $2, nil);
  1273  	}
  1274  
  1275  non_recvchantype:
  1276  	fntype
  1277  |	othertype
  1278  |	ptrtype
  1279  |	dotname
  1280  |	'(' ntype ')'
  1281  	{
  1282  		$$ = $2;
  1283  	}
  1284  
  1285  convtype:
  1286  	fntype
  1287  |	othertype
  1288  
  1289  comptype:
  1290  	othertype
  1291  
  1292  fnret_type:
  1293  	recvchantype
  1294  |	fntype
  1295  |	othertype
  1296  |	ptrtype
  1297  |	dotname
  1298  
  1299  dotname:
  1300  	name
  1301  |	name '.' sym
  1302  	{
  1303  		if $1.Op == OPACK {
  1304  			var s *Sym
  1305  			s = restrictlookup($3.Name, $1.Name.Pkg);
  1306  			$1.Used = true;
  1307  			$$ = oldname(s);
  1308  			break;
  1309  		}
  1310  		$$ = Nod(OXDOT, $1, newname($3));
  1311  	}
  1312  
  1313  othertype:
  1314  	'[' oexpr ']' ntype
  1315  	{
  1316  		$$ = Nod(OTARRAY, $2, $4);
  1317  	}
  1318  |	'[' LDDD ']' ntype
  1319  	{
  1320  		// array literal of nelem
  1321  		$$ = Nod(OTARRAY, Nod(ODDD, nil, nil), $4);
  1322  	}
  1323  |	LCHAN non_recvchantype
  1324  	{
  1325  		$$ = Nod(OTCHAN, $2, nil);
  1326  		$$.Etype = Cboth;
  1327  	}
  1328  |	LCHAN LCOMM ntype
  1329  	{
  1330  		$$ = Nod(OTCHAN, $3, nil);
  1331  		$$.Etype = Csend;
  1332  	}
  1333  |	LMAP '[' ntype ']' ntype
  1334  	{
  1335  		$$ = Nod(OTMAP, $3, $5);
  1336  	}
  1337  |	structtype
  1338  |	interfacetype
  1339  
  1340  ptrtype:
  1341  	'*' ntype
  1342  	{
  1343  		$$ = Nod(OIND, $2, nil);
  1344  	}
  1345  
  1346  recvchantype:
  1347  	LCOMM LCHAN ntype
  1348  	{
  1349  		$$ = Nod(OTCHAN, $3, nil);
  1350  		$$.Etype = Crecv;
  1351  	}
  1352  
  1353  structtype:
  1354  	LSTRUCT lbrace structdcl_list osemi '}'
  1355  	{
  1356  		$$ = Nod(OTSTRUCT, nil, nil);
  1357  		$$.List = $3;
  1358  		fixlbrace($2);
  1359  	}
  1360  |	LSTRUCT lbrace '}'
  1361  	{
  1362  		$$ = Nod(OTSTRUCT, nil, nil);
  1363  		fixlbrace($2);
  1364  	}
  1365  
  1366  interfacetype:
  1367  	LINTERFACE lbrace interfacedcl_list osemi '}'
  1368  	{
  1369  		$$ = Nod(OTINTER, nil, nil);
  1370  		$$.List = $3;
  1371  		fixlbrace($2);
  1372  	}
  1373  |	LINTERFACE lbrace '}'
  1374  	{
  1375  		$$ = Nod(OTINTER, nil, nil);
  1376  		fixlbrace($2);
  1377  	}
  1378  
  1379  /*
  1380   * function stuff
  1381   * all in one place to show how crappy it all is
  1382   */
  1383  xfndcl:
  1384  	LFUNC fndcl fnbody
  1385  	{
  1386  		$$ = $2;
  1387  		if $$ == nil {
  1388  			break;
  1389  		}
  1390  		if noescape && $3 != nil {
  1391  			Yyerror("can only use //go:noescape with external func implementations");
  1392  		}
  1393  		$$.Nbody = $3;
  1394  		$$.Func.Endlineno = lineno;
  1395  		$$.Noescape = noescape;
  1396  		$$.Func.Norace = norace;
  1397  		$$.Func.Nosplit = nosplit;
  1398  		$$.Func.Noinline = noinline;
  1399  		$$.Func.Nowritebarrier = nowritebarrier;
  1400  		$$.Func.Systemstack = systemstack;
  1401  		funcbody($$);
  1402  	}
  1403  
  1404  fndcl:
  1405  	sym '(' oarg_type_list_ocomma ')' fnres
  1406  	{
  1407  		var t *Node
  1408  
  1409  		$$ = nil;
  1410  		$3 = checkarglist($3, 1);
  1411  
  1412  		if $1.Name == "init" {
  1413  			$1 = renameinit();
  1414  			if $3 != nil || $5 != nil {
  1415  				Yyerror("func init must have no arguments and no return values");
  1416  			}
  1417  		}
  1418  		if localpkg.Name == "main" && $1.Name == "main" {
  1419  			if $3 != nil || $5 != nil {
  1420  				Yyerror("func main must have no arguments and no return values");
  1421  			}
  1422  		}
  1423  
  1424  		t = Nod(OTFUNC, nil, nil);
  1425  		t.List = $3;
  1426  		t.Rlist = $5;
  1427  
  1428  		$$ = Nod(ODCLFUNC, nil, nil);
  1429  		$$.Func.Nname = newfuncname($1);
  1430  		$$.Func.Nname.Name.Defn = $$;
  1431  		$$.Func.Nname.Name.Param.Ntype = t;		// TODO: check if nname already has an ntype
  1432  		declare($$.Func.Nname, PFUNC);
  1433  
  1434  		funchdr($$);
  1435  	}
  1436  |	'(' oarg_type_list_ocomma ')' sym '(' oarg_type_list_ocomma ')' fnres
  1437  	{
  1438  		var rcvr, t *Node
  1439  
  1440  		$$ = nil;
  1441  		$2 = checkarglist($2, 0);
  1442  		$6 = checkarglist($6, 1);
  1443  
  1444  		if $2 == nil {
  1445  			Yyerror("method has no receiver");
  1446  			break;
  1447  		}
  1448  		if $2.Next != nil {
  1449  			Yyerror("method has multiple receivers");
  1450  			break;
  1451  		}
  1452  		rcvr = $2.N;
  1453  		if rcvr.Op != ODCLFIELD {
  1454  			Yyerror("bad receiver in method");
  1455  			break;
  1456  		}
  1457  
  1458  		t = Nod(OTFUNC, rcvr, nil);
  1459  		t.List = $6;
  1460  		t.Rlist = $8;
  1461  
  1462  		$$ = Nod(ODCLFUNC, nil, nil);
  1463  		$$.Func.Shortname = newfuncname($4);
  1464  		$$.Func.Nname = methodname1($$.Func.Shortname, rcvr.Right);
  1465  		$$.Func.Nname.Name.Defn = $$;
  1466  		$$.Func.Nname.Name.Param.Ntype = t;
  1467  		$$.Func.Nname.Nointerface = nointerface;
  1468  		declare($$.Func.Nname, PFUNC);
  1469  
  1470  		funchdr($$);
  1471  	}
  1472  
  1473  hidden_fndcl:
  1474  	hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres
  1475  	{
  1476  		var s *Sym
  1477  		var t *Type
  1478  
  1479  		$$ = nil;
  1480  
  1481  		s = $1;
  1482  		t = functype(nil, $3, $5);
  1483  
  1484  		importsym(s, ONAME);
  1485  		if s.Def != nil && s.Def.Op == ONAME {
  1486  			if Eqtype(t, s.Def.Type) {
  1487  				dclcontext = PDISCARD;  // since we skip funchdr below
  1488  				break;
  1489  			}
  1490  			Yyerror("inconsistent definition for func %v during import\n\t%v\n\t%v", s, s.Def.Type, t);
  1491  		}
  1492  
  1493  		$$ = newfuncname(s);
  1494  		$$.Type = t;
  1495  		declare($$, PFUNC);
  1496  
  1497  		funchdr($$);
  1498  	}
  1499  |	'(' hidden_funarg_list ')' sym '(' ohidden_funarg_list ')' ohidden_funres
  1500  	{
  1501  		$$ = methodname1(newname($4), $2.N.Right); 
  1502  		$$.Type = functype($2.N, $6, $8);
  1503  
  1504  		checkwidth($$.Type);
  1505  		addmethod($4, $$.Type, false, nointerface);
  1506  		nointerface = false
  1507  		funchdr($$);
  1508  		
  1509  		// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
  1510  		// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
  1511  		// out by typecheck's lookdot as this $$.ttype.  So by providing
  1512  		// this back link here we avoid special casing there.
  1513  		$$.Type.Nname = $$;
  1514  	}
  1515  
  1516  fntype:
  1517  	LFUNC '(' oarg_type_list_ocomma ')' fnres
  1518  	{
  1519  		$3 = checkarglist($3, 1);
  1520  		$$ = Nod(OTFUNC, nil, nil);
  1521  		$$.List = $3;
  1522  		$$.Rlist = $5;
  1523  	}
  1524  
  1525  fnbody:
  1526  	{
  1527  		$$ = nil;
  1528  	}
  1529  |	'{' stmt_list '}'
  1530  	{
  1531  		$$ = $2;
  1532  		if $$ == nil {
  1533  			$$ = list1(Nod(OEMPTY, nil, nil));
  1534  		}
  1535  	}
  1536  
  1537  fnres:
  1538  	%prec NotParen
  1539  	{
  1540  		$$ = nil;
  1541  	}
  1542  |	fnret_type
  1543  	{
  1544  		$$ = list1(Nod(ODCLFIELD, nil, $1));
  1545  	}
  1546  |	'(' oarg_type_list_ocomma ')'
  1547  	{
  1548  		$2 = checkarglist($2, 0);
  1549  		$$ = $2;
  1550  	}
  1551  
  1552  fnlitdcl:
  1553  	fntype
  1554  	{
  1555  		closurehdr($1);
  1556  	}
  1557  
  1558  fnliteral:
  1559  	fnlitdcl lbrace stmt_list '}'
  1560  	{
  1561  		$$ = closurebody($3);
  1562  		fixlbrace($2);
  1563  	}
  1564  |	fnlitdcl error
  1565  	{
  1566  		$$ = closurebody(nil);
  1567  	}
  1568  
  1569  /*
  1570   * lists of things
  1571   * note that they are left recursive
  1572   * to conserve yacc stack. they need to
  1573   * be reversed to interpret correctly
  1574   */
  1575  xdcl_list:
  1576  	{
  1577  		$$ = nil;
  1578  	}
  1579  |	xdcl_list xdcl ';'
  1580  	{
  1581  		$$ = concat($1, $2);
  1582  		if nsyntaxerrors == 0 {
  1583  			testdclstack();
  1584  		}
  1585  		noescape = false
  1586  		noinline = false
  1587  		nointerface = false
  1588  		norace = false
  1589  		nosplit = false
  1590  		nowritebarrier = false
  1591  		systemstack = false
  1592  	}
  1593  
  1594  vardcl_list:
  1595  	vardcl
  1596  |	vardcl_list ';' vardcl
  1597  	{
  1598  		$$ = concat($1, $3);
  1599  	}
  1600  
  1601  constdcl_list:
  1602  	constdcl1
  1603  |	constdcl_list ';' constdcl1
  1604  	{
  1605  		$$ = concat($1, $3);
  1606  	}
  1607  
  1608  typedcl_list:
  1609  	typedcl
  1610  	{
  1611  		$$ = list1($1);
  1612  	}
  1613  |	typedcl_list ';' typedcl
  1614  	{
  1615  		$$ = list($1, $3);
  1616  	}
  1617  
  1618  structdcl_list:
  1619  	structdcl
  1620  |	structdcl_list ';' structdcl
  1621  	{
  1622  		$$ = concat($1, $3);
  1623  	}
  1624  
  1625  interfacedcl_list:
  1626  	interfacedcl
  1627  	{
  1628  		$$ = list1($1);
  1629  	}
  1630  |	interfacedcl_list ';' interfacedcl
  1631  	{
  1632  		$$ = list($1, $3);
  1633  	}
  1634  
  1635  structdcl:
  1636  	new_name_list ntype oliteral
  1637  	{
  1638  		var l *NodeList
  1639  
  1640  		var n *Node
  1641  		l = $1;
  1642  		if l == nil || l.N.Sym.Name == "?" {
  1643  			// ? symbol, during import (list1(nil) == nil)
  1644  			n = $2;
  1645  			if n.Op == OIND {
  1646  				n = n.Left;
  1647  			}
  1648  			n = embedded(n.Sym, importpkg);
  1649  			n.Right = $2;
  1650  			n.SetVal($3)
  1651  			$$ = list1(n);
  1652  			break;
  1653  		}
  1654  
  1655  		for l=$1; l != nil; l=l.Next {
  1656  			l.N = Nod(ODCLFIELD, l.N, $2);
  1657  			l.N.SetVal($3)
  1658  		}
  1659  	}
  1660  |	embed oliteral
  1661  	{
  1662  		$1.SetVal($2)
  1663  		$$ = list1($1);
  1664  	}
  1665  |	'(' embed ')' oliteral
  1666  	{
  1667  		$2.SetVal($4)
  1668  		$$ = list1($2);
  1669  		Yyerror("cannot parenthesize embedded type");
  1670  	}
  1671  |	'*' embed oliteral
  1672  	{
  1673  		$2.Right = Nod(OIND, $2.Right, nil);
  1674  		$2.SetVal($3)
  1675  		$$ = list1($2);
  1676  	}
  1677  |	'(' '*' embed ')' oliteral
  1678  	{
  1679  		$3.Right = Nod(OIND, $3.Right, nil);
  1680  		$3.SetVal($5)
  1681  		$$ = list1($3);
  1682  		Yyerror("cannot parenthesize embedded type");
  1683  	}
  1684  |	'*' '(' embed ')' oliteral
  1685  	{
  1686  		$3.Right = Nod(OIND, $3.Right, nil);
  1687  		$3.SetVal($5)
  1688  		$$ = list1($3);
  1689  		Yyerror("cannot parenthesize embedded type");
  1690  	}
  1691  
  1692  packname:
  1693  	LNAME
  1694  	{
  1695  		var n *Node
  1696  
  1697  		$$ = $1;
  1698  		n = oldname($1);
  1699  		if n.Name != nil && n.Name.Pack != nil {
  1700  			n.Name.Pack.Used = true;
  1701  		}
  1702  	}
  1703  |	LNAME '.' sym
  1704  	{
  1705  		var pkg *Pkg
  1706  
  1707  		if $1.Def == nil || $1.Def.Op != OPACK {
  1708  			Yyerror("%v is not a package", $1);
  1709  			pkg = localpkg;
  1710  		} else {
  1711  			$1.Def.Used = true;
  1712  			pkg = $1.Def.Name.Pkg;
  1713  		}
  1714  		$$ = restrictlookup($3.Name, pkg);
  1715  	}
  1716  
  1717  embed:
  1718  	packname
  1719  	{
  1720  		$$ = embedded($1, localpkg);
  1721  	}
  1722  
  1723  interfacedcl:
  1724  	new_name indcl
  1725  	{
  1726  		$$ = Nod(ODCLFIELD, $1, $2);
  1727  		ifacedcl($$);
  1728  	}
  1729  |	packname
  1730  	{
  1731  		$$ = Nod(ODCLFIELD, nil, oldname($1));
  1732  	}
  1733  |	'(' packname ')'
  1734  	{
  1735  		$$ = Nod(ODCLFIELD, nil, oldname($2));
  1736  		Yyerror("cannot parenthesize embedded type");
  1737  	}
  1738  
  1739  indcl:
  1740  	'(' oarg_type_list_ocomma ')' fnres
  1741  	{
  1742  		// without func keyword
  1743  		$2 = checkarglist($2, 1);
  1744  		$$ = Nod(OTFUNC, fakethis(), nil);
  1745  		$$.List = $2;
  1746  		$$.Rlist = $4;
  1747  	}
  1748  
  1749  /*
  1750   * function arguments.
  1751   */
  1752  arg_type:
  1753  	name_or_type
  1754  |	sym name_or_type
  1755  	{
  1756  		$$ = Nod(ONONAME, nil, nil);
  1757  		$$.Sym = $1;
  1758  		$$ = Nod(OKEY, $$, $2);
  1759  	}
  1760  |	sym dotdotdot
  1761  	{
  1762  		$$ = Nod(ONONAME, nil, nil);
  1763  		$$.Sym = $1;
  1764  		$$ = Nod(OKEY, $$, $2);
  1765  	}
  1766  |	dotdotdot
  1767  
  1768  arg_type_list:
  1769  	arg_type
  1770  	{
  1771  		$$ = list1($1);
  1772  	}
  1773  |	arg_type_list ',' arg_type
  1774  	{
  1775  		$$ = list($1, $3);
  1776  	}
  1777  
  1778  oarg_type_list_ocomma:
  1779  	{
  1780  		$$ = nil;
  1781  	}
  1782  |	arg_type_list ocomma
  1783  	{
  1784  		$$ = $1;
  1785  	}
  1786  
  1787  /*
  1788   * statement
  1789   */
  1790  stmt:
  1791  	{
  1792  		$$ = nil;
  1793  	}
  1794  |	compound_stmt
  1795  |	common_dcl
  1796  	{
  1797  		$$ = liststmt($1);
  1798  	}
  1799  |	non_dcl_stmt
  1800  |	error
  1801  	{
  1802  		$$ = nil;
  1803  	}
  1804  
  1805  non_dcl_stmt:
  1806  	simple_stmt
  1807  |	for_stmt
  1808  |	switch_stmt
  1809  |	select_stmt
  1810  |	if_stmt
  1811  |	labelname ':'
  1812  	{
  1813  		$1 = Nod(OLABEL, $1, nil);
  1814  		$1.Sym = dclstack;  // context, for goto restrictions
  1815  	}
  1816  	stmt
  1817  	{
  1818  		var l *NodeList
  1819  
  1820  		$1.Name.Defn = $4;
  1821  		l = list1($1);
  1822  		if $4 != nil {
  1823  			l = list(l, $4);
  1824  		}
  1825  		$$ = liststmt(l);
  1826  	}
  1827  |	LFALL
  1828  	{
  1829  		// will be converted to OFALL
  1830  		$$ = Nod(OXFALL, nil, nil);
  1831  		$$.Xoffset = int64(block);
  1832  	}
  1833  |	LBREAK onew_name
  1834  	{
  1835  		$$ = Nod(OBREAK, $2, nil);
  1836  	}
  1837  |	LCONTINUE onew_name
  1838  	{
  1839  		$$ = Nod(OCONTINUE, $2, nil);
  1840  	}
  1841  |	LGO pseudocall
  1842  	{
  1843  		$$ = Nod(OPROC, $2, nil);
  1844  	}
  1845  |	LDEFER pseudocall
  1846  	{
  1847  		$$ = Nod(ODEFER, $2, nil);
  1848  	}
  1849  |	LGOTO new_name
  1850  	{
  1851  		$$ = Nod(OGOTO, $2, nil);
  1852  		$$.Sym = dclstack;  // context, for goto restrictions
  1853  	}
  1854  |	LRETURN oexpr_list
  1855  	{
  1856  		$$ = Nod(ORETURN, nil, nil);
  1857  		$$.List = $2;
  1858  		if $$.List == nil && Curfn != nil {
  1859  			var l *NodeList
  1860  
  1861  			for l=Curfn.Func.Dcl; l != nil; l=l.Next {
  1862  				if l.N.Class == PPARAM {
  1863  					continue;
  1864  				}
  1865  				if l.N.Class != PPARAMOUT {
  1866  					break;
  1867  				}
  1868  				if l.N.Sym.Def != l.N {
  1869  					Yyerror("%s is shadowed during return", l.N.Sym.Name);
  1870  				}
  1871  			}
  1872  		}
  1873  	}
  1874  
  1875  stmt_list:
  1876  	stmt
  1877  	{
  1878  		$$ = nil;
  1879  		if $1 != nil {
  1880  			$$ = list1($1);
  1881  		}
  1882  	}
  1883  |	stmt_list ';' stmt
  1884  	{
  1885  		$$ = $1;
  1886  		if $3 != nil {
  1887  			$$ = list($$, $3);
  1888  		}
  1889  	}
  1890  
  1891  new_name_list:
  1892  	new_name
  1893  	{
  1894  		$$ = list1($1);
  1895  	}
  1896  |	new_name_list ',' new_name
  1897  	{
  1898  		$$ = list($1, $3);
  1899  	}
  1900  
  1901  dcl_name_list:
  1902  	dcl_name
  1903  	{
  1904  		$$ = list1($1);
  1905  	}
  1906  |	dcl_name_list ',' dcl_name
  1907  	{
  1908  		$$ = list($1, $3);
  1909  	}
  1910  
  1911  expr_list:
  1912  	expr
  1913  	{
  1914  		$$ = list1($1);
  1915  	}
  1916  |	expr_list ',' expr
  1917  	{
  1918  		$$ = list($1, $3);
  1919  	}
  1920  
  1921  expr_or_type_list:
  1922  	expr_or_type
  1923  	{
  1924  		$$ = list1($1);
  1925  	}
  1926  |	expr_or_type_list ',' expr_or_type
  1927  	{
  1928  		$$ = list($1, $3);
  1929  	}
  1930  
  1931  /*
  1932   * list of combo of keyval and val
  1933   */
  1934  keyval_list:
  1935  	keyval
  1936  	{
  1937  		$$ = list1($1);
  1938  	}
  1939  |	bare_complitexpr
  1940  	{
  1941  		$$ = list1($1);
  1942  	}
  1943  |	keyval_list ',' keyval
  1944  	{
  1945  		$$ = list($1, $3);
  1946  	}
  1947  |	keyval_list ',' bare_complitexpr
  1948  	{
  1949  		$$ = list($1, $3);
  1950  	}
  1951  
  1952  braced_keyval_list:
  1953  	{
  1954  		$$ = nil;
  1955  	}
  1956  |	keyval_list ocomma
  1957  	{
  1958  		$$ = $1;
  1959  	}
  1960  
  1961  /*
  1962   * optional things
  1963   */
  1964  osemi:
  1965  |	';'
  1966  
  1967  ocomma:
  1968  |	','
  1969  
  1970  oexpr:
  1971  	{
  1972  		$$ = nil;
  1973  	}
  1974  |	expr
  1975  
  1976  oexpr_list:
  1977  	{
  1978  		$$ = nil;
  1979  	}
  1980  |	expr_list
  1981  
  1982  osimple_stmt:
  1983  	{
  1984  		$$ = nil;
  1985  	}
  1986  |	simple_stmt
  1987  
  1988  ohidden_funarg_list:
  1989  	{
  1990  		$$ = nil;
  1991  	}
  1992  |	hidden_funarg_list
  1993  
  1994  ohidden_structdcl_list:
  1995  	{
  1996  		$$ = nil;
  1997  	}
  1998  |	hidden_structdcl_list
  1999  
  2000  ohidden_interfacedcl_list:
  2001  	{
  2002  		$$ = nil;
  2003  	}
  2004  |	hidden_interfacedcl_list
  2005  
  2006  oliteral:
  2007  	{
  2008  		$$.U = nil
  2009  	}
  2010  |	LLITERAL
  2011  
  2012  /*
  2013   * import syntax from package header
  2014   */
  2015  hidden_import:
  2016  	LIMPORT LNAME LLITERAL ';'
  2017  	{
  2018  		importimport($2, $3.U.(string));
  2019  	}
  2020  |	LVAR hidden_pkg_importsym hidden_type ';'
  2021  	{
  2022  		importvar($2, $3);
  2023  	}
  2024  |	LCONST hidden_pkg_importsym '=' hidden_constant ';'
  2025  	{
  2026  		importconst($2, Types[TIDEAL], $4);
  2027  	}
  2028  |	LCONST hidden_pkg_importsym hidden_type '=' hidden_constant ';'
  2029  	{
  2030  		importconst($2, $3, $5);
  2031  	}
  2032  |	LTYPE hidden_pkgtype hidden_type ';'
  2033  	{
  2034  		importtype($2, $3);
  2035  	}
  2036  |	LFUNC hidden_fndcl fnbody ';'
  2037  	{
  2038  		if $2 == nil {
  2039  			dclcontext = PEXTERN;  // since we skip the funcbody below
  2040  			break;
  2041  		}
  2042  
  2043  		$2.Func.Inl = $3;
  2044  
  2045  		funcbody($2);
  2046  		importlist = append(importlist, $2);
  2047  
  2048  		if Debug['E'] > 0 {
  2049  			fmt.Printf("import [%q] func %v \n", importpkg.Path, $2)
  2050  			if Debug['m'] > 2 && $2.Func.Inl != nil {
  2051  				fmt.Printf("inl body:%v\n", $2.Func.Inl)
  2052  			}
  2053  		}
  2054  	}
  2055  
  2056  hidden_pkg_importsym:
  2057  	hidden_importsym
  2058  	{
  2059  		$$ = $1;
  2060  		structpkg = $$.Pkg;
  2061  	}
  2062  
  2063  hidden_pkgtype:
  2064  	hidden_pkg_importsym
  2065  	{
  2066  		$$ = pkgtype($1);
  2067  		importsym($1, OTYPE);
  2068  	}
  2069  
  2070  /*
  2071   *  importing types
  2072   */
  2073  
  2074  hidden_type:
  2075  	hidden_type_misc
  2076  |	hidden_type_recv_chan
  2077  |	hidden_type_func
  2078  
  2079  hidden_type_non_recv_chan:
  2080  	hidden_type_misc
  2081  |	hidden_type_func
  2082  
  2083  hidden_type_misc:
  2084  	hidden_importsym
  2085  	{
  2086  		$$ = pkgtype($1);
  2087  	}
  2088  |	LNAME
  2089  	{
  2090  		// predefined name like uint8
  2091  		$1 = Pkglookup($1.Name, builtinpkg);
  2092  		if $1.Def == nil || $1.Def.Op != OTYPE {
  2093  			Yyerror("%s is not a type", $1.Name);
  2094  			$$ = nil;
  2095  		} else {
  2096  			$$ = $1.Def.Type;
  2097  		}
  2098  	}
  2099  |	'[' ']' hidden_type
  2100  	{
  2101  		$$ = aindex(nil, $3);
  2102  	}
  2103  |	'[' LLITERAL ']' hidden_type
  2104  	{
  2105  		$$ = aindex(nodlit($2), $4);
  2106  	}
  2107  |	LMAP '[' hidden_type ']' hidden_type
  2108  	{
  2109  		$$ = maptype($3, $5);
  2110  	}
  2111  |	LSTRUCT '{' ohidden_structdcl_list '}'
  2112  	{
  2113  		$$ = tostruct($3);
  2114  	}
  2115  |	LINTERFACE '{' ohidden_interfacedcl_list '}'
  2116  	{
  2117  		$$ = tointerface($3);
  2118  	}
  2119  |	'*' hidden_type
  2120  	{
  2121  		$$ = Ptrto($2);
  2122  	}
  2123  |	LCHAN hidden_type_non_recv_chan
  2124  	{
  2125  		$$ = typ(TCHAN);
  2126  		$$.Type = $2;
  2127  		$$.Chan = Cboth;
  2128  	}
  2129  |	LCHAN '(' hidden_type_recv_chan ')'
  2130  	{
  2131  		$$ = typ(TCHAN);
  2132  		$$.Type = $3;
  2133  		$$.Chan = Cboth;
  2134  	}
  2135  |	LCHAN LCOMM hidden_type
  2136  	{
  2137  		$$ = typ(TCHAN);
  2138  		$$.Type = $3;
  2139  		$$.Chan = Csend;
  2140  	}
  2141  
  2142  hidden_type_recv_chan:
  2143  	LCOMM LCHAN hidden_type
  2144  	{
  2145  		$$ = typ(TCHAN);
  2146  		$$.Type = $3;
  2147  		$$.Chan = Crecv;
  2148  	}
  2149  
  2150  hidden_type_func:
  2151  	LFUNC '(' ohidden_funarg_list ')' ohidden_funres
  2152  	{
  2153  		$$ = functype(nil, $3, $5);
  2154  	}
  2155  
  2156  hidden_funarg:
  2157  	sym hidden_type oliteral
  2158  	{
  2159  		$$ = Nod(ODCLFIELD, nil, typenod($2));
  2160  		if $1 != nil {
  2161  			$$.Left = newname($1);
  2162  		}
  2163  		$$.SetVal($3)
  2164  	}
  2165  |	sym LDDD hidden_type oliteral
  2166  	{
  2167  		var t *Type
  2168  	
  2169  		t = typ(TARRAY);
  2170  		t.Bound = -1;
  2171  		t.Type = $3;
  2172  
  2173  		$$ = Nod(ODCLFIELD, nil, typenod(t));
  2174  		if $1 != nil {
  2175  			$$.Left = newname($1);
  2176  		}
  2177  		$$.Isddd = true;
  2178  		$$.SetVal($4)
  2179  	}
  2180  
  2181  hidden_structdcl:
  2182  	sym hidden_type oliteral
  2183  	{
  2184  		var s *Sym
  2185  		var p *Pkg
  2186  
  2187  		if $1 != nil && $1.Name != "?" {
  2188  			$$ = Nod(ODCLFIELD, newname($1), typenod($2));
  2189  			$$.SetVal($3)
  2190  		} else {
  2191  			s = $2.Sym;
  2192  			if s == nil && Isptr[$2.Etype] {
  2193  				s = $2.Type.Sym;
  2194  			}
  2195  			p = importpkg;
  2196  			if $1 != nil {
  2197  				p = $1.Pkg;
  2198  			}
  2199  			$$ = embedded(s, p);
  2200  			$$.Right = typenod($2);
  2201  			$$.SetVal($3)
  2202  		}
  2203  	}
  2204  
  2205  hidden_interfacedcl:
  2206  	sym '(' ohidden_funarg_list ')' ohidden_funres
  2207  	{
  2208  		$$ = Nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
  2209  	}
  2210  |	hidden_type
  2211  	{
  2212  		$$ = Nod(ODCLFIELD, nil, typenod($1));
  2213  	}
  2214  
  2215  ohidden_funres:
  2216  	{
  2217  		$$ = nil;
  2218  	}
  2219  |	hidden_funres
  2220  
  2221  hidden_funres:
  2222  	'(' ohidden_funarg_list ')'
  2223  	{
  2224  		$$ = $2;
  2225  	}
  2226  |	hidden_type
  2227  	{
  2228  		$$ = list1(Nod(ODCLFIELD, nil, typenod($1)));
  2229  	}
  2230  
  2231  /*
  2232   *  importing constants
  2233   */
  2234  
  2235  hidden_literal:
  2236  	LLITERAL
  2237  	{
  2238  		$$ = nodlit($1);
  2239  	}
  2240  |	'-' LLITERAL
  2241  	{
  2242  		$$ = nodlit($2);
  2243  		switch($$.Val().Ctype()){
  2244  		case CTINT, CTRUNE:
  2245  			mpnegfix($$.Val().U.(*Mpint));
  2246  			break;
  2247  		case CTFLT:
  2248  			mpnegflt($$.Val().U.(*Mpflt));
  2249  			break;
  2250  		case CTCPLX:
  2251  			mpnegflt(&$$.Val().U.(*Mpcplx).Real);
  2252  			mpnegflt(&$$.Val().U.(*Mpcplx).Imag);
  2253  			break;
  2254  		default:
  2255  			Yyerror("bad negated constant");
  2256  		}
  2257  	}
  2258  |	sym
  2259  	{
  2260  		$$ = oldname(Pkglookup($1.Name, builtinpkg));
  2261  		if $$.Op != OLITERAL {
  2262  			Yyerror("bad constant %v", $$.Sym);
  2263  		}
  2264  	}
  2265  
  2266  hidden_constant:
  2267  	hidden_literal
  2268  |	'(' hidden_literal '+' hidden_literal ')'
  2269  	{
  2270  		if $2.Val().Ctype() == CTRUNE && $4.Val().Ctype() == CTINT {
  2271  			$$ = $2;
  2272  			mpaddfixfix($2.Val().U.(*Mpint), $4.Val().U.(*Mpint), 0);
  2273  			break;
  2274  		}
  2275  		$4.Val().U.(*Mpcplx).Real = $4.Val().U.(*Mpcplx).Imag;
  2276  		Mpmovecflt(&$4.Val().U.(*Mpcplx).Imag, 0.0);
  2277  		$$ = nodcplxlit($2.Val(), $4.Val());
  2278  	}
  2279  
  2280  hidden_import_list:
  2281  |	hidden_import_list hidden_import
  2282  
  2283  hidden_funarg_list:
  2284  	hidden_funarg
  2285  	{
  2286  		$$ = list1($1);
  2287  	}
  2288  |	hidden_funarg_list ',' hidden_funarg
  2289  	{
  2290  		$$ = list($1, $3);
  2291  	}
  2292  
  2293  hidden_structdcl_list:
  2294  	hidden_structdcl
  2295  	{
  2296  		$$ = list1($1);
  2297  	}
  2298  |	hidden_structdcl_list ';' hidden_structdcl
  2299  	{
  2300  		$$ = list($1, $3);
  2301  	}
  2302  
  2303  hidden_interfacedcl_list:
  2304  	hidden_interfacedcl
  2305  	{
  2306  		$$ = list1($1);
  2307  	}
  2308  |	hidden_interfacedcl_list ';' hidden_interfacedcl
  2309  	{
  2310  		$$ = list($1, $3);
  2311  	}
  2312  
  2313  %%
  2314  func fixlbrace(lbr int) {
  2315  	// If the opening brace was an LBODY,
  2316  	// set up for another one now that we're done.
  2317  	// See comment in lex.C about loophack.
  2318  	if lbr == LBODY {
  2319  		loophack = true
  2320  	}
  2321  }