go.y 26.6 KB
Newer Older
1 2 3 4
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Russ Cox's avatar
Russ Cox committed
5 6 7 8 9 10 11 12 13 14
/*
 * Go language grammar.
 *
 * The Go semicolon rules are:
 *
 *  1. all statements and declarations are terminated by semicolons
 *  2. semicolons can be omitted at top level.
 *  3. semicolons can be omitted before and after the closing ) or }
 *	on a list of statements or declarations.
 *
15 16 17
 * This is accomplished by calling yyoptsemi() to mark the places
 * where semicolons are optional.  That tells the lexer that if a
 * semicolon isn't the next token, it should insert one for us.
Russ Cox's avatar
Russ Cox committed
18 19
 */

20 21 22 23 24
%{
#include "go.h"
%}
%union	{
	Node*		node;
25
	NodeList*		list;
26 27 28 29 30 31
	Type*		type;
	Sym*		sym;
	struct	Val	val;
	int		lint;
}

Russ Cox's avatar
Russ Cox committed
32 33 34 35 36 37 38 39 40 41 42 43
// |sed 's/.*	//' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx		/'

%token	<val>	LLITERAL
%token	<lint>	LASOP
%token	<sym>	LBREAK LCASE LCHAN LCOLAS LCONST LCONTINUE LDDD
%token	<sym>	LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO
%token	<sym>	LIF LIMPORT LINTERFACE LMAKE LMAP LNAME LNEW
%token	<sym>	LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH
%token	<sym>	LTYPE LVAR

%token		LANDAND LANDNOT LBODY LCOMM LDEC LEQ LGE LGT
%token		LIGNORE LINC LLE LLSH LLT LNE LOROR LRSH
44
%token		LSEMIBRACE
Russ Cox's avatar
Russ Cox committed
45 46 47 48 49

%type	<lint>	lbrace
%type	<sym>	sym packname
%type	<val>	oliteral

Russ Cox's avatar
Russ Cox committed
50
%type	<node>	stmt ntype
51 52 53 54 55
%type	<node>	arg_type
%type	<node>	case caseblock
%type	<node>	compound_stmt dotname embed expr
%type	<node>	expr_or_type
%type	<node>	fndcl fnliteral
Russ Cox's avatar
Russ Cox committed
56
%type	<node>	for_body for_header for_stmt if_header if_stmt
57
%type	<node>	keyval labelname name
Russ Cox's avatar
Russ Cox committed
58
%type	<node>	name_or_type non_expr_type
59
%type	<node>	new_name dcl_name oexpr
60 61
%type	<node>	onew_name
%type	<node>	osimple_stmt pexpr
62
%type	<node>	pseudocall range_stmt select_stmt
63 64
%type	<node>	simple_stmt
%type	<node>	switch_stmt uexpr
65
%type	<node>	xfndcl typedcl
66

67 68
%type	<list>	xdcl fnbody fnres switch_body loop_body dcl_name_list
%type	<list>	new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
69 70
%type	<list>	oexpr_list oexpr_or_type_list caseblock_list stmt_list oarg_type_list arg_type_list
%type	<list>	interfacedcl_list interfacedcl vardcl vardcl_list structdcl structdcl_list
71
%type	<list>	common_dcl constdcl constdcl1 constdcl_list typedcl_list
Russ Cox's avatar
Russ Cox committed
72

Russ Cox's avatar
Russ Cox committed
73
%type	<node>	convtype dotdotdot
Russ Cox's avatar
Russ Cox committed
74
%type	<node>	indcl interfacetype structtype ptrtype
75 76
%type	<type>	new_type typedclname
%type	<node>	chantype non_chan_type othertype non_fn_type fntype fnlitdcl
Russ Cox's avatar
Russ Cox committed
77 78 79

%type	<sym>	hidden_importsym hidden_pkg_importsym

80 81 82 83 84 85 86
%type	<node>	hidden_constant hidden_dcl hidden_interfacedcl hidden_structdcl

%type	<list>	hidden_funres
%type	<list>	ohidden_funres
%type	<list>	hidden_funarg_list ohidden_funarg_list
%type	<list>	hidden_interfacedcl_list ohidden_interfacedcl_list
%type	<list>	hidden_structdcl_list ohidden_structdcl_list
Russ Cox's avatar
Russ Cox committed
87 88 89 90 91 92 93 94 95

%type	<type>	hidden_type hidden_type1 hidden_type2

%left		LOROR
%left		LANDAND
%left		LCOMM
%left		LEQ LNE LLE LGE LLT LGT
%left		'+' '-' '|' '^'
%left		'*' '/' '%' '&' LLSH LRSH LANDNOT
Russ Cox's avatar
Russ Cox committed
96

97
/*
Russ Cox's avatar
Russ Cox committed
98 99 100 101 102
 * manual override of shift/reduce conflicts.
 * the general form is that we assign a precedence
 * to the token being shifted and then introduce
 * NotToken with lower precedence or PreferToToken with higher
 * and annotate the reducing rule accordingly.
103
 */
Russ Cox's avatar
Russ Cox committed
104 105
%left		NotPackage
%left		LPACKAGE
106

Russ Cox's avatar
Russ Cox committed
107 108
%left		NotParen
%left		'('
Russ Cox's avatar
Russ Cox committed
109

Russ Cox's avatar
Russ Cox committed
110 111
%left		')'
%left		PreferToRightParen
Russ Cox's avatar
Russ Cox committed
112

Russ Cox's avatar
Russ Cox committed
113 114 115
%left		'.'

%left		'{'
116

117 118
%%
file:
Russ Cox's avatar
6g:  
Russ Cox committed
119 120 121
	loadsys
	package
	imports
122
	xdcl_list
123 124 125
	{
		if(debug['f'])
			frame(1);
Ken Thompson's avatar
Ken Thompson committed
126
		fninit($4);
Russ Cox's avatar
Russ Cox committed
127 128
		if(nsyntaxerrors == 0)
			testdclstack();
129 130 131
	}

package:
Russ Cox's avatar
Russ Cox committed
132
	%prec NotPackage
133 134 135 136 137 138 139
	{
		yyerror("package statement must be first");
		mkpackage("main");
	}
|	LPACKAGE sym
	{
		mkpackage($2->name);
Russ Cox's avatar
6g:  
Russ Cox committed
140 141 142 143 144 145 146 147 148
	}

/*
 * this loads the definitions for the sys functions,
 * so that the compiler can generate calls to them,
 * but does not make the name "sys" visible as a package.
 */
loadsys:
	{
Ken Thompson's avatar
Ken Thompson committed
149
		cannedimports("sys.6", sysimport);
150
	}
Russ Cox's avatar
6g:  
Russ Cox committed
151 152 153 154 155
	import_package
	import_there
	{
		pkgimportname = S;
	}
156 157 158 159 160 161

imports:
|	imports import

import:
	LIMPORT import_stmt
162
|	LIMPORT '(' import_stmt_list osemi ')'
163
|	LIMPORT '(' ')'
164 165

import_stmt:
Russ Cox's avatar
6g:  
Russ Cox committed
166
	import_here import_package import_there import_done
167

168 169 170 171
import_stmt_list:
	import_stmt
|	import_stmt_list ';' import_stmt

172 173 174 175
import_here:
	LLITERAL
	{
		// import with original name
Russ Cox's avatar
6g:  
Russ Cox committed
176
		pkgimportname = S;
177 178 179 180 181 182
		pkgmyname = S;
		importfile(&$1);
	}
|	sym LLITERAL
	{
		// import with given name
Russ Cox's avatar
6g:  
Russ Cox committed
183
		pkgimportname = S;
184 185 186 187 188
		pkgmyname = $1;
		importfile(&$2);
	}
|	'.' LLITERAL
	{
Russ Cox's avatar
6g:  
Russ Cox committed
189 190
		// import into my name space
		pkgmyname = lookup(".");
191 192 193
		importfile(&$2);
	}

Ken Thompson's avatar
Ken Thompson committed
194 195 196 197
import_package:
	LPACKAGE sym
	{
		pkgimportname = $2;
198 199
		if(strcmp($2->name, "main") == 0)
			yyerror("cannot import package main");
Ken Thompson's avatar
Ken Thompson committed
200 201
	}

202
import_there:
203 204 205
	{
		defercheckwidth();
	}
206
	hidden_import_list '$' '$'
207
	{
208
		resumecheckwidth();
Ken Thompson's avatar
Ken Thompson committed
209
		checkimports();
210 211
		unimportfile();
	}
212
|	LIMPORT '$' '$'
Ken Thompson's avatar
Ken Thompson committed
213
	{
214 215 216 217 218
		defercheckwidth();
	}
	hidden_import_list '$' '$'
	{
		resumecheckwidth();
Ken Thompson's avatar
Ken Thompson committed
219 220
		checkimports();
	}
