route/vendor/github.com/hashicorp/hil/ast/literal.go

89 lines
2.2 KiB
Go

package ast
import (
"fmt"
"reflect"
)
// LiteralNode represents a single literal value, such as "foo" or
// 42 or 3.14159. Based on the Type, the Value can be safely cast.
type LiteralNode struct {
Value interface{}
Typex Type
Posx Pos
}
// NewLiteralNode returns a new literal node representing the given
// literal Go value, which must correspond to one of the primitive types
// supported by HIL. Lists and maps cannot currently be constructed via
// this function.
//
// If an inappropriately-typed value is provided, this function will
// return an error. The main intended use of this function is to produce
// "synthetic" literals from constants in code, where the value type is
// well known at compile time. To easily store these in global variables,
// see also MustNewLiteralNode.
func NewLiteralNode(value interface{}, pos Pos) (*LiteralNode, error) {
goType := reflect.TypeOf(value)
var hilType Type
switch goType.Kind() {
case reflect.Bool:
hilType = TypeBool
case reflect.Int:
hilType = TypeInt
case reflect.Float64:
hilType = TypeFloat
case reflect.String:
hilType = TypeString
default:
return nil, fmt.Errorf("unsupported literal node type: %T", value)
}
return &LiteralNode{
Value: value,
Typex: hilType,
Posx: pos,
}, nil
}
// MustNewLiteralNode wraps NewLiteralNode and panics if an error is
// returned, thus allowing valid literal nodes to be easily assigned to
// global variables.
func MustNewLiteralNode(value interface{}, pos Pos) *LiteralNode {
node, err := NewLiteralNode(value, pos)
if err != nil {
panic(err)
}
return node
}
func (n *LiteralNode) Accept(v Visitor) Node {
return v(n)
}
func (n *LiteralNode) Pos() Pos {
return n.Posx
}
func (n *LiteralNode) GoString() string {
return fmt.Sprintf("*%#v", *n)
}
func (n *LiteralNode) String() string {
return fmt.Sprintf("Literal(%s, %v)", n.Typex, n.Value)
}
func (n *LiteralNode) Type(Scope) (Type, error) {
return n.Typex, nil
}
// IsUnknown returns true either if the node's value is itself unknown
// of if it is a collection containing any unknown elements, deeply.
func (n *LiteralNode) IsUnknown() bool {
return IsUnknown(Variable{
Type: n.Typex,
Value: n.Value,
})
}