github.com/aloncn/graphics-go@v0.0.1/src/go/internal/gccgoimporter/parser.go (about)

     1  // Copyright 2013 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 gccgoimporter
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"fmt"
    11  	"go/constant"
    12  	"go/token"
    13  	"go/types"
    14  	"io"
    15  	"strconv"
    16  	"strings"
    17  	"text/scanner"
    18  )
    19  
    20  type parser struct {
    21  	scanner  scanner.Scanner
    22  	tok      rune                      // current token
    23  	lit      string                    // literal string; only valid for Ident, Int, String tokens
    24  	pkgpath  string                    // package path of imported package
    25  	pkgname  string                    // name of imported package
    26  	pkg      *types.Package            // reference to imported package
    27  	imports  map[string]*types.Package // package path -> package object
    28  	typeMap  map[int]types.Type        // type number -> type
    29  	initdata InitData                  // package init priority data
    30  }
    31  
    32  func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
    33  	p.scanner.Init(src)
    34  	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
    35  	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
    36  	p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' '
    37  	p.scanner.Filename = filename // for good error messages
    38  	p.next()
    39  	p.imports = imports
    40  	p.typeMap = make(map[int]types.Type)
    41  }
    42  
    43  type importError struct {
    44  	pos scanner.Position
    45  	err error
    46  }
    47  
    48  func (e importError) Error() string {
    49  	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
    50  }
    51  
    52  func (p *parser) error(err interface{}) {
    53  	if s, ok := err.(string); ok {
    54  		err = errors.New(s)
    55  	}
    56  	// panic with a runtime.Error if err is not an error
    57  	panic(importError{p.scanner.Pos(), err.(error)})
    58  }
    59  
    60  func (p *parser) errorf(format string, args ...interface{}) {
    61  	p.error(fmt.Errorf(format, args...))
    62  }
    63  
    64  func (p *parser) expect(tok rune) string {
    65  	lit := p.lit
    66  	if p.tok != tok {
    67  		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
    68  	}
    69  	p.next()
    70  	return lit
    71  }
    72  
    73  func (p *parser) expectKeyword(keyword string) {
    74  	lit := p.expect(scanner.Ident)
    75  	if lit != keyword {
    76  		p.errorf("expected keyword %s, got %q", keyword, lit)
    77  	}
    78  }
    79  
    80  func (p *parser) parseString() string {
    81  	str, err := strconv.Unquote(p.expect(scanner.String))
    82  	if err != nil {
    83  		p.error(err)
    84  	}
    85  	return str
    86  }
    87  
    88  // unquotedString     = { unquotedStringChar } .
    89  // unquotedStringChar = <neither a whitespace nor a ';' char> .
    90  func (p *parser) parseUnquotedString() string {
    91  	if p.tok == scanner.EOF {
    92  		p.error("unexpected EOF")
    93  	}
    94  	var buf bytes.Buffer
    95  	buf.WriteString(p.scanner.TokenText())
    96  	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
    97  	// we need to let it be consumed by p.next().
    98  	for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
    99  		buf.WriteRune(ch)
   100  		p.scanner.Next()
   101  	}
   102  	p.next()
   103  	return buf.String()
   104  }
   105  
   106  func (p *parser) next() {
   107  	p.tok = p.scanner.Scan()
   108  	switch p.tok {
   109  	case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท':
   110  		p.lit = p.scanner.TokenText()
   111  	default:
   112  		p.lit = ""
   113  	}
   114  }
   115  
   116  func (p *parser) parseQualifiedName() (path, name string) {
   117  	return p.parseQualifiedNameStr(p.parseString())
   118  }
   119  
   120  func (p *parser) parseUnquotedQualifiedName() (path, name string) {
   121  	return p.parseQualifiedNameStr(p.parseUnquotedString())
   122  }
   123  
   124  // qualifiedName = [ ["."] unquotedString "." ] unquotedString .
   125  //
   126  // The above production uses greedy matching.
   127  func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
   128  	parts := strings.Split(unquotedName, ".")
   129  	if parts[0] == "" {
   130  		parts = parts[1:]
   131  	}
   132  
   133  	switch len(parts) {
   134  	case 0:
   135  		p.errorf("malformed qualified name: %q", unquotedName)
   136  	case 1:
   137  		// unqualified name
   138  		pkgpath = p.pkgpath
   139  		name = parts[0]
   140  	default:
   141  		// qualified name, which may contain periods
   142  		pkgpath = strings.Join(parts[0:len(parts)-1], ".")
   143  		name = parts[len(parts)-1]
   144  	}
   145  
   146  	return
   147  }
   148  
   149  // getPkg returns the package for a given path. If the package is
   150  // not found but we have a package name, create the package and
   151  // add it to the p.imports map.
   152  //
   153  func (p *parser) getPkg(pkgpath, name string) *types.Package {
   154  	// package unsafe is not in the imports map - handle explicitly
   155  	if pkgpath == "unsafe" {
   156  		return types.Unsafe
   157  	}
   158  	pkg := p.imports[pkgpath]
   159  	if pkg == nil && name != "" {
   160  		pkg = types.NewPackage(pkgpath, name)
   161  		p.imports[pkgpath] = pkg
   162  	}
   163  	return pkg
   164  }
   165  
   166  // parseExportedName is like parseQualifiedName, but
   167  // the package path is resolved to an imported *types.Package.
   168  //
   169  // ExportedName = string [string] .
   170  func (p *parser) parseExportedName() (pkg *types.Package, name string) {
   171  	path, name := p.parseQualifiedName()
   172  	var pkgname string
   173  	if p.tok == scanner.String {
   174  		pkgname = p.parseString()
   175  	}
   176  	pkg = p.getPkg(path, pkgname)
   177  	if pkg == nil {
   178  		p.errorf("package %s (path = %q) not found", name, path)
   179  	}
   180  	return
   181  }
   182  
   183  // Name = QualifiedName | "?" .
   184  func (p *parser) parseName() string {
   185  	if p.tok == '?' {
   186  		// Anonymous.
   187  		p.next()
   188  		return ""
   189  	}
   190  	// The package path is redundant for us. Don't try to parse it.
   191  	_, name := p.parseUnquotedQualifiedName()
   192  	return name
   193  }
   194  
   195  func deref(typ types.Type) types.Type {
   196  	if p, _ := typ.(*types.Pointer); p != nil {
   197  		typ = p.Elem()
   198  	}
   199  	return typ
   200  }
   201  
   202  // Field = Name Type [string] .
   203  func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
   204  	name := p.parseName()
   205  	typ := p.parseType(pkg)
   206  	anon := false
   207  	if name == "" {
   208  		anon = true
   209  		switch typ := deref(typ).(type) {
   210  		case *types.Basic:
   211  			name = typ.Name()
   212  		case *types.Named:
   213  			name = typ.Obj().Name()
   214  		default:
   215  			p.error("anonymous field expected")
   216  		}
   217  	}
   218  	field = types.NewField(token.NoPos, pkg, name, typ, anon)
   219  	if p.tok == scanner.String {
   220  		tag = p.parseString()
   221  	}
   222  	return
   223  }
   224  
   225  // Param = Name ["..."] Type .
   226  func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) {
   227  	name := p.parseName()
   228  	if p.tok == '.' {
   229  		p.next()
   230  		p.expect('.')
   231  		p.expect('.')
   232  		isVariadic = true
   233  	}
   234  	typ := p.parseType(pkg)
   235  	if isVariadic {
   236  		typ = types.NewSlice(typ)
   237  	}
   238  	param = types.NewParam(token.NoPos, pkg, name, typ)
   239  	return
   240  }
   241  
   242  // Var = Name Type .
   243  func (p *parser) parseVar(pkg *types.Package) *types.Var {
   244  	name := p.parseName()
   245  	return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
   246  }
   247  
   248  // ConstValue     = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) .
   249  // FloatOrComplex = float ["i" | ("+"|"-") float "i"] .
   250  func (p *parser) parseConstValue() (val constant.Value, typ types.Type) {
   251  	switch p.tok {
   252  	case scanner.String:
   253  		str := p.parseString()
   254  		val = constant.MakeString(str)
   255  		typ = types.Typ[types.UntypedString]
   256  		return
   257  
   258  	case scanner.Ident:
   259  		b := false
   260  		switch p.lit {
   261  		case "false":
   262  		case "true":
   263  			b = true
   264  
   265  		default:
   266  			p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   267  		}
   268  
   269  		p.next()
   270  		val = constant.MakeBool(b)
   271  		typ = types.Typ[types.UntypedBool]
   272  		return
   273  	}
   274  
   275  	sign := ""
   276  	if p.tok == '-' {
   277  		p.next()
   278  		sign = "-"
   279  	}
   280  
   281  	switch p.tok {
   282  	case scanner.Int:
   283  		val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
   284  		if val == nil {
   285  			p.error("could not parse integer literal")
   286  		}
   287  
   288  		p.next()
   289  		if p.tok == '\'' {
   290  			p.next()
   291  			typ = types.Typ[types.UntypedRune]
   292  		} else {
   293  			typ = types.Typ[types.UntypedInt]
   294  		}
   295  
   296  	case scanner.Float:
   297  		re := sign + p.lit
   298  		p.next()
   299  
   300  		var im string
   301  		switch p.tok {
   302  		case '+':
   303  			p.next()
   304  			im = p.expect(scanner.Float)
   305  
   306  		case '-':
   307  			p.next()
   308  			im = "-" + p.expect(scanner.Float)
   309  
   310  		case scanner.Ident:
   311  			// re is in fact the imaginary component. Expect "i" below.
   312  			im = re
   313  			re = "0"
   314  
   315  		default:
   316  			val = constant.MakeFromLiteral(re, token.FLOAT, 0)
   317  			if val == nil {
   318  				p.error("could not parse float literal")
   319  			}
   320  			typ = types.Typ[types.UntypedFloat]
   321  			return
   322  		}
   323  
   324  		p.expectKeyword("i")
   325  		reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
   326  		if reval == nil {
   327  			p.error("could not parse real component of complex literal")
   328  		}
   329  		imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
   330  		if imval == nil {
   331  			p.error("could not parse imag component of complex literal")
   332  		}
   333  		val = constant.BinaryOp(reval, token.ADD, imval)
   334  		typ = types.Typ[types.UntypedComplex]
   335  
   336  	default:
   337  		p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   338  	}
   339  
   340  	return
   341  }
   342  
   343  // Const = Name [Type] "=" ConstValue .
   344  func (p *parser) parseConst(pkg *types.Package) *types.Const {
   345  	name := p.parseName()
   346  	var typ types.Type
   347  	if p.tok == '<' {
   348  		typ = p.parseType(pkg)
   349  	}
   350  	p.expect('=')
   351  	val, vtyp := p.parseConstValue()
   352  	if typ == nil {
   353  		typ = vtyp
   354  	}
   355  	return types.NewConst(token.NoPos, pkg, name, typ, val)
   356  }
   357  
   358  // TypeName = ExportedName .
   359  func (p *parser) parseTypeName() *types.TypeName {
   360  	pkg, name := p.parseExportedName()
   361  	scope := pkg.Scope()
   362  	if obj := scope.Lookup(name); obj != nil {
   363  		return obj.(*types.TypeName)
   364  	}
   365  	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
   366  	// a named type may be referred to before the underlying type
   367  	// is known - set it up
   368  	types.NewNamed(obj, nil, nil)
   369  	scope.Insert(obj)
   370  	return obj
   371  }
   372  
   373  // NamedType = TypeName Type { Method } .
   374  // Method    = "func" "(" Param ")" Name ParamList ResultList ";" .
   375  func (p *parser) parseNamedType(n int) types.Type {
   376  	obj := p.parseTypeName()
   377  
   378  	pkg := obj.Pkg()
   379  	typ := obj.Type()
   380  	p.typeMap[n] = typ
   381  
   382  	nt, ok := typ.(*types.Named)
   383  	if !ok {
   384  		// This can happen for unsafe.Pointer, which is a TypeName holding a Basic type.
   385  		pt := p.parseType(pkg)
   386  		if pt != typ {
   387  			p.error("unexpected underlying type for non-named TypeName")
   388  		}
   389  		return typ
   390  	}
   391  
   392  	underlying := p.parseType(pkg)
   393  	if nt.Underlying() == nil {
   394  		nt.SetUnderlying(underlying.Underlying())
   395  	}
   396  
   397  	for p.tok == scanner.Ident {
   398  		// collect associated methods
   399  		p.expectKeyword("func")
   400  		p.expect('(')
   401  		receiver, _ := p.parseParam(pkg)
   402  		p.expect(')')
   403  		name := p.parseName()
   404  		params, isVariadic := p.parseParamList(pkg)
   405  		results := p.parseResultList(pkg)
   406  		p.expect(';')
   407  
   408  		sig := types.NewSignature(receiver, params, results, isVariadic)
   409  		nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
   410  	}
   411  
   412  	return nt
   413  }
   414  
   415  func (p *parser) parseInt() int64 {
   416  	lit := p.expect(scanner.Int)
   417  	n, err := strconv.ParseInt(lit, 10, 0)
   418  	if err != nil {
   419  		p.error(err)
   420  	}
   421  	return n
   422  }
   423  
   424  // ArrayOrSliceType = "[" [ int ] "]" Type .
   425  func (p *parser) parseArrayOrSliceType(pkg *types.Package) types.Type {
   426  	p.expect('[')
   427  	if p.tok == ']' {
   428  		p.next()
   429  		return types.NewSlice(p.parseType(pkg))
   430  	}
   431  
   432  	n := p.parseInt()
   433  	p.expect(']')
   434  	return types.NewArray(p.parseType(pkg), n)
   435  }
   436  
   437  // MapType = "map" "[" Type "]" Type .
   438  func (p *parser) parseMapType(pkg *types.Package) types.Type {
   439  	p.expectKeyword("map")
   440  	p.expect('[')
   441  	key := p.parseType(pkg)
   442  	p.expect(']')
   443  	elem := p.parseType(pkg)
   444  	return types.NewMap(key, elem)
   445  }
   446  
   447  // ChanType = "chan" ["<-" | "-<"] Type .
   448  func (p *parser) parseChanType(pkg *types.Package) types.Type {
   449  	p.expectKeyword("chan")
   450  	dir := types.SendRecv
   451  	switch p.tok {
   452  	case '-':
   453  		p.next()
   454  		p.expect('<')
   455  		dir = types.SendOnly
   456  
   457  	case '<':
   458  		// don't consume '<' if it belongs to Type
   459  		if p.scanner.Peek() == '-' {
   460  			p.next()
   461  			p.expect('-')
   462  			dir = types.RecvOnly
   463  		}
   464  	}
   465  
   466  	return types.NewChan(dir, p.parseType(pkg))
   467  }
   468  
   469  // StructType = "struct" "{" { Field } "}" .
   470  func (p *parser) parseStructType(pkg *types.Package) types.Type {
   471  	p.expectKeyword("struct")
   472  
   473  	var fields []*types.Var
   474  	var tags []string
   475  
   476  	p.expect('{')
   477  	for p.tok != '}' && p.tok != scanner.EOF {
   478  		field, tag := p.parseField(pkg)
   479  		p.expect(';')
   480  		fields = append(fields, field)
   481  		tags = append(tags, tag)
   482  	}
   483  	p.expect('}')
   484  
   485  	return types.NewStruct(fields, tags)
   486  }
   487  
   488  // ParamList = "(" [ { Parameter "," } Parameter ] ")" .
   489  func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) {
   490  	var list []*types.Var
   491  	isVariadic := false
   492  
   493  	p.expect('(')
   494  	for p.tok != ')' && p.tok != scanner.EOF {
   495  		if len(list) > 0 {
   496  			p.expect(',')
   497  		}
   498  		par, variadic := p.parseParam(pkg)
   499  		list = append(list, par)
   500  		if variadic {
   501  			if isVariadic {
   502  				p.error("... not on final argument")
   503  			}
   504  			isVariadic = true
   505  		}
   506  	}
   507  	p.expect(')')
   508  
   509  	return types.NewTuple(list...), isVariadic
   510  }
   511  
   512  // ResultList = Type | ParamList .
   513  func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
   514  	switch p.tok {
   515  	case '<':
   516  		return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg)))
   517  
   518  	case '(':
   519  		params, _ := p.parseParamList(pkg)
   520  		return params
   521  
   522  	default:
   523  		return nil
   524  	}
   525  }
   526  
   527  // FunctionType = ParamList ResultList .
   528  func (p *parser) parseFunctionType(pkg *types.Package) *types.Signature {
   529  	params, isVariadic := p.parseParamList(pkg)
   530  	results := p.parseResultList(pkg)
   531  	return types.NewSignature(nil, params, results, isVariadic)
   532  }
   533  
   534  // Func = Name FunctionType .
   535  func (p *parser) parseFunc(pkg *types.Package) *types.Func {
   536  	name := p.parseName()
   537  	if strings.ContainsRune(name, '$') {
   538  		// This is a Type$equal or Type$hash function, which we don't want to parse,
   539  		// except for the types.
   540  		p.discardDirectiveWhileParsingTypes(pkg)
   541  		return nil
   542  	}
   543  	return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg))
   544  }
   545  
   546  // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" .
   547  func (p *parser) parseInterfaceType(pkg *types.Package) types.Type {
   548  	p.expectKeyword("interface")
   549  
   550  	var methods []*types.Func
   551  	var typs []*types.Named
   552  
   553  	p.expect('{')
   554  	for p.tok != '}' && p.tok != scanner.EOF {
   555  		if p.tok == '?' {
   556  			p.next()
   557  			typs = append(typs, p.parseType(pkg).(*types.Named))
   558  		} else {
   559  			method := p.parseFunc(pkg)
   560  			methods = append(methods, method)
   561  		}
   562  		p.expect(';')
   563  	}
   564  	p.expect('}')
   565  
   566  	return types.NewInterface(methods, typs)
   567  }
   568  
   569  // PointerType = "*" ("any" | Type) .
   570  func (p *parser) parsePointerType(pkg *types.Package) types.Type {
   571  	p.expect('*')
   572  	if p.tok == scanner.Ident {
   573  		p.expectKeyword("any")
   574  		return types.Typ[types.UnsafePointer]
   575  	}
   576  	return types.NewPointer(p.parseType(pkg))
   577  }
   578  
   579  // TypeDefinition = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType .
   580  func (p *parser) parseTypeDefinition(pkg *types.Package, n int) types.Type {
   581  	var t types.Type
   582  	switch p.tok {
   583  	case scanner.String:
   584  		t = p.parseNamedType(n)
   585  
   586  	case scanner.Ident:
   587  		switch p.lit {
   588  		case "map":
   589  			t = p.parseMapType(pkg)
   590  
   591  		case "chan":
   592  			t = p.parseChanType(pkg)
   593  
   594  		case "struct":
   595  			t = p.parseStructType(pkg)
   596  
   597  		case "interface":
   598  			t = p.parseInterfaceType(pkg)
   599  		}
   600  
   601  	case '*':
   602  		t = p.parsePointerType(pkg)
   603  
   604  	case '[':
   605  		t = p.parseArrayOrSliceType(pkg)
   606  
   607  	case '(':
   608  		t = p.parseFunctionType(pkg)
   609  	}
   610  
   611  	p.typeMap[n] = t
   612  	return t
   613  }
   614  
   615  const (
   616  	// From gofrontend/go/export.h
   617  	// Note that these values are negative in the gofrontend and have been made positive
   618  	// in the gccgoimporter.
   619  	gccgoBuiltinINT8       = 1
   620  	gccgoBuiltinINT16      = 2
   621  	gccgoBuiltinINT32      = 3
   622  	gccgoBuiltinINT64      = 4
   623  	gccgoBuiltinUINT8      = 5
   624  	gccgoBuiltinUINT16     = 6
   625  	gccgoBuiltinUINT32     = 7
   626  	gccgoBuiltinUINT64     = 8
   627  	gccgoBuiltinFLOAT32    = 9
   628  	gccgoBuiltinFLOAT64    = 10
   629  	gccgoBuiltinINT        = 11
   630  	gccgoBuiltinUINT       = 12
   631  	gccgoBuiltinUINTPTR    = 13
   632  	gccgoBuiltinBOOL       = 15
   633  	gccgoBuiltinSTRING     = 16
   634  	gccgoBuiltinCOMPLEX64  = 17
   635  	gccgoBuiltinCOMPLEX128 = 18
   636  	gccgoBuiltinERROR      = 19
   637  	gccgoBuiltinBYTE       = 20
   638  	gccgoBuiltinRUNE       = 21
   639  )
   640  
   641  func lookupBuiltinType(typ int) types.Type {
   642  	return [...]types.Type{
   643  		gccgoBuiltinINT8:       types.Typ[types.Int8],
   644  		gccgoBuiltinINT16:      types.Typ[types.Int16],
   645  		gccgoBuiltinINT32:      types.Typ[types.Int32],
   646  		gccgoBuiltinINT64:      types.Typ[types.Int64],
   647  		gccgoBuiltinUINT8:      types.Typ[types.Uint8],
   648  		gccgoBuiltinUINT16:     types.Typ[types.Uint16],
   649  		gccgoBuiltinUINT32:     types.Typ[types.Uint32],
   650  		gccgoBuiltinUINT64:     types.Typ[types.Uint64],
   651  		gccgoBuiltinFLOAT32:    types.Typ[types.Float32],
   652  		gccgoBuiltinFLOAT64:    types.Typ[types.Float64],
   653  		gccgoBuiltinINT:        types.Typ[types.Int],
   654  		gccgoBuiltinUINT:       types.Typ[types.Uint],
   655  		gccgoBuiltinUINTPTR:    types.Typ[types.Uintptr],
   656  		gccgoBuiltinBOOL:       types.Typ[types.Bool],
   657  		gccgoBuiltinSTRING:     types.Typ[types.String],
   658  		gccgoBuiltinCOMPLEX64:  types.Typ[types.Complex64],
   659  		gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
   660  		gccgoBuiltinERROR:      types.Universe.Lookup("error").Type(),
   661  		gccgoBuiltinBYTE:       types.Universe.Lookup("byte").Type(),
   662  		gccgoBuiltinRUNE:       types.Universe.Lookup("rune").Type(),
   663  	}[typ]
   664  }
   665  
   666  // Type = "<" "type" ( "-" int | int [ TypeDefinition ] ) ">" .
   667  func (p *parser) parseType(pkg *types.Package) (t types.Type) {
   668  	p.expect('<')
   669  	p.expectKeyword("type")
   670  
   671  	switch p.tok {
   672  	case scanner.Int:
   673  		n := p.parseInt()
   674  
   675  		if p.tok == '>' {
   676  			t = p.typeMap[int(n)]
   677  		} else {
   678  			t = p.parseTypeDefinition(pkg, int(n))
   679  		}
   680  
   681  	case '-':
   682  		p.next()
   683  		n := p.parseInt()
   684  		t = lookupBuiltinType(int(n))
   685  
   686  	default:
   687  		p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
   688  		return nil
   689  	}
   690  
   691  	p.expect('>')
   692  	return
   693  }
   694  
   695  // PackageInit = unquotedString unquotedString int .
   696  func (p *parser) parsePackageInit() PackageInit {
   697  	name := p.parseUnquotedString()
   698  	initfunc := p.parseUnquotedString()
   699  	priority := int(p.parseInt())
   700  	return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
   701  }
   702  
   703  // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type.
   704  func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) {
   705  	for {
   706  		switch p.tok {
   707  		case ';':
   708  			return
   709  		case '<':
   710  			p.parseType(p.pkg)
   711  		case scanner.EOF:
   712  			p.error("unexpected EOF")
   713  		default:
   714  			p.next()
   715  		}
   716  	}
   717  }
   718  
   719  // Create the package if we have parsed both the package path and package name.
   720  func (p *parser) maybeCreatePackage() {
   721  	if p.pkgname != "" && p.pkgpath != "" {
   722  		p.pkg = p.getPkg(p.pkgpath, p.pkgname)
   723  	}
   724  }
   725  
   726  // InitDataDirective = "v1" ";" |
   727  //                     "priority" int ";" |
   728  //                     "init" { PackageInit } ";" |
   729  //                     "checksum" unquotedString ";" .
   730  func (p *parser) parseInitDataDirective() {
   731  	if p.tok != scanner.Ident {
   732  		// unexpected token kind; panic
   733  		p.expect(scanner.Ident)
   734  	}
   735  
   736  	switch p.lit {
   737  	case "v1":
   738  		p.next()
   739  		p.expect(';')
   740  
   741  	case "priority":
   742  		p.next()
   743  		p.initdata.Priority = int(p.parseInt())
   744  		p.expect(';')
   745  
   746  	case "init":
   747  		p.next()
   748  		for p.tok != ';' && p.tok != scanner.EOF {
   749  			p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
   750  		}
   751  		p.expect(';')
   752  
   753  	case "checksum":
   754  		// Don't let the scanner try to parse the checksum as a number.
   755  		defer func(mode uint) {
   756  			p.scanner.Mode = mode
   757  		}(p.scanner.Mode)
   758  		p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
   759  		p.next()
   760  		p.parseUnquotedString()
   761  		p.expect(';')
   762  
   763  	default:
   764  		p.errorf("unexpected identifier: %q", p.lit)
   765  	}
   766  }
   767  
   768  // Directive = InitDataDirective |
   769  //             "package" unquotedString ";" |
   770  //             "pkgpath" unquotedString ";" |
   771  //             "import" unquotedString unquotedString string ";" |
   772  //             "func" Func ";" |
   773  //             "type" Type ";" |
   774  //             "var" Var ";" |
   775  //             "const" Const ";" .
   776  func (p *parser) parseDirective() {
   777  	if p.tok != scanner.Ident {
   778  		// unexpected token kind; panic
   779  		p.expect(scanner.Ident)
   780  	}
   781  
   782  	switch p.lit {
   783  	case "v1", "priority", "init", "checksum":
   784  		p.parseInitDataDirective()
   785  
   786  	case "package":
   787  		p.next()
   788  		p.pkgname = p.parseUnquotedString()
   789  		p.maybeCreatePackage()
   790  		p.expect(';')
   791  
   792  	case "pkgpath":
   793  		p.next()
   794  		p.pkgpath = p.parseUnquotedString()
   795  		p.maybeCreatePackage()
   796  		p.expect(';')
   797  
   798  	case "import":
   799  		p.next()
   800  		pkgname := p.parseUnquotedString()
   801  		pkgpath := p.parseUnquotedString()
   802  		p.getPkg(pkgpath, pkgname)
   803  		p.parseString()
   804  		p.expect(';')
   805  
   806  	case "func":
   807  		p.next()
   808  		fun := p.parseFunc(p.pkg)
   809  		if fun != nil {
   810  			p.pkg.Scope().Insert(fun)
   811  		}
   812  		p.expect(';')
   813  
   814  	case "type":
   815  		p.next()
   816  		p.parseType(p.pkg)
   817  		p.expect(';')
   818  
   819  	case "var":
   820  		p.next()
   821  		v := p.parseVar(p.pkg)
   822  		p.pkg.Scope().Insert(v)
   823  		p.expect(';')
   824  
   825  	case "const":
   826  		p.next()
   827  		c := p.parseConst(p.pkg)
   828  		p.pkg.Scope().Insert(c)
   829  		p.expect(';')
   830  
   831  	default:
   832  		p.errorf("unexpected identifier: %q", p.lit)
   833  	}
   834  }
   835  
   836  // Package = { Directive } .
   837  func (p *parser) parsePackage() *types.Package {
   838  	for p.tok != scanner.EOF {
   839  		p.parseDirective()
   840  	}
   841  	for _, typ := range p.typeMap {
   842  		if it, ok := typ.(*types.Interface); ok {
   843  			it.Complete()
   844  		}
   845  	}
   846  	p.pkg.MarkComplete()
   847  	return p.pkg
   848  }
   849  
   850  // InitData = { InitDataDirective } .
   851  func (p *parser) parseInitData() {
   852  	for p.tok != scanner.EOF {
   853  		p.parseInitDataDirective()
   854  	}
   855  }