summaryrefslogtreecommitdiff
path: root/vendor/github.com/hashicorp/hil/ast/literal.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hil/ast/literal.go')
-rw-r--r--vendor/github.com/hashicorp/hil/ast/literal.go88
1 files changed, 88 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hil/ast/literal.go b/vendor/github.com/hashicorp/hil/ast/literal.go
new file mode 100644
index 00000000..da6014fe
--- /dev/null
+++ b/vendor/github.com/hashicorp/hil/ast/literal.go
@@ -0,0 +1,88 @@
+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,
+ })
+}