Error diagnostics in parsing is still a good research topic. Most commercial compilers don't even produce readable one. FPC already does a good job, as it produces much more readable error messages than Turbo Pascal/Delphi (which only consists of line number info + extremely short error message). In C family world, only Java and Clang has managed to a better level, GCC is one step behind though already a lot better than MSVC.
If you ever learned about programming language parsing, you'll know that what the compiler sees at one point is not what we see (we always see as a whole). Yes, it can be improved, but you need to be a parser writer expert. There are times when multiple possibilities exist, so the compiler can't tell you
exactly what's wrong. In the OP case:
try
writeln(somevar[1]);
if somevar[1] = 'shut up' then
writeln('take my money');
else
writeln('its a trap');
finally
somevar.free;
end;
When the parser encounters semicolon in the if body after writeln, it considers the if statement has finished, as
the syntax says. Next, since the parser knows it's inside a
statement list after a try statement, after the semicolon it expects either another statement or an except keyword or a finally keyword. But instead of either of those 3, the compiler meets else keyword, which is why it emits the error message. Certainly the error message can be extended to write all 3 possibilities (feel free to do so for those who can and is willing), or even suggests to remove the semicolon since it meets else right after it finishes parsing an if statement (heuristic error message). Just to tell you there are cases when the possibilities are 6 or perhaps more, and this could make the error message superfluous and suggestions are too long to be written.
This is how the compiler sees and parses your code.