221

Russ Cox's avatar
6g:  
Russ Cox committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
import_done:
	{
		Sym *import, *my;

		import = pkgimportname;
		my = pkgmyname;
		pkgmyname = S;
		pkgimportname = S;

		if(import == S)
			break;
		if(my == S)
			my = import;
		if(my->name[0] == '.') {
			importdot(import);
			break;
		}

		// In order to allow multifile packages to use type names
		// that are the same as the package name (i.e. go/parser
		// is package parser and has a type called parser), we have
		// to not bother trying to declare the package if it is our package.
		// TODO(rsc): Is there a better way to tell if the package is ours?
		if(my == import && strcmp(import->name, package) == 0)
			break;

Russ Cox's avatar
Russ Cox committed
248
		if(my->def != N) {
Russ Cox's avatar
6g:  
Russ Cox committed
249 250 251 252 253
			// TODO(rsc): this line is only needed because of the
			//	package net
			//	import "net"
			// convention; if we get rid of it, the check can go away
			// and we can just always print the error
Russ Cox's avatar
Russ Cox committed
254
			if(my->def->op != OPACK || strcmp(my->name, import->name) != 0)
Russ Cox's avatar
6g:  
Russ Cox committed
255 256
				yyerror("redeclaration of %S by import", my);
		}
Russ Cox's avatar
Russ Cox committed
257 258
		my->def = nod(OPACK, N, N);
		my->def->sym = import;
259
		import->block = -1;	// above top level
Russ Cox's avatar
6g:  
Russ Cox committed
260 261
	}

262 263 264 265
/*
 * declarations
 */
xdcl:
266 267 268 269 270
	{ stksize = initstksize; } common_dcl
	{
		$$ = $2;
		initstksize = stksize;
	}
Ken Thompson's avatar
Ken Thompson committed
271
|	xfndcl
272
	{
Russ Cox's avatar
Russ Cox committed
273 274
		if($1 != N && $1->nname != N && $1->type->thistuple == 0)
			autoexport($1->nname->sym);
275
		$$ = nil;
276
	}
277 278
|	';'
	{
279
		$$ = nil;
280
	}
Ken Thompson's avatar
Ken Thompson committed
281
|	error xdcl
282
	{
Ken Thompson's avatar
Ken Thompson committed
283
		$$ = $2;
284
	}
285 286

common_dcl:
287
	LVAR vardcl
288 289
	{
		$$ = $2;
290 291
		if(yylast == LSEMIBRACE)
			yyoptsemi(0);
292
	//	walkdeflist($2);
293
	}
294
|	LVAR '(' vardcl_list osemi ')'
295
	{
296
		$$ = $3;
297
		yyoptsemi(0);
298
	//	walkdeflist($3);
299
	}
300 301
|	LVAR '(' ')'
	{
302
		$$ = nil;
303 304 305 306
		yyoptsemi(0);
	}
|	LCONST constdcl
	{
307
		$$ = nil;
308
		iota = 0;
309
		lastconst = nil;
310
		walkdeflist($2);
311
	}
Ken Thompson's avatar
Ken Thompson committed
312 313
|	LCONST '(' constdcl osemi ')'
	{
314
		$$ = nil;
Ken Thompson's avatar
Ken Thompson committed
315
		iota = 0;
316
		lastconst = nil;
317
		yyoptsemi(0);
318
		walkdeflist($3);
Ken Thompson's avatar
Ken Thompson committed
319
	}
320
|	LCONST '(' constdcl ';' constdcl_list osemi ')'
321
	{
322
		$$ = nil;
323
		iota = 0;
324
		lastconst = nil;
325
		yyoptsemi(0);
326
		walkdeflist(concat($3, $5));
327
	}
328 329
|	LCONST '(' ')'
	{
330
		$$ = nil;
331
		yyoptsemi(0);
332
	}
333
|	LTYPE typedcl
334
	{
335
		$$ = nil;
336
	//	$$ = list1($2);
337 338
		if(yylast == LSEMIBRACE)
			yyoptsemi(0);
339
	}
340
|	LTYPE '(' typedcl_list osemi ')'
341
	{
342
		$$ = nil;
343
	//	$$ = $3;
344
		yyoptsemi(0);
345
	}
346 347
|	LTYPE '(' ')'
	{
348
		$$ = nil;
349
		yyoptsemi(0);
350
	}
351

352
varoptsemi:
353
	{
Russ Cox's avatar
Russ Cox committed
354 355
		if(yylast == LSEMIBRACE)
			yyoptsemi('=');
356 357 358
	}

vardcl:
Russ Cox's avatar
Russ Cox committed
359
	dcl_name_list ntype varoptsemi
360
	{
361
		$$ = variter($1, $2, nil);
362
	}
Russ Cox's avatar
Russ Cox committed
363
|	dcl_name_list ntype varoptsemi '=' expr_list
364
	{
365
		$$ = variter($1, $2, $5);
366
	}
367
|	dcl_name_list '=' expr_list
368
	{
Russ Cox's avatar
Russ Cox committed
369
		$$ = variter($1, nil, $3);
370 371 372
	}

constdcl:
373
	dcl_name_list ntype '=' expr_list
Ken Thompson's avatar
Ken Thompson committed
374
	{
375
		$$ = constiter($1, $2, $4);
Ken Thompson's avatar
Ken Thompson committed
376
	}
377
|	dcl_name_list '=' expr_list
378
	{
379
		$$ = constiter($1, N, $3);
Ken Thompson's avatar
Ken Thompson committed
380 381
	}

Ken Thompson's avatar
Ken Thompson committed
382 383
constdcl1:
	constdcl
384
|	dcl_name_list ntype
Ken Thompson's avatar
Ken Thompson committed
385
	{
386
		$$ = constiter($1, $2, nil);
387
	}
388
|	dcl_name_list
389
	{
390
		$$ = constiter($1, N, nil);
391 392
	}

393 394 395 396 397 398 399
typedclname:
	new_type
	{
		$$ = dodcltype($1);
		defercheckwidth();
	}

Russ Cox's avatar
Russ Cox committed
400
typedcl:
Russ Cox's avatar
Russ Cox committed
401
	typedclname ntype
402
	{
Russ Cox's avatar
Russ Cox committed
403 404
		walkexpr($2, Etype, &$2->ninit);
		updatetype($1, $2->type);
405 406 407
		resumecheckwidth();
	}
|	typedclname LSTRUCT
408
	{
409 410
		updatetype($1, typ(TFORWSTRUCT));
		resumecheckwidth();
411
	}
412 413 414 415 416
|	typedclname LINTERFACE
	{
		updatetype($1, typ(TFORWINTER));
		resumecheckwidth();
	}
417 418 419 420 421 422 423 424 425

simple_stmt:
	expr
	{
		$$ = $1;
	}
|	expr LASOP expr
	{
		$$ = nod(OASOP, $1, $3);
Ken Thompson's avatar
Ken Thompson committed
426
		$$->etype = $2;			// rathole to pass opcode
427
	}
Russ Cox's avatar
Russ Cox committed
428
|	expr_list '=' expr_list
429
	{
430 431 432 433 434 435 436 437 438
		if($1->next == nil && $3->next == nil) {
			// simple
			$$ = nod(OAS, $1->n, $3->n);
			break;
		}
		// multiple
		$$ = nod(OAS2, N, N);
		$$->list = $1;
		$$->rlist = $3;
439
	}
Russ Cox's avatar
Russ Cox committed
440
|	expr_list LCOLAS expr_list
441
	{
442 443 444 445 446 447
		if($3->n->op == OTYPESW) {
			if($3->next != nil)
				yyerror("expr.(type) must be alone in list");
			else if($1->next != nil)
				yyerror("argument count mismatch: %d = %d", count($1), 1);
			$$ = nod(OTYPESW, $1->n, $3->n->left);
Ken Thompson's avatar
Ken Thompson committed
448 449
			break;
		}
450
		$$ = colas($1, $3);
451
	}
Russ Cox's avatar
Russ Cox committed
452
|	expr LINC
Ken Thompson's avatar
Ken Thompson committed
453
	{
454
		$$ = nod(OASOP, $1, nodintconst(1));
Ken Thompson's avatar
Ken Thompson committed
455 456 457 458
		$$->etype = OADD;
	}
|	expr LDEC
	{
459
		$$ = nod(OASOP, $1, nodintconst(1));
Ken Thompson's avatar
Ken Thompson committed
460 461 462
		$$->etype = OSUB;
	}

Russ Cox's avatar
bug157  
Russ Cox committed
463
case:
Russ Cox's avatar
Russ Cox committed
464
	LCASE expr_or_type_list ':'
