klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 6f7bc4f5917cd9bee670371b25f7d271f075e1f3
parent 83e77d19e575de757dcb77ebc3a9c46dbfa99775
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Mon, 21 Nov 2011 02:10:43 -0300

Added error printing (with backtrace) to the new standalone interpreter.

Diffstat:
Msrc/klisp.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/src/klisp.c b/src/klisp.c @@ -22,6 +22,7 @@ #include "kenvironment.h" #include "kport.h" #include "kread.h" +#include "kwrite.h" #include "kerror.h" #include "kgcontinuations.h" /* for do_pass_value */ #include "kscript.h" @@ -82,12 +83,84 @@ static void k_message (const char *pname, const char *msg) fflush(stderr); } +/* TODO move this to a common place to use it from elsewhere */ +static void show_error(klisp_State *K, TValue obj) { + /* FOR NOW used only for irritant list */ + TValue port = kcdr(K->kd_error_port_key); + klisp_assert(ttisfport(port) && kfport_file(port) == stderr); + + /* TEMP: obj should be an error obj */ + if (ttiserror(obj)) { + Error *err_obj = tv2error(obj); + TValue who = err_obj->who; + char *who_str; + /* TEMP? */ + if (ttiscontinuation(who)) + who = tv2cont(who)->comb; + + if (ttisstring(who)) { + who_str = kstring_buf(who); +#if KTRACK_NAMES + } else if (khas_name(who)) { + TValue name = kget_name(K, who); + who_str = ksymbol_buf(name); +#endif + } else { + who_str = "?"; + } + char *msg = kstring_buf(err_obj->msg); + fprintf(stderr, "\n*ERROR*: \n"); + fprintf(stderr, "%s: %s", who_str, msg); + + krooted_tvs_push(K, obj); + + /* Msg + irritants */ + /* TODO move to a new function */ + if (!ttisnil(err_obj->irritants)) { + fprintf(stderr, ": "); + kwrite_display_to_port(K, port, err_obj->irritants, false); + } + kwrite_newline_to_port(K, port); + +#if KTRACK_NAMES +#if KTRACK_SI + /* Location */ + /* TODO move to a new function */ + /* MAYBE: remove */ + if (khas_name(who) || khas_si(who)) { + fprintf(stderr, "Location: "); + kwrite_display_to_port(K, port, who, false); + kwrite_newline_to_port(K, port); + } + + /* Backtrace */ + /* TODO move to a new function */ + TValue tv_cont = err_obj->cont; + fprintf(stderr, "Backtrace: \n"); + while(ttiscontinuation(tv_cont)) { + kwrite_display_to_port(K, port, tv_cont, false); + kwrite_newline_to_port(K, port); + Continuation *cont = tv2cont(tv_cont); + tv_cont = cont->parent; + } + /* add extra newline at the end */ + kwrite_newline_to_port(K, port); +#endif +#endif + krooted_tvs_pop(K); + } else { + fprintf(stderr, "\n*ERROR*: not an error object passed to " + "error continuation"); + } + fflush(stderr); +} + static int report (klisp_State *K, int status) { if (status != 0) { -/* TODO show error */ - const char *msg = "Error!\n"; + const char *msg = "Error!"; k_message(progname, msg); + show_error(K, K->next_value); } return status; }