github.com/DQNEO/babygo@v0.0.3/parser.go (about) 1 package main 2 3 import ( 4 "github.com/DQNEO/babygo/lib/ast" 5 "github.com/DQNEO/babygo/lib/fmt" 6 "github.com/DQNEO/babygo/lib/strconv" 7 "github.com/DQNEO/babygo/lib/token" 8 "syscall" 9 ) 10 11 const O_READONLY int = 0 12 const FILE_SIZE int = 2000000 13 14 func readFile(filename string) []uint8 { 15 var fd int 16 logf("Opening %s\n", filename) 17 fd, _ = syscall.Open(filename, O_READONLY, 0) 18 if fd < 0 { 19 panic("syscall.Open failed: " + filename) 20 } 21 var buf = make([]uint8, FILE_SIZE, FILE_SIZE) 22 var n int 23 // @TODO check error 24 n, _ = syscall.Read(fd, buf) 25 logf("syscall.Read len=%s\n", strconv.Itoa(n)) 26 syscall.Close(fd) 27 var readbytes = buf[0:n] 28 return readbytes 29 } 30 31 func (p *parser) init(src []uint8) { 32 var s = p.scanner 33 s.Init(src) 34 p.next() 35 } 36 37 type parser struct { 38 tok *TokenContainer 39 unresolved []*ast.Ident 40 topScope *ast.Scope 41 pkgScope *ast.Scope 42 scanner *scanner 43 imports []*ast.ImportSpec 44 } 45 46 func (p *parser) openScope() { 47 p.topScope = ast.NewScope(p.topScope) 48 } 49 50 func (p *parser) closeScope() { 51 p.topScope = p.topScope.Outer 52 } 53 54 func (p *parser) consumeComment() { 55 p.next0() 56 } 57 58 func (p *parser) next0() { 59 var s = p.scanner 60 p.tok = s.Scan() 61 } 62 63 func (p *parser) next() { 64 p.next0() 65 if p.tok.tok == ";" { 66 logf(" [parser] pointing at : \"%s\" newline (%s)\n", p.tok.tok, strconv.Itoa(p.scanner.offset)) 67 } else if p.tok.tok == "IDENT" { 68 logf(" [parser] pointing at: IDENT \"%s\" (%s)\n", p.tok.lit, strconv.Itoa(p.scanner.offset)) 69 } else { 70 logf(" [parser] pointing at: \"%s\" %s (%s)\n", p.tok.tok, p.tok.lit, strconv.Itoa(p.scanner.offset)) 71 } 72 73 if p.tok.tok == "COMMENT" { 74 for p.tok.tok == "COMMENT" { 75 p.consumeComment() 76 } 77 } 78 } 79 80 func (p *parser) expect(tok string, who string) { 81 if p.tok.tok != tok { 82 var s = fmt.Sprintf("%s expected, but got %s", tok, p.tok.tok) 83 panic2(who, s) 84 } 85 logf(" [%s] consumed \"%s\"\n", who, p.tok.tok) 86 p.next() 87 } 88 89 func (p *parser) expectSemi(caller string) { 90 if p.tok.tok != ")" && p.tok.tok != "}" { 91 switch p.tok.tok { 92 case ";": 93 logf(" [%s] consumed semicolon %s\n", caller, p.tok.tok) 94 p.next() 95 default: 96 panic2(caller, "semicolon expected, but got token "+p.tok.tok) 97 } 98 } 99 } 100 101 func (p *parser) parseIdent() *ast.Ident { 102 var name string 103 if p.tok.tok == "IDENT" { 104 name = p.tok.lit 105 p.next() 106 } else { 107 panic2(__func__, "IDENT expected, but got "+p.tok.tok) 108 } 109 logf(" [%s] ident name = %s\n", __func__, name) 110 return &ast.Ident{ 111 Name: name, 112 } 113 } 114 115 func (p *parser) parseImportSpec() *ast.ImportSpec { 116 var pth = p.tok.lit 117 p.next() 118 spec := &ast.ImportSpec{ 119 Path: &ast.BasicLit{ 120 Kind: token.STRING, 121 Value: pth, 122 }, 123 } 124 p.imports = append(p.imports, spec) 125 return spec 126 } 127 128 func (p *parser) tryVarType(ellipsisOK bool) ast.Expr { 129 if ellipsisOK && p.tok.tok == "..." { 130 p.next() // consume "..." 131 var typ = p.tryIdentOrType() 132 if typ != nil { 133 p.resolve(typ) 134 } else { 135 panic2(__func__, "Syntax error") 136 } 137 138 return (&ast.Ellipsis{ 139 Elt: typ, 140 }) 141 } 142 return p.tryIdentOrType() 143 } 144 145 func (p *parser) parseVarType(ellipsisOK bool) ast.Expr { 146 logf(" [%s] begin\n", __func__) 147 var typ = p.tryVarType(ellipsisOK) 148 if typ == nil { 149 panic2(__func__, "nil is not expected") 150 } 151 logf(" [%s] end\n", __func__) 152 return typ 153 } 154 155 func (p *parser) tryType() ast.Expr { 156 logf(" [%s] begin\n", __func__) 157 var typ = p.tryIdentOrType() 158 if typ != nil { 159 p.resolve(typ) 160 } 161 logf(" [%s] end\n", __func__) 162 return typ 163 } 164 165 func (p *parser) parseType() ast.Expr { 166 var typ = p.tryType() 167 return typ 168 } 169 170 func (p *parser) parsePointerType() ast.Expr { 171 p.expect("*", __func__) 172 var base = p.parseType() 173 return (&ast.StarExpr{ 174 X: base, 175 }) 176 } 177 178 func (p *parser) parseArrayType() ast.Expr { 179 p.expect("[", __func__) 180 var ln ast.Expr 181 if p.tok.tok != "]" { 182 ln = p.parseRhs() 183 } 184 p.expect("]", __func__) 185 var elt = p.parseType() 186 187 return (&ast.ArrayType{ 188 Elt: elt, 189 Len: ln, 190 }) 191 } 192 193 func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field { 194 195 var varType = p.parseVarType(false) 196 var typ = p.tryVarType(false) 197 198 p.expectSemi(__func__) 199 ident := varType.(*ast.Ident) 200 var field = &ast.Field{ 201 Type: typ, 202 Names: []*ast.Ident{ident}, 203 } 204 declareField(field, scope, ast.Var, ident) 205 p.resolve(typ) 206 return field 207 } 208 209 func (p *parser) parseStructType() ast.Expr { 210 p.expect("struct", __func__) 211 p.expect("{", __func__) 212 213 var _nil *ast.Scope 214 var scope = ast.NewScope(_nil) 215 216 var list []*ast.Field 217 for p.tok.tok == "IDENT" || p.tok.tok == "*" { 218 var field *ast.Field = p.parseFieldDecl(scope) 219 list = append(list, field) 220 } 221 p.expect("}", __func__) 222 223 return (&ast.StructType{ 224 Fields: &ast.FieldList{ 225 List: list, 226 }, 227 }) 228 } 229 230 func (p *parser) parseMaptype() ast.Expr { 231 p.expect("map", __func__) 232 p.expect("[", __func__) 233 keyType := p.parseType() 234 p.expect("]", __func__) 235 valueType := p.parseType() 236 return &ast.MapType{ 237 Key: keyType, 238 Value: valueType, 239 } 240 } 241 242 func (p *parser) parseTypeName() ast.Expr { 243 logf(" [%s] begin\n", __func__) 244 var ident = p.parseIdent() 245 if p.tok.tok == "." { 246 // ident is a package name 247 p.next() // consume "." 248 eIdent := (ident) 249 p.resolve(eIdent) 250 sel := p.parseIdent() 251 selectorExpr := &ast.SelectorExpr{ 252 X: eIdent, 253 Sel: sel, 254 } 255 return (selectorExpr) 256 } 257 logf(" [%s] end\n", __func__) 258 return (ident) 259 } 260 261 func (p *parser) tryIdentOrType() ast.Expr { 262 logf(" [%s] begin\n", __func__) 263 switch p.tok.tok { 264 case "IDENT": 265 return p.parseTypeName() 266 case "[": 267 return p.parseArrayType() 268 case "struct": 269 return p.parseStructType() 270 case "map": 271 return p.parseMaptype() 272 case "*": 273 return p.parsePointerType() 274 case "interface": 275 p.next() 276 p.expect("{", __func__) 277 // @TODO parser method sets 278 p.expect("}", __func__) 279 return (&ast.InterfaceType{ 280 Methods: nil, 281 }) 282 case "(": 283 p.next() 284 var _typ = p.parseType() 285 p.expect(")", __func__) 286 return (&ast.ParenExpr{ 287 X: _typ, 288 }) 289 case "type": 290 p.next() 291 return nil 292 } 293 294 return nil 295 } 296 297 func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOK bool) []*ast.Field { 298 logf(" [%s] begin\n", __func__) 299 var list []ast.Expr 300 for { 301 var varType = p.parseVarType(ellipsisOK) 302 list = append(list, varType) 303 if p.tok.tok != "," { 304 break 305 } 306 p.next() 307 if p.tok.tok == ")" { 308 break 309 } 310 } 311 logf(" [%s] collected list n=%s\n", __func__, strconv.Itoa(len(list))) 312 313 var params []*ast.Field 314 315 var typ = p.tryVarType(ellipsisOK) 316 if typ != nil { 317 if len(list) > 1 { 318 panic2(__func__, "Ident list is not supported") 319 } 320 var eIdent = list[0] 321 ident := eIdent.(*ast.Ident) 322 logf(" [%s] ident.Name=%s\n", __func__, ident.Name) 323 field := &ast.Field{ 324 Names: []*ast.Ident{ident}, 325 Type: typ, 326 } 327 params = append(params, field) 328 declareField(field, scope, ast.Var, ident) 329 p.resolve(typ) 330 if p.tok.tok != "," { 331 logf(" end %s\n", __func__) 332 return params 333 } 334 p.next() 335 for p.tok.tok != ")" && p.tok.tok != "EOF" { 336 ident = p.parseIdent() 337 typ = p.parseVarType(ellipsisOK) 338 field = &ast.Field{ 339 Names: []*ast.Ident{ident}, 340 Type: typ, 341 } 342 params = append(params, field) 343 declareField(field, scope, ast.Var, ident) 344 p.resolve(typ) 345 if p.tok.tok != "," { 346 break 347 } 348 p.next() 349 } 350 logf(" end %s\n", __func__) 351 return params 352 } 353 354 // Type { "," Type } (anonymous parameters) 355 params = make([]*ast.Field, len(list), len(list)) 356 357 for i, typ := range list { 358 p.resolve(typ) 359 params[i] = &ast.Field{ 360 Type: typ, 361 } 362 logf(" [DEBUG] range i = %s\n", strconv.Itoa(i)) 363 } 364 logf(" end %s\n", __func__) 365 return params 366 } 367 368 func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) *ast.FieldList { 369 logf(" [%s] begin\n", __func__) 370 var params []*ast.Field 371 p.expect("(", __func__) 372 if p.tok.tok != ")" { 373 params = p.parseParameterList(scope, ellipsisOk) 374 } 375 p.expect(")", __func__) 376 logf(" [%s] end\n", __func__) 377 return &ast.FieldList{ 378 List: params, 379 } 380 } 381 382 func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList { 383 logf(" [%s] begin\n", __func__) 384 385 if p.tok.tok == "(" { 386 var r = p.parseParameters(scope, false) 387 logf(" [%s] end\n", __func__) 388 return r 389 } 390 391 if p.tok.tok == "{" { 392 logf(" [%s] end\n", __func__) 393 var _r *ast.FieldList = nil 394 return _r 395 } 396 var typ = p.tryType() 397 var list []*ast.Field 398 if typ != nil { 399 list = append(list, &ast.Field{ 400 Type: typ, 401 }) 402 } 403 logf(" [%s] end\n", __func__) 404 return &ast.FieldList{ 405 List: list, 406 } 407 } 408 409 func (p *parser) parseSignature(scope *ast.Scope) *ast.Signature { 410 logf(" [%s] begin\n", __func__) 411 var params *ast.FieldList 412 var results *ast.FieldList 413 params = p.parseParameters(scope, true) 414 results = p.parseResult(scope) 415 return &ast.Signature{ 416 Params: params, 417 Results: results, 418 } 419 } 420 421 func declareField(decl *ast.Field, scope *ast.Scope, kind ast.ObjKind, ident *ast.Ident) { 422 // declare 423 var obj = &ast.Object{ 424 Decl: decl, 425 Name: ident.Name, 426 Kind: kind, 427 } 428 429 ident.Obj = obj 430 431 // scope insert 432 if ident.Name != "_" { 433 scope.Insert(obj) 434 } 435 } 436 437 func declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, ident *ast.Ident) { 438 logf(" [declare] ident %s\n", ident.Name) 439 440 //valSpec.Name.Obj 441 var obj = &ast.Object{ 442 Decl: decl, 443 Name: ident.Name, 444 Kind: kind, 445 } 446 ident.Obj = obj 447 448 // scope insert 449 if ident.Name != "_" { 450 scope.Insert(obj) 451 } 452 logf(" [declare] end\n") 453 454 } 455 456 func (p *parser) resolve(x ast.Expr) { 457 p.tryResolve(x, true) 458 } 459 func (p *parser) tryResolve(x ast.Expr, collectUnresolved bool) { 460 if !isExprIdent(x) { 461 return 462 } 463 ident := x.(*ast.Ident) 464 if ident.Name == "_" { 465 return 466 } 467 468 var s *ast.Scope 469 for s = p.topScope; s != nil; s = s.Outer { 470 var obj = s.Lookup(ident.Name) 471 if obj != nil { 472 ident.Obj = obj 473 return 474 } 475 } 476 477 if collectUnresolved { 478 p.unresolved = append(p.unresolved, ident) 479 logf(" appended unresolved ident %s\n", ident.Name) 480 } 481 } 482 483 func (p *parser) parseOperand() ast.Expr { 484 logf(" begin %s\n", __func__) 485 switch p.tok.tok { 486 case "IDENT": 487 var ident = p.parseIdent() 488 var eIdent = (ident) 489 p.tryResolve(eIdent, true) 490 logf(" end %s\n", __func__) 491 return eIdent 492 case "INT", "STRING", "CHAR": 493 var basicLit = &ast.BasicLit{ 494 Kind: token.Token(p.tok.tok), 495 Value: p.tok.lit, 496 } 497 p.next() 498 logf(" end %s\n", __func__) 499 return (basicLit) 500 case "(": 501 p.next() // consume "(" 502 parserExprLev++ 503 var x = p.parseRhsOrType() 504 parserExprLev-- 505 p.expect(")", __func__) 506 return (&ast.ParenExpr{ 507 X: x, 508 }) 509 } 510 511 var typ = p.tryIdentOrType() 512 if typ == nil { 513 panic2(__func__, "# typ should not be nil\n") 514 } 515 logf(" end %s\n", __func__) 516 517 return typ 518 } 519 520 func (p *parser) parseRhsOrType() ast.Expr { 521 var x = p.parseExpr() 522 return x 523 } 524 525 func (p *parser) parseCallExpr(fn ast.Expr) ast.Expr { 526 p.expect("(", __func__) 527 logf(" [parsePrimaryExpr] p.tok.tok=%s\n", p.tok.tok) 528 var list []ast.Expr 529 var ellipsis token.Pos 530 for p.tok.tok != ")" { 531 var arg = p.parseExpr() 532 list = append(list, arg) 533 if p.tok.tok == "," { 534 p.next() 535 } else if p.tok.tok == ")" { 536 break 537 } else if p.tok.tok == "..." { 538 // f(a, b, c...) 539 // ^ this 540 break 541 } 542 } 543 544 if p.tok.tok == "..." { 545 p.next() 546 ellipsis = 1 // this means true 547 } 548 549 p.expect(")", __func__) 550 return (&ast.CallExpr{ 551 Fun: fn, 552 Args: list, 553 Ellipsis: ellipsis, 554 }) 555 } 556 557 var parserExprLev int // < 0: in control clause, >= 0: in expression 558 559 func (p *parser) parsePrimaryExpr() ast.Expr { 560 logf(" begin %s\n", __func__) 561 var x = p.parseOperand() 562 563 var cnt int 564 565 for { 566 cnt++ 567 logf(" [%s] tok=%s\n", __func__, p.tok.tok) 568 if cnt > 100 { 569 panic2(__func__, "too many iteration") 570 } 571 572 switch p.tok.tok { 573 case ".": 574 p.next() // consume "." 575 576 switch p.tok.tok { 577 case "IDENT": 578 // Assume CallExpr 579 var secondIdent = p.parseIdent() 580 var sel = &ast.SelectorExpr{ 581 X: x, 582 Sel: secondIdent, 583 } 584 if p.tok.tok == "(" { 585 var fn = (sel) 586 // string = x.ident.Name + "." + secondIdent 587 x = p.parseCallExpr(fn) 588 logf(" [parsePrimaryExpr] 741 p.tok.tok=%s\n", p.tok.tok) 589 } else { 590 logf(" end parsePrimaryExpr()\n") 591 x = (sel) 592 } 593 case "(": // type assertion 594 x = p.parseTypeAssertion(x) 595 default: 596 panic2(__func__, "Unexpected token:"+p.tok.tok) 597 } 598 case "(": 599 x = p.parseCallExpr(x) 600 case "[": 601 p.resolve(x) 602 x = p.parseIndexOrSlice(x) 603 case "{": 604 if isLiteralType(x) && parserExprLev >= 0 { 605 x = p.parseLiteralValue(x) 606 } else { 607 return x 608 } 609 default: 610 logf(" end %s\n", __func__) 611 return x 612 } 613 } 614 615 logf(" end %s\n", __func__) 616 return x 617 } 618 619 func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr { 620 p.expect("(", __func__) 621 typ := p.parseType() 622 p.expect(")", __func__) 623 return (&ast.TypeAssertExpr{ 624 X: x, 625 Type: typ, 626 }) 627 } 628 629 func (p *parser) parseElement() ast.Expr { 630 var x = p.parseExpr() // key or value 631 var v ast.Expr 632 var kvExpr *ast.KeyValueExpr 633 if p.tok.tok == ":" { 634 p.next() // skip ":" 635 v = p.parseExpr() 636 kvExpr = &ast.KeyValueExpr{ 637 Key: x, 638 Value: v, 639 } 640 x = (kvExpr) 641 } 642 return x 643 } 644 645 func (p *parser) parseElementList() []ast.Expr { 646 var list []ast.Expr 647 var e ast.Expr 648 for p.tok.tok != "}" { 649 e = p.parseElement() 650 list = append(list, e) 651 if p.tok.tok != "," { 652 break 653 } 654 p.expect(",", __func__) 655 } 656 return list 657 } 658 659 func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr { 660 logf(" start %s\n", __func__) 661 p.expect("{", __func__) 662 var elts []ast.Expr 663 if p.tok.tok != "}" { 664 elts = p.parseElementList() 665 } 666 p.expect("}", __func__) 667 668 logf(" end %s\n", __func__) 669 return (&ast.CompositeLit{ 670 Type: typ, 671 Elts: elts, 672 }) 673 } 674 675 func isLiteralType(expr ast.Expr) bool { 676 switch e := expr.(type) { 677 case *ast.Ident: 678 case *ast.SelectorExpr: 679 return isExprIdent(e.X) 680 case *ast.ArrayType: 681 case *ast.StructType: 682 //case *ast.MapType: 683 default: 684 return false 685 } 686 687 return true 688 } 689 690 func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr { 691 p.expect("[", __func__) 692 var index = make([]ast.Expr, 3, 3) 693 if p.tok.tok != ":" { 694 index[0] = p.parseRhs() 695 } 696 var ncolons int 697 for p.tok.tok == ":" && ncolons < 2 { 698 ncolons++ 699 p.next() // consume ":" 700 if p.tok.tok != ":" && p.tok.tok != "]" { 701 index[ncolons] = p.parseRhs() 702 } 703 } 704 p.expect("]", __func__) 705 706 if ncolons > 0 { 707 // slice expression 708 var sliceExpr = &ast.SliceExpr{ 709 Slice3: false, 710 X: x, 711 Low: index[0], 712 High: index[1], 713 } 714 if ncolons == 2 { 715 sliceExpr.Max = index[2] 716 } 717 return (sliceExpr) 718 } 719 720 var indexExpr = &ast.IndexExpr{} 721 indexExpr.X = x 722 indexExpr.Index = index[0] 723 return (indexExpr) 724 } 725 726 func (p *parser) parseUnaryExpr() ast.Expr { 727 var r ast.Expr 728 logf(" begin parseUnaryExpr()\n") 729 switch p.tok.tok { 730 case "+", "-", "!", "&": 731 var tok = p.tok.tok 732 p.next() 733 var x = p.parseUnaryExpr() 734 logf(" [DEBUG] unary op = %s\n", tok) 735 r = (&ast.UnaryExpr{ 736 X: x, 737 Op: token.Token(tok), 738 }) 739 return r 740 case "*": 741 p.next() // consume "*" 742 var x = p.parseUnaryExpr() 743 r = (&ast.StarExpr{ 744 X: x, 745 }) 746 return r 747 } 748 r = p.parsePrimaryExpr() 749 logf(" end parseUnaryExpr()\n") 750 return r 751 } 752 753 const LowestPrec int = 0 754 755 func precedence(op string) int { 756 switch op { 757 case "||": 758 return 1 759 case "&&": 760 return 2 761 case "==", "!=", "<", "<=", ">", ">=": 762 return 3 763 case "+", "-": 764 return 4 765 case "*", "/", "%": 766 return 5 767 default: 768 return 0 769 } 770 return 0 771 } 772 773 func (p *parser) parseBinaryExpr(prec1 int) ast.Expr { 774 logf(" begin parseBinaryExpr() prec1=%s\n", strconv.Itoa(prec1)) 775 var x = p.parseUnaryExpr() 776 var oprec int 777 for { 778 var op = p.tok.tok 779 oprec = precedence(op) 780 logf(" oprec %s\n", strconv.Itoa(oprec)) 781 logf(" precedence \"%s\" %s < %s\n", op, strconv.Itoa(oprec), strconv.Itoa(prec1)) 782 if oprec < prec1 { 783 logf(" end parseBinaryExpr() (NonBinary)\n") 784 return x 785 } 786 p.expect(op, __func__) 787 var y = p.parseBinaryExpr(oprec + 1) 788 var binaryExpr = &ast.BinaryExpr{} 789 binaryExpr.X = x 790 binaryExpr.Y = y 791 binaryExpr.Op = token.Token(op) 792 var r = (binaryExpr) 793 x = r 794 } 795 logf(" end parseBinaryExpr()\n") 796 return x 797 } 798 799 func (p *parser) parseExpr() ast.Expr { 800 logf(" begin p.parseExpr()\n") 801 var e = p.parseBinaryExpr(1) 802 logf(" end p.parseExpr()\n") 803 return e 804 } 805 806 func (p *parser) parseRhs() ast.Expr { 807 var x = p.parseExpr() 808 return x 809 } 810 811 // Extract ast.Expr from ExprStmt. Returns nil if input is nil 812 func makeExpr(s ast.Stmt) ast.Expr { 813 logf(" begin %s\n", __func__) 814 if s == nil { 815 var r ast.Expr 816 return r 817 } 818 return s.(*ast.ExprStmt).X 819 } 820 821 func (p *parser) parseForStmt() ast.Stmt { 822 logf(" begin %s\n", __func__) 823 p.expect("for", __func__) 824 p.openScope() 825 826 var s1 ast.Stmt 827 var s2 ast.Stmt 828 var s3 ast.Stmt 829 var isRange bool 830 parserExprLev = -1 831 if p.tok.tok != "{" { 832 if p.tok.tok != ";" { 833 s2 = p.parseSimpleStmt(true) 834 var isAssign bool 835 var assign *ast.AssignStmt 836 assign, isAssign = s2.(*ast.AssignStmt) 837 isRange = isAssign && assign.IsRange 838 logf(" [%s] isRange=true\n", __func__) 839 } 840 if !isRange && p.tok.tok == ";" { 841 p.next() // consume ";" 842 s1 = s2 843 s2 = nil 844 if p.tok.tok != ";" { 845 s2 = p.parseSimpleStmt(false) 846 } 847 p.expectSemi(__func__) 848 if p.tok.tok != "{" { 849 s3 = p.parseSimpleStmt(false) 850 } 851 } 852 } 853 854 parserExprLev = 0 855 var body = p.parseBlockStmt() 856 p.expectSemi(__func__) 857 858 var as *ast.AssignStmt 859 var rangeX ast.Expr 860 if isRange { 861 as = s2.(*ast.AssignStmt) 862 logf(" [DEBUG] range as len lhs=%s\n", strconv.Itoa(len(as.Lhs))) 863 var key ast.Expr 864 var value ast.Expr 865 switch len(as.Lhs) { 866 case 0: 867 case 1: 868 key = as.Lhs[0] 869 case 2: 870 key = as.Lhs[0] 871 value = as.Lhs[1] 872 default: 873 panic2(__func__, "Unexpected len of as.Lhs") 874 } 875 876 rangeX = as.Rhs[0].(*ast.UnaryExpr).X 877 var rangeStmt = &ast.RangeStmt{} 878 rangeStmt.Key = key 879 rangeStmt.Value = value 880 rangeStmt.X = rangeX 881 rangeStmt.Body = body 882 rangeStmt.Tok = token.Token(as.Tok) 883 p.closeScope() 884 logf(" end %s\n", __func__) 885 return rangeStmt 886 } 887 var forStmt = &ast.ForStmt{} 888 forStmt.Init = s1 889 forStmt.Cond = makeExpr(s2) 890 forStmt.Post = s3 891 forStmt.Body = body 892 p.closeScope() 893 logf(" end %s\n", __func__) 894 return forStmt 895 } 896 897 func (p *parser) parseIfStmt() ast.Stmt { 898 p.expect("if", __func__) 899 parserExprLev = -1 900 var condStmt ast.Stmt = p.parseSimpleStmt(false) 901 exprStmt := condStmt.(*ast.ExprStmt) 902 var cond = exprStmt.X 903 parserExprLev = 0 904 var body = p.parseBlockStmt() 905 var else_ ast.Stmt 906 if p.tok.tok == "else" { 907 p.next() 908 if p.tok.tok == "if" { 909 else_ = p.parseIfStmt() 910 } else { 911 var elseblock = p.parseBlockStmt() 912 p.expectSemi(__func__) 913 else_ = elseblock 914 } 915 } else { 916 p.expectSemi(__func__) 917 } 918 var ifStmt = &ast.IfStmt{} 919 ifStmt.Cond = cond 920 ifStmt.Body = body 921 ifStmt.Else = else_ 922 923 return ifStmt 924 } 925 926 func (p *parser) parseCaseClause() *ast.CaseClause { 927 logf(" [%s] start\n", __func__) 928 var list []ast.Expr 929 if p.tok.tok == "case" { 930 p.next() // consume "case" 931 list = p.parseRhsList() 932 } else { 933 p.expect("default", __func__) 934 } 935 p.expect(":", __func__) 936 p.openScope() 937 var body = p.parseStmtList() 938 var r = &ast.CaseClause{} 939 r.Body = body 940 r.List = list 941 p.closeScope() 942 logf(" [%s] end\n", __func__) 943 return r 944 } 945 946 func isTypeSwitchAssert(e ast.Expr) bool { 947 _, ok := e.(*ast.TypeAssertExpr) 948 return ok 949 } 950 951 func isTypeSwitchGuard(stmt ast.Stmt) bool { 952 switch s := stmt.(type) { 953 case *ast.ExprStmt: 954 if isTypeSwitchAssert(s.X) { 955 return true 956 } 957 case *ast.AssignStmt: 958 if len(s.Lhs) == 1 && len(s.Rhs) == 1 && isTypeSwitchAssert(s.Rhs[0]) { 959 return true 960 } 961 } 962 return false 963 } 964 965 func (p *parser) parseSwitchStmt() ast.Stmt { 966 p.expect("switch", __func__) 967 p.openScope() 968 969 var s2 ast.Stmt 970 parserExprLev = -1 971 s2 = p.parseSimpleStmt(false) 972 parserExprLev = 0 973 974 p.expect("{", __func__) 975 var list []ast.Stmt 976 var cc *ast.CaseClause 977 var ccs ast.Stmt 978 for p.tok.tok == "case" || p.tok.tok == "default" { 979 cc = p.parseCaseClause() 980 ccs = cc 981 list = append(list, ccs) 982 } 983 p.expect("}", __func__) 984 p.expectSemi(__func__) 985 var body = &ast.BlockStmt{} 986 body.List = list 987 988 typeSwitch := isTypeSwitchGuard(s2) 989 990 p.closeScope() 991 if typeSwitch { 992 return &ast.TypeSwitchStmt{ 993 Assign: s2, 994 Body: body, 995 } 996 } else { 997 return &ast.SwitchStmt{ 998 Body: body, 999 Tag: makeExpr(s2), 1000 } 1001 } 1002 } 1003 1004 func (p *parser) parseLhsList() []ast.Expr { 1005 logf(" [%s] start\n", __func__) 1006 var list = p.parseExprList() 1007 logf(" end %s\n", __func__) 1008 return list 1009 } 1010 1011 func (p *parser) parseSimpleStmt(isRangeOK bool) ast.Stmt { 1012 logf(" begin %s\n", __func__) 1013 var x = p.parseLhsList() 1014 stok := p.tok.tok 1015 var isRange = false 1016 var y ast.Expr 1017 var rangeX ast.Expr 1018 var rangeUnary *ast.UnaryExpr 1019 switch stok { 1020 case ":=", "=", "+=", "-=": 1021 var assignToken = stok 1022 p.next() // consume = 1023 if isRangeOK && p.tok.tok == "range" { 1024 p.next() // consume "range" 1025 rangeX = p.parseRhs() 1026 rangeUnary = &ast.UnaryExpr{} 1027 rangeUnary.Op = "range" 1028 rangeUnary.X = rangeX 1029 y = (rangeUnary) 1030 isRange = true 1031 } else { 1032 y = p.parseExpr() // rhs 1033 } 1034 var as = &ast.AssignStmt{} 1035 as.Tok = token.Token(assignToken) 1036 as.Lhs = x 1037 as.Rhs = make([]ast.Expr, 1, 1) 1038 as.Rhs[0] = y 1039 as.IsRange = isRange 1040 s := as 1041 if as.Tok == ":=" { 1042 lhss := x 1043 for _, lhs := range lhss { 1044 declare(as, p.topScope, ast.Var, lhs.(*ast.Ident)) 1045 } 1046 } 1047 logf(" parseSimpleStmt end =, := %s\n", __func__) 1048 return s 1049 case ";": 1050 var exprStmt = &ast.ExprStmt{} 1051 exprStmt.X = x[0] 1052 logf(" parseSimpleStmt end ; %s\n", __func__) 1053 return exprStmt 1054 } 1055 1056 switch stok { 1057 case "++", "--": 1058 var sInc = &ast.IncDecStmt{} 1059 sInc.X = x[0] 1060 sInc.Tok = token.Token(stok) 1061 p.next() // consume "++" or "--" 1062 return sInc 1063 } 1064 var exprStmt = &ast.ExprStmt{} 1065 exprStmt.X = x[0] 1066 logf(" parseSimpleStmt end (final) %s\n", __func__) 1067 return exprStmt 1068 } 1069 1070 func (p *parser) parseStmt() ast.Stmt { 1071 logf("\n") 1072 logf(" = begin %s\n", __func__) 1073 var s ast.Stmt 1074 switch p.tok.tok { 1075 case "var": 1076 s = &ast.DeclStmt{ 1077 Decl: p.parseDecl("var"), 1078 } 1079 logf(" = end parseStmt()\n") 1080 case "IDENT", "*": 1081 s = p.parseSimpleStmt(false) 1082 p.expectSemi(__func__) 1083 case "return": 1084 s = p.parseReturnStmt() 1085 case "break", "continue": 1086 s = p.parseBranchStmt(p.tok.tok) 1087 case "if": 1088 s = p.parseIfStmt() 1089 case "switch": 1090 s = p.parseSwitchStmt() 1091 case "for": 1092 s = p.parseForStmt() 1093 default: 1094 panic2(__func__, "TBI 3:"+p.tok.tok) 1095 } 1096 logf(" = end parseStmt()\n") 1097 return s 1098 } 1099 1100 func (p *parser) parseExprList() []ast.Expr { 1101 logf(" [%s] start\n", __func__) 1102 var list []ast.Expr 1103 var e = p.parseExpr() 1104 list = append(list, e) 1105 for p.tok.tok == "," { 1106 p.next() // consume "," 1107 e = p.parseExpr() 1108 list = append(list, e) 1109 } 1110 1111 logf(" [%s] end\n", __func__) 1112 return list 1113 } 1114 1115 func (p *parser) parseRhsList() []ast.Expr { 1116 var list = p.parseExprList() 1117 return list 1118 } 1119 1120 func (p *parser) parseBranchStmt(tok string) ast.Stmt { 1121 p.expect(tok, __func__) 1122 1123 p.expectSemi(__func__) 1124 1125 var branchStmt = &ast.BranchStmt{} 1126 branchStmt.Tok = token.Token(tok) 1127 return branchStmt 1128 } 1129 1130 func (p *parser) parseReturnStmt() ast.Stmt { 1131 p.expect("return", __func__) 1132 var x []ast.Expr 1133 if p.tok.tok != ";" && p.tok.tok != "}" { 1134 x = p.parseRhsList() 1135 } 1136 p.expectSemi(__func__) 1137 var returnStmt = &ast.ReturnStmt{} 1138 returnStmt.Results = x 1139 return returnStmt 1140 } 1141 1142 func (p *parser) parseStmtList() []ast.Stmt { 1143 var list []ast.Stmt 1144 for p.tok.tok != "}" && p.tok.tok != "EOF" && p.tok.tok != "case" && p.tok.tok != "default" { 1145 var stmt = p.parseStmt() 1146 list = append(list, stmt) 1147 } 1148 return list 1149 } 1150 1151 func (p *parser) parseBody(scope *ast.Scope) *ast.BlockStmt { 1152 p.expect("{", __func__) 1153 p.topScope = scope 1154 logf(" begin parseStmtList()\n") 1155 var list = p.parseStmtList() 1156 logf(" end parseStmtList()\n") 1157 1158 p.closeScope() 1159 p.expect("}", __func__) 1160 var r = &ast.BlockStmt{} 1161 r.List = list 1162 return r 1163 } 1164 1165 func (p *parser) parseBlockStmt() *ast.BlockStmt { 1166 p.expect("{", __func__) 1167 p.openScope() 1168 logf(" begin parseStmtList()\n") 1169 var list = p.parseStmtList() 1170 logf(" end parseStmtList()\n") 1171 p.closeScope() 1172 p.expect("}", __func__) 1173 var r = &ast.BlockStmt{} 1174 r.List = list 1175 return r 1176 } 1177 1178 func (p *parser) parseDecl(keyword string) *ast.GenDecl { 1179 var r *ast.GenDecl 1180 switch p.tok.tok { 1181 case "var": 1182 p.expect(keyword, __func__) 1183 var ident = p.parseIdent() 1184 var typ = p.parseType() 1185 var value ast.Expr 1186 var values []ast.Expr 1187 if p.tok.tok == "=" { 1188 p.next() 1189 value = p.parseExpr() 1190 values = []ast.Expr{value} 1191 } 1192 p.expectSemi(__func__) 1193 names := []*ast.Ident{ident} 1194 valSpec := &ast.ValueSpec{ 1195 Names: names, 1196 Type: typ, 1197 Values: values, 1198 } 1199 declare(valSpec, p.topScope, ast.Var, ident) 1200 specs := []ast.Spec{valSpec} 1201 return &ast.GenDecl{ 1202 Specs: specs, 1203 } 1204 default: 1205 panic2(__func__, "TBI\n") 1206 } 1207 return r 1208 } 1209 1210 func (p *parser) parserTypeSpec() *ast.TypeSpec { 1211 logf(" [%s] start\n", __func__) 1212 p.expect("type", __func__) 1213 var ident = p.parseIdent() 1214 logf(" decl type %s\n", ident.Name) 1215 1216 var spec = &ast.TypeSpec{} 1217 spec.Name = ident 1218 declare(spec, p.topScope, ast.Typ, ident) 1219 if p.tok.tok == "=" { 1220 // type alias 1221 p.next() 1222 spec.Assign = true 1223 } 1224 var typ = p.parseType() 1225 1226 p.expectSemi(__func__) 1227 spec.Type = typ 1228 return spec 1229 } 1230 1231 func (p *parser) parseValueSpec(keyword string) *ast.ValueSpec { 1232 logf(" [parserValueSpec] start\n") 1233 p.expect(keyword, __func__) 1234 var ident = p.parseIdent() 1235 logf(" var = %s\n", ident.Name) 1236 var typ = p.parseType() 1237 var value ast.Expr 1238 var values []ast.Expr 1239 if p.tok.tok == "=" { 1240 p.next() 1241 value = p.parseExpr() 1242 values = []ast.Expr{value} 1243 } 1244 p.expectSemi(__func__) 1245 names := []*ast.Ident{ident} 1246 spec := &ast.ValueSpec{ 1247 Names: names, 1248 Type: typ, 1249 Values: values, 1250 } 1251 var kind = ast.Con 1252 if keyword == "var" { 1253 kind = ast.Var 1254 } 1255 declare(spec, p.topScope, kind, ident) 1256 logf(" [parserValueSpec] end\n") 1257 return spec 1258 } 1259 1260 func (p *parser) parseFuncDecl() ast.Decl { 1261 p.expect("func", __func__) 1262 var scope = ast.NewScope(p.topScope) // function scope 1263 var receivers *ast.FieldList 1264 if p.tok.tok == "(" { 1265 logf(" [parserFuncDecl] parsing method") 1266 receivers = p.parseParameters(scope, false) 1267 } else { 1268 logf(" [parserFuncDecl] parsing function") 1269 } 1270 var ident = p.parseIdent() // func name 1271 var sig = p.parseSignature(scope) 1272 var params = sig.Params 1273 var results = sig.Results 1274 if results == nil { 1275 logf(" [parserFuncDecl] %s sig.results is nil\n", ident.Name) 1276 } else { 1277 logf(" [parserFuncDecl] %s sig.results.List = %s\n", ident.Name, strconv.Itoa(len(sig.Results.List))) 1278 } 1279 var body *ast.BlockStmt 1280 if p.tok.tok == "{" { 1281 logf(" begin parseBody()\n") 1282 body = p.parseBody(scope) 1283 logf(" end parseBody()\n") 1284 p.expectSemi(__func__) 1285 } else { 1286 logf(" no function body\n") 1287 p.expectSemi(__func__) 1288 } 1289 var decl ast.Decl 1290 1291 var funcDecl = &ast.FuncDecl{} 1292 funcDecl.Recv = receivers 1293 funcDecl.Name = ident 1294 funcDecl.Type = &ast.FuncType{} 1295 funcDecl.Type.Params = params 1296 funcDecl.Type.Results = results 1297 funcDecl.Body = body 1298 decl = funcDecl 1299 if receivers == nil { 1300 declare(funcDecl, p.pkgScope, ast.Fun, ident) 1301 } 1302 return decl 1303 } 1304 1305 func (p *parser) parseFile(importsOnly bool) *ast.File { 1306 // expect "package" keyword 1307 p.expect("package", __func__) 1308 p.unresolved = nil 1309 var ident = p.parseIdent() 1310 packageName := ident 1311 p.expectSemi(__func__) 1312 1313 p.topScope = ast.NewScope(nil) // open scope 1314 p.pkgScope = p.topScope 1315 1316 for p.tok.tok == "import" { 1317 p.expect("import", __func__) 1318 if p.tok.tok == "(" { 1319 p.next() 1320 for p.tok.tok != ")" { 1321 p.parseImportSpec() 1322 p.expectSemi(__func__) 1323 } 1324 p.next() 1325 p.expectSemi(__func__) 1326 } else { 1327 p.parseImportSpec() 1328 p.expectSemi(__func__) 1329 } 1330 } 1331 1332 logf("\n") 1333 logf(" [parser] Parsing Top level decls\n") 1334 var decls []ast.Decl 1335 var decl ast.Decl 1336 1337 for !importsOnly && p.tok.tok != "EOF" { 1338 switch p.tok.tok { 1339 case "var", "const": 1340 var spec = p.parseValueSpec(p.tok.tok) 1341 specs := []ast.Spec{spec} 1342 decl = &ast.GenDecl{ 1343 Specs: specs, 1344 } 1345 case "func": 1346 logf("\n\n") 1347 decl = p.parseFuncDecl() 1348 //logf(" func decl parsed:%s\n", decl.funcDecl.Name.Name) 1349 case "type": 1350 spec := p.parserTypeSpec() 1351 specs := []ast.Spec{spec} 1352 decl = &ast.GenDecl{ 1353 Specs: specs, 1354 } 1355 logf(" type parsed:%s\n", "") 1356 default: 1357 panic2(__func__, "TBI:"+p.tok.tok) 1358 } 1359 decls = append(decls, decl) 1360 } 1361 1362 p.topScope = nil 1363 1364 // dump p.pkgScope 1365 logf("[DEBUG] Dump objects in the package scope\n") 1366 1367 var unresolved []*ast.Ident 1368 logf(" [parserFile] resolving parser's unresolved (n=%s)\n", strconv.Itoa(len(p.unresolved))) 1369 for _, idnt := range p.unresolved { 1370 logf(" [parserFile] resolving ident %s ...\n", idnt.Name) 1371 ps := p.pkgScope 1372 var obj *ast.Object = ps.Lookup(idnt.Name) 1373 if obj != nil { 1374 logf(" resolved \n") 1375 idnt.Obj = obj 1376 } else { 1377 logf(" unresolved \n") 1378 unresolved = append(unresolved, idnt) 1379 } 1380 } 1381 logf(" [parserFile] Unresolved (n=%s)\n", strconv.Itoa(len(unresolved))) 1382 1383 var f = &ast.File{} 1384 f.Name = packageName 1385 f.Scope = p.pkgScope 1386 f.Decls = decls 1387 f.Unresolved = unresolved 1388 f.Imports = p.imports 1389 logf(" [%s] end\n", __func__) 1390 return f 1391 } 1392 1393 func readSource(filename string) []uint8 { 1394 return readFile(filename) 1395 } 1396 1397 const parserImportsOnly = 1 1398 1399 func parserParseFile(fset *token.FileSet, filename string, src interface{}, mode uint8) (*ast.File, *ParserError) { 1400 var importsOnly bool 1401 if mode == parserImportsOnly { 1402 importsOnly = true 1403 } 1404 1405 var text = readSource(filename) 1406 1407 var p = &parser{} 1408 p.scanner = &scanner{} 1409 p.init(text) 1410 return p.parseFile(importsOnly), nil 1411 } 1412 1413 func isExprIdent(e ast.Expr) bool { 1414 _, ok := e.(*ast.Ident) 1415 return ok 1416 } 1417 1418 func panic2(caller string, x string) { 1419 panic(caller + ": " + x) 1420 } 1421 1422 type ParserError struct { 1423 msg string 1424 } 1425 1426 func (err *ParserError) Error() string { 1427 return err.msg 1428 }