Skip to content

Commit

Permalink
Allowed exponential notation when parsing numbers, closes #173
Browse files Browse the repository at this point in the history
```
⧐  1e-10
0.0000000001
⧐  '1e-10'.json()
0.0000000001
```
  • Loading branch information
odino committed Feb 8, 2019
1 parent cb3464f commit 565b28e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
3 changes: 3 additions & 0 deletions evaluator/evaluator_test.go
Expand Up @@ -48,6 +48,9 @@ func TestEvalNumberExpression(t *testing.T) {
input string
expected float64
}{
{"1e1", 10},
{"1e-1", 0.1},
{"1e+1", 10},
{"5.5", 5.5},
{"1.1 + 2.1", 3.2},
{"5.5 + 2.2", 7.7},
Expand Down
31 changes: 30 additions & 1 deletion lexer/lexer.go
Expand Up @@ -346,17 +346,40 @@ func (l *Lexer) readIdentifier() string {
return l.input[position:l.position]
}

// 12
// 12.2
// 12e-1
// 12e+1
// 12e1
func (l *Lexer) readNumber() (number string, kind token.TokenType) {
position := l.position
kind = token.NUMBER
hasDot := false
hasExponent := false

// List of character that can appear in a "number"
for isDigit(l.ch) || l.ch == '.' || l.ch == '+' || l.ch == '-' || l.ch == 'e' {
// If we have a plus / minus but there was no exponent
// in this number, it means we're at the end of the
// number and we're at an addition / subtraction.
if (l.ch == '+' || l.ch == '-') && !hasExponent {
return l.input[position:l.position], kind
}

// If the number contains as 'e',
// we're using scientific notation
if l.ch == 'e' {
hasExponent = true
}

for isDigit(l.ch) || l.ch == '.' {
// If we have a dot, let's check whether this is a range
// or maybe a method call (122.string())
if l.ch == '.' && (l.peekChar() == '.' || !isDigit(l.peekChar())) {
return l.input[position:l.position], token.NUMBER
}

if l.ch == '.' {
// If we have 2 dots in a number, there's a problem
if hasDot {
return "", token.ILLEGAL
}
Expand All @@ -367,6 +390,12 @@ func (l *Lexer) readNumber() (number string, kind token.TokenType) {
l.readChar()
}

// If the number ends with the exponent,
// there's a problem.
if l.input[l.position-1] == 'e' {
return "", token.ILLEGAL
}

return l.input[position:l.position], kind
}

Expand Down
12 changes: 12 additions & 0 deletions lexer/lexer_test.go
Expand Up @@ -76,6 +76,11 @@ nullo
&^>><<
$111
'123'
12+12
12e10
12e+10
12e-10
12e
`

tests := []struct {
Expand Down Expand Up @@ -282,6 +287,13 @@ $111
{token.BIT_LSHIFT, "<<"},
{token.ILLEGAL, "$111"},
{token.STRING, "123"},
{token.NUMBER, "12"},
{token.PLUS, "+"},
{token.NUMBER, "12"},
{token.NUMBER, "12e10"},
{token.NUMBER, "12e+10"},
{token.NUMBER, "12e-10"},
{token.ILLEGAL, ""},
{token.EOF, ""},
}

Expand Down

0 comments on commit 565b28e

Please sign in to comment.