465
	{
466 467
		int e;
		Node *n;
468

469 470 471 472
		// will be converted to OCASE
		// right will point to next case
		// done in casebody()
		poptodcl();
473
		$$ = nod(OXCASE, N, N);
Russ Cox's avatar
Russ Cox committed
474
		if(typeswvar != N && typeswvar->right != N) {
475 476 477 478 479 480 481
			// type switch
			n = $2->n;
			if($2->next != nil)
				yyerror("type switch case cannot be list");
			if(n->op == OLITERAL && n->val.ctype == CTNIL) {
				// case nil
				$$->list = list1(nod(OTYPESW, N, N));
Russ Cox's avatar
Russ Cox committed
482 483
				break;
			}
484 485

			// TODO: move
Russ Cox's avatar
Russ Cox committed
486
			e = nerrors;
487 488 489 490
			walkexpr(n, Etype | Erv, &$$->ninit);
			if(n->op == OTYPE) {
				n = old2new(typeswvar->right, n->type, &$$->ninit);
				$$->list = list1(nod(OTYPESW, n, N));
Russ Cox's avatar
Russ Cox committed
491 492
				break;
			}
Russ Cox's avatar
Russ Cox committed
493
			// maybe walkexpr found problems that keep
Russ Cox's avatar
Russ Cox committed
494
			// e from being valid even outside a type switch.
Russ Cox's avatar
Russ Cox committed
495
			// only complain if walkexpr didn't print new errors.
Russ Cox's avatar
Russ Cox committed
496 497 498
			if(nerrors == e)
				yyerror("non-type case in type switch");
			$$->diag = 1;
499 500 501
		} else {
			// expr switch
			$$->list = $2;
Ken Thompson's avatar
Ken Thompson committed
502
		}
503
		break;
504
	}
Rob Pike's avatar
Rob Pike committed
505 506 507 508 509 510
|	LCASE name '=' expr ':'
	{
		// will be converted to OCASE
		// right will point to next case
		// done in casebody()
		poptodcl();
511 512
		$$ = nod(OXCASE, N, N);
		$$->list = list1(nod(OAS, $2, $4));
Rob Pike's avatar
Rob Pike committed
513 514 515 516 517 518 519
	}
|	LCASE name LCOLAS expr ':'
	{
		// will be converted to OCASE
		// right will point to next case
		// done in casebody()
		poptodcl();
520 521
		$$ = nod(OXCASE, N, N);
		$$->list = list1(nod(OAS, selectas($2, $4, &$$->ninit), $4));
Rob Pike's avatar
Rob Pike committed
522
	}
523 524 525 526 527
|	LDEFAULT ':'
	{
		poptodcl();
		$$ = nod(OXCASE, N, N);
	}
Ken Thompson's avatar
Ken Thompson committed
528

529 530 531
compound_stmt:
	'{'
	{
Ken Thompson's avatar
Ken Thompson committed
532
		markdcl();
Russ Cox's avatar
Russ Cox committed
533
	}
534
	stmt_list '}'
535
	{
536
		$$ = liststmt($3);
Ken Thompson's avatar
Ken Thompson committed
537
		popdcl();
538
		yyoptsemi(0);
539 540
	}

Russ Cox's avatar
bug157  
Russ Cox committed
541
switch_body:
Russ Cox's avatar
Russ Cox committed
542
	LBODY
Russ Cox's avatar
bug157  
Russ Cox committed
543 544 545
	{
		markdcl();
	}
546
	caseblock_list '}'
Russ Cox's avatar
bug157  
Russ Cox committed
547 548 549
	{
		$$ = $3;
		popdcl();
550
		yyoptsemi(0);
Russ Cox's avatar
bug157  
Russ Cox committed
551 552 553
	}

caseblock:
554
	case stmt_list
Russ Cox's avatar
bug157  
Russ Cox committed
555 556 557 558 559
	{
		$$ = $1;
		$$->nbody = $2;
	}

560
caseblock_list:
Russ Cox's avatar
bug157  
Russ Cox committed
561
	{
562 563 564 565 566
		$$ = nil;
	}
|	caseblock_list caseblock
	{
		$$ = list($1, $2);
Russ Cox's avatar
bug157  
Russ Cox committed
567 568
	}

Russ Cox's avatar
Russ Cox committed
569 570 571 572 573
loop_body:
	LBODY
	{
		markdcl();
	}
574
	stmt_list '}'
Russ Cox's avatar
Russ Cox committed
575 576 577 578 579
	{
		$$ = $3;
		popdcl();
	}

Russ Cox's avatar
Russ Cox committed
580
range_stmt:
Russ Cox's avatar
Russ Cox committed
581
	expr_list '=' LRANGE expr
Ken Thompson's avatar
Ken Thompson committed
582
	{
583 584
		$$ = nod(ORANGE, N, $4);
		$$->list = $1;
Ken Thompson's avatar
Ken Thompson committed
585 586
		$$->etype = 0;	// := flag
	}
Russ Cox's avatar
Russ Cox committed
587
|	expr_list LCOLAS LRANGE expr
Ken Thompson's avatar
Ken Thompson committed
588
	{
589 590
		$$ = nod(ORANGE, N, $4);
		$$->list = $1;
Ken Thompson's avatar
Ken Thompson committed
591 592 593 594
		$$->etype = 1;
	}

for_header:
Russ Cox's avatar
Russ Cox committed
595 596
	osimple_stmt ';' osimple_stmt ';' osimple_stmt
	{
597
		// init ; test ; incr
Ken Thompson's avatar
Ken Thompson committed
598 599
		if($5 != N && $5->colas != 0)
			yyerror("cannot declare in the for-increment");
600
		$$ = nod(OFOR, N, N);
601 602
		if($1 != N)
			$$->ninit = list1($1);
603 604 605
		$$->ntest = $3;
		$$->nincr = $5;
	}
Russ Cox's avatar
Russ Cox committed
606
|	osimple_stmt
607
	{
Ken Thompson's avatar
Ken Thompson committed
608
		// normal test
609 610 611
		$$ = nod(OFOR, N, N);
		$$->ntest = $1;
	}
Russ Cox's avatar
Russ Cox committed
612 613 614 615
|	range_stmt
	{
		$$ = dorange($1);
	}
616 617

for_body:
Russ Cox's avatar
Russ Cox committed
618
	for_header loop_body
619 620
	{
		$$ = $1;
621
		$$->nbody = concat($$->nbody, $2);
622
		yyoptsemi(0);
623 624 625
	}

for_stmt:
Russ Cox's avatar
bug157  
Russ Cox committed
626
	LFOR
627
	{
Ken Thompson's avatar
Ken Thompson committed
628
		markdcl();
Russ Cox's avatar
bug157  
Russ Cox committed
629 630
	}
	for_body
631
	{
Russ Cox's avatar
bug157  
Russ Cox committed
632 633
		$$ = $3;
		popdcl();
634 635 636
	}

if_header:
Russ Cox's avatar
Russ Cox committed
637
	osimple_stmt
638 639 640 641 642
	{
		// test
		$$ = nod(OIF, N, N);
		$$->ntest = $1;
	}
Russ Cox's avatar
Russ Cox committed
643
|	osimple_stmt ';' osimple_stmt
644 645 646
	{
		// init ; test
		$$ = nod(OIF, N, N);
647 648
		if($1 != N)
			$$->ninit = list1($1);
649 650 651
		$$->ntest = $3;
	}

Russ Cox's avatar
bug157  
Russ Cox committed
652 653 654 655 656
if_stmt:
	LIF
	{
		markdcl();
	}
Russ Cox's avatar
Russ Cox committed
657
	if_header loop_body
Russ Cox's avatar
bug157  
Russ Cox committed
658 659 660 661
	{
		$$ = $3;
		$$->nbody = $4;
		// no popdcl; maybe there's an LELSE
662
		yyoptsemi(LELSE);
Russ Cox's avatar
bug157  
Russ Cox committed
663 664 665 666 667 668 669
	}

switch_stmt:
	LSWITCH
	{
		markdcl();
	}
Ken Thompson's avatar
Ken Thompson committed
670 671 672
	if_header
	{
		Node *n;
Russ Cox's avatar
bug157  
Russ Cox committed
673
		n = $3->ntest;
Ken Thompson's avatar
Ken Thompson committed
674 675 676 677
		if(n != N && n->op == OTYPESW)
			n = n->left;
		else
			n = N;
678
		typeswvar = nod(OXXX, typeswvar, n);
679
	}
Russ Cox's avatar
bug157  
Russ Cox committed
680
	switch_body
