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  }