Apply go fmt
This commit is contained in:
+29
-25
@@ -10,14 +10,13 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var dateRegexp *regexp.Regexp
|
var dateRegexp *regexp.Regexp
|
||||||
|
|
||||||
// Define tokens
|
// Define tokens
|
||||||
type tokenType int
|
type tokenType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
eof = - (iota + 1)
|
eof = -(iota + 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -44,7 +43,6 @@ type token struct {
|
|||||||
val string
|
val string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (i token) String() string {
|
func (i token) String() string {
|
||||||
switch i.typ {
|
switch i.typ {
|
||||||
case tokenEOF:
|
case tokenEOF:
|
||||||
@@ -54,12 +52,11 @@ func (i token) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(i.val) > 10 {
|
if len(i.val) > 10 {
|
||||||
return fmt.Sprintf("%.10q...", i.val);
|
return fmt.Sprintf("%.10q...", i.val)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%q", i.val)
|
return fmt.Sprintf("%q", i.val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func isSpace(r rune) bool {
|
func isSpace(r rune) bool {
|
||||||
return r == ' ' || r == '\t'
|
return r == ' ' || r == '\t'
|
||||||
}
|
}
|
||||||
@@ -72,22 +69,20 @@ func isDigit(r rune) bool {
|
|||||||
return r >= '0' && r <= '9'
|
return r >= '0' && r <= '9'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Define lexer
|
// Define lexer
|
||||||
type lexer struct {
|
type lexer struct {
|
||||||
input string
|
input string
|
||||||
start int
|
start int
|
||||||
pos int
|
pos int
|
||||||
width int
|
width int
|
||||||
tokens chan token
|
tokens chan token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (l *lexer) run() {
|
func (l *lexer) run() {
|
||||||
for state := lexVoid; state != nil; {
|
for state := lexVoid; state != nil; {
|
||||||
state = state(l)
|
state = state(l)
|
||||||
}
|
}
|
||||||
close (l.tokens)
|
close(l.tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lexer) emit(t tokenType) {
|
func (l *lexer) emit(t tokenType) {
|
||||||
@@ -100,8 +95,7 @@ func (l *lexer) emitWithValue(t tokenType, value string) {
|
|||||||
l.start = l.pos
|
l.start = l.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *lexer) next() rune {
|
||||||
func (l *lexer) next() (rune) {
|
|
||||||
if l.pos >= len(l.input) {
|
if l.pos >= len(l.input) {
|
||||||
l.width = 0
|
l.width = 0
|
||||||
return eof
|
return eof
|
||||||
@@ -146,7 +140,6 @@ func (l *lexer) follow(next string) bool {
|
|||||||
return strings.HasPrefix(l.input[l.pos:], next)
|
return strings.HasPrefix(l.input[l.pos:], next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Define state functions
|
// Define state functions
|
||||||
type stateFn func(*lexer) stateFn
|
type stateFn func(*lexer) stateFn
|
||||||
|
|
||||||
@@ -170,7 +163,9 @@ func lexVoid(l *lexer) stateFn {
|
|||||||
l.ignore()
|
l.ignore()
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.next() == eof { break }
|
if l.next() == eof {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.emit(tokenEOF)
|
l.emit(tokenEOF)
|
||||||
@@ -222,7 +217,9 @@ func lexRvalue(l *lexer) stateFn {
|
|||||||
l.ignore()
|
l.ignore()
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.next() == eof { break }
|
if l.next() == eof {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.emit(tokenEOF)
|
l.emit(tokenEOF)
|
||||||
@@ -311,7 +308,9 @@ func lexString(l *lexer) stateFn {
|
|||||||
growing_string += string(l.peek())
|
growing_string += string(l.peek())
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.next() == eof { break }
|
if l.next() == eof {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.errorf("unclosed string")
|
return l.errorf("unclosed string")
|
||||||
@@ -336,7 +335,9 @@ func lexInsideKeyGroup(l *lexer) stateFn {
|
|||||||
return lexVoid
|
return lexVoid
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.next() == eof { break }
|
if l.next() == eof {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return l.errorf("unclosed key group")
|
return l.errorf("unclosed key group")
|
||||||
}
|
}
|
||||||
@@ -350,13 +351,17 @@ func lexRightBracket(l *lexer) stateFn {
|
|||||||
|
|
||||||
func lexNumber(l *lexer) stateFn {
|
func lexNumber(l *lexer) stateFn {
|
||||||
l.ignore()
|
l.ignore()
|
||||||
if !l.accept("+") { l.accept("-") }
|
if !l.accept("+") {
|
||||||
|
l.accept("-")
|
||||||
|
}
|
||||||
point_seen := false
|
point_seen := false
|
||||||
digit_seen := false
|
digit_seen := false
|
||||||
for {
|
for {
|
||||||
next := l.next()
|
next := l.next()
|
||||||
if next == '.' { point_seen = true
|
if next == '.' {
|
||||||
} else if isDigit(next) { digit_seen = true
|
point_seen = true
|
||||||
|
} else if isDigit(next) {
|
||||||
|
digit_seen = true
|
||||||
} else {
|
} else {
|
||||||
l.backup()
|
l.backup()
|
||||||
break
|
break
|
||||||
@@ -378,11 +383,10 @@ func init() {
|
|||||||
dateRegexp = regexp.MustCompile("^\\d{1,4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z")
|
dateRegexp = regexp.MustCompile("^\\d{1,4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Entry point
|
// Entry point
|
||||||
func lex(input string) (*lexer, chan token) {
|
func lex(input string) (*lexer, chan token) {
|
||||||
l := &lexer {
|
l := &lexer{
|
||||||
input: input,
|
input: input,
|
||||||
tokens: make(chan token),
|
tokens: make(chan token),
|
||||||
}
|
}
|
||||||
go l.run()
|
go l.run()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import "testing"
|
|||||||
func testFlow(t *testing.T, input string, expectedFlow []token) {
|
func testFlow(t *testing.T, input string, expectedFlow []token) {
|
||||||
_, ch := lex(input)
|
_, ch := lex(input)
|
||||||
for _, expected := range expectedFlow {
|
for _, expected := range expectedFlow {
|
||||||
token := <- ch
|
token := <-ch
|
||||||
if token != expected {
|
if token != expected {
|
||||||
t.Log("compared", token, "to", expected)
|
t.Log("compared", token, "to", expected)
|
||||||
t.Log(token.val, "<->", expected.val)
|
t.Log(token.val, "<->", expected.val)
|
||||||
@@ -14,10 +14,10 @@ func testFlow(t *testing.T, input string, expectedFlow []token) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tok, ok := <- ch
|
tok, ok := <-ch
|
||||||
if ok {
|
if ok {
|
||||||
t.Log("channel is not closed!")
|
t.Log("channel is not closed!")
|
||||||
t.Log(len(ch) + 1, "tokens remaining:")
|
t.Log(len(ch)+1, "tokens remaining:")
|
||||||
|
|
||||||
t.Log("token ->", tok)
|
t.Log("token ->", tok)
|
||||||
for token := range ch {
|
for token := range ch {
|
||||||
@@ -43,7 +43,6 @@ func TestUnclosedKeyGroup(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestComment(t *testing.T) {
|
func TestComment(t *testing.T) {
|
||||||
testFlow(t, "# blahblah", []token{
|
testFlow(t, "# blahblah", []token{
|
||||||
token{tokenEOF, ""},
|
token{tokenEOF, ""},
|
||||||
|
|||||||
+22
-14
@@ -8,10 +8,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type parser struct {
|
type parser struct {
|
||||||
flow chan token
|
flow chan token
|
||||||
tree *TomlTree
|
tree *TomlTree
|
||||||
tokensBuffer []token
|
tokensBuffer []token
|
||||||
currentGroup string
|
currentGroup string
|
||||||
}
|
}
|
||||||
@@ -29,7 +28,7 @@ func (p *parser) peek() *token {
|
|||||||
return &(p.tokensBuffer[0])
|
return &(p.tokensBuffer[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
tok, ok := <- p.flow
|
tok, ok := <-p.flow
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -53,7 +52,7 @@ func (p *parser) getToken() *token {
|
|||||||
p.tokensBuffer = p.tokensBuffer[1:]
|
p.tokensBuffer = p.tokensBuffer[1:]
|
||||||
return &tok
|
return &tok
|
||||||
}
|
}
|
||||||
tok, ok := <- p.flow
|
tok, ok := <-p.flow
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -120,15 +119,21 @@ func parseRvalue(p *parser) interface{} {
|
|||||||
return false
|
return false
|
||||||
case tokenInteger:
|
case tokenInteger:
|
||||||
val, err := strconv.ParseInt(tok.val, 10, 64)
|
val, err := strconv.ParseInt(tok.val, 10, 64)
|
||||||
if err != nil { panic(err) }
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return val
|
return val
|
||||||
case tokenFloat:
|
case tokenFloat:
|
||||||
val, err := strconv.ParseFloat(tok.val, 64)
|
val, err := strconv.ParseFloat(tok.val, 64)
|
||||||
if err != nil { panic(err) }
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return val
|
return val
|
||||||
case tokenDate:
|
case tokenDate:
|
||||||
val, err := time.Parse(time.RFC3339, tok.val)
|
val, err := time.Parse(time.RFC3339, tok.val)
|
||||||
if err != nil { panic(err) }
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return val
|
return val
|
||||||
case tokenLeftBracket:
|
case tokenLeftBracket:
|
||||||
return parseArray(p)
|
return parseArray(p)
|
||||||
@@ -143,7 +148,9 @@ func parseArray(p *parser) []interface{} {
|
|||||||
array := make([]interface{}, 0)
|
array := make([]interface{}, 0)
|
||||||
for {
|
for {
|
||||||
follow := p.peek()
|
follow := p.peek()
|
||||||
if follow == nil { panic("unterminated array") }
|
if follow == nil {
|
||||||
|
panic("unterminated array")
|
||||||
|
}
|
||||||
if follow.typ == tokenRightBracket {
|
if follow.typ == tokenRightBracket {
|
||||||
p.getToken()
|
p.getToken()
|
||||||
return array
|
return array
|
||||||
@@ -151,7 +158,9 @@ func parseArray(p *parser) []interface{} {
|
|||||||
val := parseRvalue(p)
|
val := parseRvalue(p)
|
||||||
array = append(array, val)
|
array = append(array, val)
|
||||||
follow = p.peek()
|
follow = p.peek()
|
||||||
if follow == nil { panic("unterminated array") }
|
if follow == nil {
|
||||||
|
panic("unterminated array")
|
||||||
|
}
|
||||||
if follow.typ != tokenRightBracket && follow.typ != tokenComma {
|
if follow.typ != tokenRightBracket && follow.typ != tokenComma {
|
||||||
panic("missing comma")
|
panic("missing comma")
|
||||||
}
|
}
|
||||||
@@ -162,12 +171,11 @@ func parseArray(p *parser) []interface{} {
|
|||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func parse(flow chan token) *TomlTree {
|
func parse(flow chan token) *TomlTree {
|
||||||
result := make(TomlTree)
|
result := make(TomlTree)
|
||||||
parser := &parser {
|
parser := &parser{
|
||||||
flow: flow,
|
flow: flow,
|
||||||
tree: &result,
|
tree: &result,
|
||||||
tokensBuffer: make([]token, 0),
|
tokensBuffer: make([]token, 0),
|
||||||
currentGroup: "",
|
currentGroup: "",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func assertTree(t *testing.T, tree *TomlTree, ref map[string]interface{}) {
|
func assertTree(t *testing.T, tree *TomlTree, ref map[string]interface{}) {
|
||||||
for k, v := range ref {
|
for k, v := range ref {
|
||||||
if fmt.Sprintf("%v", tree.Get(k)) != fmt.Sprintf("%v", v) {
|
if fmt.Sprintf("%v", tree.Get(k)) != fmt.Sprintf("%v", v) {
|
||||||
@@ -25,7 +24,6 @@ func TestCreateSubTree(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestSimpleKV(t *testing.T) {
|
func TestSimpleKV(t *testing.T) {
|
||||||
tree := Load("a = 42")
|
tree := Load("a = 42")
|
||||||
assertTree(t, tree, map[string]interface{}{
|
assertTree(t, tree, map[string]interface{}{
|
||||||
@@ -81,18 +79,18 @@ func TestNestedKeys(t *testing.T) {
|
|||||||
func TestArraySimple(t *testing.T) {
|
func TestArraySimple(t *testing.T) {
|
||||||
tree := Load("a = [42, 21, 10]")
|
tree := Load("a = [42, 21, 10]")
|
||||||
assertTree(t, tree, map[string]interface{}{
|
assertTree(t, tree, map[string]interface{}{
|
||||||
"a": []int64{int64(42), int64(21), int64(10),},
|
"a": []int64{int64(42), int64(21), int64(10)},
|
||||||
})
|
})
|
||||||
|
|
||||||
tree = Load("a = [42, 21, 10,]")
|
tree = Load("a = [42, 21, 10,]")
|
||||||
assertTree(t, tree, map[string]interface{}{
|
assertTree(t, tree, map[string]interface{}{
|
||||||
"a": []int64{int64(42), int64(21), int64(10),},
|
"a": []int64{int64(42), int64(21), int64(10)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayNested(t *testing.T) {
|
func TestArrayNested(t *testing.T) {
|
||||||
tree := Load("a = [[42, 21], [10]]")
|
tree := Load("a = [[42, 21], [10]]")
|
||||||
assertTree(t, tree, map[string]interface{}{
|
assertTree(t, tree, map[string]interface{}{
|
||||||
"a": [][]int64{[]int64{int64(42), int64(21),}, []int64{int64(10),},},
|
"a": [][]int64{[]int64{int64(42), int64(21)}, []int64{int64(10)}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -30,7 +30,7 @@ func (t *TomlTree) Get(key string) interface{} {
|
|||||||
}
|
}
|
||||||
subtree = (*subtree)[intermediate_key].(*TomlTree)
|
subtree = (*subtree)[intermediate_key].(*TomlTree)
|
||||||
}
|
}
|
||||||
return (*subtree)[keys[len(keys) - 1]]
|
return (*subtree)[keys[len(keys)-1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set an element in the tree.
|
// Set an element in the tree.
|
||||||
@@ -46,7 +46,7 @@ func (t *TomlTree) Set(key string, value interface{}) {
|
|||||||
}
|
}
|
||||||
subtree = (*subtree)[intermediate_key].(*TomlTree)
|
subtree = (*subtree)[intermediate_key].(*TomlTree)
|
||||||
}
|
}
|
||||||
(*subtree)[keys[len(keys) - 1]] = value
|
(*subtree)[keys[len(keys)-1]] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// createSubTree takes a tree and a key andcreate the necessary intermediate
|
// createSubTree takes a tree and a key andcreate the necessary intermediate
|
||||||
@@ -66,7 +66,6 @@ func (t *TomlTree) createSubTree(key string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Load(content string) *TomlTree {
|
func Load(content string) *TomlTree {
|
||||||
_, flow := lex(content)
|
_, flow := lex(content)
|
||||||
return parse(flow)
|
return parse(flow)
|
||||||
|
|||||||
Reference in New Issue
Block a user