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