Fixes #30: Implement exp notation in floats
diff --git a/lexer.go b/lexer.go index c1b4998..001049d 100644 --- a/lexer.go +++ b/lexer.go
@@ -418,6 +418,7 @@ l.accept("-") } pointSeen := false + expSeen := false digitSeen := false for { next := l.next() @@ -429,6 +430,11 @@ return l.errorf("float cannot end with a dot") } pointSeen = true + } else if next == 'e' || next == 'E' { + expSeen = true + if !l.accept("+") { + l.accept("-") + } } else if isDigit(next) { digitSeen = true } else { @@ -443,7 +449,7 @@ if !digitSeen { return l.errorf("no digit in that number") } - if pointSeen { + if pointSeen || expSeen { l.emit(tokenFloat) } else { l.emit(tokenInteger)
diff --git a/lexer_test.go b/lexer_test.go index 5114223..019a496 100644 --- a/lexer_test.go +++ b/lexer_test.go
@@ -305,6 +305,51 @@ }) } +func TestFloatWithExponent1(t *testing.T) { + testFlow(t, "a = 5e+22", []token{ + token{Position{1, 1}, tokenKey, "a"}, + token{Position{1, 3}, tokenEqual, "="}, + token{Position{1, 5}, tokenFloat, "5e+22"}, + token{Position{1, 10}, tokenEOF, ""}, + }) +} + +func TestFloatWithExponent2(t *testing.T) { + testFlow(t, "a = 5E+22", []token{ + token{Position{1, 1}, tokenKey, "a"}, + token{Position{1, 3}, tokenEqual, "="}, + token{Position{1, 5}, tokenFloat, "5E+22"}, + token{Position{1, 10}, tokenEOF, ""}, + }) +} + +func TestFloatWithExponent3(t *testing.T) { + testFlow(t, "a = -5e+22", []token{ + token{Position{1, 1}, tokenKey, "a"}, + token{Position{1, 3}, tokenEqual, "="}, + token{Position{1, 5}, tokenFloat, "-5e+22"}, + token{Position{1, 11}, tokenEOF, ""}, + }) +} + +func TestFloatWithExponent4(t *testing.T) { + testFlow(t, "a = -5e-22", []token{ + token{Position{1, 1}, tokenKey, "a"}, + token{Position{1, 3}, tokenEqual, "="}, + token{Position{1, 5}, tokenFloat, "-5e-22"}, + token{Position{1, 11}, tokenEOF, ""}, + }) +} + +func TestFloatWithExponent5(t *testing.T) { + testFlow(t, "a = 6.626e-34", []token{ + token{Position{1, 1}, tokenKey, "a"}, + token{Position{1, 3}, tokenEqual, "="}, + token{Position{1, 5}, tokenFloat, "6.626e-34"}, + token{Position{1, 14}, tokenEOF, ""}, + }) +} + func TestDoubleEqualKey(t *testing.T) { testFlow(t, "foo= = 2", []token{ token{Position{1, 1}, tokenKey, "foo"},
diff --git a/parser_test.go b/parser_test.go index 8160905..238ca2f 100644 --- a/parser_test.go +++ b/parser_test.go
@@ -70,6 +70,17 @@ }) } +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{}{ + "a": float64(5e+22), + "b": float64(5E+22), + "c": float64(-5e+22), + "d": float64(-5e-22), + "e": float64(6.626e-34), + }) +} + func TestSimpleDate(t *testing.T) { tree, err := Load("a = 1979-05-27T07:32:00Z") assertTree(t, tree, err, map[string]interface{}{