github.com/gmemcc/yaegi@v0.12.1-0.20221128122509-aa99124c5d16/internal/cmd/extract/types/universe.go (about) 1 // Copyright 2011 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 // This file sets up the universe scope and the unsafe package. 6 7 package types 8 9 import ( 10 "go/constant" 11 "go/token" 12 "strings" 13 ) 14 15 // The Universe scope contains all predeclared objects of Go. 16 // It is the outermost scope of any chain of nested scopes. 17 var Universe *Scope 18 19 // The Unsafe package is the package returned by an importer 20 // for the import path "unsafe". 21 var Unsafe *Package 22 23 var ( 24 universeIota *Const 25 universeByte *Basic // uint8 alias, but has name "byte" 26 universeRune *Basic // int32 alias, but has name "rune" 27 universeError *Named 28 ) 29 30 // Typ contains the predeclared *Basic types indexed by their 31 // corresponding BasicKind. 32 // 33 // The *Basic type for Typ[Byte] will have the name "uint8". 34 // Use Universe.Lookup("byte").Type() to obtain the specific 35 // alias basic type named "byte" (and analogous for "rune"). 36 var Typ = []*Basic{ 37 Invalid: {Invalid, 0, "invalid type"}, 38 39 Bool: {Bool, IsBoolean, "bool"}, 40 Int: {Int, IsInteger, "int"}, 41 Int8: {Int8, IsInteger, "int8"}, 42 Int16: {Int16, IsInteger, "int16"}, 43 Int32: {Int32, IsInteger, "int32"}, 44 Int64: {Int64, IsInteger, "int64"}, 45 Uint: {Uint, IsInteger | IsUnsigned, "uint"}, 46 Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"}, 47 Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"}, 48 Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"}, 49 Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"}, 50 Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"}, 51 Float32: {Float32, IsFloat, "float32"}, 52 Float64: {Float64, IsFloat, "float64"}, 53 Complex64: {Complex64, IsComplex, "complex64"}, 54 Complex128: {Complex128, IsComplex, "complex128"}, 55 String: {String, IsString, "string"}, 56 UnsafePointer: {UnsafePointer, 0, "Pointer"}, 57 58 UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"}, 59 UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"}, 60 UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"}, 61 UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"}, 62 UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"}, 63 UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"}, 64 UntypedNil: {UntypedNil, IsUntyped, "untyped nil"}, 65 } 66 67 var aliases = [...]*Basic{ 68 {Byte, IsInteger | IsUnsigned, "byte"}, 69 {Rune, IsInteger, "rune"}, 70 } 71 72 func defPredeclaredTypes() { 73 for _, t := range Typ { 74 def(NewTypeName(token.NoPos, nil, t.name, t)) 75 } 76 for _, t := range aliases { 77 def(NewTypeName(token.NoPos, nil, t.name, t)) 78 } 79 80 // Error has a nil package in its qualified name since it is in no package 81 res := NewVar(token.NoPos, nil, "", Typ[String]) 82 sig := &Signature{results: NewTuple(res)} 83 err := NewFunc(token.NoPos, nil, "Error", sig) 84 typ := &Named{underlying: NewInterfaceType([]*Func{err}, nil).Complete()} 85 sig.recv = NewVar(token.NoPos, nil, "", typ) 86 def(NewTypeName(token.NoPos, nil, "error", typ)) 87 } 88 89 var predeclaredConsts = [...]struct { 90 name string 91 kind BasicKind 92 val constant.Value 93 }{ 94 {"true", UntypedBool, constant.MakeBool(true)}, 95 {"false", UntypedBool, constant.MakeBool(false)}, 96 {"iota", UntypedInt, constant.MakeInt64(0)}, 97 } 98 99 func defPredeclaredConsts() { 100 for _, c := range predeclaredConsts { 101 def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val)) 102 } 103 } 104 105 func defPredeclaredNil() { 106 def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}}) 107 } 108 109 // A builtinId is the id of a builtin function. 110 type builtinId int 111 112 const ( 113 // universe scope 114 _Append builtinId = iota 115 _Cap 116 _Close 117 _Complex 118 _Copy 119 _Delete 120 _Imag 121 _Len 122 _Make 123 _New 124 _Panic 125 _Print 126 _Println 127 _Real 128 _Recover 129 130 // package unsafe 131 _Alignof 132 _Offsetof 133 _Sizeof 134 135 // testing support 136 _Assert 137 _Trace 138 ) 139 140 var predeclaredFuncs = [...]struct { 141 name string 142 nargs int 143 variadic bool 144 kind exprKind 145 }{ 146 _Append: {"append", 1, true, expression}, 147 _Cap: {"cap", 1, false, expression}, 148 _Close: {"close", 1, false, statement}, 149 _Complex: {"complex", 2, false, expression}, 150 _Copy: {"copy", 2, false, statement}, 151 _Delete: {"delete", 2, false, statement}, 152 _Imag: {"imag", 1, false, expression}, 153 _Len: {"len", 1, false, expression}, 154 _Make: {"make", 1, true, expression}, 155 _New: {"new", 1, false, expression}, 156 _Panic: {"panic", 1, false, statement}, 157 _Print: {"print", 0, true, statement}, 158 _Println: {"println", 0, true, statement}, 159 _Real: {"real", 1, false, expression}, 160 _Recover: {"recover", 0, false, statement}, 161 162 _Alignof: {"Alignof", 1, false, expression}, 163 _Offsetof: {"Offsetof", 1, false, expression}, 164 _Sizeof: {"Sizeof", 1, false, expression}, 165 166 _Assert: {"assert", 1, false, statement}, 167 _Trace: {"trace", 0, true, statement}, 168 } 169 170 func defPredeclaredFuncs() { 171 for i := range predeclaredFuncs { 172 id := builtinId(i) 173 if id == _Assert || id == _Trace { 174 continue // only define these in testing environment 175 } 176 def(newBuiltin(id)) 177 } 178 } 179 180 // DefPredeclaredTestFuncs defines the assert and trace built-ins. 181 // These built-ins are intended for debugging and testing of this 182 // package only. 183 func DefPredeclaredTestFuncs() { 184 if Universe.Lookup("assert") != nil { 185 return // already defined 186 } 187 def(newBuiltin(_Assert)) 188 def(newBuiltin(_Trace)) 189 } 190 191 func init() { 192 Universe = NewScope(nil, token.NoPos, token.NoPos, "universe") 193 Unsafe = NewPackage("unsafe", "unsafe") 194 Unsafe.complete = true 195 196 defPredeclaredTypes() 197 defPredeclaredConsts() 198 defPredeclaredNil() 199 defPredeclaredFuncs() 200 201 universeIota = Universe.Lookup("iota").(*Const) 202 universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) 203 universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) 204 universeError = Universe.Lookup("error").(*TypeName).typ.(*Named) 205 } 206 207 // Objects with names containing blanks are internal and not entered into 208 // a scope. Objects with exported names are inserted in the unsafe package 209 // scope; other objects are inserted in the universe scope. 210 // 211 func def(obj Object) { 212 assert(obj.color() == black) 213 name := obj.Name() 214 if strings.Contains(name, " ") { 215 return // nothing to do 216 } 217 // fix Obj link for named types 218 if typ, ok := obj.Type().(*Named); ok { 219 typ.obj = obj.(*TypeName) 220 } 221 // exported identifiers go into package unsafe 222 scope := Universe 223 if obj.Exported() { 224 scope = Unsafe.scope 225 // set Pkg field 226 switch obj := obj.(type) { 227 case *TypeName: 228 obj.pkg = Unsafe 229 case *Builtin: 230 obj.pkg = Unsafe 231 default: 232 unreachable() 233 } 234 } 235 if scope.Insert(obj) != nil { 236 panic("internal error: double declaration") 237 } 238 }