Add support for map properties

Example:

foo {
  // string property
  name: "hello",
  // map property
  translations: {
    ge: "guten tag",
    fr: "bonjour",
  },
}

Change-Id: Ib9e6570cb6f355677b4ba0235e8fb4186e40f5f8
This commit is contained in:
Romain Guy 2014-07-25 17:01:20 -07:00
parent 5f7ef51f7a
commit 2476f81d84
2 changed files with 73 additions and 0 deletions

View file

@ -201,6 +201,8 @@ func (p *parser) parseValue() (value Value) {
return p.parseStringValue() return p.parseStringValue()
case '[': case '[':
return p.parseListValue() return p.parseListValue()
case '{':
return p.parseMapValue()
default: default:
p.errorf("expected bool, list, or string value; found %s", p.errorf("expected bool, list, or string value; found %s",
scanner.TokenString(p.tok)) scanner.TokenString(p.tok))
@ -262,12 +264,27 @@ func (p *parser) parseListValue() (value Value) {
return return
} }
func (p *parser) parseMapValue() (value Value) {
value.Type = Map
value.Pos = p.scanner.Position
if !p.accept('{') {
return
}
properties := p.parsePropertyList()
value.MapValue = properties
p.accept('}')
return
}
type ValueType int type ValueType int
const ( const (
Bool ValueType = iota Bool ValueType = iota
String String
List List
Map
) )
func (p ValueType) String() string { func (p ValueType) String() string {
@ -278,6 +295,8 @@ func (p ValueType) String() string {
return "string" return "string"
case List: case List:
return "list" return "list"
case Map:
return "map"
default: default:
panic(fmt.Errorf("unknown value type: %d", p)) panic(fmt.Errorf("unknown value type: %d", p))
} }
@ -332,6 +351,7 @@ type Value struct {
BoolValue bool BoolValue bool
StringValue string StringValue string
ListValue []Value ListValue []Value
MapValue []*Property
Pos scanner.Position Pos scanner.Position
} }
@ -348,6 +368,13 @@ func (p Value) String() string {
} }
return fmt.Sprintf("@%d:%s[%s]", p.Pos.Offset, p.Pos, return fmt.Sprintf("@%d:%s[%s]", p.Pos.Offset, p.Pos,
strings.Join(valueStrings, ", ")) strings.Join(valueStrings, ", "))
case Map:
propertyStrings := make([]string, len(p.MapValue))
for i, property := range p.MapValue {
propertyStrings[i] = property.String()
}
return fmt.Sprintf("@%d:%s{%s}", p.Pos.Offset, p.Pos,
strings.Join(propertyStrings, ", "))
default: default:
panic(fmt.Errorf("bad property type: %d", p.Type)) panic(fmt.Errorf("bad property type: %d", p.Type))
} }

View file

@ -130,6 +130,52 @@ var validParseTestCases = []struct {
}, },
}, },
{`
foo {
stuff: {
isGood: true,
name: "bar"
}
}
`,
[]Definition{
&Module{
Type: "foo",
Pos: mkpos(3, 2, 3),
Properties: []*Property{
{
Name: "stuff",
Pos: mkpos(12, 3, 4),
Value: Value{
Type: Map,
Pos: mkpos(19, 3, 11),
MapValue: []*Property{
{
Name: "isGood",
Pos: mkpos(25, 4, 5),
Value: Value{
Type: Bool,
Pos: mkpos(33, 4, 13),
BoolValue: true,
},
},
{
Name: "name",
Pos: mkpos(43, 5, 5),
Value: Value{
Type: String,
Pos: mkpos(49, 5, 11),
StringValue: "bar",
},
},
},
},
},
},
},
},
},
{` {`
// comment // comment
foo { foo {