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