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