Make errors in REPL more human-readable
This commit is contained in:
parent
2bad87d0b0
commit
d280c34e66
5 changed files with 43 additions and 31 deletions
|
@ -898,3 +898,14 @@ Result<String> build_string(uint64_t value) {
|
||||||
auto val = Value(TRY(Int64::create((int64_t)value)));
|
auto val = Value(TRY(Int64::create((int64_t)value)));
|
||||||
return write_one(val);
|
return write_one(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<void> print_string(const String& s) {
|
||||||
|
auto ba = TRY(ByteArray::create(s));
|
||||||
|
auto size = TRY(ba.size());
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
|
std::cout << TRY(ba[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result<void>();
|
||||||
|
}
|
||||||
|
|
|
@ -1336,3 +1336,5 @@ Result<String> build_string(const T& value, Args&&... args) {
|
||||||
first = TRY(first.concat(rest));
|
first = TRY(first.concat(rest));
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<void> print_string(const String& s);
|
||||||
|
|
|
@ -622,29 +622,25 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
Context ctx = TRY(Context::create(context));
|
Context ctx = TRY(Context::create(context));
|
||||||
ctx.maxreg = 1; // Reserve the slot for function itself
|
ctx.maxreg = 1; // Reserve the slot for function itself
|
||||||
|
|
||||||
auto first = TRY(expr.rest());
|
auto rest = TRY(expr.rest());
|
||||||
|
|
||||||
if (!TRY(syntax_is_list(first))) {
|
|
||||||
return ERROR(CompilationError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value name = TRY(Nil::create());
|
Value name = TRY(Nil::create());
|
||||||
|
|
||||||
auto maybe_name = TRY(first.first());
|
auto maybe_name = TRY(expr.second());
|
||||||
auto maybe_name_unwrapped = TRY(syntax_unwrap(maybe_name));
|
auto maybe_name_unwrapped = TRY(syntax_unwrap(maybe_name));
|
||||||
|
|
||||||
if (maybe_name_unwrapped.is<Symbol>()) {
|
if (maybe_name_unwrapped.is<Symbol>()) {
|
||||||
name = TRY(maybe_name_unwrapped.copy());
|
name = TRY(maybe_name_unwrapped.copy());
|
||||||
ctx.fname = TRY(name.copy());
|
ctx.fname = TRY(name.copy());
|
||||||
|
|
||||||
first = TRY(first.rest());
|
rest = TRY(rest.rest());
|
||||||
|
|
||||||
if (!TRY(syntax_is_list(first))) {
|
if (!TRY(syntax_is_list(rest))) {
|
||||||
return ERROR(CompilationError);
|
return ERROR(CompilationError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto param = TRY(first.first());
|
auto param = TRY(rest.first());
|
||||||
|
|
||||||
uint64_t arity = 0;
|
uint64_t arity = 0;
|
||||||
while (!TRY(syntax_is_nil(param))) {
|
while (!TRY(syntax_is_nil(param))) {
|
||||||
|
@ -655,7 +651,7 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
auto param_name_unwrapped = TRY(syntax_unwrap(param_name));
|
auto param_name_unwrapped = TRY(syntax_unwrap(param_name));
|
||||||
|
|
||||||
if (!param_name_unwrapped.is<Symbol>()) {
|
if (!param_name_unwrapped.is<Symbol>()) {
|
||||||
return ERROR(CompilationError);
|
return syntax_error(param_name, "Parameter name must be a symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t reg = TRY(ctx.add_var(param_name_unwrapped));
|
int64_t reg = TRY(ctx.add_var(param_name_unwrapped));
|
||||||
|
@ -664,13 +660,13 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
arity++;
|
arity++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value second = TRY(first.rest());
|
Value body = TRY(rest.rest());
|
||||||
|
|
||||||
if (!TRY(syntax_is_list(second))) {
|
if (!TRY(syntax_is_list(body))) {
|
||||||
return ERROR(CompilationError);
|
return ERROR(CompilationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ex = TRY(compile_body(ctx, second));
|
auto ex = TRY(compile_body(ctx, body));
|
||||||
|
|
||||||
TRY(ex.add_opcode(Oc::Mov, {0, (int64_t)0}, {0, (int64_t)ex.reg}));
|
TRY(ex.add_opcode(Oc::Mov, {0, (int64_t)0}, {0, (int64_t)ex.reg}));
|
||||||
TRY(ex.add_opcode(Oc::Ret, {0, (int64_t)0}));
|
TRY(ex.add_opcode(Oc::Ret, {0, (int64_t)0}));
|
||||||
|
@ -821,9 +817,6 @@ Result<Expression> Compiler::compile_body(Context& context, const Value& expr) {
|
||||||
int64_t maxreg = context.maxreg;
|
int64_t maxreg = context.maxreg;
|
||||||
|
|
||||||
while (!cur.is<Nil>()) {
|
while (!cur.is<Nil>()) {
|
||||||
if (!TRY(syntax_is_list(cur))) {
|
|
||||||
return ERROR(CompilationError);
|
|
||||||
}
|
|
||||||
auto expr_val = TRY(cur.first());
|
auto expr_val = TRY(cur.first());
|
||||||
|
|
||||||
// debug_print(expr_val);
|
// debug_print(expr_val);
|
||||||
|
|
|
@ -17,17 +17,6 @@ Result<Value> stdlib_unknown(const Array& params) {
|
||||||
return ERROR(NotImplemented);
|
return ERROR(NotImplemented);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> print_string(const String& s) {
|
|
||||||
auto ba = TRY(ByteArray::create(s));
|
|
||||||
auto size = TRY(ba.size());
|
|
||||||
|
|
||||||
for (uint64_t i = 0; i < size; i++) {
|
|
||||||
std::cout << TRY(ba[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result<void>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<Value> stdlib_print(const Array& params) {
|
Result<Value> stdlib_print(const Array& params) {
|
||||||
auto size = TRY(params.size());
|
auto size = TRY(params.size());
|
||||||
for (uint64_t i = 0; i < size; i++) {
|
for (uint64_t i = 0; i < size; i++) {
|
||||||
|
|
|
@ -34,7 +34,9 @@ Result<void> print_error(const Result<Value>& res) {
|
||||||
if (errobj.is<Nil>()) {
|
if (errobj.is<Nil>()) {
|
||||||
debug_print(geterr());
|
debug_print(geterr());
|
||||||
} else {
|
} else {
|
||||||
debug_print(errobj);
|
auto message = TRY(errobj.to<Error>()->message());
|
||||||
|
print_string(*message.to<String>());
|
||||||
|
std::cout << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +56,13 @@ Result<void> run_repl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsed = maybe_parsed.release_value();
|
auto parsed = maybe_parsed.release_value();
|
||||||
auto compiled = TRY(compile(fname, parsed));
|
auto maybe_compiled = compile(fname, parsed);
|
||||||
|
if (maybe_compiled.has_error()) {
|
||||||
|
print_error(maybe_compiled);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto compiled = maybe_compiled.release_value();
|
||||||
|
|
||||||
Module& mod = *compiled.to<Module>();
|
Module& mod = *compiled.to<Module>();
|
||||||
auto vm = TRY(VM::create());
|
auto vm = TRY(VM::create());
|
||||||
auto maybe_res = vm.run(mod, globals);
|
auto maybe_res = vm.run(mod, globals);
|
||||||
|
@ -85,11 +93,20 @@ Result<void> run(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
src = TRY(read_stdin());
|
src = TRY(read_stdin());
|
||||||
auto fname = TRY(String::create("<stdin>"));
|
auto fname = TRY(String::create("<stdin>"));
|
||||||
TRY(run_string(fname, src));
|
auto res = run_string(fname, src);
|
||||||
|
if (res.has_error()) {
|
||||||
|
print_error(res);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
src = TRY(read_file(argv[1]));
|
src = TRY(read_file(argv[1]));
|
||||||
auto fname = TRY(String::create(argv[1]));
|
auto fname = TRY(String::create(argv[1]));
|
||||||
TRY(run_string(fname, src));
|
auto res = run_string(fname, src);
|
||||||
|
if (res.has_error()) {
|
||||||
|
print_error(res);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result<void>();
|
return Result<void>();
|
||||||
|
|
Loading…
Reference in a new issue