github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/cmd/compile/internal/gc/parser.go (about) 1 // Copyright 2015 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 package gc 6 7 // The recursive-descent parser is built around a slighty modified grammar 8 // of Go to accomodate for the constraints imposed by strict one token look- 9 // ahead, and for better error handling. Subsequent checks of the constructed 10 // syntax tree restrict the language accepted by the compiler to proper Go. 11 // 12 // Semicolons are inserted by the lexer. The parser uses one-token look-ahead 13 // to handle optional commas and semicolons before a closing ) or } . 14 15 import ( 16 "fmt" 17 "strconv" 18 "strings" 19 ) 20 21 const trace = false // if set, parse tracing can be enabled with -x 22 23 // TODO(gri) Once we handle imports w/o redirecting the underlying 24 // source of the lexer we can get rid of these. They are here for 25 // compatibility with the existing yacc-based parser setup (issue 13242). 26 var thenewparser parser // the parser in use 27 var savedstate []parser // saved parser state, used during import 28 29 func push_parser() { 30 // Indentation (for tracing) must be preserved across parsers 31 // since we are changing the lexer source (and parser state) 32 // under foot, in the middle of productions. This won't be 33 // needed anymore once we fix issue 13242, but neither will 34 // be the push/pop_parser functionality. 35 // (Instead we could just use a global variable indent, but 36 // but eventually indent should be parser-specific anyway.) 37 indent := thenewparser.indent 38 savedstate = append(savedstate, thenewparser) 39 thenewparser = parser{indent: indent} // preserve indentation 40 thenewparser.next() 41 } 42 43 func pop_parser() { 44 indent := thenewparser.indent 45 n := len(savedstate) - 1 46 thenewparser = savedstate[n] 47 thenewparser.indent = indent // preserve indentation 48 savedstate = savedstate[:n] 49 } 50 51 // parse_file sets up a new parser and parses a single Go source file. 52 func parse_file() { 53 thenewparser = parser{} 54 thenewparser.loadsys() 55 thenewparser.next() 56 thenewparser.file() 57 } 58 59 // loadsys loads the definitions for the low-level runtime functions, 60 // so that the compiler can generate calls to them, 61 // but does not make the name "runtime" visible as a package. 62 func (p *parser) loadsys() { 63 if trace && Debug['x'] != 0 { 64 defer p.trace("loadsys")() 65 } 66 67 importpkg = Runtimepkg 68 69 if Debug['A'] != 0 { 70 cannedimports("runtime.Builtin", "package runtime\n\n$$\n\n") 71 } else { 72 cannedimports("runtime.Builtin", runtimeimport) 73 } 74 curio.importsafe = true 75 76 p.import_package() 77 p.import_there() 78 79 importpkg = nil 80 } 81 82 type parser struct { 83 tok int32 // next token (one-token look-ahead) 84 op Op // valid if tok == LASOP 85 val Val // valid if tok == LLITERAL 86 sym_ *Sym // valid if tok == LNAME 87 fnest int // function nesting level (for error handling) 88 xnest int // expression nesting level (for complit ambiguity resolution) 89 yy yySymType // for temporary use by next 90 indent []byte // tracing support 91 } 92 93 func (p *parser) next() { 94 p.tok = yylex(&p.yy) 95 p.op = p.yy.op 96 p.val = p.yy.val 97 p.sym_ = p.yy.sym 98 } 99 100 func (p *parser) got(tok int32) bool { 101 if p.tok == tok { 102 p.next() 103 return true 104 } 105 return false 106 } 107 108 func (p *parser) want(tok int32) { 109 if !p.got(tok) { 110 p.syntax_error("expecting " + tokstring(tok)) 111 p.advance() 112 } 113 } 114 115 // ---------------------------------------------------------------------------- 116 // Syntax error handling 117 118 func (p *parser) syntax_error(msg string) { 119 if trace && Debug['x'] != 0 { 120 defer p.trace("syntax_error (" + msg + ")")() 121 } 122 123 if p.tok == EOF && nerrors > 0 { 124 return // avoid meaningless follow-up errors 125 } 126 127 // add punctuation etc. as needed to msg 128 switch { 129 case msg == "": 130 // nothing to do 131 case strings.HasPrefix(msg, "in"), strings.HasPrefix(msg, "at"), strings.HasPrefix(msg, "after"): 132 msg = " " + msg 133 case strings.HasPrefix(msg, "expecting"): 134 msg = ", " + msg 135 default: 136 // plain error - we don't care about current token 137 Yyerror("syntax error: %s", msg) 138 return 139 } 140 141 // determine token string 142 var tok string 143 switch p.tok { 144 case LLITERAL: 145 // this is also done in Yyerror but it's cleaner to do it here 146 tok = litbuf 147 case LNAME: 148 if p.sym_ != nil && p.sym_.Name != "" { 149 tok = p.sym_.Name 150 } else { 151 tok = "name" 152 } 153 case LASOP: 154 tok = goopnames[p.op] + "=" 155 default: 156 tok = tokstring(p.tok) 157 } 158 159 Yyerror("syntax error: unexpected %s", tok+msg) 160 } 161 162 // Like syntax_error, but reports error at given line rather than current lexer line. 163 func (p *parser) syntax_error_at(lineno int32, msg string) { 164 defer func(lineno int32) { 165 lexlineno = lineno 166 }(lexlineno) 167 lexlineno = lineno 168 p.syntax_error(msg) 169 } 170 171 // The stoplist contains keywords that start a statement. 172 // They are good synchronization points in case of syntax 173 // errors and (usually) shouldn't be skipped over. 174 var stoplist = map[int32]bool{ 175 LBREAK: true, 176 LCONST: true, 177 LCONTINUE: true, 178 LDEFER: true, 179 LFALL: true, 180 LFOR: true, 181 LFUNC: true, 182 LGO: true, 183 LGOTO: true, 184 LIF: true, 185 LRETURN: true, 186 LSELECT: true, 187 LSWITCH: true, 188 LTYPE: true, 189 LVAR: true, 190 } 191 192 // Advance consumes tokens until it finds a token of the stop- or followlist. 193 // The stoplist is only considered if we are inside a function (p.fnest > 0). 194 // The followlist is the list of valid tokens that can follow a production; 195 // if it is empty, exactly one token is consumed to ensure progress. 196 func (p *parser) advance(followlist ...int32) { 197 if len(followlist) == 0 { 198 p.next() 199 return 200 } 201 for p.tok != EOF { 202 if p.fnest > 0 && stoplist[p.tok] { 203 return 204 } 205 for _, follow := range followlist { 206 if p.tok == follow { 207 return 208 } 209 } 210 p.next() 211 } 212 } 213 214 func tokstring(tok int32) string { 215 switch tok { 216 case EOF: 217 return "EOF" 218 case ',': 219 return "comma" 220 case ';': 221 return "semicolon or newline" 222 } 223 if 0 <= tok && tok < 128 { 224 // get invisibles properly backslashed 225 s := strconv.QuoteRune(tok) 226 if n := len(s); n > 0 && s[0] == '\'' && s[n-1] == '\'' { 227 s = s[1 : n-1] 228 } 229 return s 230 } 231 if s := tokstrings[tok]; s != "" { 232 return s 233 } 234 // catchall 235 return fmt.Sprintf("tok-%v", tok) 236 } 237 238 var tokstrings = map[int32]string{ 239 LLITERAL: "LLITERAL", 240 LASOP: "op=", 241 LCOLAS: ":=", 242 LBREAK: "break", 243 LCASE: "case", 244 LCHAN: "chan", 245 LCONST: "const", 246 LCONTINUE: "continue", 247 LDDD: "...", 248 LDEFAULT: "default", 249 LDEFER: "defer", 250 LELSE: "else", 251 LFALL: "fallthrough", 252 LFOR: "for", 253 LFUNC: "func", 254 LGO: "go", 255 LGOTO: "goto", 256 LIF: "if", 257 LIMPORT: "import", 258 LINTERFACE: "interface", 259 LMAP: "map", 260 LNAME: "LNAME", 261 LPACKAGE: "package", 262 LRANGE: "range", 263 LRETURN: "return", 264 LSELECT: "select", 265 LSTRUCT: "struct", 266 LSWITCH: "switch", 267 LTYPE: "type", 268 LVAR: "var", 269 LANDAND: "&&", 270 LANDNOT: "&^", 271 LCOMM: "<-", 272 LDEC: "--", 273 LEQ: "==", 274 LGE: ">=", 275 LGT: ">", 276 LIGNORE: "LIGNORE", // we should never see this one 277 LINC: "++", 278 LLE: "<=", 279 LLSH: "<<", 280 LLT: "<", 281 LNE: "!=", 282 LOROR: "||", 283 LRSH: ">>", 284 } 285 286 // usage: defer p.trace(msg)() 287 func (p *parser) trace(msg string) func() { 288 fmt.Printf("%5d: %s%s (\n", lineno, p.indent, msg) 289 const tab = ". " 290 p.indent = append(p.indent, tab...) 291 return func() { 292 p.indent = p.indent[:len(p.indent)-len(tab)] 293 if x := recover(); x != nil { 294 panic(x) // skip print_trace 295 } 296 fmt.Printf("%5d: %s)\n", lineno, p.indent) 297 } 298 } 299 300 // ---------------------------------------------------------------------------- 301 // Parsing package files 302 // 303 // Parse methods are annotated with matching Go productions as appropriate. 304 // The annotations are intended as guidelines only since a single Go grammar 305 // rule may be covered by multiple parse methods and vice versa. 306 307 // SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } . 308 func (p *parser) file() { 309 if trace && Debug['x'] != 0 { 310 defer p.trace("file")() 311 } 312 313 p.package_() 314 p.want(';') 315 316 for p.tok == LIMPORT { 317 p.import_() 318 p.want(';') 319 } 320 321 xtop = concat(xtop, p.xdcl_list()) 322 323 p.want(EOF) 324 } 325 326 // PackageClause = "package" PackageName . 327 // PackageName = identifier . 328 func (p *parser) package_() { 329 if trace && Debug['x'] != 0 { 330 defer p.trace("package_")() 331 } 332 333 if p.got(LPACKAGE) { 334 mkpackage(p.sym().Name) 335 } else { 336 prevlineno = lineno // see issue #13267 337 p.syntax_error("package statement must be first") 338 errorexit() 339 } 340 } 341 342 // ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) . 343 func (p *parser) import_() { 344 if trace && Debug['x'] != 0 { 345 defer p.trace("import_")() 346 } 347 348 p.want(LIMPORT) 349 if p.got('(') { 350 for p.tok != EOF && p.tok != ')' { 351 p.import_stmt() 352 if !p.osemi(')') { 353 break 354 } 355 } 356 p.want(')') 357 } else { 358 p.import_stmt() 359 } 360 } 361 362 func (p *parser) import_stmt() { 363 if trace && Debug['x'] != 0 { 364 defer p.trace("import_stmt")() 365 } 366 367 line := int32(p.import_here()) 368 if p.tok == LPACKAGE { 369 p.import_package() 370 p.import_there() 371 372 ipkg := importpkg 373 my := importmyname 374 importpkg = nil 375 importmyname = nil 376 377 if my == nil { 378 my = Lookup(ipkg.Name) 379 } 380 381 pack := Nod(OPACK, nil, nil) 382 pack.Sym = my 383 pack.Name.Pkg = ipkg 384 pack.Lineno = line 385 386 if strings.HasPrefix(my.Name, ".") { 387 importdot(ipkg, pack) 388 return 389 } 390 if my.Name == "init" { 391 lineno = line 392 Yyerror("cannot import package as init - init must be a func") 393 return 394 } 395 if my.Name == "_" { 396 return 397 } 398 if my.Def != nil { 399 lineno = line 400 redeclare(my, "as imported package name") 401 } 402 my.Def = pack 403 my.Lastlineno = line 404 my.Block = 1 // at top level 405 406 return 407 } 408 409 p.import_there() 410 // When an invalid import path is passed to importfile, 411 // it calls Yyerror and then sets up a fake import with 412 // no package statement. This allows us to test more 413 // than one invalid import statement in a single file. 414 if nerrors == 0 { 415 Fatalf("phase error in import") 416 } 417 } 418 419 // ImportSpec = [ "." | PackageName ] ImportPath . 420 // ImportPath = string_lit . 421 // 422 // import_here switches the underlying lexed source to the export data 423 // of the imported package. 424 func (p *parser) import_here() int { 425 if trace && Debug['x'] != 0 { 426 defer p.trace("import_here")() 427 } 428 429 importmyname = nil 430 switch p.tok { 431 case LNAME, '@', '?': 432 // import with given name 433 importmyname = p.sym() 434 435 case '.': 436 // import into my name space 437 importmyname = Lookup(".") 438 p.next() 439 } 440 441 var path Val 442 if p.tok == LLITERAL { 443 path = p.val 444 p.next() 445 } else { 446 p.syntax_error("missing import path; require quoted string") 447 p.advance(';', ')') 448 } 449 450 line := parserline() 451 importfile(&path, line) 452 return line 453 } 454 455 // import_package parses the header of an imported package as exported 456 // in textual format from another package. 457 func (p *parser) import_package() { 458 if trace && Debug['x'] != 0 { 459 defer p.trace("import_package")() 460 } 461 462 p.want(LPACKAGE) 463 var name string 464 if p.tok == LNAME { 465 name = p.sym_.Name 466 p.next() 467 } else { 468 p.import_error() 469 } 470 471 if p.tok == LNAME { 472 if p.sym_.Name == "safe" { 473 curio.importsafe = true 474 } 475 p.next() 476 } 477 p.want(';') 478 479 if importpkg.Name == "" { 480 importpkg.Name = name 481 numImport[name]++ 482 } else if importpkg.Name != name { 483 Yyerror("conflicting names %s and %s for package %q", importpkg.Name, name, importpkg.Path) 484 } 485 if incannedimport == 0 { 486 importpkg.Direct = true 487 } 488 importpkg.Safe = curio.importsafe 489 490 if safemode != 0 && !curio.importsafe { 491 Yyerror("cannot import unsafe package %q", importpkg.Path) 492 } 493 } 494 495 // import_there parses the imported package definitions and then switches 496 // the underlying lexed source back to the importing package. 497 func (p *parser) import_there() { 498 if trace && Debug['x'] != 0 { 499 defer p.trace("import_there")() 500 } 501 502 defercheckwidth() 503 504 p.hidden_import_list() 505 p.want('$') 506 // don't read past 2nd '$' 507 if p.tok != '$' { 508 p.import_error() 509 } 510 511 resumecheckwidth() 512 unimportfile() 513 } 514 515 // Declaration = ConstDecl | TypeDecl | VarDecl . 516 // ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) . 517 // TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) . 518 // VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) . 519 func (p *parser) common_dcl() *NodeList { 520 if trace && Debug['x'] != 0 { 521 defer p.trace("common_dcl")() 522 } 523 524 var dcl func() *NodeList 525 switch p.tok { 526 case LVAR: 527 dcl = p.vardcl 528 529 case LCONST: 530 iota_ = 0 531 dcl = p.constdcl 532 533 case LTYPE: 534 dcl = p.typedcl 535 536 default: 537 panic("unreachable") 538 } 539 540 p.next() 541 var l *NodeList 542 if p.got('(') { 543 for p.tok != EOF && p.tok != ')' { 544 l = concat(l, dcl()) 545 if !p.osemi(')') { 546 break 547 } 548 } 549 p.want(')') 550 } else { 551 l = dcl() 552 } 553 554 iota_ = -100000 555 lastconst = nil 556 557 return l 558 } 559 560 // VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) . 561 func (p *parser) vardcl() *NodeList { 562 if trace && Debug['x'] != 0 { 563 defer p.trace("vardcl")() 564 } 565 566 names := p.dcl_name_list() 567 var typ *Node 568 var exprs *NodeList 569 if p.got('=') { 570 exprs = p.expr_list() 571 } else { 572 typ = p.ntype() 573 if p.got('=') { 574 exprs = p.expr_list() 575 } 576 } 577 578 return variter(names, typ, exprs) 579 } 580 581 // ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . 582 func (p *parser) constdcl() *NodeList { 583 if trace && Debug['x'] != 0 { 584 defer p.trace("constdcl")() 585 } 586 587 names := p.dcl_name_list() 588 var typ *Node 589 var exprs *NodeList 590 if p.tok != EOF && p.tok != ';' && p.tok != ')' { 591 typ = p.try_ntype() 592 if p.got('=') { 593 exprs = p.expr_list() 594 } 595 } 596 597 return constiter(names, typ, exprs) 598 } 599 600 // TypeSpec = identifier Type . 601 func (p *parser) typedcl() *NodeList { 602 if trace && Debug['x'] != 0 { 603 defer p.trace("typedcl")() 604 } 605 606 name := typedcl0(p.sym()) 607 608 typ := p.try_ntype() 609 // handle case where type is missing 610 if typ == nil { 611 p.syntax_error("in type declaration") 612 p.advance(';', ')') 613 } 614 615 return list1(typedcl1(name, typ, true)) 616 } 617 618 // SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl . 619 // 620 // simple_stmt may return missing_stmt if labelOk is set. 621 func (p *parser) simple_stmt(labelOk, rangeOk bool) *Node { 622 if trace && Debug['x'] != 0 { 623 defer p.trace("simple_stmt")() 624 } 625 626 if rangeOk && p.got(LRANGE) { 627 // LRANGE expr 628 r := Nod(ORANGE, nil, p.expr()) 629 r.Etype = 0 // := flag 630 return r 631 } 632 633 lhs := p.expr_list() 634 635 if count(lhs) == 1 && p.tok != '=' && p.tok != LCOLAS && p.tok != LRANGE { 636 // expr 637 lhs := lhs.N 638 switch p.tok { 639 case LASOP: 640 // expr LASOP expr 641 op := p.op 642 p.next() 643 rhs := p.expr() 644 645 stmt := Nod(OASOP, lhs, rhs) 646 stmt.Etype = EType(op) // rathole to pass opcode 647 return stmt 648 649 case LINC: 650 // expr LINC 651 p.next() 652 653 stmt := Nod(OASOP, lhs, Nodintconst(1)) 654 stmt.Implicit = true 655 stmt.Etype = EType(OADD) 656 return stmt 657 658 case LDEC: 659 // expr LDEC 660 p.next() 661 662 stmt := Nod(OASOP, lhs, Nodintconst(1)) 663 stmt.Implicit = true 664 stmt.Etype = EType(OSUB) 665 return stmt 666 667 case ':': 668 // labelname ':' stmt 669 if labelOk { 670 // If we have a labelname, it was parsed by operand 671 // (calling p.name()) and given an ONAME, ONONAME, or OTYPE node. 672 if lhs.Op == ONAME || lhs.Op == ONONAME || lhs.Op == OTYPE { 673 lhs = newname(lhs.Sym) 674 } else { 675 p.syntax_error("expecting semicolon or newline or }") 676 // we already progressed, no need to advance 677 } 678 lhs := Nod(OLABEL, lhs, nil) 679 lhs.Sym = dclstack // context, for goto restrictions 680 p.next() // consume ':' after making label node for correct lineno 681 return p.labeled_stmt(lhs) 682 } 683 fallthrough 684 685 default: 686 // expr 687 // Since a bare name used as an expression is an error, 688 // introduce a wrapper node where necessary to give the 689 // correct line. 690 return wrapname(lhs) 691 } 692 } 693 694 // expr_list 695 switch p.tok { 696 case '=': 697 p.next() 698 if rangeOk && p.got(LRANGE) { 699 // expr_list '=' LRANGE expr 700 r := Nod(ORANGE, nil, p.expr()) 701 r.List = lhs 702 r.Etype = 0 // := flag 703 return r 704 } 705 706 // expr_list '=' expr_list 707 rhs := p.expr_list() 708 709 if lhs.Next == nil && rhs.Next == nil { 710 // simple 711 return Nod(OAS, lhs.N, rhs.N) 712 } 713 // multiple 714 stmt := Nod(OAS2, nil, nil) 715 stmt.List = lhs 716 stmt.Rlist = rhs 717 return stmt 718 719 case LCOLAS: 720 lno := lineno 721 p.next() 722 723 if rangeOk && p.got(LRANGE) { 724 // expr_list LCOLAS LRANGE expr 725 r := Nod(ORANGE, nil, p.expr()) 726 r.List = lhs 727 r.Colas = true 728 colasdefn(lhs, r) 729 return r 730 } 731 732 // expr_list LCOLAS expr_list 733 rhs := p.expr_list() 734 735 if rhs.N.Op == OTYPESW { 736 ts := Nod(OTYPESW, nil, rhs.N.Right) 737 if rhs.Next != nil { 738 Yyerror("expr.(type) must be alone in list") 739 } 740 if lhs.Next != nil { 741 Yyerror("argument count mismatch: %d = %d", count(lhs), 1) 742 } else if (lhs.N.Op != ONAME && lhs.N.Op != OTYPE && lhs.N.Op != ONONAME && (lhs.N.Op != OLITERAL || lhs.N.Name == nil)) || isblank(lhs.N) { 743 Yyerror("invalid variable name %s in type switch", lhs.N) 744 } else { 745 ts.Left = dclname(lhs.N.Sym) 746 } // it's a colas, so must not re-use an oldname 747 return ts 748 } 749 return colas(lhs, rhs, int32(lno)) 750 751 default: 752 p.syntax_error("expecting := or = or comma") 753 p.advance(';', '}') 754 return nil 755 } 756 } 757 758 // LabeledStmt = Label ":" Statement . 759 // Label = identifier . 760 func (p *parser) labeled_stmt(label *Node) *Node { 761 if trace && Debug['x'] != 0 { 762 defer p.trace("labeled_stmt")() 763 } 764 765 var ls *Node // labeled statement 766 if p.tok != '}' && p.tok != EOF { 767 ls = p.stmt() 768 if ls == missing_stmt { 769 // report error at line of ':' token 770 p.syntax_error_at(prevlineno, "missing statement after label") 771 // we are already at the end of the labeled statement - no need to advance 772 return missing_stmt 773 } 774 } 775 776 label.Name.Defn = ls 777 l := list1(label) 778 if ls != nil { 779 l = list(l, ls) 780 } 781 return liststmt(l) 782 } 783 784 // case_ parses a superset of switch and select statement cases. 785 // Later checks restrict the syntax to valid forms. 786 // 787 // ExprSwitchCase = "case" ExpressionList | "default" . 788 // TypeSwitchCase = "case" TypeList | "default" . 789 // TypeList = Type { "," Type } . 790 // CommCase = "case" ( SendStmt | RecvStmt ) | "default" . 791 // RecvStmt = [ ExpressionList "=" | IdentifierList ":=" ] RecvExpr . 792 // RecvExpr = Expression . 793 func (p *parser) case_(tswitch *Node) *Node { 794 if trace && Debug['x'] != 0 { 795 defer p.trace("case_")() 796 } 797 798 switch p.tok { 799 case LCASE: 800 p.next() 801 cases := p.expr_list() // expr_or_type_list 802 switch p.tok { 803 case ':': 804 // LCASE expr_or_type_list ':' 805 806 // will be converted to OCASE 807 // right will point to next case 808 // done in casebody() 809 markdcl() // matching popdcl in caseblock 810 stmt := Nod(OXCASE, nil, nil) 811 stmt.List = cases 812 if tswitch != nil { 813 if n := tswitch.Left; n != nil { 814 // type switch - declare variable 815 nn := newname(n.Sym) 816 declare(nn, dclcontext) 817 stmt.Rlist = list1(nn) 818 819 // keep track of the instances for reporting unused 820 nn.Name.Defn = tswitch 821 } 822 } 823 824 p.next() // consume ':' after declaring type switch var for correct lineno 825 return stmt 826 827 case '=': 828 // LCASE expr_or_type_list '=' expr ':' 829 p.next() 830 rhs := p.expr() 831 832 // will be converted to OCASE 833 // right will point to next case 834 // done in casebody() 835 markdcl() // matching popdcl in caseblock 836 stmt := Nod(OXCASE, nil, nil) 837 var n *Node 838 if cases.Next == nil { 839 n = Nod(OAS, cases.N, rhs) 840 } else { 841 n = Nod(OAS2, nil, nil) 842 n.List = cases 843 n.Rlist = list1(rhs) 844 } 845 stmt.List = list1(n) 846 847 p.want(':') // consume ':' after declaring select cases for correct lineno 848 return stmt 849 850 case LCOLAS: 851 // LCASE expr_or_type_list LCOLAS expr ':' 852 lno := lineno 853 p.next() 854 rhs := p.expr() 855 856 // will be converted to OCASE 857 // right will point to next case 858 // done in casebody() 859 markdcl() // matching popdcl in caseblock 860 stmt := Nod(OXCASE, nil, nil) 861 stmt.List = list1(colas(cases, list1(rhs), int32(lno))) 862 863 p.want(':') // consume ':' after declaring select cases for correct lineno 864 return stmt 865 866 default: 867 markdcl() // for matching popdcl in caseblock 868 stmt := Nod(OXCASE, nil, nil) // don't return nil 869 p.syntax_error("expecting := or = or : or comma") 870 p.advance(LCASE, LDEFAULT, '}') 871 return stmt 872 } 873 874 case LDEFAULT: 875 // LDEFAULT ':' 876 p.next() 877 878 markdcl() // matching popdcl in caseblock 879 stmt := Nod(OXCASE, nil, nil) 880 if tswitch != nil { 881 if n := tswitch.Left; n != nil { 882 // type switch - declare variable 883 nn := newname(n.Sym) 884 declare(nn, dclcontext) 885 stmt.Rlist = list1(nn) 886 887 // keep track of the instances for reporting unused 888 nn.Name.Defn = tswitch 889 } 890 } 891 892 p.want(':') // consume ':' after declaring type switch var for correct lineno 893 return stmt 894 895 default: 896 markdcl() // matching popdcl in caseblock 897 stmt := Nod(OXCASE, nil, nil) // don't return nil 898 p.syntax_error("expecting case or default or }") 899 p.advance(LCASE, LDEFAULT, '}') 900 return stmt 901 } 902 } 903 904 // Block = "{" StatementList "}" . 905 // StatementList = { Statement ";" } . 906 func (p *parser) compound_stmt(else_clause bool) *Node { 907 if trace && Debug['x'] != 0 { 908 defer p.trace("compound_stmt")() 909 } 910 911 markdcl() 912 if p.got('{') { 913 // ok 914 } else if else_clause { 915 p.syntax_error("else must be followed by if or statement block") 916 p.advance(LNAME, '}') 917 } else { 918 panic("unreachable") 919 } 920 921 l := p.stmt_list() 922 p.want('}') 923 924 var stmt *Node 925 if l == nil { 926 stmt = Nod(OEMPTY, nil, nil) 927 } else { 928 stmt = liststmt(l) 929 } 930 popdcl() 931 932 return stmt 933 } 934 935 // caseblock parses a superset of switch and select clauses. 936 // 937 // ExprCaseClause = ExprSwitchCase ":" StatementList . 938 // TypeCaseClause = TypeSwitchCase ":" StatementList . 939 // CommClause = CommCase ":" StatementList . 940 func (p *parser) caseblock(tswitch *Node) *Node { 941 if trace && Debug['x'] != 0 { 942 defer p.trace("caseblock")() 943 } 944 945 stmt := p.case_(tswitch) // does markdcl 946 stmt.Xoffset = int64(block) 947 stmt.Nbody = p.stmt_list() 948 949 popdcl() 950 951 return stmt 952 } 953 954 // caseblock_list parses a superset of switch and select clause lists. 955 func (p *parser) caseblock_list(tswitch *Node) (l *NodeList) { 956 if trace && Debug['x'] != 0 { 957 defer p.trace("caseblock_list")() 958 } 959 960 if !p.got('{') { 961 p.syntax_error("missing { after switch clause") 962 p.advance(LCASE, LDEFAULT, '}') 963 } 964 965 for p.tok != EOF && p.tok != '}' { 966 l = list(l, p.caseblock(tswitch)) 967 } 968 p.want('}') 969 return 970 } 971 972 // loop_body parses if and for statement bodies. 973 func (p *parser) loop_body(context string) *NodeList { 974 if trace && Debug['x'] != 0 { 975 defer p.trace("loop_body")() 976 } 977 978 markdcl() 979 if !p.got('{') { 980 p.syntax_error("missing { after " + context) 981 p.advance(LNAME, '}') 982 } 983 984 body := p.stmt_list() 985 popdcl() 986 p.want('}') 987 988 return body 989 } 990 991 // for_header parses the header portion of a for statement. 992 // 993 // ForStmt = "for" [ Condition | ForClause | RangeClause ] Block . 994 // Condition = Expression . 995 func (p *parser) for_header() *Node { 996 if trace && Debug['x'] != 0 { 997 defer p.trace("for_header")() 998 } 999 1000 init, cond, post := p.header(true) 1001 1002 if init != nil || post != nil { 1003 // init ; test ; incr 1004 if post != nil && post.Colas { 1005 Yyerror("cannot declare in the for-increment") 1006 } 1007 h := Nod(OFOR, nil, nil) 1008 if init != nil { 1009 h.Ninit = list1(init) 1010 } 1011 h.Left = cond 1012 h.Right = post 1013 return h 1014 } 1015 1016 if cond != nil && cond.Op == ORANGE { 1017 // range_stmt - handled by pexpr 1018 return cond 1019 } 1020 1021 // normal test 1022 h := Nod(OFOR, nil, nil) 1023 h.Left = cond 1024 return h 1025 } 1026 1027 func (p *parser) for_body() *Node { 1028 if trace && Debug['x'] != 0 { 1029 defer p.trace("for_body")() 1030 } 1031 1032 stmt := p.for_header() 1033 body := p.loop_body("for clause") 1034 1035 stmt.Nbody = concat(stmt.Nbody, body) 1036 return stmt 1037 } 1038 1039 // ForStmt = "for" [ Condition | ForClause | RangeClause ] Block . 1040 func (p *parser) for_stmt() *Node { 1041 if trace && Debug['x'] != 0 { 1042 defer p.trace("for_stmt")() 1043 } 1044 1045 p.want(LFOR) 1046 markdcl() 1047 body := p.for_body() 1048 popdcl() 1049 1050 return body 1051 } 1052 1053 // header parses a combination of if, switch, and for statement headers: 1054 // 1055 // Header = [ InitStmt ";" ] [ Expression ] . 1056 // Header = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] . // for_stmt only 1057 // InitStmt = SimpleStmt . 1058 // PostStmt = SimpleStmt . 1059 func (p *parser) header(for_stmt bool) (init, cond, post *Node) { 1060 if p.tok == '{' { 1061 return 1062 } 1063 1064 outer := p.xnest 1065 p.xnest = -1 1066 1067 if p.tok != ';' { 1068 // accept potential vardcl but complain 1069 // (for test/syntax/forvar.go) 1070 if for_stmt && p.tok == LVAR { 1071 Yyerror("var declaration not allowed in for initializer") 1072 p.next() 1073 } 1074 init = p.simple_stmt(false, for_stmt) 1075 // If we have a range clause, we are done. 1076 if for_stmt && init.Op == ORANGE { 1077 cond = init 1078 init = nil 1079 1080 p.xnest = outer 1081 return 1082 } 1083 } 1084 if p.got(';') { 1085 if for_stmt { 1086 if p.tok != ';' { 1087 cond = p.simple_stmt(false, false) 1088 } 1089 p.want(';') 1090 if p.tok != '{' { 1091 post = p.simple_stmt(false, false) 1092 } 1093 } else if p.tok != '{' { 1094 cond = p.simple_stmt(false, false) 1095 } 1096 } else { 1097 cond = init 1098 init = nil 1099 } 1100 1101 p.xnest = outer 1102 return 1103 } 1104 1105 func (p *parser) if_header() *Node { 1106 if trace && Debug['x'] != 0 { 1107 defer p.trace("if_header")() 1108 } 1109 1110 init, cond, _ := p.header(false) 1111 h := Nod(OIF, nil, nil) 1112 h.Ninit = list1(init) 1113 h.Left = cond 1114 return h 1115 } 1116 1117 // IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] . 1118 func (p *parser) if_stmt() *Node { 1119 if trace && Debug['x'] != 0 { 1120 defer p.trace("if_stmt")() 1121 } 1122 1123 p.want(LIF) 1124 1125 markdcl() 1126 1127 stmt := p.if_header() 1128 if stmt.Left == nil { 1129 Yyerror("missing condition in if statement") 1130 } 1131 1132 stmt.Nbody = p.loop_body("if clause") 1133 1134 l := p.elseif_list_else() // does markdcl 1135 1136 n := stmt 1137 popdcl() 1138 for nn := l; nn != nil; nn = nn.Next { 1139 if nn.N.Op == OIF { 1140 popdcl() 1141 } 1142 n.Rlist = list1(nn.N) 1143 n = nn.N 1144 } 1145 1146 return stmt 1147 } 1148 1149 func (p *parser) elseif() *NodeList { 1150 if trace && Debug['x'] != 0 { 1151 defer p.trace("elseif")() 1152 } 1153 1154 // LELSE LIF already consumed 1155 markdcl() // matching popdcl in if_stmt 1156 1157 stmt := p.if_header() 1158 if stmt.Left == nil { 1159 Yyerror("missing condition in if statement") 1160 } 1161 1162 stmt.Nbody = p.loop_body("if clause") 1163 1164 return list1(stmt) 1165 } 1166 1167 func (p *parser) elseif_list_else() (l *NodeList) { 1168 if trace && Debug['x'] != 0 { 1169 defer p.trace("elseif_list_else")() 1170 } 1171 1172 for p.got(LELSE) { 1173 if p.got(LIF) { 1174 l = concat(l, p.elseif()) 1175 } else { 1176 l = concat(l, p.else_()) 1177 break 1178 } 1179 } 1180 1181 return l 1182 } 1183 1184 func (p *parser) else_() *NodeList { 1185 if trace && Debug['x'] != 0 { 1186 defer p.trace("else")() 1187 } 1188 1189 l := &NodeList{N: p.compound_stmt(true)} 1190 l.End = l 1191 return l 1192 1193 } 1194 1195 // switch_stmt parses both expression and type switch statements. 1196 // 1197 // SwitchStmt = ExprSwitchStmt | TypeSwitchStmt . 1198 // ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" . 1199 // TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" . 1200 func (p *parser) switch_stmt() *Node { 1201 if trace && Debug['x'] != 0 { 1202 defer p.trace("switch_stmt")() 1203 } 1204 1205 p.want(LSWITCH) 1206 markdcl() 1207 1208 hdr := p.if_header() 1209 hdr.Op = OSWITCH 1210 1211 tswitch := hdr.Left 1212 if tswitch != nil && tswitch.Op != OTYPESW { 1213 tswitch = nil 1214 } 1215 1216 hdr.List = p.caseblock_list(tswitch) 1217 popdcl() 1218 1219 return hdr 1220 } 1221 1222 // SelectStmt = "select" "{" { CommClause } "}" . 1223 func (p *parser) select_stmt() *Node { 1224 if trace && Debug['x'] != 0 { 1225 defer p.trace("select_stmt")() 1226 } 1227 1228 p.want(LSELECT) 1229 hdr := Nod(OSELECT, nil, nil) 1230 hdr.List = p.caseblock_list(nil) 1231 return hdr 1232 } 1233 1234 // TODO(gri) should have lexer return this info - no need for separate lookup 1235 // (issue 13244) 1236 var prectab = map[int32]struct { 1237 prec int // > 0 (0 indicates not found) 1238 op Op 1239 }{ 1240 // not an expression anymore, but left in so we can give a good error 1241 // message when used in expression context 1242 LCOMM: {1, OSEND}, 1243 1244 LOROR: {2, OOROR}, 1245 1246 LANDAND: {3, OANDAND}, 1247 1248 LEQ: {4, OEQ}, 1249 LNE: {4, ONE}, 1250 LLE: {4, OLE}, 1251 LGE: {4, OGE}, 1252 LLT: {4, OLT}, 1253 LGT: {4, OGT}, 1254 1255 '+': {5, OADD}, 1256 '-': {5, OSUB}, 1257 '|': {5, OOR}, 1258 '^': {5, OXOR}, 1259 1260 '*': {6, OMUL}, 1261 '/': {6, ODIV}, 1262 '%': {6, OMOD}, 1263 '&': {6, OAND}, 1264 LLSH: {6, OLSH}, 1265 LRSH: {6, ORSH}, 1266 LANDNOT: {6, OANDNOT}, 1267 } 1268 1269 // Expression = UnaryExpr | Expression binary_op Expression . 1270 func (p *parser) bexpr(prec int) *Node { 1271 // don't trace bexpr - only leads to overly nested trace output 1272 1273 x := p.uexpr() 1274 t := prectab[p.tok] 1275 for tprec := t.prec; tprec >= prec; tprec-- { 1276 for tprec == prec { 1277 p.next() 1278 y := p.bexpr(t.prec + 1) 1279 x = Nod(t.op, x, y) 1280 t = prectab[p.tok] 1281 tprec = t.prec 1282 } 1283 } 1284 return x 1285 } 1286 1287 func (p *parser) expr() *Node { 1288 if trace && Debug['x'] != 0 { 1289 defer p.trace("expr")() 1290 } 1291 1292 return p.bexpr(1) 1293 } 1294 1295 func unparen(x *Node) *Node { 1296 for x.Op == OPAREN { 1297 x = x.Left 1298 } 1299 return x 1300 } 1301 1302 // UnaryExpr = PrimaryExpr | unary_op UnaryExpr . 1303 func (p *parser) uexpr() *Node { 1304 if trace && Debug['x'] != 0 { 1305 defer p.trace("uexpr")() 1306 } 1307 1308 var op Op 1309 switch p.tok { 1310 case '*': 1311 op = OIND 1312 1313 case '&': 1314 p.next() 1315 // uexpr may have returned a parenthesized composite literal 1316 // (see comment in operand) - remove parentheses if any 1317 x := unparen(p.uexpr()) 1318 if x.Op == OCOMPLIT { 1319 // Special case for &T{...}: turn into (*T){...}. 1320 x.Right = Nod(OIND, x.Right, nil) 1321 x.Right.Implicit = true 1322 } else { 1323 x = Nod(OADDR, x, nil) 1324 } 1325 return x 1326 1327 case '+': 1328 op = OPLUS 1329 1330 case '-': 1331 op = OMINUS 1332 1333 case '!': 1334 op = ONOT 1335 1336 case '~': 1337 // TODO(gri) do this in the lexer instead (issue 13244) 1338 p.next() 1339 x := p.uexpr() 1340 Yyerror("the bitwise complement operator is ^") 1341 return Nod(OCOM, x, nil) 1342 1343 case '^': 1344 op = OCOM 1345 1346 case LCOMM: 1347 // receive op (<-x) or receive-only channel (<-chan E) 1348 p.next() 1349 1350 // If the next token is LCHAN we still don't know if it is 1351 // a channel (<-chan int) or a receive op (<-chan int(ch)). 1352 // We only know once we have found the end of the uexpr. 1353 1354 x := p.uexpr() 1355 1356 // There are two cases: 1357 // 1358 // <-chan... => <-x is a channel type 1359 // <-x => <-x is a receive operation 1360 // 1361 // In the first case, <- must be re-associated with 1362 // the channel type parsed already: 1363 // 1364 // <-(chan E) => (<-chan E) 1365 // <-(chan<-E) => (<-chan (<-E)) 1366 1367 if x.Op == OTCHAN { 1368 // x is a channel type => re-associate <- 1369 dir := EType(Csend) 1370 t := x 1371 for ; t.Op == OTCHAN && dir == Csend; t = t.Left { 1372 dir = t.Etype 1373 if dir == Crecv { 1374 // t is type <-chan E but <-<-chan E is not permitted 1375 // (report same error as for "type _ <-<-chan E") 1376 p.syntax_error("unexpected <-, expecting chan") 1377 // already progressed, no need to advance 1378 } 1379 t.Etype = Crecv 1380 } 1381 if dir == Csend { 1382 // channel dir is <- but channel element E is not a channel 1383 // (report same error as for "type _ <-chan<-E") 1384 p.syntax_error(fmt.Sprintf("unexpected %v, expecting chan", t)) 1385 // already progressed, no need to advance 1386 } 1387 return x 1388 } 1389 1390 // x is not a channel type => we have a receive op 1391 return Nod(ORECV, x, nil) 1392 1393 default: 1394 return p.pexpr(false) 1395 } 1396 1397 // simple uexpr 1398 p.next() 1399 return Nod(op, p.uexpr(), nil) 1400 } 1401 1402 // pseudocall parses call-like statements that can be preceded by 'defer' and 'go'. 1403 func (p *parser) pseudocall() *Node { 1404 if trace && Debug['x'] != 0 { 1405 defer p.trace("pseudocall")() 1406 } 1407 1408 x := p.pexpr(p.tok == '(') // keep_parens so we can report error below 1409 switch x.Op { 1410 case OCALL: 1411 return x 1412 case OPAREN: 1413 Yyerror("expression in go/defer must not be parenthesized") 1414 // already progressed, no need to advance 1415 default: 1416 Yyerror("expression in go/defer must be function call") 1417 // already progressed, no need to advance 1418 } 1419 return nil 1420 } 1421 1422 // Operand = Literal | OperandName | MethodExpr | "(" Expression ")" . 1423 // Literal = BasicLit | CompositeLit | FunctionLit . 1424 // BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit . 1425 // OperandName = identifier | QualifiedIdent. 1426 func (p *parser) operand(keep_parens bool) *Node { 1427 if trace && Debug['x'] != 0 { 1428 defer p.trace("operand")() 1429 } 1430 1431 switch p.tok { 1432 case LLITERAL: 1433 x := nodlit(p.val) 1434 p.next() 1435 return x 1436 1437 case LNAME, '@', '?': 1438 return p.name() 1439 1440 case '(': 1441 p.next() 1442 p.xnest++ 1443 x := p.expr() // expr_or_type 1444 p.xnest-- 1445 p.want(')') 1446 1447 // Optimization: Record presence of ()'s only where needed 1448 // for error reporting. Don't bother in other cases; it is 1449 // just a waste of memory and time. 1450 1451 // Parentheses are not permitted on lhs of := . 1452 switch x.Op { 1453 case ONAME, ONONAME, OPACK, OTYPE, OLITERAL, OTYPESW: 1454 keep_parens = true 1455 } 1456 1457 // Parentheses are not permitted around T in a composite 1458 // literal T{}. If the next token is a {, assume x is a 1459 // composite literal type T (it may not be, { could be 1460 // the opening brace of a block, but we don't know yet). 1461 if p.tok == '{' { 1462 keep_parens = true 1463 } 1464 1465 // Parentheses are also not permitted around the expression 1466 // in a go/defer statement. In that case, operand is called 1467 // with keep_parens set. 1468 if keep_parens { 1469 x = Nod(OPAREN, x, nil) 1470 } 1471 return x 1472 1473 case LFUNC: 1474 t := p.ntype() // fntype 1475 if p.tok == '{' { 1476 // fnlitdcl 1477 closurehdr(t) 1478 // fnliteral 1479 p.next() // consume '{' 1480 p.fnest++ 1481 p.xnest++ 1482 body := p.stmt_list() 1483 p.xnest-- 1484 p.fnest-- 1485 p.want('}') 1486 return closurebody(body) 1487 } 1488 return t 1489 1490 case '[', LCHAN, LMAP, LSTRUCT, LINTERFACE: 1491 return p.ntype() // othertype 1492 1493 case '{': 1494 // common case: p.header is missing simple_stmt before { in if, for, switch 1495 p.syntax_error("missing operand") 1496 // '{' will be consumed in pexpr - no need to consume it here 1497 return nil 1498 1499 default: 1500 p.syntax_error("expecting expression") 1501 p.advance() 1502 return nil 1503 } 1504 1505 // Syntactically, composite literals are operands. Because a complit 1506 // type may be a qualified identifier which is handled by pexpr 1507 // (together with selector expressions), complits are parsed there 1508 // as well (operand is only called from pexpr). 1509 } 1510 1511 // PrimaryExpr = 1512 // Operand | 1513 // Conversion | 1514 // PrimaryExpr Selector | 1515 // PrimaryExpr Index | 1516 // PrimaryExpr Slice | 1517 // PrimaryExpr TypeAssertion | 1518 // PrimaryExpr Arguments . 1519 // 1520 // Selector = "." identifier . 1521 // Index = "[" Expression "]" . 1522 // Slice = "[" ( [ Expression ] ":" [ Expression ] ) | 1523 // ( [ Expression ] ":" Expression ":" Expression ) 1524 // "]" . 1525 // TypeAssertion = "." "(" Type ")" . 1526 // Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" . 1527 func (p *parser) pexpr(keep_parens bool) *Node { 1528 if trace && Debug['x'] != 0 { 1529 defer p.trace("pexpr")() 1530 } 1531 1532 x := p.operand(keep_parens) 1533 1534 loop: 1535 for { 1536 switch p.tok { 1537 case '.': 1538 p.next() 1539 switch p.tok { 1540 case LNAME, '@', '?': 1541 // pexpr '.' sym 1542 x = p.new_dotname(x) 1543 1544 case '(': 1545 p.next() 1546 switch p.tok { 1547 default: 1548 // pexpr '.' '(' expr_or_type ')' 1549 t := p.expr() // expr_or_type 1550 p.want(')') 1551 x = Nod(ODOTTYPE, x, t) 1552 1553 case LTYPE: 1554 // pexpr '.' '(' LTYPE ')' 1555 p.next() 1556 p.want(')') 1557 x = Nod(OTYPESW, nil, x) 1558 } 1559 1560 default: 1561 p.syntax_error("expecting name or (") 1562 p.advance(';', '}') 1563 } 1564 1565 case '[': 1566 p.next() 1567 p.xnest++ 1568 var index [3]*Node 1569 if p.tok != ':' { 1570 index[0] = p.expr() 1571 } 1572 ncol := 0 1573 for ncol < len(index)-1 && p.got(':') { 1574 ncol++ 1575 if p.tok != EOF && p.tok != ':' && p.tok != ']' { 1576 index[ncol] = p.expr() 1577 } 1578 } 1579 p.xnest-- 1580 p.want(']') 1581 1582 switch ncol { 1583 case 0: 1584 i := index[0] 1585 if i == nil { 1586 Yyerror("missing index in index expression") 1587 } 1588 x = Nod(OINDEX, x, i) 1589 case 1: 1590 i := index[0] 1591 j := index[1] 1592 x = Nod(OSLICE, x, Nod(OKEY, i, j)) 1593 case 2: 1594 i := index[0] 1595 j := index[1] 1596 k := index[2] 1597 if j == nil { 1598 Yyerror("middle index required in 3-index slice") 1599 } 1600 if k == nil { 1601 Yyerror("final index required in 3-index slice") 1602 } 1603 x = Nod(OSLICE3, x, Nod(OKEY, i, Nod(OKEY, j, k))) 1604 1605 default: 1606 panic("unreachable") 1607 } 1608 1609 case '(': 1610 // convtype '(' expr ocomma ')' 1611 args, ddd := p.arg_list() 1612 1613 // call or conversion 1614 x = Nod(OCALL, x, nil) 1615 x.List = args 1616 x.Isddd = ddd 1617 1618 case '{': 1619 // operand may have returned a parenthesized complit 1620 // type; accept it but complain if we have a complit 1621 t := unparen(x) 1622 // determine if '{' belongs to a complit or a compound_stmt 1623 complit_ok := false 1624 switch t.Op { 1625 case ONAME, ONONAME, OTYPE, OPACK, OXDOT, ODOT: 1626 if p.xnest >= 0 { 1627 // x is considered a comptype 1628 complit_ok = true 1629 } 1630 case OTARRAY, OTSTRUCT, OTMAP: 1631 // x is a comptype 1632 complit_ok = true 1633 } 1634 if !complit_ok { 1635 break loop 1636 } 1637 if t != x { 1638 p.syntax_error("cannot parenthesize type in composite literal") 1639 // already progressed, no need to advance 1640 } 1641 n := p.complitexpr() 1642 n.Right = x 1643 x = n 1644 1645 default: 1646 break loop 1647 } 1648 } 1649 1650 return x 1651 } 1652 1653 // KeyedElement = [ Key ":" ] Element . 1654 func (p *parser) keyval() *Node { 1655 if trace && Debug['x'] != 0 { 1656 defer p.trace("keyval")() 1657 } 1658 1659 // A composite literal commonly spans several lines, 1660 // so the line number on errors may be misleading. 1661 // Wrap values (but not keys!) that don't carry line 1662 // numbers. 1663 1664 x := p.bare_complitexpr() 1665 1666 if p.got(':') { 1667 // key ':' value 1668 return Nod(OKEY, x, wrapname(p.bare_complitexpr())) 1669 } 1670 1671 // value 1672 return wrapname(x) 1673 } 1674 1675 func wrapname(x *Node) *Node { 1676 // These nodes do not carry line numbers. 1677 // Introduce a wrapper node to give the correct line. 1678 switch x.Op { 1679 case ONAME, ONONAME, OTYPE, OPACK, OLITERAL: 1680 x = Nod(OPAREN, x, nil) 1681 x.Implicit = true 1682 } 1683 return x 1684 } 1685 1686 // Element = Expression | LiteralValue . 1687 func (p *parser) bare_complitexpr() *Node { 1688 if trace && Debug['x'] != 0 { 1689 defer p.trace("bare_complitexpr")() 1690 } 1691 1692 if p.tok == '{' { 1693 // '{' start_complit braced_keyval_list '}' 1694 return p.complitexpr() 1695 } 1696 1697 return p.expr() 1698 } 1699 1700 // LiteralValue = "{" [ ElementList [ "," ] ] "}" . 1701 func (p *parser) complitexpr() *Node { 1702 if trace && Debug['x'] != 0 { 1703 defer p.trace("complitexpr")() 1704 } 1705 1706 // make node early so we get the right line number 1707 n := Nod(OCOMPLIT, nil, nil) 1708 1709 p.want('{') 1710 p.xnest++ 1711 1712 var l *NodeList 1713 for p.tok != EOF && p.tok != '}' { 1714 l = list(l, p.keyval()) 1715 if !p.ocomma('}') { 1716 break 1717 } 1718 } 1719 1720 p.xnest-- 1721 p.want('}') 1722 1723 n.List = l 1724 return n 1725 } 1726 1727 // names and types 1728 // newname is used before declared 1729 // oldname is used after declared 1730 func (p *parser) new_name(sym *Sym) *Node { 1731 if trace && Debug['x'] != 0 { 1732 defer p.trace("new_name")() 1733 } 1734 1735 if sym != nil { 1736 return newname(sym) 1737 } 1738 return nil 1739 } 1740 1741 func (p *parser) onew_name() *Node { 1742 if trace && Debug['x'] != 0 { 1743 defer p.trace("onew_name")() 1744 } 1745 1746 switch p.tok { 1747 case LNAME, '@', '?': 1748 return p.new_name(p.sym()) 1749 } 1750 return nil 1751 } 1752 1753 func (p *parser) sym() *Sym { 1754 switch p.tok { 1755 case LNAME: 1756 s := p.sym_ 1757 p.next() 1758 // during imports, unqualified non-exported identifiers are from builtinpkg 1759 if importpkg != nil && !exportname(s.Name) { 1760 s = Pkglookup(s.Name, builtinpkg) 1761 } 1762 return s 1763 1764 case '@': 1765 return p.hidden_importsym() 1766 1767 case '?': 1768 p.next() 1769 return nil 1770 1771 default: 1772 p.syntax_error("expecting name") 1773 p.advance() 1774 return new(Sym) 1775 } 1776 } 1777 1778 func mkname(sym *Sym) *Node { 1779 n := oldname(sym) 1780 if n.Name != nil && n.Name.Pack != nil { 1781 n.Name.Pack.Used = true 1782 } 1783 return n 1784 } 1785 1786 func (p *parser) name() *Node { 1787 if trace && Debug['x'] != 0 { 1788 defer p.trace("name")() 1789 } 1790 1791 return mkname(p.sym()) 1792 } 1793 1794 // [ "..." ] Type 1795 func (p *parser) dotdotdot() *Node { 1796 if trace && Debug['x'] != 0 { 1797 defer p.trace("dotdotdot")() 1798 } 1799 1800 p.want(LDDD) 1801 if typ := p.try_ntype(); typ != nil { 1802 return Nod(ODDD, typ, nil) 1803 } 1804 1805 Yyerror("final argument in variadic function missing type") 1806 return Nod(ODDD, typenod(typ(TINTER)), nil) 1807 } 1808 1809 func (p *parser) ntype() *Node { 1810 if trace && Debug['x'] != 0 { 1811 defer p.trace("ntype")() 1812 } 1813 1814 if typ := p.try_ntype(); typ != nil { 1815 return typ 1816 } 1817 1818 p.syntax_error("") 1819 p.advance() 1820 return nil 1821 } 1822 1823 // try_ntype is like ntype but it returns nil if there was no type 1824 // instead of reporting an error. 1825 // 1826 // Type = TypeName | TypeLit | "(" Type ")" . 1827 // TypeName = identifier | QualifiedIdent . 1828 // TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType | 1829 // SliceType | MapType | ChannelType . 1830 func (p *parser) try_ntype() *Node { 1831 if trace && Debug['x'] != 0 { 1832 defer p.trace("try_ntype")() 1833 } 1834 1835 switch p.tok { 1836 case LCOMM: 1837 // recvchantype 1838 p.next() 1839 p.want(LCHAN) 1840 t := Nod(OTCHAN, p.chan_elem(), nil) 1841 t.Etype = Crecv 1842 return t 1843 1844 case LFUNC: 1845 // fntype 1846 p.next() 1847 params := p.param_list() 1848 result := p.fnres() 1849 params = checkarglist(params, 1) 1850 t := Nod(OTFUNC, nil, nil) 1851 t.List = params 1852 t.Rlist = result 1853 return t 1854 1855 case '[': 1856 // '[' oexpr ']' ntype 1857 // '[' LDDD ']' ntype 1858 p.next() 1859 p.xnest++ 1860 var len *Node 1861 if p.tok != ']' { 1862 if p.got(LDDD) { 1863 len = Nod(ODDD, nil, nil) 1864 } else { 1865 len = p.expr() 1866 } 1867 } 1868 p.xnest-- 1869 p.want(']') 1870 return Nod(OTARRAY, len, p.ntype()) 1871 1872 case LCHAN: 1873 // LCHAN non_recvchantype 1874 // LCHAN LCOMM ntype 1875 p.next() 1876 var dir EType = Cboth 1877 if p.got(LCOMM) { 1878 dir = Csend 1879 } 1880 t := Nod(OTCHAN, p.chan_elem(), nil) 1881 t.Etype = dir 1882 return t 1883 1884 case LMAP: 1885 // LMAP '[' ntype ']' ntype 1886 p.next() 1887 p.want('[') 1888 key := p.ntype() 1889 p.want(']') 1890 val := p.ntype() 1891 return Nod(OTMAP, key, val) 1892 1893 case LSTRUCT: 1894 return p.structtype() 1895 1896 case LINTERFACE: 1897 return p.interfacetype() 1898 1899 case '*': 1900 // ptrtype 1901 p.next() 1902 return Nod(OIND, p.ntype(), nil) 1903 1904 case LNAME, '@', '?': 1905 return p.dotname() 1906 1907 case '(': 1908 p.next() 1909 t := p.ntype() 1910 p.want(')') 1911 return t 1912 1913 default: 1914 return nil 1915 } 1916 } 1917 1918 func (p *parser) chan_elem() *Node { 1919 if trace && Debug['x'] != 0 { 1920 defer p.trace("chan_elem")() 1921 } 1922 1923 if typ := p.try_ntype(); typ != nil { 1924 return typ 1925 } 1926 1927 p.syntax_error("missing channel element type") 1928 // assume element type is simply absent - don't advance 1929 return nil 1930 } 1931 1932 func (p *parser) new_dotname(pkg *Node) *Node { 1933 if trace && Debug['x'] != 0 { 1934 defer p.trace("new_dotname")() 1935 } 1936 1937 sel := p.sym() 1938 if pkg.Op == OPACK { 1939 s := restrictlookup(sel.Name, pkg.Name.Pkg) 1940 pkg.Used = true 1941 return oldname(s) 1942 } 1943 return Nod(OXDOT, pkg, newname(sel)) 1944 1945 } 1946 1947 func (p *parser) dotname() *Node { 1948 if trace && Debug['x'] != 0 { 1949 defer p.trace("dotname")() 1950 } 1951 1952 name := p.name() 1953 if p.got('.') { 1954 return p.new_dotname(name) 1955 } 1956 return name 1957 } 1958 1959 // StructType = "struct" "{" { FieldDecl ";" } "}" . 1960 func (p *parser) structtype() *Node { 1961 if trace && Debug['x'] != 0 { 1962 defer p.trace("structtype")() 1963 } 1964 1965 p.want(LSTRUCT) 1966 p.want('{') 1967 var l *NodeList 1968 for p.tok != EOF && p.tok != '}' { 1969 l = concat(l, p.structdcl()) 1970 if !p.osemi('}') { 1971 break 1972 } 1973 } 1974 p.want('}') 1975 1976 t := Nod(OTSTRUCT, nil, nil) 1977 t.List = l 1978 return t 1979 } 1980 1981 // InterfaceType = "interface" "{" { MethodSpec ";" } "}" . 1982 func (p *parser) interfacetype() *Node { 1983 if trace && Debug['x'] != 0 { 1984 defer p.trace("interfacetype")() 1985 } 1986 1987 p.want(LINTERFACE) 1988 p.want('{') 1989 var l *NodeList 1990 for p.tok != EOF && p.tok != '}' { 1991 l = list(l, p.interfacedcl()) 1992 if !p.osemi('}') { 1993 break 1994 } 1995 } 1996 p.want('}') 1997 1998 t := Nod(OTINTER, nil, nil) 1999 t.List = l 2000 return t 2001 } 2002 2003 // Function stuff. 2004 // All in one place to show how crappy it all is. 2005 2006 func (p *parser) xfndcl() *Node { 2007 if trace && Debug['x'] != 0 { 2008 defer p.trace("xfndcl")() 2009 } 2010 2011 p.want(LFUNC) 2012 f := p.fndcl() 2013 body := p.fnbody() 2014 2015 if f == nil { 2016 return nil 2017 } 2018 if noescape && body != nil { 2019 Yyerror("can only use //go:noescape with external func implementations") 2020 } 2021 2022 f.Nbody = body 2023 f.Func.Endlineno = lineno 2024 f.Noescape = noescape 2025 f.Func.Norace = norace 2026 f.Func.Nosplit = nosplit 2027 f.Func.Noinline = noinline 2028 f.Func.Nowritebarrier = nowritebarrier 2029 f.Func.Nowritebarrierrec = nowritebarrierrec 2030 f.Func.Systemstack = systemstack 2031 funcbody(f) 2032 2033 return f 2034 } 2035 2036 // FunctionDecl = "func" FunctionName ( Function | Signature ) . 2037 // FunctionName = identifier . 2038 // Function = Signature FunctionBody . 2039 // MethodDecl = "func" Receiver MethodName ( Function | Signature ) . 2040 // Receiver = Parameters . 2041 func (p *parser) fndcl() *Node { 2042 if trace && Debug['x'] != 0 { 2043 defer p.trace("fndcl")() 2044 } 2045 2046 switch p.tok { 2047 case LNAME, '@', '?': 2048 // sym '(' oarg_type_list_ocomma ')' fnres 2049 name := p.sym() 2050 params := p.param_list() 2051 result := p.fnres() 2052 2053 params = checkarglist(params, 1) 2054 2055 if name.Name == "init" { 2056 name = renameinit() 2057 if params != nil || result != nil { 2058 Yyerror("func init must have no arguments and no return values") 2059 } 2060 } 2061 2062 if localpkg.Name == "main" && name.Name == "main" { 2063 if params != nil || result != nil { 2064 Yyerror("func main must have no arguments and no return values") 2065 } 2066 } 2067 2068 t := Nod(OTFUNC, nil, nil) 2069 t.List = params 2070 t.Rlist = result 2071 2072 f := Nod(ODCLFUNC, nil, nil) 2073 f.Func.Nname = newfuncname(name) 2074 f.Func.Nname.Name.Defn = f 2075 f.Func.Nname.Name.Param.Ntype = t // TODO: check if nname already has an ntype 2076 declare(f.Func.Nname, PFUNC) 2077 2078 funchdr(f) 2079 return f 2080 2081 case '(': 2082 // '(' oarg_type_list_ocomma ')' sym '(' oarg_type_list_ocomma ')' fnres 2083 rparam := p.param_list() 2084 name := p.sym() 2085 params := p.param_list() 2086 result := p.fnres() 2087 2088 rparam = checkarglist(rparam, 0) 2089 params = checkarglist(params, 1) 2090 2091 if rparam == nil { 2092 Yyerror("method has no receiver") 2093 return nil 2094 } 2095 2096 if rparam.Next != nil { 2097 Yyerror("method has multiple receivers") 2098 return nil 2099 } 2100 2101 rcvr := rparam.N 2102 if rcvr.Op != ODCLFIELD { 2103 Yyerror("bad receiver in method") 2104 return nil 2105 } 2106 2107 t := Nod(OTFUNC, rcvr, nil) 2108 t.List = params 2109 t.Rlist = result 2110 2111 f := Nod(ODCLFUNC, nil, nil) 2112 f.Func.Shortname = newfuncname(name) 2113 f.Func.Nname = methodname1(f.Func.Shortname, rcvr.Right) 2114 f.Func.Nname.Name.Defn = f 2115 f.Func.Nname.Name.Param.Ntype = t 2116 f.Func.Nname.Nointerface = nointerface 2117 declare(f.Func.Nname, PFUNC) 2118 2119 funchdr(f) 2120 return f 2121 2122 default: 2123 p.syntax_error("expecting name or (") 2124 p.advance('{', ';') 2125 return nil 2126 } 2127 } 2128 2129 func (p *parser) hidden_fndcl() *Node { 2130 if trace && Debug['x'] != 0 { 2131 defer p.trace("hidden_fndcl")() 2132 } 2133 2134 switch p.tok { 2135 default: 2136 // hidden_pkg_importsym '(' ohidden_funarg_list ')' ohidden_funres 2137 s1 := p.hidden_pkg_importsym() 2138 p.want('(') 2139 s3 := p.ohidden_funarg_list() 2140 p.want(')') 2141 s5 := p.ohidden_funres() 2142 2143 s := s1 2144 t := functype(nil, s3, s5) 2145 2146 importsym(s, ONAME) 2147 if s.Def != nil && s.Def.Op == ONAME { 2148 if Eqtype(t, s.Def.Type) { 2149 dclcontext = PDISCARD // since we skip funchdr below 2150 return nil 2151 } 2152 Yyerror("inconsistent definition for func %v during import\n\t%v\n\t%v", s, s.Def.Type, t) 2153 } 2154 2155 ss := newfuncname(s) 2156 ss.Type = t 2157 declare(ss, PFUNC) 2158 2159 funchdr(ss) 2160 return ss 2161 2162 case '(': 2163 // '(' hidden_funarg_list ')' sym '(' ohidden_funarg_list ')' ohidden_funres 2164 p.next() 2165 s2 := p.hidden_funarg_list() 2166 p.want(')') 2167 s4 := p.sym() 2168 p.want('(') 2169 s6 := p.ohidden_funarg_list() 2170 p.want(')') 2171 s8 := p.ohidden_funres() 2172 2173 ss := methodname1(newname(s4), s2.N.Right) 2174 ss.Type = functype(s2.N, s6, s8) 2175 2176 checkwidth(ss.Type) 2177 addmethod(s4, ss.Type, false, nointerface) 2178 nointerface = false 2179 funchdr(ss) 2180 2181 // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as 2182 // (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled 2183 // out by typecheck's lookdot as this $$.ttype. So by providing 2184 // this back link here we avoid special casing there. 2185 ss.Type.Nname = ss 2186 return ss 2187 } 2188 } 2189 2190 // FunctionBody = Block . 2191 func (p *parser) fnbody() *NodeList { 2192 if trace && Debug['x'] != 0 { 2193 defer p.trace("fnbody")() 2194 } 2195 2196 if p.got('{') { 2197 p.fnest++ 2198 body := p.stmt_list() 2199 p.fnest-- 2200 p.want('}') 2201 if body == nil { 2202 body = list1(Nod(OEMPTY, nil, nil)) 2203 } 2204 return body 2205 } 2206 2207 return nil 2208 } 2209 2210 // Result = Parameters | Type . 2211 func (p *parser) fnres() *NodeList { 2212 if trace && Debug['x'] != 0 { 2213 defer p.trace("fnres")() 2214 } 2215 2216 if p.tok == '(' { 2217 result := p.param_list() 2218 return checkarglist(result, 0) 2219 } 2220 2221 if result := p.try_ntype(); result != nil { 2222 return list1(Nod(ODCLFIELD, nil, result)) 2223 } 2224 2225 return nil 2226 } 2227 2228 // Declaration = ConstDecl | TypeDecl | VarDecl . 2229 // TopLevelDecl = Declaration | FunctionDecl | MethodDecl . 2230 func (p *parser) xdcl_list() (l *NodeList) { 2231 if trace && Debug['x'] != 0 { 2232 defer p.trace("xdcl_list")() 2233 } 2234 2235 loop: 2236 for p.tok != EOF { 2237 switch p.tok { 2238 case LVAR, LCONST, LTYPE: 2239 l = concat(l, p.common_dcl()) 2240 2241 case LFUNC: 2242 l = list(l, p.xfndcl()) 2243 2244 default: 2245 if p.tok == '{' && l != nil && l.End.N.Op == ODCLFUNC && l.End.N.Nbody == nil { 2246 // opening { of function declaration on next line 2247 p.syntax_error("unexpected semicolon or newline before {") 2248 } else { 2249 p.syntax_error("non-declaration statement outside function body") 2250 } 2251 p.advance(LVAR, LCONST, LTYPE, LFUNC) 2252 goto loop 2253 } 2254 2255 if nsyntaxerrors == 0 { 2256 testdclstack() 2257 } 2258 2259 noescape = false 2260 noinline = false 2261 nointerface = false 2262 norace = false 2263 nosplit = false 2264 nowritebarrier = false 2265 nowritebarrierrec = false 2266 systemstack = false 2267 2268 // Consume ';' AFTER resetting the above flags since 2269 // it may read the subsequent comment line which may 2270 // set the flags for the next function declaration. 2271 if p.tok != EOF && !p.got(';') { 2272 p.syntax_error("after top level declaration") 2273 p.advance(LVAR, LCONST, LTYPE, LFUNC) 2274 goto loop 2275 } 2276 } 2277 return 2278 } 2279 2280 // FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] . 2281 // AnonymousField = [ "*" ] TypeName . 2282 // Tag = string_lit . 2283 func (p *parser) structdcl() *NodeList { 2284 if trace && Debug['x'] != 0 { 2285 defer p.trace("structdcl")() 2286 } 2287 2288 var sym *Sym 2289 switch p.tok { 2290 case LNAME: 2291 sym = p.sym_ 2292 p.next() 2293 if sym == nil { 2294 panic("unreachable") // we must have a sym for LNAME 2295 } 2296 if p.tok == '.' || p.tok == LLITERAL || p.tok == ';' || p.tok == '}' { 2297 // embed oliteral 2298 field := p.embed(sym) 2299 tag := p.oliteral() 2300 2301 field.SetVal(tag) 2302 return list1(field) 2303 } 2304 2305 // LNAME belongs to first *Sym of new_name_list 2306 // 2307 // during imports, unqualified non-exported identifiers are from builtinpkg 2308 if importpkg != nil && !exportname(sym.Name) { 2309 sym = Pkglookup(sym.Name, builtinpkg) 2310 if sym == nil { 2311 p.import_error() 2312 } 2313 } 2314 fallthrough 2315 2316 case '@', '?': 2317 // new_name_list ntype oliteral 2318 fields := p.new_name_list(sym) 2319 typ := p.ntype() 2320 tag := p.oliteral() 2321 2322 if l := fields; l == nil || l.N.Sym.Name == "?" { 2323 // ? symbol, during import (list1(nil) == nil) 2324 n := typ 2325 if n.Op == OIND { 2326 n = n.Left 2327 } 2328 n = embedded(n.Sym, importpkg) 2329 n.Right = typ 2330 n.SetVal(tag) 2331 return list1(n) 2332 } 2333 2334 for l := fields; l != nil; l = l.Next { 2335 l.N = Nod(ODCLFIELD, l.N, typ) 2336 l.N.SetVal(tag) 2337 } 2338 return fields 2339 2340 case '(': 2341 p.next() 2342 if p.got('*') { 2343 // '(' '*' embed ')' oliteral 2344 field := p.embed(nil) 2345 p.want(')') 2346 tag := p.oliteral() 2347 2348 field.Right = Nod(OIND, field.Right, nil) 2349 field.SetVal(tag) 2350 Yyerror("cannot parenthesize embedded type") 2351 return list1(field) 2352 2353 } else { 2354 // '(' embed ')' oliteral 2355 field := p.embed(nil) 2356 p.want(')') 2357 tag := p.oliteral() 2358 2359 field.SetVal(tag) 2360 Yyerror("cannot parenthesize embedded type") 2361 return list1(field) 2362 } 2363 2364 case '*': 2365 p.next() 2366 if p.got('(') { 2367 // '*' '(' embed ')' oliteral 2368 field := p.embed(nil) 2369 p.want(')') 2370 tag := p.oliteral() 2371 2372 field.Right = Nod(OIND, field.Right, nil) 2373 field.SetVal(tag) 2374 Yyerror("cannot parenthesize embedded type") 2375 return list1(field) 2376 2377 } else { 2378 // '*' embed oliteral 2379 field := p.embed(nil) 2380 tag := p.oliteral() 2381 2382 field.Right = Nod(OIND, field.Right, nil) 2383 field.SetVal(tag) 2384 return list1(field) 2385 } 2386 2387 default: 2388 p.syntax_error("expecting field name or embedded type") 2389 p.advance(';', '}') 2390 return nil 2391 } 2392 } 2393 2394 func (p *parser) oliteral() (v Val) { 2395 if p.tok == LLITERAL { 2396 v = p.val 2397 p.next() 2398 } 2399 return 2400 } 2401 2402 func (p *parser) packname(name *Sym) *Sym { 2403 if trace && Debug['x'] != 0 { 2404 defer p.trace("embed")() 2405 } 2406 2407 if name != nil { 2408 // LNAME was already consumed and is coming in as name 2409 } else if p.tok == LNAME { 2410 name = p.sym_ 2411 p.next() 2412 } else { 2413 p.syntax_error("expecting name") 2414 p.advance('.', ';', '}') 2415 name = new(Sym) 2416 } 2417 2418 if p.got('.') { 2419 // LNAME '.' sym 2420 s := p.sym() 2421 2422 var pkg *Pkg 2423 if name.Def == nil || name.Def.Op != OPACK { 2424 Yyerror("%v is not a package", name) 2425 pkg = localpkg 2426 } else { 2427 name.Def.Used = true 2428 pkg = name.Def.Name.Pkg 2429 } 2430 return restrictlookup(s.Name, pkg) 2431 } 2432 2433 // LNAME 2434 if n := oldname(name); n.Name != nil && n.Name.Pack != nil { 2435 n.Name.Pack.Used = true 2436 } 2437 return name 2438 } 2439 2440 func (p *parser) embed(sym *Sym) *Node { 2441 if trace && Debug['x'] != 0 { 2442 defer p.trace("embed")() 2443 } 2444 2445 pkgname := p.packname(sym) 2446 return embedded(pkgname, localpkg) 2447 } 2448 2449 // MethodSpec = MethodName Signature | InterfaceTypeName . 2450 // MethodName = identifier . 2451 // InterfaceTypeName = TypeName . 2452 func (p *parser) interfacedcl() *Node { 2453 if trace && Debug['x'] != 0 { 2454 defer p.trace("interfacedcl")() 2455 } 2456 2457 switch p.tok { 2458 case LNAME: 2459 sym := p.sym_ 2460 p.next() 2461 2462 // accept potential name list but complain 2463 hasNameList := false 2464 for p.got(',') { 2465 p.sym() 2466 hasNameList = true 2467 } 2468 if hasNameList { 2469 p.syntax_error("name list not allowed in interface type") 2470 // already progressed, no need to advance 2471 } 2472 2473 if p.tok != '(' { 2474 // packname 2475 pname := p.packname(sym) 2476 return Nod(ODCLFIELD, nil, oldname(pname)) 2477 } 2478 2479 // newname indcl 2480 mname := newname(sym) 2481 sig := p.indcl() 2482 2483 meth := Nod(ODCLFIELD, mname, sig) 2484 ifacedcl(meth) 2485 return meth 2486 2487 case '(': 2488 p.next() 2489 pname := p.packname(nil) 2490 p.want(')') 2491 n := Nod(ODCLFIELD, nil, oldname(pname)) 2492 Yyerror("cannot parenthesize embedded type") 2493 return n 2494 2495 default: 2496 p.syntax_error("") 2497 p.advance(';', '}') 2498 return nil 2499 } 2500 } 2501 2502 // MethodSpec = MethodName Signature . 2503 // MethodName = identifier . 2504 func (p *parser) indcl() *Node { 2505 if trace && Debug['x'] != 0 { 2506 defer p.trace("indcl")() 2507 } 2508 2509 params := p.param_list() 2510 result := p.fnres() 2511 2512 // without func keyword 2513 params = checkarglist(params, 1) 2514 t := Nod(OTFUNC, fakethis(), nil) 2515 t.List = params 2516 t.Rlist = result 2517 2518 return t 2519 } 2520 2521 // ParameterDecl = [ IdentifierList ] [ "..." ] Type . 2522 func (p *parser) arg_type() *Node { 2523 if trace && Debug['x'] != 0 { 2524 defer p.trace("arg_type")() 2525 } 2526 2527 switch p.tok { 2528 case LNAME, '@', '?': 2529 name := p.sym() 2530 switch p.tok { 2531 case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?', '(': 2532 // sym name_or_type 2533 typ := p.ntype() 2534 nn := Nod(ONONAME, nil, nil) 2535 nn.Sym = name 2536 return Nod(OKEY, nn, typ) 2537 2538 case LDDD: 2539 // sym dotdotdot 2540 typ := p.dotdotdot() 2541 nn := Nod(ONONAME, nil, nil) 2542 nn.Sym = name 2543 return Nod(OKEY, nn, typ) 2544 2545 default: 2546 // name_or_type 2547 name := mkname(name) 2548 // from dotname 2549 if p.got('.') { 2550 return p.new_dotname(name) 2551 } 2552 return name 2553 } 2554 2555 case LDDD: 2556 // dotdotdot 2557 return p.dotdotdot() 2558 2559 case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', '(': 2560 // name_or_type 2561 return p.ntype() 2562 2563 default: 2564 p.syntax_error("expecting )") 2565 p.advance(',', ')') 2566 return nil 2567 } 2568 } 2569 2570 // Parameters = "(" [ ParameterList [ "," ] ] ")" . 2571 // ParameterList = ParameterDecl { "," ParameterDecl } . 2572 func (p *parser) param_list() (l *NodeList) { 2573 if trace && Debug['x'] != 0 { 2574 defer p.trace("param_list")() 2575 } 2576 2577 p.want('(') 2578 2579 for p.tok != EOF && p.tok != ')' { 2580 l = list(l, p.arg_type()) 2581 if !p.ocomma(')') { 2582 break 2583 } 2584 } 2585 2586 p.want(')') 2587 return 2588 } 2589 2590 var missing_stmt = Nod(OXXX, nil, nil) 2591 2592 // Statement = 2593 // Declaration | LabeledStmt | SimpleStmt | 2594 // GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt | 2595 // FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt | 2596 // DeferStmt . 2597 // 2598 // stmt may return missing_stmt. 2599 func (p *parser) stmt() *Node { 2600 if trace && Debug['x'] != 0 { 2601 defer p.trace("stmt")() 2602 } 2603 2604 switch p.tok { 2605 case '{': 2606 return p.compound_stmt(false) 2607 2608 case LVAR, LCONST, LTYPE: 2609 return liststmt(p.common_dcl()) 2610 2611 case LNAME, '@', '?', LLITERAL, LFUNC, '(', // operands 2612 '[', LSTRUCT, LMAP, LCHAN, LINTERFACE, // composite types 2613 '+', '-', '*', '&', '^', '~', LCOMM, '!': // unary operators 2614 return p.simple_stmt(true, false) 2615 2616 case LFOR: 2617 return p.for_stmt() 2618 2619 case LSWITCH: 2620 return p.switch_stmt() 2621 2622 case LSELECT: 2623 return p.select_stmt() 2624 2625 case LIF: 2626 return p.if_stmt() 2627 2628 case LFALL: 2629 p.next() 2630 // will be converted to OFALL 2631 stmt := Nod(OXFALL, nil, nil) 2632 stmt.Xoffset = int64(block) 2633 return stmt 2634 2635 case LBREAK: 2636 p.next() 2637 return Nod(OBREAK, p.onew_name(), nil) 2638 2639 case LCONTINUE: 2640 p.next() 2641 return Nod(OCONTINUE, p.onew_name(), nil) 2642 2643 case LGO: 2644 p.next() 2645 return Nod(OPROC, p.pseudocall(), nil) 2646 2647 case LDEFER: 2648 p.next() 2649 return Nod(ODEFER, p.pseudocall(), nil) 2650 2651 case LGOTO: 2652 p.next() 2653 stmt := Nod(OGOTO, p.new_name(p.sym()), nil) 2654 stmt.Sym = dclstack // context, for goto restrictions 2655 return stmt 2656 2657 case LRETURN: 2658 p.next() 2659 var results *NodeList 2660 if p.tok != ';' && p.tok != '}' { 2661 results = p.expr_list() 2662 } 2663 2664 stmt := Nod(ORETURN, nil, nil) 2665 stmt.List = results 2666 if stmt.List == nil && Curfn != nil { 2667 for l := Curfn.Func.Dcl; l != nil; l = l.Next { 2668 if l.N.Class == PPARAM { 2669 continue 2670 } 2671 if l.N.Class != PPARAMOUT { 2672 break 2673 } 2674 if l.N.Sym.Def != l.N { 2675 Yyerror("%s is shadowed during return", l.N.Sym.Name) 2676 } 2677 } 2678 } 2679 2680 return stmt 2681 2682 case ';': 2683 return nil 2684 2685 default: 2686 return missing_stmt 2687 } 2688 } 2689 2690 // StatementList = { Statement ";" } . 2691 func (p *parser) stmt_list() (l *NodeList) { 2692 if trace && Debug['x'] != 0 { 2693 defer p.trace("stmt_list")() 2694 } 2695 2696 for p.tok != EOF && p.tok != '}' && p.tok != LCASE && p.tok != LDEFAULT { 2697 s := p.stmt() 2698 if s == missing_stmt { 2699 break 2700 } 2701 l = list(l, s) 2702 // customized version of osemi: 2703 // ';' is optional before a closing ')' or '}' 2704 if p.tok == ')' || p.tok == '}' { 2705 continue 2706 } 2707 if !p.got(';') { 2708 p.syntax_error("at end of statement") 2709 p.advance(';', '}') 2710 } 2711 } 2712 return 2713 } 2714 2715 // IdentifierList = identifier { "," identifier } . 2716 // 2717 // If first != nil we have the first symbol already. 2718 func (p *parser) new_name_list(first *Sym) *NodeList { 2719 if trace && Debug['x'] != 0 { 2720 defer p.trace("new_name_list")() 2721 } 2722 2723 if first == nil { 2724 first = p.sym() // may still be nil 2725 } 2726 l := list1(p.new_name(first)) 2727 for p.got(',') { 2728 l = list(l, p.new_name(p.sym())) 2729 } 2730 return l 2731 } 2732 2733 // IdentifierList = identifier { "," identifier } . 2734 func (p *parser) dcl_name_list() *NodeList { 2735 if trace && Debug['x'] != 0 { 2736 defer p.trace("dcl_name_list")() 2737 } 2738 2739 l := list1(dclname(p.sym())) 2740 for p.got(',') { 2741 l = list(l, dclname(p.sym())) 2742 } 2743 return l 2744 } 2745 2746 // ExpressionList = Expression { "," Expression } . 2747 func (p *parser) expr_list() *NodeList { 2748 if trace && Debug['x'] != 0 { 2749 defer p.trace("expr_list")() 2750 } 2751 2752 l := list1(p.expr()) 2753 for p.got(',') { 2754 l = list(l, p.expr()) 2755 } 2756 return l 2757 } 2758 2759 // Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" . 2760 func (p *parser) arg_list() (l *NodeList, ddd bool) { 2761 if trace && Debug['x'] != 0 { 2762 defer p.trace("arg_list")() 2763 } 2764 2765 p.want('(') 2766 p.xnest++ 2767 2768 for p.tok != EOF && p.tok != ')' && !ddd { 2769 l = list(l, p.expr()) // expr_or_type 2770 ddd = p.got(LDDD) 2771 if !p.ocomma(')') { 2772 break 2773 } 2774 } 2775 2776 p.xnest-- 2777 p.want(')') 2778 2779 return 2780 } 2781 2782 // osemi parses an optional semicolon. 2783 func (p *parser) osemi(follow int32) bool { 2784 switch p.tok { 2785 case ';': 2786 p.next() 2787 return true 2788 2789 case ')', '}': 2790 // semicolon is optional before ) or } 2791 return true 2792 } 2793 2794 p.syntax_error("expecting semicolon, newline, or " + tokstring(follow)) 2795 p.advance(follow) 2796 return false 2797 } 2798 2799 // ocomma parses an optional comma. 2800 func (p *parser) ocomma(follow int32) bool { 2801 switch p.tok { 2802 case ',': 2803 p.next() 2804 return true 2805 2806 case ')', '}': 2807 // comma is optional before ) or } 2808 return true 2809 } 2810 2811 p.syntax_error("expecting comma or " + tokstring(follow)) 2812 p.advance(follow) 2813 return false 2814 } 2815 2816 // ---------------------------------------------------------------------------- 2817 // Importing packages 2818 2819 func (p *parser) import_error() { 2820 p.syntax_error("in export data of imported package") 2821 p.next() 2822 } 2823 2824 // The methods below reflect a 1:1 translation of the original (and now defunct) 2825 // go.y yacc productions. They could be simplified significantly and also use better 2826 // variable names. However, we will be able to delete them once we enable the 2827 // new export format by default, so it's not worth the effort (issue 13241). 2828 2829 func (p *parser) hidden_importsym() *Sym { 2830 if trace && Debug['x'] != 0 { 2831 defer p.trace("hidden_importsym")() 2832 } 2833 2834 p.want('@') 2835 var s2 Val 2836 if p.tok == LLITERAL { 2837 s2 = p.val 2838 p.next() 2839 } else { 2840 p.import_error() 2841 } 2842 p.want('.') 2843 2844 switch p.tok { 2845 case LNAME: 2846 s4 := p.sym_ 2847 p.next() 2848 2849 var p *Pkg 2850 2851 if s2.U.(string) == "" { 2852 p = importpkg 2853 } else { 2854 if isbadimport(s2.U.(string)) { 2855 errorexit() 2856 } 2857 p = mkpkg(s2.U.(string)) 2858 } 2859 return Pkglookup(s4.Name, p) 2860 2861 case '?': 2862 p.next() 2863 2864 var p *Pkg 2865 2866 if s2.U.(string) == "" { 2867 p = importpkg 2868 } else { 2869 if isbadimport(s2.U.(string)) { 2870 errorexit() 2871 } 2872 p = mkpkg(s2.U.(string)) 2873 } 2874 return Pkglookup("?", p) 2875 2876 default: 2877 p.import_error() 2878 return nil 2879 } 2880 } 2881 2882 func (p *parser) ohidden_funarg_list() *NodeList { 2883 if trace && Debug['x'] != 0 { 2884 defer p.trace("ohidden_funarg_list")() 2885 } 2886 2887 var ss *NodeList 2888 if p.tok != ')' { 2889 ss = p.hidden_funarg_list() 2890 } 2891 return ss 2892 } 2893 2894 func (p *parser) ohidden_structdcl_list() *NodeList { 2895 if trace && Debug['x'] != 0 { 2896 defer p.trace("ohidden_structdcl_list")() 2897 } 2898 2899 var ss *NodeList 2900 if p.tok != '}' { 2901 ss = p.hidden_structdcl_list() 2902 } 2903 return ss 2904 } 2905 2906 func (p *parser) ohidden_interfacedcl_list() *NodeList { 2907 if trace && Debug['x'] != 0 { 2908 defer p.trace("ohidden_interfacedcl_list")() 2909 } 2910 2911 var ss *NodeList 2912 if p.tok != '}' { 2913 ss = p.hidden_interfacedcl_list() 2914 } 2915 return ss 2916 } 2917 2918 // import syntax from package header 2919 func (p *parser) hidden_import() { 2920 if trace && Debug['x'] != 0 { 2921 defer p.trace("hidden_import")() 2922 } 2923 2924 switch p.tok { 2925 case LIMPORT: 2926 // LIMPORT LNAME LLITERAL ';' 2927 p.next() 2928 var s2 *Sym 2929 if p.tok == LNAME { 2930 s2 = p.sym_ 2931 p.next() 2932 } else { 2933 p.import_error() 2934 } 2935 var s3 Val 2936 if p.tok == LLITERAL { 2937 s3 = p.val 2938 p.next() 2939 } else { 2940 p.import_error() 2941 } 2942 p.want(';') 2943 2944 importimport(s2, s3.U.(string)) 2945 2946 case LVAR: 2947 // LVAR hidden_pkg_importsym hidden_type ';' 2948 p.next() 2949 s2 := p.hidden_pkg_importsym() 2950 s3 := p.hidden_type() 2951 p.want(';') 2952 2953 importvar(s2, s3) 2954 2955 case LCONST: 2956 // LCONST hidden_pkg_importsym '=' hidden_constant ';' 2957 // LCONST hidden_pkg_importsym hidden_type '=' hidden_constant ';' 2958 p.next() 2959 s2 := p.hidden_pkg_importsym() 2960 var s3 *Type = Types[TIDEAL] 2961 if p.tok != '=' { 2962 s3 = p.hidden_type() 2963 } 2964 p.want('=') 2965 s4 := p.hidden_constant() 2966 p.want(';') 2967 2968 importconst(s2, s3, s4) 2969 2970 case LTYPE: 2971 // LTYPE hidden_pkgtype hidden_type ';' 2972 p.next() 2973 s2 := p.hidden_pkgtype() 2974 s3 := p.hidden_type() 2975 p.want(';') 2976 2977 importtype(s2, s3) 2978 2979 case LFUNC: 2980 // LFUNC hidden_fndcl fnbody ';' 2981 p.next() 2982 s2 := p.hidden_fndcl() 2983 s3 := p.fnbody() 2984 p.want(';') 2985 2986 if s2 == nil { 2987 dclcontext = PEXTERN // since we skip the funcbody below 2988 return 2989 } 2990 2991 s2.Func.Inl = s3 2992 2993 funcbody(s2) 2994 importlist = append(importlist, s2) 2995 2996 if Debug['E'] > 0 { 2997 fmt.Printf("import [%q] func %v \n", importpkg.Path, s2) 2998 if Debug['m'] > 2 && s2.Func.Inl != nil { 2999 fmt.Printf("inl body:%v\n", s2.Func.Inl) 3000 } 3001 } 3002 3003 default: 3004 p.import_error() 3005 } 3006 } 3007 3008 func (p *parser) hidden_pkg_importsym() *Sym { 3009 if trace && Debug['x'] != 0 { 3010 defer p.trace("hidden_pkg_importsym")() 3011 } 3012 3013 s1 := p.hidden_importsym() 3014 3015 ss := s1 3016 structpkg = ss.Pkg 3017 3018 return ss 3019 } 3020 3021 func (p *parser) hidden_pkgtype() *Type { 3022 if trace && Debug['x'] != 0 { 3023 defer p.trace("hidden_pkgtype")() 3024 } 3025 3026 s1 := p.hidden_pkg_importsym() 3027 3028 ss := pkgtype(s1) 3029 importsym(s1, OTYPE) 3030 3031 return ss 3032 } 3033 3034 // ---------------------------------------------------------------------------- 3035 // Importing types 3036 3037 func (p *parser) hidden_type() *Type { 3038 if trace && Debug['x'] != 0 { 3039 defer p.trace("hidden_type")() 3040 } 3041 3042 switch p.tok { 3043 default: 3044 return p.hidden_type_misc() 3045 case LCOMM: 3046 return p.hidden_type_recv_chan() 3047 case LFUNC: 3048 return p.hidden_type_func() 3049 } 3050 } 3051 3052 func (p *parser) hidden_type_non_recv_chan() *Type { 3053 if trace && Debug['x'] != 0 { 3054 defer p.trace("hidden_type_non_recv_chan")() 3055 } 3056 3057 switch p.tok { 3058 default: 3059 return p.hidden_type_misc() 3060 case LFUNC: 3061 return p.hidden_type_func() 3062 } 3063 } 3064 3065 func (p *parser) hidden_type_misc() *Type { 3066 if trace && Debug['x'] != 0 { 3067 defer p.trace("hidden_type_misc")() 3068 } 3069 3070 switch p.tok { 3071 case '@': 3072 // hidden_importsym 3073 s1 := p.hidden_importsym() 3074 return pkgtype(s1) 3075 3076 case LNAME: 3077 // LNAME 3078 s1 := p.sym_ 3079 p.next() 3080 3081 // predefined name like uint8 3082 s1 = Pkglookup(s1.Name, builtinpkg) 3083 if s1.Def == nil || s1.Def.Op != OTYPE { 3084 Yyerror("%s is not a type", s1.Name) 3085 return nil 3086 } else { 3087 return s1.Def.Type 3088 } 3089 3090 case '[': 3091 // '[' ']' hidden_type 3092 // '[' LLITERAL ']' hidden_type 3093 p.next() 3094 var s2 *Node 3095 if p.tok == LLITERAL { 3096 s2 = nodlit(p.val) 3097 p.next() 3098 } 3099 p.want(']') 3100 s4 := p.hidden_type() 3101 3102 return aindex(s2, s4) 3103 3104 case LMAP: 3105 // LMAP '[' hidden_type ']' hidden_type 3106 p.next() 3107 p.want('[') 3108 s3 := p.hidden_type() 3109 p.want(']') 3110 s5 := p.hidden_type() 3111 3112 return maptype(s3, s5) 3113 3114 case LSTRUCT: 3115 // LSTRUCT '{' ohidden_structdcl_list '}' 3116 p.next() 3117 p.want('{') 3118 s3 := p.ohidden_structdcl_list() 3119 p.want('}') 3120 3121 return tostruct(s3) 3122 3123 case LINTERFACE: 3124 // LINTERFACE '{' ohidden_interfacedcl_list '}' 3125 p.next() 3126 p.want('{') 3127 s3 := p.ohidden_interfacedcl_list() 3128 p.want('}') 3129 3130 return tointerface(s3) 3131 3132 case '*': 3133 // '*' hidden_type 3134 p.next() 3135 s2 := p.hidden_type() 3136 return Ptrto(s2) 3137 3138 case LCHAN: 3139 p.next() 3140 switch p.tok { 3141 default: 3142 // LCHAN hidden_type_non_recv_chan 3143 s2 := p.hidden_type_non_recv_chan() 3144 ss := typ(TCHAN) 3145 ss.Type = s2 3146 ss.Chan = Cboth 3147 return ss 3148 3149 case '(': 3150 // LCHAN '(' hidden_type_recv_chan ')' 3151 p.next() 3152 s3 := p.hidden_type_recv_chan() 3153 p.want(')') 3154 ss := typ(TCHAN) 3155 ss.Type = s3 3156 ss.Chan = Cboth 3157 return ss 3158 3159 case LCOMM: 3160 // LCHAN hidden_type 3161 p.next() 3162 s3 := p.hidden_type() 3163 ss := typ(TCHAN) 3164 ss.Type = s3 3165 ss.Chan = Csend 3166 return ss 3167 } 3168 3169 default: 3170 p.import_error() 3171 return nil 3172 } 3173 } 3174 3175 func (p *parser) hidden_type_recv_chan() *Type { 3176 if trace && Debug['x'] != 0 { 3177 defer p.trace("hidden_type_recv_chan")() 3178 } 3179 3180 p.want(LCOMM) 3181 p.want(LCHAN) 3182 s3 := p.hidden_type() 3183 3184 ss := typ(TCHAN) 3185 ss.Type = s3 3186 ss.Chan = Crecv 3187 return ss 3188 } 3189 3190 func (p *parser) hidden_type_func() *Type { 3191 if trace && Debug['x'] != 0 { 3192 defer p.trace("hidden_type_func")() 3193 } 3194 3195 p.want(LFUNC) 3196 p.want('(') 3197 s3 := p.ohidden_funarg_list() 3198 p.want(')') 3199 s5 := p.ohidden_funres() 3200 3201 return functype(nil, s3, s5) 3202 } 3203 3204 func (p *parser) hidden_funarg() *Node { 3205 if trace && Debug['x'] != 0 { 3206 defer p.trace("hidden_funarg")() 3207 } 3208 3209 s1 := p.sym() 3210 switch p.tok { 3211 default: 3212 s2 := p.hidden_type() 3213 s3 := p.oliteral() 3214 3215 ss := Nod(ODCLFIELD, nil, typenod(s2)) 3216 if s1 != nil { 3217 ss.Left = newname(s1) 3218 } 3219 ss.SetVal(s3) 3220 return ss 3221 3222 case LDDD: 3223 p.next() 3224 s3 := p.hidden_type() 3225 s4 := p.oliteral() 3226 3227 var t *Type 3228 3229 t = typ(TARRAY) 3230 t.Bound = -1 3231 t.Type = s3 3232 3233 ss := Nod(ODCLFIELD, nil, typenod(t)) 3234 if s1 != nil { 3235 ss.Left = newname(s1) 3236 } 3237 ss.Isddd = true 3238 ss.SetVal(s4) 3239 3240 return ss 3241 } 3242 } 3243 3244 func (p *parser) hidden_structdcl() *Node { 3245 if trace && Debug['x'] != 0 { 3246 defer p.trace("hidden_structdcl")() 3247 } 3248 3249 s1 := p.sym() 3250 s2 := p.hidden_type() 3251 s3 := p.oliteral() 3252 3253 var s *Sym 3254 var pkg *Pkg 3255 3256 var ss *Node 3257 if s1 != nil && s1.Name != "?" { 3258 ss = Nod(ODCLFIELD, newname(s1), typenod(s2)) 3259 ss.SetVal(s3) 3260 } else { 3261 s = s2.Sym 3262 if s == nil && Isptr[s2.Etype] { 3263 s = s2.Type.Sym 3264 } 3265 pkg = importpkg 3266 if s1 != nil { 3267 pkg = s1.Pkg 3268 } 3269 ss = embedded(s, pkg) 3270 ss.Right = typenod(s2) 3271 ss.SetVal(s3) 3272 } 3273 3274 return ss 3275 } 3276 3277 func (p *parser) hidden_interfacedcl() *Node { 3278 if trace && Debug['x'] != 0 { 3279 defer p.trace("hidden_interfacedcl")() 3280 } 3281 3282 // The original (now defunct) grammar in go.y accepted both a method 3283 // or an (embedded) type: 3284 // 3285 // hidden_interfacedcl: 3286 // sym '(' ohidden_funarg_list ')' ohidden_funres 3287 // { 3288 // $$ = Nod(ODCLFIELD, newname($1), typenod(functype(fakethis(), $3, $5))); 3289 // } 3290 // | hidden_type 3291 // { 3292 // $$ = Nod(ODCLFIELD, nil, typenod($1)); 3293 // } 3294 // 3295 // But the current textual export code only exports (inlined) methods, 3296 // even if the methods came from embedded interfaces. Furthermore, in 3297 // the original grammar, hidden_type may also start with a sym (LNAME 3298 // or '@'), complicating matters further. Since we never have embedded 3299 // types, only parse methods here. 3300 3301 s1 := p.sym() 3302 p.want('(') 3303 s3 := p.ohidden_funarg_list() 3304 p.want(')') 3305 s5 := p.ohidden_funres() 3306 3307 return Nod(ODCLFIELD, newname(s1), typenod(functype(fakethis(), s3, s5))) 3308 } 3309 3310 func (p *parser) ohidden_funres() *NodeList { 3311 if trace && Debug['x'] != 0 { 3312 defer p.trace("ohidden_funres")() 3313 } 3314 3315 switch p.tok { 3316 default: 3317 return nil 3318 3319 case '(', '@', LNAME, '[', LMAP, LSTRUCT, LINTERFACE, '*', LCHAN, LCOMM, LFUNC: 3320 return p.hidden_funres() 3321 } 3322 } 3323 3324 func (p *parser) hidden_funres() *NodeList { 3325 if trace && Debug['x'] != 0 { 3326 defer p.trace("hidden_funres")() 3327 } 3328 3329 switch p.tok { 3330 case '(': 3331 p.next() 3332 s2 := p.ohidden_funarg_list() 3333 p.want(')') 3334 return s2 3335 3336 default: 3337 s1 := p.hidden_type() 3338 return list1(Nod(ODCLFIELD, nil, typenod(s1))) 3339 } 3340 } 3341 3342 // ---------------------------------------------------------------------------- 3343 // Importing constants 3344 3345 func (p *parser) hidden_literal() *Node { 3346 if trace && Debug['x'] != 0 { 3347 defer p.trace("hidden_literal")() 3348 } 3349 3350 switch p.tok { 3351 case LLITERAL: 3352 ss := nodlit(p.val) 3353 p.next() 3354 return ss 3355 3356 case '-': 3357 p.next() 3358 if p.tok == LLITERAL { 3359 ss := nodlit(p.val) 3360 p.next() 3361 switch ss.Val().Ctype() { 3362 case CTINT, CTRUNE: 3363 mpnegfix(ss.Val().U.(*Mpint)) 3364 break 3365 case CTFLT: 3366 mpnegflt(ss.Val().U.(*Mpflt)) 3367 break 3368 case CTCPLX: 3369 mpnegflt(&ss.Val().U.(*Mpcplx).Real) 3370 mpnegflt(&ss.Val().U.(*Mpcplx).Imag) 3371 break 3372 default: 3373 Yyerror("bad negated constant") 3374 } 3375 return ss 3376 } else { 3377 p.import_error() 3378 return nil 3379 } 3380 3381 case LNAME, '@', '?': 3382 s1 := p.sym() 3383 ss := oldname(Pkglookup(s1.Name, builtinpkg)) 3384 if ss.Op != OLITERAL { 3385 Yyerror("bad constant %v", ss.Sym) 3386 } 3387 return ss 3388 3389 default: 3390 p.import_error() 3391 return nil 3392 } 3393 } 3394 3395 func (p *parser) hidden_constant() *Node { 3396 if trace && Debug['x'] != 0 { 3397 defer p.trace("hidden_constant")() 3398 } 3399 3400 switch p.tok { 3401 default: 3402 return p.hidden_literal() 3403 case '(': 3404 p.next() 3405 s2 := p.hidden_literal() 3406 p.want('+') 3407 s4 := p.hidden_literal() 3408 p.want(')') 3409 3410 if s2.Val().Ctype() == CTRUNE && s4.Val().Ctype() == CTINT { 3411 ss := s2 3412 mpaddfixfix(s2.Val().U.(*Mpint), s4.Val().U.(*Mpint), 0) 3413 return ss 3414 } 3415 s4.Val().U.(*Mpcplx).Real = s4.Val().U.(*Mpcplx).Imag 3416 Mpmovecflt(&s4.Val().U.(*Mpcplx).Imag, 0.0) 3417 return nodcplxlit(s2.Val(), s4.Val()) 3418 } 3419 } 3420 3421 func (p *parser) hidden_import_list() { 3422 if trace && Debug['x'] != 0 { 3423 defer p.trace("hidden_import_list")() 3424 } 3425 3426 for p.tok != '$' { 3427 p.hidden_import() 3428 } 3429 } 3430 3431 func (p *parser) hidden_funarg_list() *NodeList { 3432 if trace && Debug['x'] != 0 { 3433 defer p.trace("hidden_funarg_list")() 3434 } 3435 3436 s1 := p.hidden_funarg() 3437 ss := list1(s1) 3438 for p.got(',') { 3439 s3 := p.hidden_funarg() 3440 ss = list(ss, s3) 3441 } 3442 return ss 3443 } 3444 3445 func (p *parser) hidden_structdcl_list() *NodeList { 3446 if trace && Debug['x'] != 0 { 3447 defer p.trace("hidden_structdcl_list")() 3448 } 3449 3450 s1 := p.hidden_structdcl() 3451 ss := list1(s1) 3452 for p.got(';') { 3453 s3 := p.hidden_structdcl() 3454 ss = list(ss, s3) 3455 } 3456 return ss 3457 } 3458 3459 func (p *parser) hidden_interfacedcl_list() *NodeList { 3460 if trace && Debug['x'] != 0 { 3461 defer p.trace("hidden_interfacedcl_list")() 3462 } 3463 3464 s1 := p.hidden_interfacedcl() 3465 ss := list1(s1) 3466 for p.got(';') { 3467 s3 := p.hidden_interfacedcl() 3468 ss = list(ss, s3) 3469 } 3470 return ss 3471 }