hcl/ast/ast.go

121 lines
2.2 KiB
Go
Raw Normal View History

2014-08-02 18:38:41 +00:00
package ast
2014-08-01 01:44:21 +00:00
// ValueType is an enum represnting the type of a value in
// a LiteralNode.
2014-08-01 01:44:21 +00:00
type ValueType byte
const (
ValueTypeUnknown ValueType = iota
ValueTypeFloat
2014-08-01 01:44:21 +00:00
ValueTypeInt
ValueTypeString
2014-08-02 18:38:41 +00:00
ValueTypeBool
ValueTypeNil
2014-08-01 01:44:21 +00:00
)
// Node is implemented by all AST nodes for HCL.
type Node interface {
Accept(Visitor)
}
2014-08-02 22:44:45 +00:00
// KeyedNode is a node that has a key associated with it.
type KeyedNode interface {
Node
Key() string
}
// Visitor is the interface that must be implemented by any
// structures who want to be visited as part of the visitor pattern
// on the AST.
type Visitor interface {
Visit(Node)
}
2014-08-01 01:44:21 +00:00
// ObjectNode represents an object that has multiple elements.
// An object's elements may repeat (keys). This is expected to
// be validated/removed at a semantic check, rather than at a
// syntax level.
2014-08-01 01:44:21 +00:00
type ObjectNode struct {
2014-08-02 22:44:45 +00:00
K string
Elem []KeyedNode
2014-08-01 01:44:21 +00:00
}
// AssignmentNode represents a direct assignment with an equals
// sign.
type AssignmentNode struct {
2014-08-02 22:44:45 +00:00
K string
Value Node
}
// ListNode represents a list or array of items.
type ListNode struct {
Elem []Node
}
// LiteralNode is a direct value.
type LiteralNode struct {
2014-08-01 01:44:21 +00:00
Type ValueType
Value interface{}
}
func (n ObjectNode) Accept(v Visitor) {
2014-08-02 22:44:45 +00:00
v.Visit(n)
for _, e := range n.Elem {
e.Accept(v)
}
2014-08-02 22:44:45 +00:00
}
2014-08-03 21:06:18 +00:00
// Get returns all the elements of this object with the given key.
// This is a case-sensitive search.
2014-08-04 00:17:17 +00:00
func (n ObjectNode) Get(k string) []Node {
result := make([]Node, 0, 1)
2014-08-03 21:06:18 +00:00
for _, elem := range n.Elem {
2014-08-04 00:17:17 +00:00
if elem.Key() != k {
continue
}
switch n := elem.(type) {
case AssignmentNode:
result = append(result, n.Value)
default:
panic("unknown type")
2014-08-03 21:06:18 +00:00
}
}
return result
}
// Key returns the key of this object. If this is "", then it is
// the root object.
2014-08-02 22:44:45 +00:00
func (n ObjectNode) Key() string {
return n.K
}
2014-08-03 21:06:18 +00:00
// Len returns the number of elements of this object.
func (n ObjectNode) Len() int {
return len(n.Elem)
}
func (n AssignmentNode) Accept(v Visitor) {
v.Visit(n)
2014-08-02 22:44:45 +00:00
n.Value.Accept(v)
}
func (n AssignmentNode) Key() string {
return n.K
}
func (n ListNode) Accept(v Visitor) {
2014-08-02 22:44:45 +00:00
v.Visit(n)
for _, e := range n.Elem {
e.Accept(v)
}
}
func (n LiteralNode) Accept(v Visitor) {
v.Visit(n)
}