681
	{
Russ Cox's avatar
bug157  
Russ Cox committed
682 683
		$$ = $3;
		$$->op = OSWITCH;
684
		$$->list = $5;
Russ Cox's avatar
bug157  
Russ Cox committed
685 686
		typeswvar = typeswvar->left;
		popdcl();
687 688
	}

Ken Thompson's avatar
Ken Thompson committed
689
select_stmt:
Russ Cox's avatar
bug157  
Russ Cox committed
690
	LSELECT
Ken Thompson's avatar
Ken Thompson committed
691 692 693
	{
		markdcl();
	}
Russ Cox's avatar
bug157  
Russ Cox committed
694
	switch_body
Ken Thompson's avatar
Ken Thompson committed
695
	{
696 697
		$$ = nod(OSELECT, N, N);
		$$->list = $3;
Russ Cox's avatar
bug157  
Russ Cox committed
698
		popdcl();
Ken Thompson's avatar
Ken Thompson committed
699 700
	}

701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
/*
 * expressions
 */
expr:
	uexpr
|	expr LOROR expr
	{
		$$ = nod(OOROR, $1, $3);
	}
|	expr LANDAND expr
	{
		$$ = nod(OANDAND, $1, $3);
	}
|	expr LEQ expr
	{
		$$ = nod(OEQ, $1, $3);
	}
|	expr LNE expr
	{
		$$ = nod(ONE, $1, $3);
	}
|	expr LLT expr
	{
		$$ = nod(OLT, $1, $3);
	}
|	expr LLE expr
	{
		$$ = nod(OLE, $1, $3);
	}
|	expr LGE expr
	{
		$$ = nod(OGE, $1, $3);
	}
|	expr LGT expr
	{
		$$ = nod(OGT, $1, $3);
	}
|	expr '+' expr
	{
		$$ = nod(OADD, $1, $3);
	}
|	expr '-' expr
	{
		$$ = nod(OSUB, $1, $3);
	}
|	expr '|' expr
	{
		$$ = nod(OOR, $1, $3);
	}
|	expr '^' expr
	{
		$$ = nod(OXOR, $1, $3);
	}
|	expr '*' expr
	{
		$$ = nod(OMUL, $1, $3);
	}
|	expr '/' expr
	{
		$$ = nod(ODIV, $1, $3);
	}
|	expr '%' expr
	{
		$$ = nod(OMOD, $1, $3);
	}
|	expr '&' expr
	{
		$$ = nod(OAND, $1, $3);
	}
770 771 772 773
|	expr LANDNOT expr
	{
		$$ = nod(OANDNOT, $1, $3);
	}
774 775 776 777 778 779 780 781
|	expr LLSH expr
	{
		$$ = nod(OLSH, $1, $3);
	}
|	expr LRSH expr
	{
		$$ = nod(ORSH, $1, $3);
	}
Rob Pike's avatar
Rob Pike committed
782
|	expr LCOMM expr
Ken Thompson's avatar
Ken Thompson committed
783 784 785
	{
		$$ = nod(OSEND, $1, $3);
	}
786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817

uexpr:
	pexpr
|	'*' uexpr
	{
		$$ = nod(OIND, $2, N);
	}
|	'&' uexpr
	{
		$$ = nod(OADDR, $2, N);
	}
|	'+' uexpr
	{
		$$ = nod(OPLUS, $2, N);
	}
|	'-' uexpr
	{
		$$ = nod(OMINUS, $2, N);
	}
|	'!' uexpr
	{
		$$ = nod(ONOT, $2, N);
	}
|	'~' uexpr
	{
		yyerror("the OCOM operator is ^");
		$$ = nod(OCOM, $2, N);
	}
|	'^' uexpr
	{
		$$ = nod(OCOM, $2, N);
	}
Rob Pike's avatar
Rob Pike committed
818
|	LCOMM uexpr
819 820 821 822
	{
		$$ = nod(ORECV, $2, N);
	}

Ken Thompson's avatar
Ken Thompson committed
823 824
/*
 * call-like statements that
825
 * can be preceded by 'defer' and 'go'
Ken Thompson's avatar
Ken Thompson committed
826 827
 */
pseudocall:
Russ Cox's avatar
Russ Cox committed
828
	pexpr '(' oexpr_or_type_list ')'
Ken Thompson's avatar
Ken Thompson committed
829 830
	{
		$$ = unsafenmagic($1, $3);
Russ Cox's avatar
Russ Cox committed
831 832
		if($$)
			break;
833 834
		$$ = nod(OCALL, $1, N);
		$$->list = $3;
Ken Thompson's avatar
Ken Thompson committed
835 836
	}

837 838 839
pexpr:
	LLITERAL
	{
840
		$$ = nodlit($1);
841
	}
Russ Cox's avatar
Russ Cox committed
842
|	name
Russ Cox's avatar
Russ Cox committed
843
|	pexpr '.' sym
844
	{
Russ Cox's avatar
Russ Cox committed
845 846
		if($1->op == OPACK) {
			Sym *s;
Russ Cox's avatar
Russ Cox committed
847
			s = restrictlookup($3->name, $1->sym->name);
Russ Cox's avatar
Russ Cox committed
848 849 850 851 852
			$$ = oldname(s);
			break;
		}
		$$ = nod(ODOT, $1, newname($3));
		$$ = adddot($$);
853
	}
Russ Cox's avatar
Russ Cox committed
854
|	'(' expr_or_type ')'
855 856 857
	{
		$$ = $2;
	}
Russ Cox's avatar
Russ Cox committed
858
|	pexpr '.' '(' expr_or_type ')'
859
	{
Russ Cox's avatar
Russ Cox committed
860
		$$ = nod(ODOTTYPE, $1, $4);
861
	}
Ken Thompson's avatar
Ken Thompson committed
862 863 864 865
|	pexpr '.' '(' LTYPE ')'
	{
		$$ = nod(OTYPESW, $1, N);
	}
866 867 868 869 870 871 872 873
|	pexpr '[' expr ']'
	{
		$$ = nod(OINDEX, $1, $3);
	}
|	pexpr '[' keyval ']'
	{
		$$ = nod(OSLICE, $1, $3);
	}
Ken Thompson's avatar
Ken Thompson committed
874
|	pseudocall
875
|	convtype '(' expr ')'
Ken Thompson's avatar
Ken Thompson committed
876
	{
877
		// conversion
878 879
		$$ = nod(OCALL, $1, N);
		$$->list = list1($3);
Russ Cox's avatar
Russ Cox committed
880
	}
881
|	convtype lbrace braced_keyval_list '}'
Russ Cox's avatar
Russ Cox committed
882 883
	{
		// composite expression
884 885
		$$ = nod(OCOMPOS, N, $1);
		$$->list = $3;
Russ Cox's avatar
Russ Cox committed
886 887 888 889 890 891

		// If the opening brace was an LBODY,
		// set up for another one now that we're done.
		// See comment in lex.c about loophack.
		if($2 == LBODY)
			loophack = 1;
Ken Thompson's avatar
Ken Thompson committed
892
	}
893
|	pexpr '{' braced_keyval_list '}'
Ken Thompson's avatar
Ken Thompson committed
894
	{
895
		// composite expression
896 897
		$$ = nod(OCOMPOS, N, $1);
		$$->list = $3;
Ken Thompson's avatar
Ken Thompson committed
898 899
	}
|	fnliteral
900

Russ Cox's avatar
Russ Cox committed
901 902
expr_or_type:
	expr
Russ Cox's avatar
Russ Cox committed
903
|	non_expr_type	%prec PreferToRightParen
Russ Cox's avatar
Russ Cox committed
904 905

name_or_type:
Russ Cox's avatar
Russ Cox committed
906
	ntype
907

Russ Cox's avatar
Russ Cox committed
908 909
lbrace:
	LBODY
910
	{
Russ Cox's avatar
Russ Cox committed
911
		$$ = LBODY;
912
	}
Russ Cox's avatar
Russ Cox committed
913
|	'{'
914
	{
Russ Cox's avatar
Russ Cox committed
915
		$$ = '{';
916 917 918 919 920 921 922 923
	}

/*
 * names and types
 *	newname is used before declared
 *	oldname is used after declared
 */
new_name:
Russ Cox's avatar
Russ Cox committed
924
	sym
925 926 927 928
	{
		$$ = newname($1);
	}

929 930 931 932 933 934
dcl_name:
	sym
	{
		$$ = dclname($1);
	}

935
new_type:
Russ Cox's avatar
Russ Cox committed
936
	sym
937 938 939 940
	{
		$$ = newtype($1);
	}

941 942 943 944 945 946
onew_name:
	{
		$$ = N;
	}
|	new_name

947
sym:
Russ Cox's avatar
Russ Cox committed
948
	LNAME
Ken Thompson's avatar
Ken Thompson committed
949

