#include "lisp.h" #include "read.h" #include #include static jmp_buf toplevel_error_jmp_buf; static void toplevel_error_handler(LispVal *name, LispVal *data, void *ignored) { fprintf(stderr, "Caught exception: "); Fprint_condition(name, data, Qerror_write_byte); fprintf(stderr, "\nBacktrace (toplevel comes last):\n"); LispVal *backtrace = Fbacktrace(); DOLIST(frame, backtrace) { LispVal *name = FIRST(frame); bool evaled = !NILP(THIRD(frame)); LispVal *args = FOURTH(frame); fprintf(stderr, " %c ", evaled ? '-' : '*'); Fprinc(name, Qerror_write_byte); if (NILP(args)) { fprintf(stderr, "()\n"); } else { Fprinc(args, Qerror_write_byte); fputc('\n', stderr); } } longjmp(toplevel_error_jmp_buf, 1); } int main(int argc, const char **argv) { FILE *in = fopen(argv[1], "r"); fseek(in, 0, SEEK_END); off_t src_len = ftello(in); char *src = malloc(src_len); rewind(in); fread(src, 1, src_len, in); fclose(in); lisp_init(); push_local_reference_frame(); StackFrame *toplevel = LISP_STACK_REF(); ReadStream s; read_stream_init(&s, src, src_len); LispVal *r; push_handler_bind_frame(LIST(Qt), toplevel_error_handler, NULL, NULL); volatile bool had_toplevel_error = false; if (setjmp(toplevel_error_jmp_buf) == 0) { while ((r = read(&s))) { Feval(r, Qnil); } } else { had_toplevel_error = true; } unwind_to(toplevel); lisp_shutdown(); free(src); return had_toplevel_error ? EXIT_FAILURE : EXIT_SUCCESS; }