Add location-aware error reporting function to the compiler

This commit is contained in:
Konstantin Nazarov 2024-09-10 01:42:47 +01:00
parent b63b17ed5a
commit 3c30440d65
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
3 changed files with 39 additions and 10 deletions

View file

@ -170,7 +170,7 @@ Result<bool> is_comparison_op(Symbol& sym) {
return false;
}
Result<Value> Compiler::compile(Value& expr) {
Result<Value> Compiler::compile(const Value& expr) {
auto context = TRY(Context::create());
// If expression is empty - just return nil
@ -1020,7 +1020,25 @@ Result<Expression> Compiler::compile_symbol(Context& context,
return std::move(ex);
}
Result<Value> compile(Value& expr) {
Compiler c = Compiler();
Result<Expression> Compiler::syntax_error(const Value& expr, const char* msg) {
if (expr.is<Syntax>()) {
Syntax& stx = *expr.to<Syntax>();
auto srcloc = TRY(stx.srcloc());
SrcLoc& loc = *srcloc.to<SrcLoc>();
auto range = loc.sourcerange();
auto pos = range.start;
return ERROR_FMT(SyntaxError, _fname, ":", pos.line, ":", pos.column,
" Syntax error: ", msg);
}
return ERROR_FMT(SyntaxError, _fname, " Syntax error: ", msg);
}
Result<Compiler> Compiler::create(const String& fname) {
return Compiler(TRY(fname.copy()));
}
Result<Value> compile(const String& fname, const Value& expr) {
Compiler c = TRY(Compiler::create(fname));
return c.compile(expr);
}

View file

@ -27,8 +27,11 @@ struct Expression {
class Compiler {
public:
Compiler() {}
Compiler(String&& fname) : _fname(std::move(fname)) {}
Result<Value> compile(Value& expr);
static Result<Compiler> create(const String& fname);
Result<Value> compile(const Value& expr);
Result<Expression> compile_expr(Context& context, const Value& expr);
Result<Expression> compile_list(Context& context, const Value& expr);
Result<Expression> compile_primop(Context& context, Symbol& op,
@ -57,6 +60,11 @@ class Compiler {
const Value& expr);
Result<Expression> compile_body(Context& context, const Value& expr);
Result<Expression> compile_function_call(Context& context, const Value& expr);
Result<Expression> syntax_error(const Value& expr, const char* message);
private:
String _fname;
};
Result<Value> compile(Value& expr);
Result<Value> compile(const String& fname, const Value& expr);

View file

@ -13,12 +13,12 @@
StaticArena<64 * 1024 * 1024> arena;
Result<Value> run_string(const String& src) {
Result<Value> run_string(const String& fname, const String& src) {
auto parsed = TRY(read_multiple(src));
TRY(arena_gc());
auto compiled = TRY(compile(parsed));
auto compiled = TRY(compile(fname, parsed));
Module& mod = *compiled.to<Module>();
auto vm = TRY(VM::create());
@ -44,6 +44,7 @@ Result<void> print_error(const Result<Value>& res) {
Result<void> run_repl() {
Dict globals = TRY(Dict::create());
auto fname = TRY(String::create("<stdin>"));
while (true) {
auto src = TRY(read_line("valeri> "));
auto maybe_parsed = read_multiple(src);
@ -53,7 +54,7 @@ Result<void> run_repl() {
}
auto parsed = maybe_parsed.release_value();
auto compiled = TRY(compile(parsed));
auto compiled = TRY(compile(fname, parsed));
Module& mod = *compiled.to<Module>();
auto vm = TRY(VM::create());
auto maybe_res = vm.run(mod, globals);
@ -83,10 +84,12 @@ Result<void> run(int argc, const char* argv[]) {
return run_repl();
}
src = TRY(read_stdin());
TRY(run_string(src));
auto fname = TRY(String::create("<stdin>"));
TRY(run_string(fname, src));
} else {
src = TRY(read_file(argv[1]));
TRY(run_string(src));
auto fname = TRY(String::create(argv[1]));
TRY(run_string(fname, src));
}
return Result<void>();