950
name:
Russ Cox's avatar
Russ Cox committed
951
	sym
Russ Cox's avatar
Russ Cox committed
952 953 954 955 956 957
	{
		$$ = oldname($1);
	}

labelname:
	name
958

Ken Thompson's avatar
Ken Thompson committed
959
convtype:
Russ Cox's avatar
Russ Cox committed
960
	'[' oexpr ']' ntype
Ken Thompson's avatar
Ken Thompson committed
961
	{
Ken Thompson's avatar
Ken Thompson committed
962
		// array literal
Russ Cox's avatar
Russ Cox committed
963
		$$ = nod(OTARRAY, $2, $4);
Ken Thompson's avatar
Ken Thompson committed
964
	}
Russ Cox's avatar
Russ Cox committed
965
|	'[' dotdotdot ']' ntype
Ken Thompson's avatar
Ken Thompson committed
966 967
	{
		// array literal of nelem
Russ Cox's avatar
Russ Cox committed
968
		$$ = nod(OTARRAY, $2, $4);
Ken Thompson's avatar
Ken Thompson committed
969
	}
Russ Cox's avatar
Russ Cox committed
970
|	LMAP '[' ntype ']' ntype
Ken Thompson's avatar
Ken Thompson committed
971
	{
Ken Thompson's avatar
Ken Thompson committed
972
		// map literal
Russ Cox's avatar
Russ Cox committed
973
		$$ = nod(OTMAP, $3, $5);
Ken Thompson's avatar
Ken Thompson committed
974
	}
Ken Thompson's avatar
Ken Thompson committed
975
|	structtype
Ken Thompson's avatar
Ken Thompson committed
976

Russ Cox's avatar
Russ Cox committed
977 978 979 980
/*
 * to avoid parsing conflicts, type is split into
 *	channel types
 *	function types
981
 *	parenthesized types
Russ Cox's avatar
Russ Cox committed
982 983 984 985
 *	any other type
 * the type system makes additional restrictions,
 * but those are not implemented in the grammar.
 */
Ken Thompson's avatar
Ken Thompson committed
986 987 988
dotdotdot:
	LDDD
	{
Russ Cox's avatar
Russ Cox committed
989
		$$ = typenod(typ(TDDD));
Ken Thompson's avatar
Ken Thompson committed
990
	}
Russ Cox's avatar
Russ Cox committed
991

Russ Cox's avatar
Russ Cox committed
992 993 994 995 996 997 998
ntype:
	chantype
|	fntype
|	othertype
|	ptrtype
|	dotname
|	'(' ntype ')'
Russ Cox's avatar
Russ Cox committed
999
	{
Russ Cox's avatar
Russ Cox committed
1000
		$$ = $2;
Russ Cox's avatar
Russ Cox committed
1001 1002
	}

Russ Cox's avatar
Russ Cox committed
1003
non_expr_type:
1004
	chantype
1005
|	fntype
1006
|	othertype
Russ Cox's avatar
Russ Cox committed
1007 1008 1009 1010 1011
|	'*' non_expr_type
	{
		$$ = nod(OIND, $2, N);
	}
|	'(' non_expr_type ')'
Russ Cox's avatar
Russ Cox committed
1012 1013 1014
	{
		$$ = $2;
	}
Russ Cox's avatar
Russ Cox committed
1015

1016
non_chan_type:
1017
	fntype
1018
|	othertype
Russ Cox's avatar
Russ Cox committed
1019 1020
|	ptrtype
|	dotname
Russ Cox's avatar
Russ Cox committed
1021
|	'(' ntype ')'
1022
	{
1023
		$$ = $2;
1024 1025
	}

1026 1027 1028
non_fn_type:
	chantype
|	othertype
Russ Cox's avatar
Russ Cox committed
1029 1030
|	ptrtype
|	dotname
1031

Russ Cox's avatar
Russ Cox committed
1032
dotname:
Russ Cox's avatar
Russ Cox committed
1033
	name
Russ Cox's avatar
Russ Cox committed
1034 1035 1036 1037
|	name '.' sym
	{
		if($1->op == OPACK) {
			Sym *s;
Russ Cox's avatar
Russ Cox committed
1038
			s = restrictlookup($3->name, $1->sym->name);
Russ Cox's avatar
Russ Cox committed
1039 1040 1041 1042 1043 1044
			$$ = oldname(s);
			break;
		}
		$$ = nod(ODOT, $1, newname($3));
		$$ = adddot($$);
	}
Russ Cox's avatar
Russ Cox committed
1045

1046
othertype:
Russ Cox's avatar
Russ Cox committed
1047
	'[' oexpr ']' ntype
1048
	{
Russ Cox's avatar
Russ Cox committed
1049
		$$ = nod(OTARRAY, $2, $4);
1050
	}
Russ Cox's avatar
Russ Cox committed
1051
|	LCOMM LCHAN ntype
1052
	{
Russ Cox's avatar
Russ Cox committed
1053 1054
		$$ = nod(OTCHAN, $3, N);
		$$->etype = Crecv;
Rob Pike's avatar
Rob Pike committed
1055
	}
1056
|	LCHAN LCOMM non_chan_type
Rob Pike's avatar
Rob Pike committed
1057
	{
Russ Cox's avatar
Russ Cox committed
1058 1059
		$$ = nod(OTCHAN, $3, N);
		$$->etype = Csend;
1060
	}
Russ Cox's avatar
Russ Cox committed
1061
|	LMAP '[' ntype ']' ntype
1062
	{
Russ Cox's avatar
Russ Cox committed
1063
		$$ = nod(OTMAP, $3, $5);
1064
	}
Russ Cox's avatar
Russ Cox committed
1065 1066 1067 1068 1069
|	structtype
|	interfacetype

ptrtype:
	'*' ntype
1070
	{
Russ Cox's avatar
Russ Cox committed
1071
		$$ = nod(OIND, $2, N);
1072
	}
1073

1074
chantype:
Russ Cox's avatar
Russ Cox committed
1075
	LCHAN ntype
Rob Pike's avatar
Rob Pike committed
1076
	{
Russ Cox's avatar
Russ Cox committed
1077 1078
		$$ = nod(OTCHAN, $2, N);
		$$->etype = Cboth;
Rob Pike's avatar
Rob Pike committed
1079 1080
	}

Ken Thompson's avatar
Ken Thompson committed
1081
structtype:
1082
	LSTRUCT '{' structdcl_list osemi '}'
Ken Thompson's avatar
Ken Thompson committed
1083
	{
1084 1085
		$$ = nod(OTSTRUCT, N, N);
		$$->list = $3;
1086 1087 1088 1089
		// Distinguish closing brace in struct from
		// other closing braces by explicitly marking it.
		// Used above (yylast == LSEMIBRACE).
		yylast = LSEMIBRACE;
Ken Thompson's avatar
Ken Thompson committed
1090 1091 1092
	}
|	LSTRUCT '{' '}'
	{
Russ Cox's avatar
Russ Cox committed
1093
		$$ = nod(OTSTRUCT, N, N);
1094
		yylast = LSEMIBRACE;
Ken Thompson's avatar
Ken Thompson committed
1095 1096 1097
	}

interfacetype:
1098
	LINTERFACE '{' interfacedcl_list osemi '}'
Ken Thompson's avatar
Ken Thompson committed
1099
	{
1100 1101
		$$ = nod(OTINTER, N, N);
		$$->list = $3;
1102
		yylast = LSEMIBRACE;
Ken Thompson's avatar
Ken Thompson committed
1103 1104 1105
	}
|	LINTERFACE '{' '}'
	{
Russ Cox's avatar
Russ Cox committed
1106
		$$ = nod(OTINTER, N, N);
1107
		yylast = LSEMIBRACE;
Ken Thompson's avatar
Ken Thompson committed
1108 1109
	}

1110 1111 1112
keyval:
	expr ':' expr
	{
Ken Thompson's avatar
Ken Thompson committed
1113
		$$ = nod(OKEY, $1, $3);
1114
	}
1115

1116 1117 1118 1119 1120 1121

/*
 * function stuff
 * all in one place to show how crappy it all is
 */
xfndcl:
Ken Thompson's avatar
Ken Thompson committed
1122
	LFUNC
1123
	{
Ken Thompson's avatar
Ken Thompson committed
1124 1125 1126 1127 1128 1129
		maxarg = 0;
		stksize = 0;
	} fndcl fnbody
	{
		$$ = $3;
		$$->nbody = $4;
1130 1131 1132 1133
		funcbody($$);
	}

fndcl:
1134
	dcl_name '(' oarg_type_list ')' fnres
