Konstantin Nazarov

Reporting errors from the compilation phase

Latest changes to Valeri have introduced significant improvements to error reporting, not only within the parser, but also within the compiler. Where previously the compiler will error out with a cryptic "compilation error", it now explains what went wrong and where.

As an example, let's input an incorrect expression in the REPL:

valeri> (let (("x" 1)) x)
<stdin>:1:8 Syntax error: Binding name must be a symbol

As you can see, it shows you that the error happened in <stdin> at a specific location, and that it is because you specified a variable binding that is not a symbol.

The same happens when you write the expression to the file, and call the file. But additionally it will show you the filename:

./valeri error_report.vli
error_report.vli:1:8 Syntax error: Binding name must be a symbol

There aren't that many syntax errors that you can make in a real program, because only special forms get this type of treatment (such as function definitions, conditions, comparison, etc). But it's already quite a bit better than what you may find in other Lisp flavors. For example, if you do this in Guile:

scheme@(guile-user)> (let (("x" 1)) x)
While compiling expression:
Syntax error:
unknown file:1:0: let: bad let in form (let (("x" 1)) x)

Alright, it is a "bad let", but why? I guess the poor error reporting in this case is due to the fact that in Scheme a lot of basic operations like "let" are actually "lowered" to more primitive things such as lambdas. And this lowering is performed by macros, and not by special-purpose handlers in the compiler.

I'm sure the error reporing will become 10x harder when I make it to implementing macros. But as it stands right now, I'm happy with the current implementation for the purpose of writing simple programs.