Skip to content

Commit

Permalink
Parser: tests & fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Jun 8, 2023
1 parent ffb37fc commit b461e35
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 11 deletions.
9 changes: 7 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { tokenize } from './lexer/lexer'
import { readFileSync } from 'fs'
import { existsSync, readFileSync } from 'fs'
import { join, resolve } from 'path'
import { compactNode, parseModule, Parser } from './parser/parser'
import { prettySourceMessage, prettySyntaxError } from './error'
Expand All @@ -17,7 +17,12 @@ if (!path) {
console.log(usage)
process.exit()
}
const source = { str: readFileSync(resolve(path)).toString(), filename: path }
const sourcePath = resolve(path)
if (!existsSync(sourcePath)) {
console.error(`no such file \`${path}\``)
process.exit()
}
const source = { str: readFileSync(sourcePath).toString(), filename: path }

const tokens = tokenize(source.str)
const parser = new Parser(tokens)
Expand Down
71 changes: 71 additions & 0 deletions src/parser/parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,75 @@ describe('parser', () => {
}]
})
})

it('parse if-expr', () => {
const { tree, errors } = parse('if a { b } else { c }')
expect(errors.length).toEqual(0)
expect(tree).toEqual({
'module': [{
'statement': [{
'expr': [{
'sub-expr': [{
'operand': [{
'if-expr': [
{ 'if-keyword': 'if' },
{ 'expr': [{ 'sub-expr': [{ 'operand': [{ 'identifier': 'a' }] }] }] },
{
'block': [
{ 'o-brace': '{' },
{
'statement': [{
'expr': [{ 'sub-expr': [{ 'operand': [{ 'identifier': 'b' }] }] }]
}]
},
{ 'c-brace': '}' }
]
},
{ 'else-keyword': 'else' },
{
'block': [
{ 'o-brace': '{' },
{
'statement': [{
'expr': [{ 'sub-expr': [{ 'operand': [{ 'identifier': 'c' }] }] }]
}]
},
{ 'c-brace': '}' }
]
}
]
}]
}]
}]
}]
}]
})
})

it('parse var-def miss identifier', () => {
const { errors } = parse('let = 4')
expect(errors.length).toEqual(1)
expect(errors[0]).toEqual({
'expected': ['identifier'],
'got': {
'kind': 'equals',
'location': {
'end': 4,
'start': 4
},
'value': '='
}
})
})

it('parse if-expr mismatch paren', () => {
const { errors } = parse('if a { b) }')
expect(errors.length).toEqual(1)
expect(errors[0]).toEqual({
'expected': [],
'got': { 'kind': 'c-paren', 'location': { 'end': 8, 'start': 8 }, 'value': ')' },
'message': 'expected operand'
})
})

})
18 changes: 10 additions & 8 deletions src/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ const parseSubExpr = (parser: Parser): void => {
* operand ::= if-expr | lambda-expr | O-PAREN expr C-PAREN | STRING | CHAR | NUMBER | IDENTIFIER | type-expr
*/
const parseOperand = (parser: Parser): void => {
const dynamicTokens: TokenKind[] = ['string', 'char', 'number', 'identifier']

const mark = parser.open()
if (parser.at('if-keyword')) {
parseIfExpr(parser)
Expand All @@ -386,12 +388,12 @@ const parseOperand = (parser: Parser): void => {
parser.expect('c-paren')
} else if (parser.at('identifier') && parser.nth(1) === 'o-angle') {
parseTypeExpr(parser)
} else if (parser.atAny(dynamicTokens)) {
parser.expectAny(dynamicTokens)
} else {
const dynamicTokens: TokenKind[] = ['string', 'char', 'number', 'identifier']
if (parser.atAny(dynamicTokens)) {
parser.expectAny(dynamicTokens)
}
parser.advanceWithError('expected operand')
}

parser.close(mark, 'operand')
}

Expand Down Expand Up @@ -501,9 +503,9 @@ const parsePrefixOp = (parser: Parser): void => {
const parsePostfixOp = (parser: Parser): void => {
if (parser.at('o-paren')) {
parseCallOp(parser)
} else {
parser.advanceWithError('expected postfix operator')
}

parser.advanceWithError('expected postfix operator')
}

/**
Expand All @@ -512,9 +514,9 @@ const parsePostfixOp = (parser: Parser): void => {
const parseCallOp = (parser: Parser): void => {
if (parser.at('o-paren')) {
parseArgs(parser)
} else {
parser.advanceWithError('expected call operator')
}

parser.advanceWithError('expected call operator')
}

/**
Expand Down
1 change: 0 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"sourceMap": true,
"outDir": "./dist",
"lib": [
"dom",
"es5",
"scripthost",
"es2015.symbol.wellknown",
Expand Down

0 comments on commit b461e35

Please sign in to comment.