1135
	{
Russ Cox's avatar
Russ Cox committed
1136 1137
		Node *n;

1138 1139 1140
		b0stack = dclstack;	// mark base for fn literals
		$$ = nod(ODCLFUNC, N, N);
		$$->nname = $1;
1141
		if($3 == nil && $5 == nil)
Ken Thompson's avatar
init  
Ken Thompson committed
1142
			$$->nname = renameinit($1);
Russ Cox's avatar
Russ Cox committed
1143 1144 1145 1146 1147
		n = nod(OTFUNC, N, N);
		n->list = $3;
		n->rlist = $5;
		walkexpr(n, Etype, &n->ninit);
		$$->type = n->type;
1148 1149 1150 1151
		funchdr($$);
	}
|	'(' oarg_type_list ')' new_name '(' oarg_type_list ')' fnres
	{
1152 1153 1154 1155 1156 1157 1158 1159
		Node *rcvr;

		rcvr = $2->n;
		if($2->next != nil || $2->n->op != ODCLFIELD) {
			yyerror("bad receiver in method");
			rcvr = N;
		}

1160 1161
		b0stack = dclstack;	// mark base for fn literals
		$$ = nod(ODCLFUNC, N, N);
1162 1163 1164 1165 1166
		$$->nname = $4;
		$$->nname = methodname($4, rcvr->type);
		$$->type = functype(rcvr, $6, $8);
		funchdr($$);
		if(rcvr != N)
Ken Thompson's avatar
Ken Thompson committed
1167
			addmethod($4, $$->type, 1);
1168 1169
	}

Ken Thompson's avatar
Ken Thompson committed
1170
fntype:
1171
	LFUNC '(' oarg_type_list ')' fnres
1172
	{
1173 1174 1175
		$$ = nod(OTFUNC, N, N);
		$$->list = $3;
		$$->rlist = $5;
1176 1177 1178 1179 1180
	}

fnlitdcl:
	fntype
	{
Russ Cox's avatar
Russ Cox committed
1181
		markdcl();
1182
		$$ = funclit0($$);
1183 1184 1185
	}

fnliteral:
1186
	fnlitdcl '{' stmt_list '}'
1187
	{
Russ Cox's avatar
Russ Cox committed
1188
		$$ = funclit1($1, $3);
1189 1190 1191
	}

fnbody:
1192 1193 1194 1195
	{
		$$ = nil;
	}
|	'{' stmt_list '}'
1196
	{
Ken Thompson's avatar
Ken Thompson committed
1197
		$$ = $2;
1198 1199
		if($$ == nil)
			$$ = list1(nod(ORETURN, N, N));
1200
		yyoptsemi(0);
1201
	}
Ken Thompson's avatar
Ken Thompson committed
1202

1203
fnres:
Russ Cox's avatar
Russ Cox committed
1204
	%prec NotParen
1205
	{
1206
		$$ = nil;
1207
	}
1208
|	non_fn_type
1209
	{
1210
		$$ = list1(nod(ODCLFIELD, N, $1));
1211
	}
Russ Cox's avatar
Russ Cox committed
1212 1213 1214 1215
|	'(' oarg_type_list ')'
	{
		$$ = $2;
	}
1216

1217 1218 1219 1220 1221 1222
/*
 * lists of things
 * note that they are left recursive
 * to conserve yacc stack. they need to
 * be reversed to interpret correctly
 */
1223
xdcl_list:
1224
	{
1225 1226 1227 1228 1229
		$$ = nil;
	}
|	xdcl_list xdcl
	{
		$$ = concat($1, $2);
1230 1231
	}

1232
vardcl_list:
1233
	vardcl
1234
|	vardcl_list ';' vardcl
1235
	{
1236
		$$ = concat($1, $3);
1237 1238
	}

1239
constdcl_list:
Ken Thompson's avatar
Ken Thompson committed
1240
	constdcl1
1241
|	constdcl_list ';' constdcl1
1242 1243 1244
	{
		$$ = concat($1, $3);
	}
1245

1246
typedcl_list:
1247
	typedcl
1248 1249 1250
	{
		$$ = list1($1);
	}
1251
|	typedcl_list ';' typedcl
1252 1253 1254
	{
		$$ = list($1, $3);
	}
1255

1256
structdcl_list:
1257
	structdcl
1258
|	structdcl_list ';' structdcl
1259
	{
1260
		$$ = concat($1, $3);
1261 1262
	}

1263
interfacedcl_list:
1264
	interfacedcl
1265
|	interfacedcl_list ';' interfacedcl
1266
	{
1267
		$$ = concat($1, $3);
1268 1269 1270
	}

structdcl:
1271
	new_name_list ntype oliteral
1272
	{
1273 1274 1275 1276 1277 1278
		NodeList *l;

		for(l=$1; l; l=l->next) {
			l->n = nod(ODCLFIELD, l->n, $2);
			l->n->val = $3;
		}
1279
	}
Russ Cox's avatar
Russ Cox committed
1280 1281
|	embed oliteral
	{
1282 1283
		$1->val = $2;
		$$ = list1($1);
Russ Cox's avatar
Russ Cox committed
1284 1285
	}
|	'*' embed oliteral
Ken Thompson's avatar
export  
Ken Thompson committed
1286
	{
1287 1288 1289
		$2->right = nod(OIND, $2->right, N);
		$2->val = $3;
		$$ = list1($2);
Ken Thompson's avatar
Ken Thompson committed
1290 1291
	}

Russ Cox's avatar
Russ Cox committed
1292 1293 1294
packname:
	LNAME
|	LNAME '.' sym
Ken Thompson's avatar
Ken Thompson committed
1295
	{
Russ Cox's avatar
Russ Cox committed
1296 1297 1298 1299 1300 1301 1302
		char *pkg;

		if($1->def == N || $1->def->op != OPACK) {
			yyerror("%S is not a package", $1);
			pkg = $1->name;
		} else
			pkg = $1->def->sym->name;
Russ Cox's avatar
Russ Cox committed
1303
		$$ = restrictlookup($3->name, pkg);
1304
	}
Russ Cox's avatar
Russ Cox committed
1305 1306 1307

embed:
	packname
1308
	{
Russ Cox's avatar
Russ Cox committed
1309
		$$ = embedded($1);
Ken Thompson's avatar
export  
Ken Thompson committed
1310
	}
1311

1312
interfacedcl:
1313
	new_name_list indcl
1314
	{
1315
		NodeList *l;
1316

1317 1318 1319 1320
		for(l=$1; l; l=l->next)
			l->n = nod(ODCLFIELD, l->n, $2);
		$$ = $1;
	}
Russ Cox's avatar
Russ Cox committed
1321
|	packname
1322
	{
Russ Cox's avatar
Russ Cox committed
1323
		$$ = list1(nod(ODCLFIELD, N, oldname($1)));
1324 1325
	}

Ken Thompson's avatar
Ken Thompson committed
1326
indcl:
1327 1328 1329
	'(' oarg_type_list ')' fnres
	{
		// without func keyword
Russ Cox's avatar
Russ Cox committed
1330 1331 1332
		$$ = nod(OTFUNC, fakethis(), N);
		$$->list = $2;
		$$->rlist = $4;
1333 1334
	}

1335 1336 1337
/*
 * function arguments.
 */
Russ Cox's avatar
Russ Cox committed
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
arg_type:
	name_or_type
|	sym name_or_type
	{
		$$ = $1->def;
		if($$ == N) {
			$$ = nod(ONONAME, N, N);
			$$->sym = $1;
		}
		$$ = nod(OKEY, $$, $2);
1348
	}
Russ Cox's avatar
Russ Cox committed
1349
|	sym dotdotdot
1350
	{
Russ Cox's avatar
Russ Cox committed
1351 1352 1353 1354 1355
		$$ = $1->def;
		if($$ == N) {
			$$ = nod(ONONAME, N, N);
			$$->sym = $1;
		}
Russ Cox's avatar
Russ Cox committed
1356
		$$ = nod(OKEY, $$, $2);
1357
	}
Russ Cox's avatar
Russ Cox committed
1358
|	dotdotdot
1359

1360
arg_type_list:
Russ Cox's avatar
Russ Cox committed
1361
	arg_type
1362
	{
1363 1364 1365 1366 1367
		$$ = list1($1);
	}
|	arg_type_list ',' arg_type
	{
		$$ = list($1, $3);
1368 1369
	}

1370 1371 1372 1373 1374
oarg_type_list:
	{
		$$ = nil;
	}
|	arg_type_list
1375
	{
1376
		$$ = checkarglist($1);
1377 1378
	}

Ken Thompson's avatar
Ken Thompson committed
1379
/*
1380
 * statement
Ken Thompson's avatar
Ken Thompson committed
1381
 */
1382
stmt:
Ken Thompson's avatar
asdf  
Ken Thompson committed
1383 1384 1385
	{
		$$ = N;
	}
