Implement inline tables

This commit is contained in:
Thomas Pelletier
2015-08-19 10:24:53 -07:00
parent f58048cec0
commit dd4c4ffc2b
6 changed files with 131 additions and 16 deletions
+54 -1
View File
@@ -244,6 +244,8 @@ func (p *tomlParser) parseRvalue() interface{} {
return val
case tokenLeftBracket:
return p.parseArray()
case tokenLeftCurlyBrace:
return p.parseInlineTable()
case tokenError:
p.raiseError(tok, "%s", tok)
}
@@ -253,7 +255,51 @@ func (p *tomlParser) parseRvalue() interface{} {
return nil
}
func (p *tomlParser) parseArray() []interface{} {
func tokenIsComma(t *token) bool {
return t != nil && t.typ == tokenComma
}
func (p *tomlParser) parseInlineTable() *TomlTree {
tree := newTomlTree()
var previous *token
Loop:
for {
follow := p.peek()
if follow == nil || follow.typ == tokenEOF {
p.raiseError(follow, "unterminated inline table")
}
switch follow.typ {
case tokenRightCurlyBrace:
p.getToken()
break Loop
case tokenKey:
if !tokenIsComma(previous) && previous != nil {
p.raiseError(follow, "comma expected between fields in inline table")
}
key := p.getToken()
p.assume(tokenEqual)
value := p.parseRvalue()
tree.Set(key.val, value)
case tokenComma:
if previous == nil {
p.raiseError(follow, "inline table cannot start with a comma")
}
if tokenIsComma(previous) {
p.raiseError(follow, "need field between two commas in inline table")
}
p.getToken()
default:
p.raiseError(follow, "unexpected token type in inline table: %s", follow.typ.String())
}
previous = follow
}
if tokenIsComma(previous) {
p.raiseError(previous, "trailing comma at the end of inline table")
}
return tree
}
func (p *tomlParser) parseArray() interface{} {
var array []interface{}
arrayType := reflect.TypeOf(nil)
for {
@@ -263,6 +309,13 @@ func (p *tomlParser) parseArray() []interface{} {
}
if follow.typ == tokenRightBracket {
p.getToken()
if arrayType == reflect.TypeOf(newTomlTree()) {
tomlArray := make([]*TomlTree, len(array))
for i, v := range array {
tomlArray[i] = v.(*TomlTree)
}
return tomlArray
}
return array
}
val := p.parseRvalue()