ObjectNodes can only have assignments

This commit is contained in:
Mitchell Hashimoto 2014-08-03 21:56:50 -07:00
parent a095771be9
commit 783acc2aa1
7 changed files with 45 additions and 38 deletions

View File

@ -42,7 +42,7 @@ type Visitor interface {
// syntax level. // syntax level.
type ObjectNode struct { type ObjectNode struct {
K string K string
Elem []KeyedNode Elem []AssignmentNode
} }
// AssignmentNode represents a direct assignment with an equals // AssignmentNode represents a direct assignment with an equals
@ -82,12 +82,7 @@ func (n ObjectNode) Get(k string, insensitive bool) []Node {
} }
} }
switch n := elem.(type) { result = append(result, elem.Value)
case AssignmentNode:
result = append(result, n.Value)
default:
panic("unknown type")
}
} }
return result return result
@ -121,6 +116,19 @@ func (n ListNode) Accept(v Visitor) {
} }
} }
func (n ListNode) Flatten() ListNode {
var elem []Node
for _, e := range n.Elem {
if ln, ok := e.(ListNode); ok {
elem = append(elem, ln.Flatten().Elem...)
} else {
elem = append(elem, e)
}
}
return ListNode{Elem: elem}
}
func (n LiteralNode) Accept(v Visitor) { func (n LiteralNode) Accept(v Visitor) {
v.Visit(n) v.Visit(n)
} }

View File

@ -49,7 +49,7 @@ func TestListNode_accept(t *testing.T) {
func TestObjectNode_accept(t *testing.T) { func TestObjectNode_accept(t *testing.T) {
n := ObjectNode{ n := ObjectNode{
K: "foo", K: "foo",
Elem: []KeyedNode{ Elem: []AssignmentNode{
AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}}, AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}},
AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}}, AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}},
}, },
@ -58,9 +58,9 @@ func TestObjectNode_accept(t *testing.T) {
expected := []Node{ expected := []Node{
n, n,
n.Elem[0], n.Elem[0],
n.Elem[0].(AssignmentNode).Value, n.Elem[0].Value,
n.Elem[1], n.Elem[1],
n.Elem[1].(AssignmentNode).Value, n.Elem[1].Value,
} }
v := new(MockVisitor) v := new(MockVisitor)
@ -74,7 +74,7 @@ func TestObjectNode_accept(t *testing.T) {
func TestObjectNodeGet(t *testing.T) { func TestObjectNodeGet(t *testing.T) {
n := ObjectNode{ n := ObjectNode{
K: "foo", K: "foo",
Elem: []KeyedNode{ Elem: []AssignmentNode{
AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}}, AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}},
AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}}, AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}},
AssignmentNode{K: "foo", Value: LiteralNode{Value: "baz"}}, AssignmentNode{K: "foo", Value: LiteralNode{Value: "baz"}},

View File