1386 1387 1388
|	simple_stmt
|	compound_stmt
|	common_dcl
1389 1390 1391
	{
		$$ = liststmt($1);
	}
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403
|	for_stmt
|	switch_stmt
|	select_stmt
|	if_stmt
	{
		popdcl();
		$$ = $1;
	}
|	if_stmt LELSE stmt
	{
		popdcl();
		$$ = $1;
1404
		$$->nelse = list1($3);
1405 1406
	}
|	error
1407 1408 1409
	{
		$$ = N;
	}
1410
|	labelname ':' stmt
Russ Cox's avatar
Russ Cox committed
1411
	{
1412 1413 1414 1415 1416 1417
		NodeList *l;

		l = list1(nod(OLABEL, $1, N));
		if($3)
			l = list(l, $3);
		$$ = liststmt(l);
Russ Cox's avatar
Russ Cox committed
1418
	}
1419
|	LFALL
1420
	{
1421 1422
		// will be converted to OFALL
		$$ = nod(OXFALL, N, N);
Ken Thompson's avatar
Ken Thompson committed
1423
	}
1424
|	LBREAK onew_name
1425
	{
1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445
		$$ = nod(OBREAK, $2, N);
	}
|	LCONTINUE onew_name
	{
		$$ = nod(OCONTINUE, $2, N);
	}
|	LGO pseudocall
	{
		$$ = nod(OPROC, $2, N);
	}
|	LDEFER pseudocall
	{
		$$ = nod(ODEFER, $2, N);
	}
|	LGOTO new_name
	{
		$$ = nod(OGOTO, $2, N);
	}
|	LRETURN oexpr_list
	{
1446 1447
		$$ = nod(ORETURN, N, N);
		$$->list = $2;
1448
	}
Ken Thompson's avatar
Ken Thompson committed
1449

1450
stmt_list:
1451
	stmt
Ken Thompson's avatar
bug 145  
Ken Thompson committed
1452
	{
1453 1454 1455
		$$ = nil;
		if($1 != N)
			$$ = list1($1);
Ken Thompson's avatar
bug 145  
Ken Thompson committed
1456
	}
1457
|	stmt_list ';' stmt
Ken Thompson's avatar
Ken Thompson committed
1458
	{
1459 1460 1461
		$$ = $1;
		if($3 != N)
			$$ = list($$, $3);
Ken Thompson's avatar
Ken Thompson committed
1462 1463
	}

1464 1465
new_name_list:
	new_name
Russ Cox's avatar
Russ Cox committed
1466
	{
1467
		$$ = list1($1);
Russ Cox's avatar
Russ Cox committed
1468
	}
1469
|	new_name_list ',' new_name
Russ Cox's avatar
Russ Cox committed
1470
	{
1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
		$$ = list($1, $3);
	}

dcl_name_list:
	dcl_name
	{
		$$ = list1($1);
	}
|	dcl_name_list ',' dcl_name
	{
		$$ = list($1, $3);
Russ Cox's avatar
Russ Cox committed
1482 1483
	}

1484 1485
expr_list:
	expr
Russ Cox's avatar
Russ Cox committed
1486
	{
1487
		$$ = list1($1);
Russ Cox's avatar
Russ Cox committed
1488
	}
1489
|	expr_list ',' expr
1490
	{
1491
		$$ = list($1, $3);
1492 1493
	}

1494 1495
expr_or_type_list:
	expr_or_type
1496
	{
1497
		$$ = list1($1);
Russ Cox's avatar
Russ Cox committed
1498
	}
1499
|	expr_or_type_list ',' expr_or_type
Russ Cox's avatar
Russ Cox committed
1500
	{
1501
		$$ = list($1, $3);
1502 1503
	}

Ken Thompson's avatar
Ken Thompson committed
1504 1505 1506
/*
 * list of combo of keyval and val
 */
1507
keyval_list:
1508
	keyval
Ken Thompson's avatar
Ken Thompson committed
1509
	{
1510
		$$ = list1($1);
Ken Thompson's avatar
Ken Thompson committed
1511
	}
1512
|	expr
1513
	{
1514
		$$ = list1($1);
1515
	}
1516
|	keyval_list ',' keyval
1517
	{
1518
		$$ = list($1, $3);
1519
	}
1520
|	keyval_list ',' expr
1521
	{
1522
		$$ = list($1, $3);
1523 1524
	}

1525
braced_keyval_list:
Russ Cox's avatar
Russ Cox committed
1526
	{
1527
		$$ = nil;
Russ Cox's avatar
Russ Cox committed
1528
	}
1529
|	keyval_list ocomma
Russ Cox's avatar
Russ Cox committed
1530
	{
1531
		$$ = $1;
Russ Cox's avatar
Russ Cox committed
1532 1533
	}

1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
/*
 * optional things
 */
osemi:
|	';'

ocomma:
|	','

oexpr:
	{
		$$ = N;
	}
|	expr

oexpr_list:
	{
1551
		$$ = nil;
1552 1553 1554
	}
|	expr_list

Russ Cox's avatar
Russ Cox committed
1555 1556
oexpr_or_type_list:
	{
1557
		$$ = nil;
Russ Cox's avatar
Russ Cox committed
1558 1559 1560
	}
|	expr_or_type_list

1561 1562 1563 1564 1565 1566
osimple_stmt:
	{
		$$ = N;
	}
|	simple_stmt

Russ Cox's avatar
Russ Cox committed
1567
ohidden_funarg_list:
1568
	{
1569
		$$ = nil;
1570
	}
Russ Cox's avatar
Russ Cox committed
1571
|	hidden_funarg_list
1572

Russ Cox's avatar
Russ Cox committed
1573
ohidden_structdcl_list:
1574
	{
1575
		$$ = nil;
1576
	}
Russ Cox's avatar
Russ Cox committed
1577 1578 1579
|	hidden_structdcl_list

ohidden_interfacedcl_list:
1580
	{
1581
		$$ = nil;
1582
	}
Russ Cox's avatar
Russ Cox committed
1583
|	hidden_interfacedcl_list
1584

Russ Cox's avatar
Russ Cox committed
1585 1586 1587 1588 1589 1590
oliteral:
	{
		$$.ctype = CTxxx;
	}
|	LLITERAL

1591 1592 1593 1594 1595
/*
 * import syntax from header of
 * an output package
 */
hidden_import:
Russ Cox's avatar
Russ Cox committed
1596
	LPACKAGE sym
1597
	/* variables */
Russ Cox's avatar
bug133  
Russ Cox committed
1598
|	LVAR hidden_pkg_importsym hidden_type
Russ Cox's avatar
Russ Cox committed
1599
	{
Russ Cox's avatar
Russ Cox committed
1600
		importvar($2, $3, PEXTERN);
Russ Cox's avatar
Russ Cox committed
1601
	}
Russ Cox's avatar
bug133  
Russ Cox committed
1602
|	LCONST hidden_pkg_importsym '=' hidden_constant
Russ Cox's avatar
Russ Cox committed
1603
	{
1604
		importconst($2, types[TIDEAL], $4);
Russ Cox's avatar
Russ Cox committed
1605
	}
Russ Cox's avatar
bug133  
Russ Cox committed
1606
|	LCONST hidden_pkg_importsym hidden_type '=' hidden_constant
Russ Cox's avatar
Russ Cox committed
1607
	{
1608
		importconst($2, $3, $5);
Russ Cox's avatar
Russ Cox committed
1609
	}
Russ Cox's avatar
bug133  
Russ Cox committed
1610
|	LTYPE hidden_pkg_importsym hidden_type
Russ Cox's avatar
Russ Cox committed
1611
	{
Russ Cox's avatar
Russ Cox committed
1612
		importtype($2, $3);
Russ Cox's avatar
Russ Cox committed
1613
	}
1614 1615 1616 1617 1618 1619 1620 1621
|	LTYPE hidden_pkg_importsym LSTRUCT
	{
		importtype($2, typ(TFORWSTRUCT));
	}
|	LTYPE hidden_pkg_importsym LINTERFACE
	{
		importtype($2, typ(TFORWINTER));
	}
Russ Cox's avatar
bug133  
Russ Cox committed
1622
|	LFUNC hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres
1623
	{
Russ Cox's avatar
Russ Cox committed
1624
		importvar($2, functype(N, $4, $6), PFUNC);
1625
	}
Russ Cox's avatar
Russ Cox committed
1626
|	LFUNC '(' hidden_funarg_list ')' sym '(' ohidden_funarg_list ')' ohidden_funres
Russ Cox's avatar
Russ Cox committed
1627
	{
1628
		if($3->next != nil || $3->n->op != ODCLFIELD) {
Russ Cox's avatar
Russ Cox committed
1629 1630 1631
			yyerror("bad receiver in method");
			YYERROR;
		}
1632
		importmethod($5, functype($3->n, $7, $9));
Russ Cox's avatar
Russ Cox committed
1633 1634 1635 1636 1637
	}

