1 // Copyright 2009 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.
14 "unsafe" // For Sizeof
18 // XXX(Spec) The type compatibility section is very confusing because
19 // it makes it seem like there are three distinct types of
20 // compatibility: plain compatibility, assignment compatibility, and
21 // comparison compatibility. As I understand it, there's really only
22 // assignment compatibility and comparison and conversion have some
23 // restrictions and have special meaning in some cases where the types
24 // are not otherwise assignment compatible. The comparison
25 // compatibility section is almost all about the semantics of
26 // comparison, not the type checking of it, so it would make much more
27 // sense in the comparison operators section. The compatibility and
28 // assignment compatibility sections should be rolled into one.
31 // compat returns whether this type is compatible with another
32 // type. If conv is false, this is normal compatibility,
33 // where two named types are compatible only if they are the
34 // same named type. If conv if true, this is conversion
35 // compatibility, where two named types are conversion
36 // compatible if their definitions are conversion compatible.
38 // TODO(austin) Deal with recursive types
39 compat(o Type, conv bool) bool
40 // lit returns this type's literal. If this is a named type,
41 // this is the unnamed underlying type. Otherwise, this is an
42 // identity operation.
44 // isBoolean returns true if this is a boolean type.
46 // isInteger returns true if this is an integer type.
48 // isFloat returns true if this is a floating type.
50 // isIdeal returns true if this is an ideal int or float.
52 // Zero returns a new zero value of this type.
54 // String returns the string representation of this type.
56 // The position where this type was defined, if any.
60 type BoundedType interface {
62 // minVal returns the smallest value of this type.
64 // maxVal returns the largest value of this type.
68 var universePos = token.NoPos
71 * Type array maps. These are used to memoize composite types.
74 type typeArrayMapEntry struct {
77 next *typeArrayMapEntry
80 type typeArrayMap map[uintptr]*typeArrayMapEntry
82 func hashTypeArray(key []Type) uintptr {
84 for _, t := range key {
89 addr := reflect.ValueOf(t).Pointer()
95 func newTypeArrayMap() typeArrayMap { return make(map[uintptr]*typeArrayMapEntry) }
97 func (m typeArrayMap) Get(key []Type) interface{} {
98 ent, ok := m[hashTypeArray(key)]
104 for ; ent != nil; ent = ent.next {
105 if len(key) != len(ent.key) {
108 for i := 0; i < len(key); i++ {
109 if key[i] != ent.key[i] {
120 func (m typeArrayMap) Put(key []Type, v interface{}) interface{} {
121 hash := hashTypeArray(key)
124 new := &typeArrayMapEntry{key, v, ent}
133 type commonType struct{}
135 func (commonType) isBoolean() bool { return false }
137 func (commonType) isInteger() bool { return false }
139 func (commonType) isFloat() bool { return false }
141 func (commonType) isIdeal() bool { return false }
143 func (commonType) Pos() token.Pos { return token.NoPos }
149 type boolType struct {
153 var BoolType = universe.DefineType("bool", universePos, &boolType{})
155 func (t *boolType) compat(o Type, conv bool) bool {
156 _, ok := o.lit().(*boolType)
160 func (t *boolType) lit() Type { return t }
162 func (t *boolType) isBoolean() bool { return true }
164 func (boolType) String() string {
165 // Use angle brackets as a convention for printing the
166 // underlying, unnamed type. This should only show up in
171 func (t *boolType) Zero() Value {
180 type uintType struct {
183 // 0 for architecture-dependent types
185 // true for uintptr, false for all others
191 Uint8Type = universe.DefineType("uint8", universePos, &uintType{commonType{}, 8, false, "uint8"})
192 Uint16Type = universe.DefineType("uint16", universePos, &uintType{commonType{}, 16, false, "uint16"})
193 Uint32Type = universe.DefineType("uint32", universePos, &uintType{commonType{}, 32, false, "uint32"})
194 Uint64Type = universe.DefineType("uint64", universePos, &uintType{commonType{}, 64, false, "uint64"})
196 UintType = universe.DefineType("uint", universePos, &uintType{commonType{}, 0, false, "uint"})
197 UintptrType = universe.DefineType("uintptr", universePos, &uintType{commonType{}, 0, true, "uintptr"})
200 func (t *uintType) compat(o Type, conv bool) bool {
201 t2, ok := o.lit().(*uintType)
205 func (t *uintType) lit() Type { return t }
207 func (t *uintType) isInteger() bool { return true }
209 func (t *uintType) String() string { return "<" + t.name + ">" }
211 func (t *uintType) Zero() Value {
234 panic("unexpected uint bit count")
237 func (t *uintType) minVal() *big.Rat { return big.NewRat(0, 1) }
239 func (t *uintType) maxVal() *big.Rat {
243 bits = uint(8 * unsafe.Sizeof(uintptr(0)))
245 bits = uint(8 * unsafe.Sizeof(uint(0)))
248 numer := big.NewInt(1)
249 numer.Lsh(numer, bits)
250 numer.Sub(numer, idealOne)
251 return new(big.Rat).SetInt(numer)
258 type intType struct {
261 // XXX(Spec) Numeric types: "There is also a set of
262 // architecture-independent basic numeric types whose size
263 // depends on the architecture." Should that be
264 // architecture-dependent?
266 // 0 for architecture-dependent types
272 Int8Type = universe.DefineType("int8", universePos, &intType{commonType{}, 8, "int8"})
273 Int16Type = universe.DefineType("int16", universePos, &intType{commonType{}, 16, "int16"})
274 Int32Type = universe.DefineType("int32", universePos, &intType{commonType{}, 32, "int32"})
275 Int64Type = universe.DefineType("int64", universePos, &intType{commonType{}, 64, "int64"})
277 IntType = universe.DefineType("int", universePos, &intType{commonType{}, 0, "int"})
280 func (t *intType) compat(o Type, conv bool) bool {
281 t2, ok := o.lit().(*intType)
285 func (t *intType) lit() Type { return t }
287 func (t *intType) isInteger() bool { return true }
289 func (t *intType) String() string { return "<" + t.name + ">" }
291 func (t *intType) Zero() Value {
310 panic("unexpected int bit count")
313 func (t *intType) minVal() *big.Rat {
316 bits = uint(8 * unsafe.Sizeof(int(0)))
318 numer := big.NewInt(-1)
319 numer.Lsh(numer, bits-1)
320 return new(big.Rat).SetInt(numer)
323 func (t *intType) maxVal() *big.Rat {
326 bits = uint(8 * unsafe.Sizeof(int(0)))
328 numer := big.NewInt(1)
329 numer.Lsh(numer, bits-1)
330 numer.Sub(numer, idealOne)
331 return new(big.Rat).SetInt(numer)
338 type idealIntType struct {
342 var IdealIntType Type = &idealIntType{}
344 func (t *idealIntType) compat(o Type, conv bool) bool {
345 _, ok := o.lit().(*idealIntType)
349 func (t *idealIntType) lit() Type { return t }
351 func (t *idealIntType) isInteger() bool { return true }
353 func (t *idealIntType) isIdeal() bool { return true }
355 func (t *idealIntType) String() string { return "ideal integer" }
357 func (t *idealIntType) Zero() Value { return &idealIntV{idealZero} }
363 type floatType struct {
366 // 0 for architecture-dependent type
373 Float32Type = universe.DefineType("float32", universePos, &floatType{commonType{}, 32, "float32"})
374 Float64Type = universe.DefineType("float64", universePos, &floatType{commonType{}, 64, "float64"})
377 func (t *floatType) compat(o Type, conv bool) bool {
378 t2, ok := o.lit().(*floatType)
382 func (t *floatType) lit() Type { return t }
384 func (t *floatType) isFloat() bool { return true }
386 func (t *floatType) String() string { return "<" + t.name + ">" }
388 func (t *floatType) Zero() Value {
397 panic("unexpected float bit count")
400 var maxFloat32Val *big.Rat
401 var maxFloat64Val *big.Rat
402 var minFloat32Val *big.Rat
403 var minFloat64Val *big.Rat
405 func (t *floatType) minVal() *big.Rat {
413 log.Panicf("unexpected floating point bit count: %d", bits)
417 func (t *floatType) maxVal() *big.Rat {
425 log.Panicf("unexpected floating point bit count: %d", bits)
433 type idealFloatType struct {
437 var IdealFloatType Type = &idealFloatType{}
439 func (t *idealFloatType) compat(o Type, conv bool) bool {
440 _, ok := o.lit().(*idealFloatType)
444 func (t *idealFloatType) lit() Type { return t }
446 func (t *idealFloatType) isFloat() bool { return true }
448 func (t *idealFloatType) isIdeal() bool { return true }
450 func (t *idealFloatType) String() string { return "ideal float" }
452 func (t *idealFloatType) Zero() Value { return &idealFloatV{big.NewRat(0, 1)} }
458 type stringType struct {
462 var StringType = universe.DefineType("string", universePos, &stringType{})
464 func (t *stringType) compat(o Type, conv bool) bool {
465 _, ok := o.lit().(*stringType)
469 func (t *stringType) lit() Type { return t }
471 func (t *stringType) String() string { return "<string>" }
473 func (t *stringType) Zero() Value {
482 type ArrayType struct {
488 var arrayTypes = make(map[int64]map[Type]*ArrayType)
490 // Two array types are identical if they have identical element types
491 // and the same array length.
493 func NewArrayType(len int64, elem Type) *ArrayType {
494 ts, ok := arrayTypes[len]
496 ts = make(map[Type]*ArrayType)
501 t = &ArrayType{commonType{}, len, elem}
507 func (t *ArrayType) compat(o Type, conv bool) bool {
508 t2, ok := o.lit().(*ArrayType)
512 return t.Len == t2.Len && t.Elem.compat(t2.Elem, conv)
515 func (t *ArrayType) lit() Type { return t }
517 func (t *ArrayType) String() string { return "[]" + t.Elem.String() }
519 func (t *ArrayType) Zero() Value {
520 res := arrayV(make([]Value, t.Len))
521 // TODO(austin) It's unfortunate that each element is
522 // separately heap allocated. We could add ZeroArray to
523 // everything, though that doesn't help with multidimensional
524 // arrays. Or we could do something unsafe. We'll have this
525 // same problem with structs.
526 for i := int64(0); i < t.Len; i++ {
527 res[i] = t.Elem.Zero()
536 type StructField struct {
542 type StructType struct {
547 var structTypes = newTypeArrayMap()
549 // Two struct types are identical if they have the same sequence of
550 // fields, and if corresponding fields have the same names and
551 // identical types. Two anonymous fields are considered to have the
554 func NewStructType(fields []StructField) *StructType {
555 // Start by looking up just the types
556 fts := make([]Type, len(fields))
557 for i, f := range fields {
560 tMapI := structTypes.Get(fts)
562 tMapI = structTypes.Put(fts, make(map[string]*StructType))
564 tMap := tMapI.(map[string]*StructType)
566 // Construct key for field names
568 for _, f := range fields {
569 // XXX(Spec) It's not clear if struct { T } and struct
570 // { T T } are either identical or compatible. The
571 // "Struct Types" section says that the name of that
572 // field is "T", which suggests that they are
573 // identical, but it really means that it's the name
574 // for the purpose of selector expressions and nothing
575 // else. We decided that they should be neither
576 // identical or compatible.
583 // XXX(Spec) Do the tags also have to be identical for the
584 // types to be identical? I certainly hope so, because
585 // otherwise, this is the only case where two distinct type
586 // objects can represent identical types.
590 // Create new struct type
591 t = &StructType{commonType{}, fields}
597 func (t *StructType) compat(o Type, conv bool) bool {
598 t2, ok := o.lit().(*StructType)
602 if len(t.Elems) != len(t2.Elems) {
605 for i, e := range t.Elems {
607 // XXX(Spec) An anonymous and a non-anonymous field
608 // are neither identical nor compatible.
609 if e.Anonymous != e2.Anonymous ||
610 (!e.Anonymous && e.Name != e2.Name) ||
611 !e.Type.compat(e2.Type, conv) {
618 func (t *StructType) lit() Type { return t }
620 func (t *StructType) String() string {
622 for i, f := range t.Elems {
634 func (t *StructType) Zero() Value {
635 res := structV(make([]Value, len(t.Elems)))
636 for i, f := range t.Elems {
637 res[i] = f.Type.Zero()
646 type PtrType struct {
651 var ptrTypes = make(map[Type]*PtrType)
653 // Two pointer types are identical if they have identical base types.
655 func NewPtrType(elem Type) *PtrType {
656 t, ok := ptrTypes[elem]
658 t = &PtrType{commonType{}, elem}
664 func (t *PtrType) compat(o Type, conv bool) bool {
665 t2, ok := o.lit().(*PtrType)
669 return t.Elem.compat(t2.Elem, conv)
672 func (t *PtrType) lit() Type { return t }
674 func (t *PtrType) String() string { return "*" + t.Elem.String() }
676 func (t *PtrType) Zero() Value { return &ptrV{nil} }
682 type FuncType struct {
684 // TODO(austin) Separate receiver Type for methods?
691 var funcTypes = newTypeArrayMap()
692 var variadicFuncTypes = newTypeArrayMap()
694 // Create singleton function types for magic built-in functions
696 capType = &FuncType{builtin: "cap"}
697 closeType = &FuncType{builtin: "close"}
698 closedType = &FuncType{builtin: "closed"}
699 lenType = &FuncType{builtin: "len"}
700 makeType = &FuncType{builtin: "make"}
701 newType = &FuncType{builtin: "new"}
702 panicType = &FuncType{builtin: "panic"}
703 printType = &FuncType{builtin: "print"}
704 printlnType = &FuncType{builtin: "println"}
705 copyType = &FuncType{builtin: "copy"}
708 // Two function types are identical if they have the same number of
709 // parameters and result values and if corresponding parameter and
710 // result types are identical. All "..." parameters have identical
711 // type. Parameter and result names are not required to match.
713 func NewFuncType(in []Type, variadic bool, out []Type) *FuncType {
716 inMap = variadicFuncTypes
719 outMapI := inMap.Get(in)
721 outMapI = inMap.Put(in, newTypeArrayMap())
723 outMap := outMapI.(typeArrayMap)
725 tI := outMap.Get(out)
727 return tI.(*FuncType)
730 t := &FuncType{commonType{}, in, variadic, out, ""}
735 func (t *FuncType) compat(o Type, conv bool) bool {
736 t2, ok := o.lit().(*FuncType)
740 if len(t.In) != len(t2.In) || t.Variadic != t2.Variadic || len(t.Out) != len(t2.Out) {
743 for i := range t.In {
744 if !t.In[i].compat(t2.In[i], conv) {
748 for i := range t.Out {
749 if !t.Out[i].compat(t2.Out[i], conv) {
756 func (t *FuncType) lit() Type { return t }
758 func typeListString(ts []Type, ns []*ast.Ident) string {
760 for i, t := range ts {
764 if ns != nil && ns[i] != nil {
765 s += ns[i].Name + " "
768 // Some places use nil types to represent errors
777 func (t *FuncType) String() string {
779 return "built-in function " + t.builtin
781 args := typeListString(t.In, nil)
788 s := "func(" + args + ")"
790 s += " (" + typeListString(t.Out, nil) + ")"
795 func (t *FuncType) Zero() Value { return &funcV{nil} }
797 type FuncDecl struct {
799 Name *ast.Ident // nil for function literals
800 // InNames will be one longer than Type.In if this function is
803 OutNames []*ast.Ident
806 func (t *FuncDecl) String() string {
809 s += " " + t.Name.Name
811 s += funcTypeString(t.Type, t.InNames, t.OutNames)
815 func funcTypeString(ft *FuncType, ins []*ast.Ident, outs []*ast.Ident) string {
817 s += typeListString(ft.In, ins)
826 s += " (" + typeListString(ft.Out, outs) + ")"
835 // TODO(austin) Interface values, types, and type compilation are
836 // implemented, but none of the type checking or semantics of
839 type InterfaceType struct {
841 // TODO(austin) This should be a map from names to
842 // *FuncType's. We only need the sorted list for generating
843 // the type map key. It's detrimental for everything else.
847 type IMethod struct {
852 var interfaceTypes = newTypeArrayMap()
854 func NewInterfaceType(methods []IMethod, embeds []*InterfaceType) *InterfaceType {
855 // Count methods of embedded interfaces
856 nMethods := len(methods)
857 for _, e := range embeds {
858 nMethods += len(e.methods)
862 allMethods := make([]IMethod, nMethods)
863 copy(allMethods, methods)
865 for _, e := range embeds {
866 for _, m := range e.methods {
873 sort.Sort(iMethodSorter(allMethods))
875 mts := make([]Type, len(allMethods))
876 for i, m := range methods {
879 tMapI := interfaceTypes.Get(mts)
881 tMapI = interfaceTypes.Put(mts, make(map[string]*InterfaceType))
883 tMap := tMapI.(map[string]*InterfaceType)
886 for _, m := range allMethods {
892 t = &InterfaceType{commonType{}, allMethods}
898 type iMethodSorter []IMethod
900 func (s iMethodSorter) Less(a, b int) bool { return s[a].Name < s[b].Name }
902 func (s iMethodSorter) Swap(a, b int) { s[a], s[b] = s[b], s[a] }
904 func (s iMethodSorter) Len() int { return len(s) }
906 func (t *InterfaceType) compat(o Type, conv bool) bool {
907 t2, ok := o.lit().(*InterfaceType)
911 if len(t.methods) != len(t2.methods) {
914 for i, e := range t.methods {
916 if e.Name != e2.Name || !e.Type.compat(e2.Type, conv) {
923 func (t *InterfaceType) lit() Type { return t }
925 func (t *InterfaceType) String() string {
926 // TODO(austin) Instead of showing embedded interfaces, this
927 // shows their methods.
929 for i, m := range t.methods {
933 s += m.Name + funcTypeString(m.Type, nil, nil)
938 // implementedBy tests if o implements t, returning nil, true if it does.
939 // Otherwise, it returns a method of t that o is missing and false.
940 func (t *InterfaceType) implementedBy(o Type) (*IMethod, bool) {
941 if len(t.methods) == 0 {
945 // The methods of a named interface types are those of the
947 if it, ok := o.lit().(*InterfaceType); ok {
951 // XXX(Spec) Interface types: "A type implements any interface
952 // comprising any subset of its methods" It's unclear if
953 // methods must have identical or compatible types. 6g
954 // requires identical types.
956 switch o := o.(type) {
958 for _, tm := range t.methods {
959 sm, ok := o.methods[tm.Name]
960 if !ok || sm.decl.Type != tm.Type {
968 for ti < len(t.methods) && oi < len(o.methods) {
969 tm, om := &t.methods[ti], &o.methods[oi]
971 case tm.Name == om.Name:
972 if tm.Type != om.Type {
977 case tm.Name > om.Name:
983 if ti < len(t.methods) {
984 return &t.methods[ti], false
989 return &t.methods[0], false
992 func (t *InterfaceType) Zero() Value { return &interfaceV{} }
998 type SliceType struct {
1003 var sliceTypes = make(map[Type]*SliceType)
1005 // Two slice types are identical if they have identical element types.
1007 func NewSliceType(elem Type) *SliceType {
1008 t, ok := sliceTypes[elem]
1010 t = &SliceType{commonType{}, elem}
1011 sliceTypes[elem] = t
1016 func (t *SliceType) compat(o Type, conv bool) bool {
1017 t2, ok := o.lit().(*SliceType)
1021 return t.Elem.compat(t2.Elem, conv)
1024 func (t *SliceType) lit() Type { return t }
1026 func (t *SliceType) String() string { return "[]" + t.Elem.String() }
1028 func (t *SliceType) Zero() Value {
1029 // The value of an uninitialized slice is nil. The length and
1030 // capacity of a nil slice are 0.
1031 return &sliceV{Slice{nil, 0, 0}}
1038 type MapType struct {
1044 var mapTypes = make(map[Type]map[Type]*MapType)
1046 func NewMapType(key Type, elem Type) *MapType {
1047 ts, ok := mapTypes[key]
1049 ts = make(map[Type]*MapType)
1054 t = &MapType{commonType{}, key, elem}
1060 func (t *MapType) compat(o Type, conv bool) bool {
1061 t2, ok := o.lit().(*MapType)
1065 return t.Elem.compat(t2.Elem, conv) && t.Key.compat(t2.Key, conv)
1068 func (t *MapType) lit() Type { return t }
1070 func (t *MapType) String() string { return "map[" + t.Key.String() + "] " + t.Elem.String() }
1072 func (t *MapType) Zero() Value {
1073 // The value of an uninitialized map is nil.
1078 type ChanType struct {
1087 type Method struct {
1092 type NamedType struct {
1095 // Underlying type. If incomplete is true, this will be nil.
1096 // If incomplete is false and this is still nil, then this is
1097 // a placeholder type representing an error.
1099 // True while this type is being defined.
1101 methods map[string]Method
1104 // TODO(austin) This is temporarily needed by the debugger's remote
1105 // type parser. This should only be possible with block.DefineType.
1106 func NewNamedType(name string) *NamedType {
1107 return &NamedType{token.NoPos, name, nil, true, make(map[string]Method)}
1110 func (t *NamedType) Pos() token.Pos {
1114 func (t *NamedType) Complete(def Type) {
1116 log.Panicf("cannot complete already completed NamedType %+v", *t)
1118 // We strip the name from def because multiple levels of
1119 // naming are useless.
1120 if ndef, ok := def.(*NamedType); ok {
1124 t.incomplete = false
1127 func (t *NamedType) compat(o Type, conv bool) bool {
1128 t2, ok := o.(*NamedType)
1131 // Two named types are conversion compatible
1132 // if their literals are conversion
1134 return t.Def.compat(t2.Def, conv)
1136 // Two named types are compatible if their
1137 // type names originate in the same type
1142 // A named and an unnamed type are compatible if the
1143 // respective type literals are compatible.
1144 return o.compat(t.Def, conv)
1147 func (t *NamedType) lit() Type { return t.Def.lit() }
1149 func (t *NamedType) isBoolean() bool { return t.Def.isBoolean() }
1151 func (t *NamedType) isInteger() bool { return t.Def.isInteger() }
1153 func (t *NamedType) isFloat() bool { return t.Def.isFloat() }
1155 func (t *NamedType) isIdeal() bool { return false }
1157 func (t *NamedType) String() string { return t.Name }
1159 func (t *NamedType) Zero() Value { return t.Def.Zero() }
1165 // MultiType is a special type used for multi-valued expressions, akin
1166 // to a tuple type. It's not generally accessible within the
1168 type MultiType struct {
1173 var multiTypes = newTypeArrayMap()
1175 func NewMultiType(elems []Type) *MultiType {
1176 if t := multiTypes.Get(elems); t != nil {
1177 return t.(*MultiType)
1180 t := &MultiType{commonType{}, elems}
1181 multiTypes.Put(elems, t)
1185 func (t *MultiType) compat(o Type, conv bool) bool {
1186 t2, ok := o.lit().(*MultiType)
1190 if len(t.Elems) != len(t2.Elems) {
1193 for i := range t.Elems {
1194 if !t.Elems[i].compat(t2.Elems[i], conv) {
1201 var EmptyType Type = NewMultiType([]Type{})
1203 func (t *MultiType) lit() Type { return t }
1205 func (t *MultiType) String() string {
1206 if len(t.Elems) == 0 {
1209 return typeListString(t.Elems, nil)
1212 func (t *MultiType) Zero() Value {
1213 res := make([]Value, len(t.Elems))
1214 for i, t := range t.Elems {
1221 * Initialize the universe
1225 numer := big.NewInt(0xffffff)
1226 numer.Lsh(numer, 127-23)
1227 maxFloat32Val = new(big.Rat).SetInt(numer)
1228 numer.SetInt64(0x1fffffffffffff)
1229 numer.Lsh(numer, 1023-52)
1230 maxFloat64Val = new(big.Rat).SetInt(numer)
1231 minFloat32Val = new(big.Rat).Neg(maxFloat32Val)
1232 minFloat64Val = new(big.Rat).Neg(maxFloat64Val)
1234 // To avoid portability issues all numeric types are distinct
1235 // except byte, which is an alias for uint8.
1237 // Make byte an alias for the named type uint8. Type aliases
1238 // are otherwise impossible in Go, so just hack it here.
1239 universe.defs["byte"] = universe.defs["uint8"]
1241 // Built-in functions
1242 universe.DefineConst("cap", universePos, capType, nil)
1243 universe.DefineConst("close", universePos, closeType, nil)
1244 universe.DefineConst("closed", universePos, closedType, nil)
1245 universe.DefineConst("copy", universePos, copyType, nil)
1246 universe.DefineConst("len", universePos, lenType, nil)
1247 universe.DefineConst("make", universePos, makeType, nil)
1248 universe.DefineConst("new", universePos, newType, nil)
1249 universe.DefineConst("panic", universePos, panicType, nil)
1250 universe.DefineConst("print", universePos, printType, nil)
1251 universe.DefineConst("println", universePos, printlnType, nil)