Accept underscores in integers
diff --git a/lexer.go b/lexer.go index 7cb789b..b8ba2ed 100644 --- a/lexer.go +++ b/lexer.go
@@ -527,6 +527,8 @@ } } else if isDigit(next) { digitSeen = true + } else if next == '_' { + l.pos++ } else { l.backup() break
diff --git a/lexer_test.go b/lexer_test.go index d1cd130..37535e5 100644 --- a/lexer_test.go +++ b/lexer_test.go
@@ -434,6 +434,27 @@ token{Position{1, 7}, tokenFloat, "-4.2"}, token{Position{1, 11}, tokenEOF, ""}, }) + + testFlow(t, "foo = 1_000", []token{ + token{Position{1, 1}, tokenKey, "foo"}, + token{Position{1, 5}, tokenEqual, "="}, + token{Position{1, 7}, tokenInteger, "1_000"}, + token{Position{1, 12}, tokenEOF, ""}, + }) + + testFlow(t, "foo = 5_349_221", []token{ + token{Position{1, 1}, tokenKey, "foo"}, + token{Position{1, 5}, tokenEqual, "="}, + token{Position{1, 7}, tokenInteger, "5_349_221"}, + token{Position{1, 16}, tokenEOF, ""}, + }) + + testFlow(t, "foo = 1_2_3_4_5", []token{ + token{Position{1, 1}, tokenKey, "foo"}, + token{Position{1, 5}, tokenEqual, "="}, + token{Position{1, 7}, tokenInteger, "1_2_3_4_5"}, + token{Position{1, 16}, tokenEOF, ""}, + }) } func TestMultiline(t *testing.T) {
diff --git a/parser.go b/parser.go index e550967..59f513b 100644 --- a/parser.go +++ b/parser.go
@@ -224,7 +224,8 @@ case tokenFalse: return false case tokenInteger: - val, err := strconv.ParseInt(tok.val, 10, 64) + cleanedVal := strings.Replace(tok.val, "_", "", -1) + val, err := strconv.ParseInt(cleanedVal, 10, 64) if err != nil { p.raiseError(tok, "%s", err) }
diff --git a/parser_test.go b/parser_test.go index 2998913..9bdf9b2 100644 --- a/parser_test.go +++ b/parser_test.go
@@ -68,6 +68,23 @@ }) } +func TestIntegersWithUnderscores(t *testing.T) { + tree, err := Load("a = 1_000") + assertTree(t, tree, err, map[string]interface{}{ + "a": int64(1000), + }) + + tree, err = Load("a = 5_349_221") + assertTree(t, tree, err, map[string]interface{}{ + "a": int64(5349221), + }) + + tree, err = Load("a = 1_2_3_4_5") + assertTree(t, tree, err, map[string]interface{}{ + "a": int64(12345), + }) +} + func TestFloatsWithExponents(t *testing.T) { tree, err := Load("a = 5e+22\nb = 5E+22\nc = -5e+22\nd = -5e-22\ne = 6.626e-34") assertTree(t, tree, err, map[string]interface{}{