hidden_type:
	hidden_type1
|	hidden_type2
1638

Russ Cox's avatar
Russ Cox committed
1639 1640
hidden_type1:
	hidden_importsym
1641
	{
Russ Cox's avatar
Russ Cox committed
1642
		$$ = pkgtype($1);
1643
	}
Russ Cox's avatar
Russ Cox committed
1644
|	LNAME
1645
	{
Russ Cox's avatar
Russ Cox committed
1646
		$$ = oldtype($1);
1647
	}
Russ Cox's avatar
Russ Cox committed
1648 1649 1650 1651 1652 1653
|	'[' ']' hidden_type
	{
		$$ = aindex(N, $3);
	}
|	'[' LLITERAL ']' hidden_type
	{
1654
		$$ = aindex(nodlit($2), $4);
Russ Cox's avatar
Russ Cox committed
1655 1656 1657
	}
|	LMAP '[' hidden_type ']' hidden_type
	{
1658
		$$ = maptype($3, $5);
Russ Cox's avatar
Russ Cox committed
1659 1660
	}
|	LSTRUCT '{' ohidden_structdcl_list '}'
1661
	{
Russ Cox's avatar
Russ Cox committed
1662
		$$ = dostruct($3, TSTRUCT);
1663
	}
Russ Cox's avatar
Russ Cox committed
1664
|	LINTERFACE '{' ohidden_interfacedcl_list '}'
1665
	{
Russ Cox's avatar
Russ Cox committed
1666 1667
		$$ = dostruct($3, TINTER);
		$$ = sortinter($$);
1668
	}
Russ Cox's avatar
Russ Cox committed
1669
|	'*' hidden_type
Ken Thompson's avatar
arrays  
Ken Thompson committed
1670
	{
Russ Cox's avatar
Russ Cox committed
1671
		$$ = ptrto($2);
Ken Thompson's avatar
arrays  
Ken Thompson committed
1672
	}
Russ Cox's avatar
Russ Cox committed
1673
|	LCOMM LCHAN hidden_type
1674
	{
Russ Cox's avatar
Russ Cox committed
1675 1676 1677
		$$ = typ(TCHAN);
		$$->type = $3;
		$$->chan = Crecv;
1678
	}
Russ Cox's avatar
Russ Cox committed
1679
|	LCHAN LCOMM hidden_type1
1680
	{
Russ Cox's avatar
Russ Cox committed
1681 1682 1683
		$$ = typ(TCHAN);
		$$->type = $3;
		$$->chan = Csend;
1684
	}
Ken Thompson's avatar
Ken Thompson committed
1685 1686 1687 1688
|	LDDD
	{
		$$ = typ(TDDD);
	}
Russ Cox's avatar
Russ Cox committed
1689 1690 1691

hidden_type2:
	LCHAN hidden_type
1692
	{
Russ Cox's avatar
Russ Cox committed
1693 1694 1695
		$$ = typ(TCHAN);
		$$->type = $2;
		$$->chan = Cboth;
1696
	}
Russ Cox's avatar
Russ Cox committed
1697
|	LFUNC '(' ohidden_funarg_list ')' ohidden_funres
1698
	{
1699
		$$ = functype(nil, $3, $5);
1700
	}
Russ Cox's avatar
Russ Cox committed
1701 1702

hidden_dcl:
Russ Cox's avatar
Russ Cox committed
1703
	sym hidden_type
1704
	{
Russ Cox's avatar
Russ Cox committed
1705 1706
		$$ = nod(ODCLFIELD, newname($1), N);
		$$->type = $2;
1707
	}
Russ Cox's avatar
Russ Cox committed
1708
|	'?' hidden_type
Ken Thompson's avatar
Ken Thompson committed
1709
	{
Russ Cox's avatar
Russ Cox committed
1710 1711
		$$ = nod(ODCLFIELD, N, N);
		$$->type = $2;
Ken Thompson's avatar
Ken Thompson committed
1712
	}
Russ Cox's avatar
Russ Cox committed
1713

Russ Cox's avatar
Russ Cox committed
1714
hidden_structdcl:
Russ Cox's avatar
Russ Cox committed
1715
	sym hidden_type oliteral
Russ Cox's avatar
Russ Cox committed
1716
	{
Russ Cox's avatar
Russ Cox committed
1717
		$$ = nod(ODCLFIELD, newname($1), typenod($2));
Russ Cox's avatar
Russ Cox committed
1718
		$$->val = $3;
Russ Cox's avatar
Russ Cox committed
1719
	}
Russ Cox's avatar
Russ Cox committed
1720
|	'?' hidden_type oliteral
Russ Cox's avatar
Russ Cox committed
1721
	{
Ken Thompson's avatar
Ken Thompson committed
1722 1723
		if(isptr[$2->etype]) {
			$$ = embedded($2->type->sym);
Russ Cox's avatar
Russ Cox committed
1724
			$$->right = nod(OIND, $$->right, N);
Ken Thompson's avatar
Ken Thompson committed
1725 1726
		} else
			$$ = embedded($2->sym);
Russ Cox's avatar
Russ Cox committed
1727
		$$->val = $3;
Russ Cox's avatar
Russ Cox committed
1728 1729
	}

Russ Cox's avatar
Russ Cox committed
1730
hidden_interfacedcl:
Russ Cox's avatar
Russ Cox committed
1731
	sym '(' ohidden_funarg_list ')' ohidden_funres
Ken Thompson's avatar
Ken Thompson committed
1732
	{
Russ Cox's avatar
Russ Cox committed
1733
		$$ = nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5)));
Russ Cox's avatar
Russ Cox committed
1734 1735 1736 1737
	}

ohidden_funres:
	{
1738
		$$ = nil;
Russ Cox's avatar
Russ Cox committed
1739 1740 1741 1742 1743 1744 1745 1746 1747 1748
	}
|	hidden_funres

hidden_funres:
	'(' ohidden_funarg_list ')'
	{
		$$ = $2;
	}
|	hidden_type1
	{
1749 1750 1751 1752 1753
		Node *n;

		n = nod(ODCLFIELD, N, N);
		n->type = $1;
		$$ = list1(n);
Ken Thompson's avatar
Ken Thompson committed
1754
	}
1755

1756 1757
hidden_constant:
	LLITERAL
1758 1759 1760
	{
		$$ = nodlit($1);
	}
1761 1762
|	'-' LLITERAL
	{
1763 1764
		$$ = nodlit($2);
		switch($$->val.ctype){
1765
		case CTINT:
1766
			mpnegfix($$->val.u.xval);
1767 1768
			break;
		case CTFLT:
1769
			mpnegflt($$->val.u.fval);
1770 1771 1772 1773 1774
			break;
		default:
			yyerror("bad negated constant");
		}
	}
Russ Cox's avatar
Russ Cox committed
1775
|	name
Russ Cox's avatar
Russ Cox committed
1776
	{
Russ Cox's avatar
Russ Cox committed
1777 1778 1779
		$$ = $1;
		if($$->op != OLITERAL)
			yyerror("bad constant %S", $$->sym);
Russ Cox's avatar
Russ Cox committed
1780
	}
1781

Russ Cox's avatar
Russ Cox committed
1782
hidden_importsym:
Russ Cox's avatar
Russ Cox committed
1783
	sym '.' sym
1784
	{
Russ Cox's avatar
Russ Cox committed
1785
		$$ = pkglookup($3->name, $1->name);
1786
	}
1787

Russ Cox's avatar
bug133  
Russ Cox committed
1788 1789 1790 1791
hidden_pkg_importsym:
	hidden_importsym
	{
		$$ = $1;
Russ Cox's avatar
Russ Cox committed
1792
		structpkg = $$->package;
Russ Cox's avatar
Russ Cox committed
1793 1794
	}

1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816
hidden_import_list:
|	hidden_import_list hidden_import

hidden_funarg_list:
	hidden_dcl
	{
		$$ = list1($1);
	}
|	hidden_funarg_list ',' hidden_dcl
	{
		$$ = list($1, $3);
	}

hidden_structdcl_list:
	hidden_structdcl
	{
		$$ = list1($1);
	}
|	hidden_structdcl_list ';' hidden_structdcl
	{
		$$ = list($1, $3);
	}
1817

1818 1819 1820 1821 1822 1823 1824 1825 1826
hidden_interfacedcl_list:
	hidden_interfacedcl
	{
		$$ = list1($1);
	}
|	hidden_interfacedcl_list ';' hidden_interfacedcl
	{
		$$ = list($1, $3);
	}