github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/ir/val.go (about) 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. 4 5 package ir 6 7 import ( 8 "github.com/bir3/gocompiler/src/go/constant" 9 10 "github.com/bir3/gocompiler/src/cmd/compile/internal/base" 11 "github.com/bir3/gocompiler/src/cmd/compile/internal/types" 12 ) 13 14 func ConstType(n Node) constant.Kind { 15 if n == nil || n.Op() != OLITERAL { 16 return constant.Unknown 17 } 18 return n.Val().Kind() 19 } 20 21 // IntVal returns v converted to int64. 22 // Note: if t is uint64, very large values will be converted to negative int64. 23 func IntVal(t *types.Type, v constant.Value) int64 { 24 if t.IsUnsigned() { 25 if x, ok := constant.Uint64Val(v); ok { 26 return int64(x) 27 } 28 } else { 29 if x, ok := constant.Int64Val(v); ok { 30 return x 31 } 32 } 33 base.Fatalf("%v out of range for %v", v, t) 34 panic("unreachable") 35 } 36 37 func AssertValidTypeForConst(t *types.Type, v constant.Value) { 38 if !ValidTypeForConst(t, v) { 39 base.Fatalf("%v (%v) does not represent %v (%v)", t, t.Kind(), v, v.Kind()) 40 } 41 } 42 43 func ValidTypeForConst(t *types.Type, v constant.Value) bool { 44 switch v.Kind() { 45 case constant.Unknown: 46 return OKForConst[t.Kind()] 47 case constant.Bool: 48 return t.IsBoolean() 49 case constant.String: 50 return t.IsString() 51 case constant.Int: 52 return t.IsInteger() 53 case constant.Float: 54 return t.IsFloat() 55 case constant.Complex: 56 return t.IsComplex() 57 } 58 59 base.Fatalf("unexpected constant kind: %v", v) 60 panic("unreachable") 61 } 62 63 // NewLiteral returns a new untyped constant with value v. 64 func NewLiteral(v constant.Value) Node { 65 return NewBasicLit(base.Pos, v) 66 } 67 68 func idealType(ct constant.Kind) *types.Type { 69 switch ct { 70 case constant.String: 71 return types.UntypedString 72 case constant.Bool: 73 return types.UntypedBool 74 case constant.Int: 75 return types.UntypedInt 76 case constant.Float: 77 return types.UntypedFloat 78 case constant.Complex: 79 return types.UntypedComplex 80 } 81 base.Fatalf("unexpected Ctype: %v", ct) 82 return nil 83 } 84 85 var OKForConst [types.NTYPE]bool 86 87 // Int64Val returns n as an int64. 88 // n must be an integer or rune constant. 89 func Int64Val(n Node) int64 { 90 if !IsConst(n, constant.Int) { 91 base.Fatalf("Int64Val(%v)", n) 92 } 93 x, ok := constant.Int64Val(n.Val()) 94 if !ok { 95 base.Fatalf("Int64Val(%v)", n) 96 } 97 return x 98 } 99 100 // Uint64Val returns n as an uint64. 101 // n must be an integer or rune constant. 102 func Uint64Val(n Node) uint64 { 103 if !IsConst(n, constant.Int) { 104 base.Fatalf("Uint64Val(%v)", n) 105 } 106 x, ok := constant.Uint64Val(n.Val()) 107 if !ok { 108 base.Fatalf("Uint64Val(%v)", n) 109 } 110 return x 111 } 112 113 // BoolVal returns n as a bool. 114 // n must be a boolean constant. 115 func BoolVal(n Node) bool { 116 if !IsConst(n, constant.Bool) { 117 base.Fatalf("BoolVal(%v)", n) 118 } 119 return constant.BoolVal(n.Val()) 120 } 121 122 // StringVal returns the value of a literal string Node as a string. 123 // n must be a string constant. 124 func StringVal(n Node) string { 125 if !IsConst(n, constant.String) { 126 base.Fatalf("StringVal(%v)", n) 127 } 128 return constant.StringVal(n.Val()) 129 }