Skip to content

Commit

Permalink
fix: allow more numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
simonseyock committed Dec 28, 2021
1 parent 7d96841 commit 923050f
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 40 deletions.
20 changes: 4 additions & 16 deletions src/lexer/Lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,9 @@ function getIdentifier (text: string): string|null {
return text.slice(0, position)
}

const numberRegex = /[0-9]/
const numberRegex = /^(NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity))/
function getNumber (text: string): string|null {
let position = 0
let char
do {
char = text[position]
if (!numberRegex.test(char)) {
break
}
position++
} while (position < text.length)
if (position === 0) {
return null
}
return text.slice(0, position)
return numberRegex.exec(text)?.[0] ?? null
}

const identifierRule: Rule = text => {
Expand Down Expand Up @@ -174,9 +162,9 @@ const rules = [
makeKeyWordRule('keyof'),
makeKeyWordRule('readonly'),
makeKeyWordRule('import'),
numberRule,
identifierRule,
stringValueRule,
numberRule
stringValueRule
]

export class Lexer {
Expand Down
105 changes: 81 additions & 24 deletions test/lexer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@ import { expect } from 'chai'
import { Lexer } from '../src/lexer/Lexer'
import { Token } from '../src/lexer/Token'

describe('lexer', () => {
it('should lex name', () => {
const typeString = 'sometype'
const expected: Token = {
type: 'Identifier',
text: 'sometype'
}
function expectTokens(text: string, tokens: Token[]) {
const lexer = new Lexer()
lexer.lex(text)

let position = 0

const lexer = new Lexer()
lexer.lex(typeString)
const token = lexer.token()
while (lexer.token().type !== 'EOF') {
const nextToken = lexer.token()
const nextExpected = tokens[position]
expect(nextToken).to.deep.equal(nextExpected)
lexer.advance()
position++
}

expect(token).to.deep.equal(expected)
expect(lexer.token().type).to.equal('EOF')
expect(tokens.length).to.equal(position)
}

describe('lexer', () => {
it('should lex name', () => {
expectTokens('sometype', [
{
type: 'Identifier',
text: 'sometype'
}
])
})

it('should parse a complex expression', () => {
const typeString = 'Array<(AType|OtherType)>|\'test\'|undefined'
const expected: Token[] = [
expectTokens('Array<(AType|OtherType)>|\'test\'|undefined', [
{
type: 'Identifier',
text: 'Array'
Expand Down Expand Up @@ -70,18 +79,66 @@ describe('lexer', () => {
type: 'undefined',
text: 'undefined'
}
]
])
})

it('should parse numbers', () => {
expectTokens('12345', [
{
type: 'Number',
text: '12345'
}
])

const lexer = new Lexer()
lexer.lex(typeString)
expectTokens('-12345', [
{
type: 'Number',
text: '-12345'
}
])

while (lexer.token().type !== 'EOF') {
const nextToken = lexer.token()
const nextExpected = expected.shift()
expect(nextToken).to.deep.equal(nextExpected)
lexer.advance()
}
expectTokens('Infinity', [
{
type: 'Number',
text: 'Infinity'
}
])
})

expect(expected.length).to.equal(0)
it('should parse an expression containing multiple numbers', () => {
expectTokens('123|-Infinity|Array<NaN>', [
{
type: 'Number',
text: '123'
},
{
type: '|',
text: '|'
},
{
type: 'Number',
text: '-Infinity'
},
{
type: '|',
text: '|'
},
{
type: 'Identifier',
text: 'Array'
},
{
type: '<',
text: '<'
},
{
type: 'Number',
text: 'NaN'
},
{
type: '>',
text: '>'
}
])
})
})

0 comments on commit 923050f

Please sign in to comment.