github.com/tardisgo/tardisgo@v0.0.0-20161119180838-e0dd9a7e46b5/pogo/constants.go (about) 1 // Copyright 2014 Elliott Stoneham and The TARDIS Go Authors 2 // Use of this source code is governed by an MIT-style 3 // license that can be found in the LICENSE file. 4 5 package pogo 6 7 import ( 8 "fmt" 9 "go/constant" 10 "go/token" 11 "sort" 12 "strconv" 13 14 "golang.org/x/tools/go/ssa" 15 ) 16 17 // emit the constant declarations 18 func (comp *Compilation) emitNamedConstants() { 19 allPack := comp.rootProgram.AllPackages() 20 sort.Sort(PackageSorter(allPack)) 21 for pkgIdx := range allPack { 22 pkg := allPack[pkgIdx] 23 allMem := MemberNamesSorted(pkg) 24 for _, mName := range allMem { 25 mem := pkg.Members[mName] 26 if mem.Token() == token.CONST { 27 lit := mem.(*ssa.NamedConst).Value 28 posStr := comp.CodePosition(lit.Pos()) 29 pName := mem.(*ssa.NamedConst).Object().Pkg().Path() // was .Name() 30 switch lit.Value.Kind() { // non language specific validation 31 case constant.Bool, constant.String, constant.Float, constant.Int, constant.Complex: //OK 32 isPublic := mem.Object().Exported() 33 if isPublic { // constants will be inserted inline, these declarations of public constants are for exteral use in target language 34 l := comp.TargetLang 35 fmt.Fprintln(&LanguageList[l].buffer, LanguageList[l].NamedConst(pName, mName, *lit, posStr)) 36 } 37 default: 38 comp.LogError(posStr, "pogo", fmt.Errorf("%s.%s : emitConstants() internal error, unrecognised constant type: %v", 39 pName, mName, lit.Value.Kind())) 40 } 41 } 42 } 43 } 44 } 45 46 // FloatVal is a utility function returns a string constant value from a constant.Value. 47 func (comp *Compilation) FloatVal(eVal constant.Value, bits int, posStr string) string { 48 fVal, isExact := constant.Float64Val(eVal) 49 if !isExact { 50 comp.LogWarning(posStr, "inexact", fmt.Errorf("constant value %g cannot be accurately represented in float64", fVal)) 51 } 52 ret := strconv.FormatFloat(fVal, byte('g'), -1, bits) 53 if fVal < 0.0 { 54 return fmt.Sprintf("(%s)", ret) 55 } 56 return ret 57 } 58 59 // IntVal is a utility function returns an int64 constant value from a constant.Value, split into high and low int32. 60 func (comp *Compilation) IntVal(eVal constant.Value, posStr string) (high, low int32) { 61 iVal, isExact := constant.Int64Val(eVal) 62 if !isExact { 63 comp.LogWarning(posStr, "inexact", fmt.Errorf("constant value %d cannot be accurately represented in int64", iVal)) 64 } 65 return int32(iVal >> 32), int32(iVal & 0xFFFFFFFF) 66 }