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  }