func init() { scope = ast.NewScope(nil) Universe = scope Bool = defType("bool") defType("byte") // TODO(gri) should be an alias for uint8 defType("complex64") Complex128 = defType("complex128") defType("float32") Float64 = defType("float64") defType("int8") defType("int16") defType("int32") defType("int64") String = defType("string") defType("uint8") defType("uint16") defType("uint32") defType("uint64") Int = defType("int") defType("uint") defType("uintptr") defConst("true") defConst("false") defConst("iota") defConst("nil") defFun("append") defFun("cap") defFun("close") defFun("complex") defFun("copy") defFun("imag") defFun("len") defFun("make") defFun("new") defFun("panic") defFun("print") defFun("println") defFun("real") defFun("recover") scope = ast.NewScope(nil) Unsafe = ast.NewObj(ast.Pkg, "unsafe") Unsafe.Data = scope defType("Pointer") defFun("Alignof") defFun("New") defFun("NewArray") defFun("Offsetof") defFun("Reflect") defFun("Sizeof") defFun("Typeof") defFun("Unreflect") }
// Export = "PackageClause { Decl } "$$" . // PackageClause = "package" identifier [ "safe" ] "\n" . // func (p *gcParser) parseExport() *ast.Object { p.expectKeyword("package") name := p.expect(scanner.Ident) if p.tok != '\n' { // A package is safe if it was compiled with the -u flag, // which disables the unsafe package. // TODO(gri) remember "safe" package p.expectKeyword("safe") } p.expect('\n') assert(p.imports[p.id] == nil) pkg := ast.NewObj(ast.Pkg, name) pkg.Data = ast.NewScope(nil) p.imports[p.id] = pkg for p.tok != '$' && p.tok != scanner.EOF { p.parseDecl() } if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' { // don't call next()/expect() since reading past the // export data may cause scanner errors (e.g. NUL chars) p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch) } if n := p.scanner.ErrorCount; n != 0 { p.errorf("expected no scanner errors, got %d", n) } return pkg }
// ImportPath = string_lit . // func (p *gcParser) parsePkgId() *ast.Object { id, err := strconv.Unquote(p.expect(scanner.String)) if err != nil { p.error(err) } switch id { case "": // id == "" stands for the imported package id // (only known at time of package installation) id = p.id case "unsafe": // package unsafe is not in the imports map - handle explicitly return Unsafe } pkg := p.imports[id] if pkg == nil { scope = ast.NewScope(nil) pkg = ast.NewObj(ast.Pkg, "") pkg.Data = scope p.imports[id] = pkg } return pkg }
func (tc *typechecker) declSignature(typ *Type, recv, params, results *ast.FieldList) { assert((typ.Form == Method) == (recv != nil)) typ.Params = ast.NewScope(nil) tc.declFields(typ.Params, recv, true) tc.declFields(typ.Params, params, true) typ.N = tc.declFields(typ.Params, results, true) }
func (tc *typechecker) bindMethod(method *ast.FuncDecl) { // a method is declared in the receiver base type's scope var scope *ast.Scope base := deref(method.Recv.List[0].Type) if name, isIdent := base.(*ast.Ident); isIdent { // if base is not an *ast.Ident, we had a syntax // error and the parser reported an error already obj := tc.topScope.Lookup(name.Name) if obj == nil { tc.Errorf(name.Pos(), "invalid receiver: %s is not declared in this package", name.Name) } else if obj.Kind != ast.Typ { tc.Errorf(name.Pos(), "invalid receiver: %s is not a type", name.Name) } else { typ := obj.Type.(*Type) assert(typ.Form == Unresolved) scope = typ.Scope } } if scope == nil { // no receiver type found; use a dummy scope // (we still want to type-check the method // body, so make sure there is a name object // and type) // TODO(gri) should we record the scope so // that we don't lose the receiver for type- // checking of the method body? scope = ast.NewScope(nil) } tc.declInScope(scope, ast.Fun, method.Name, method, 0) }
func init() { Universe = ast.NewScope(nil) // basic types for n, name := range BasicTypes { typ := NewType(Basic) typ.N = n obj := ast.NewObj(ast.Typ, name) obj.Type = typ typ.Obj = obj def(obj) } // built-in functions // TODO(gri) implement this }
// NewType creates a new type of a given form. func NewType(form Form) *Type { return &Type{Form: form, Scope: ast.NewScope(nil)} }
func (tc *typechecker) openScope() *ast.Scope { tc.topScope = ast.NewScope(tc.topScope) return tc.topScope }