@ -202,8 +202,7 @@ func (d *decoder) decodeMap(name string, raw ast.Node, result reflect.Value) err
} }
// Go through each element and decode it. // Go through each element and decode it.
for _, elem := range obj.Elem { for _, n := range obj.Elem {
n := elem.(ast.AssignmentNode)
objValue := n.Value objValue := n.Value
// If we have an object node, expand to a list of objects // If we have an object node, expand to a list of objects

View File

@ -15,8 +15,8 @@ import (
%union { %union {
item ast.Node item ast.Node
list []ast.Node list []ast.Node
klist []ast.KeyedNode alist []ast.AssignmentNode
kitem ast.KeyedNode aitem ast.AssignmentNode
listitem ast.Node listitem ast.Node
num int num int
obj ast.ObjectNode obj ast.ObjectNode
@ -25,8 +25,8 @@ import (
%type <item> number %type <item> number
%type <list> list %type <list> list
%type <klist> objectlist %type <alist> objectlist
%type <kitem> objectitem block %type <aitem> objectitem block
%type <listitem> listitem %type <listitem> listitem
%type <num> int %type <num> int
%type <obj> object %type <obj> object
@ -50,7 +50,7 @@ top:
objectlist: objectlist:
objectitem objectitem
{ {
$$ = []ast.KeyedNode{$1} $$ = []ast.AssignmentNode{$1}
} }
| objectitem objectlist | objectitem objectlist
{ {
@ -118,7 +118,7 @@ block:
{ {
obj := ast.ObjectNode{ obj := ast.ObjectNode{
K: $2.Key(), K: $2.Key(),
Elem: []ast.KeyedNode{$2}, Elem: []ast.AssignmentNode{$2},
} }
$$ = ast.AssignmentNode{ $$ = ast.AssignmentNode{

View File

@ -16,8 +16,8 @@ type hclSymType struct {
yys int yys int
item ast.Node item ast.Node
list []ast.Node list []ast.Node
klist []ast.KeyedNode alist []ast.AssignmentNode
kitem ast.KeyedNode aitem ast.AssignmentNode
listitem ast.Node listitem ast.Node
num int num int
obj ast.ObjectNode obj ast.ObjectNode
@ -363,23 +363,23 @@ hcldefault:
{ {
hclResult = &ast.ObjectNode{ hclResult = &ast.ObjectNode{
K: "", K: "",
Elem: hclS[hclpt-0].klist, Elem: hclS[hclpt-0].alist,
} }
} }
case 2: case 2:
//line parse.y:52 //line parse.y:52
{ {
hclVAL.klist = []ast.KeyedNode{hclS[hclpt-0].kitem} hclVAL.alist = []ast.AssignmentNode{hclS[hclpt-0].aitem}
} }
case 3: case 3:
//line parse.y:56 //line parse.y:56
{ {
hclVAL.klist = append(hclS[hclpt-0].klist, hclS[hclpt-1].kitem) hclVAL.alist = append(hclS[hclpt-0].alist, hclS[hclpt-1].aitem)
} }
case 4: case 4:
//line parse.y:62 //line parse.y:62
{ {
hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].klist} hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].alist}
} }
case 5: case 5:
//line parse.y:66 //line parse.y:66
@ -389,7 +389,7 @@ hcldefault:
case 6: case 6:
//line parse.y:72 //line parse.y:72
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.aitem = ast.AssignmentNode{
K: hclS[hclpt-2].str, K: hclS[hclpt-2].str,
Value: hclS[hclpt-0].item, Value: hclS[hclpt-0].item,
} }
@ -397,7 +397,7 @@ hcldefault:
case 7: case 7:
//line parse.y:79 //line parse.y:79
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.aitem = ast.AssignmentNode{
K: hclS[hclpt-2].str, K: hclS[hclpt-2].str,
Value: ast.LiteralNode{ Value: ast.LiteralNode{
Type: ast.ValueTypeString, Type: ast.ValueTypeString,
@ -408,7 +408,7 @@ hcldefault:
case 8: case 8:
//line parse.y:89 //line parse.y:89
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.aitem = ast.AssignmentNode{
K: hclS[hclpt-2].str, K: hclS[hclpt-2].str,
Value: hclS[hclpt-0].obj, Value: hclS[hclpt-0].obj,
} }
@ -416,7 +416,7 @@ hcldefault:
case 9: case 9:
//line parse.y:96 //line parse.y:96
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.aitem = ast.AssignmentNode{
K: hclS[hclpt-4].str, K: hclS[hclpt-4].str,
Value: ast.ListNode{Elem: hclS[hclpt-1].list}, Value: ast.ListNode{Elem: hclS[hclpt-1].list},
} }
@ -424,12 +424,12 @@ hcldefault:
case 10: case 10:
//line parse.y:103 //line parse.y:103
{ {
hclVAL.kitem = hclS[hclpt-0].kitem hclVAL.aitem = hclS[hclpt-0].aitem
} }
case 11: case 11:
//line parse.y:109 //line parse.y:109
{ {
hclVAL.kitem = ast.AssignmentNode{ hclVAL.aitem = ast.AssignmentNode{
K: hclS[hclpt-1].str, K: hclS[hclpt-1].str,
Value: ast.ListNode{ Value: ast.ListNode{
Elem: []ast.Node{hclS[hclpt-0].obj}, Elem: []ast.Node{hclS[hclpt-0].obj},
@ -440,11 +440,11 @@ hcldefault:
//line parse.y:118 //line parse.y:118
{ {
obj := ast.ObjectNode{ obj := ast.ObjectNode{
K: hclS[hclpt-0].kitem.Key(), K: hclS[hclpt-0].aitem.Key(),
Elem: []ast.KeyedNode{hclS[hclpt-0].kitem}, Elem: []ast.AssignmentNode{hclS[hclpt-0].aitem},
} }
hclVAL.kitem = ast.AssignmentNode{ hclVAL.aitem = ast.AssignmentNode{
K: hclS[hclpt-1].str, K: hclS[hclpt-1].str,
Value: ast.ListNode{ Value: ast.ListNode{
Elem: []ast.Node{obj}, Elem: []ast.Node{obj},

View File

@ -16,7 +16,7 @@ import (
array ast.ListNode array ast.ListNode
assign ast.AssignmentNode assign ast.AssignmentNode
item ast.Node item ast.Node
klist []ast.KeyedNode klist []ast.AssignmentNode
list []ast.Node list []ast.Node
num int num int
str string str string
@ -59,7 +59,7 @@ object:
members: members:
pair pair
{ {
$$ = []ast.KeyedNode{$1} $$ = []ast.AssignmentNode{$1}
} }
| pair COMMA members | pair COMMA members
{ {

View File

@ -17,7 +17,7 @@ type jsonSymType struct {
array ast.ListNode array ast.ListNode
assign ast.AssignmentNode assign ast.AssignmentNode
item ast.Node item ast.Node
klist []ast.KeyedNode klist []ast.AssignmentNode
list []ast.Node list []ast.Node
num int num int
str string str string
@ -385,7 +385,7 @@ jsondefault:
case 4: case 4:
//line parse.y:61 //line parse.y:61
{ {
jsonVAL.klist = []ast.KeyedNode{jsonS[jsonpt-0].assign} jsonVAL.klist = []ast.AssignmentNode{jsonS[jsonpt-0].assign}
} }
case 5: case 5:
//line parse.y:65 //line parse.y:65