Skip to content

Commit

Permalink
Merge pull request #9 from fink-lang/error-reporting
Browse files Browse the repository at this point in the history
feat(errors): include filename in errors
  • Loading branch information
kollhof authored Mar 4, 2020
2 parents fae8973 + 84f958a commit 9d04a37
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 37 deletions.
14 changes: 10 additions & 4 deletions src/errors.fnk
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
{highlight_code_loc} = import '@fink/snippet'


token_error = fn msg, token, {tokenizer: {code, filename}}:
{loc} = token
{start: {line, column}} = loc

token_error = fn msg, token, {tokenizer: {code}}:
snippet = highlight_code_loc(code, token.loc)
# TODO: remove first line of err.stack
new Error(`${msg}\n${snippet}`)
snippet = `
${filename}:${line}:${column}
${highlight_code_loc(code, loc)}

${msg}
`

# TODO: remove first line of err.stack
new SyntaxError(snippet)
8 changes: 4 additions & 4 deletions src/index.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ assert_token = fn token, expected, ctx:
match true:
token.value != expected:
throw token_error(
`Expected ${inspect(expected)} but found ${inspect(token.value)}:`,
`Expected ${inspect(expected)} but found ${inspect(token.value)}.`,
token, ctx
)

Expand All @@ -60,7 +60,7 @@ assert_curr = fn ctx, expected:
assert_not_end = fn ctx:
match true:
next_is_end(ctx):
throw token_error(`Unexpected end of code:`, ctx.curr_token, ctx)
throw token_error(`Unexpected end of code.`, ctx.curr_token, ctx)


advance = fn ctx:
Expand Down Expand Up @@ -143,7 +143,7 @@ expression = fn ctx, rbp:
[left, next_ctx]


init_parser = fn {code}:
init_parser = fn {code, filename}:
{
curr_token: null,
next_token: {
Expand All @@ -154,7 +154,7 @@ init_parser = fn {code}:
},
ignored_tokens: [],

tokenizer: init_tokenizer(code),
tokenizer: init_tokenizer(code, filename),
symbols: init_symbols()
}

Expand Down
65 changes: 39 additions & 26 deletions src/index.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ init_test_lang = fn ctx:


parse = fn code:
ctx = pipe {code}:
ctx = pipe {code, filename: 'test.fnk'}:
init_parser
init_test_lang
start_parser
Expand Down Expand Up @@ -121,9 +121,12 @@ describe:: 'curr token tests, values, and assertions', fn:

(fn: assert_curr(ctx, '123')) not_to_throw anything
(fn: assert_curr(ctx, 'foobar')) to_throw `
Expected 'foobar' but found '123':
test.fnk:1:9
1| foobar = 123
^`
^

Expected 'foobar' but found '123'.
`


describe:: 'next token tests and assertions', fn:
Expand Down Expand Up @@ -154,9 +157,12 @@ describe:: 'next token tests and assertions', fn:
(fn: assert_next(ctx, end_token)) not_to_throw anything

(fn: assert_next(ctx, '123')) to_throw `
Expected '123' but found Symbol(end):
test.fnk:1:12
1| foobar = 123
^`
^

Expected '123' but found Symbol(end).
`


describe:: 'advance to next token or throw', fn:
Expand All @@ -173,52 +179,59 @@ describe:: 'advance to next token or throw', fn:
[, ctx] = parse(`foobar = 123; shrub = ni`)

(fn: assert_advance(ctx, '==')) to_throw `
Expected '==' but found ';':
test.fnk:1:12
1| foobar = 123; shrub = ni
^`
^

Expected '==' but found ';'.
`


describe:: 'parse exceptions', fn:
it:: 'throws unexpected end of code', fn:
test_parse = fn: parse(`
foobar =
`)
test_parse = fn: parse(`foobar =`)

test_parse to_throw `
Unexpected end of code:
test.fnk:1:7
1| foobar =
^`
^

Unexpected end of code.
`


it:: 'throws unexpected infix', fn:
test_parse = fn: parse(`
= 123`)
test_parse = fn: parse(`= 123`)

test_parse to_throw `
Cannot use '123' as an infix operator:
test.fnk:1:2
1| = 123
^`
^

Cannot use '123' as an infix operator.
`


it:: 'throws non infix operator', fn:
test_parse = fn: parse(`
foo = spam ni
`)
test_parse = fn: parse(`foo = spam ni`)

test_parse to_throw `
Cannot use 'ni' as an infix operator:
test.fnk:1:11
1| foo = spam ni
^
2| `

Cannot use 'ni' as an infix operator.
`


it:: 'throws collecting text when not finding expected end', fn:
test_parse = fn: parse(`
'foo bar`
)
test_parse = fn: parse(`'foo bar`)

test_parse to_throw `
Unexpected end of code:
test.fnk:1:5
1| 'foo bar
^`
^

Unexpected end of code.
`

2 changes: 1 addition & 1 deletion src/symbols.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ led = fn ctx, left:
match !led_fn:
true:
throw token_error(
`Cannot use ${inspect(curr_token.value)} as an infix operator:`,
`Cannot use ${inspect(curr_token.value)} as an infix operator.`,
curr_token, ctx
)
else: led_fn(ctx, left)
Expand Down
3 changes: 2 additions & 1 deletion src/tokenizer.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ get_next_token = fn ctx:
[foo, next_ctx]


init_tokenizer = fn code:
init_tokenizer = fn code, filename:
{
code,
filename,
partials: {},
separators: {},
partial_token: {
Expand Down
2 changes: 1 addition & 1 deletion src/tokenizer.test.fnk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

describe:: 'tokenizer', fn:
tokenize = fn code:
ctx = pipe init_tokenizer(code):
ctx = pipe init_tokenizer(code, 'test.fnk'):
add_token(' ')
add_token('\n')
add_token('=')
Expand Down

0 comments on commit 9d04a37

Please sign in to comment.