rewrite error handling module in scheme

This commit is contained in:
Yuichi Nishiwaki 2017-05-06 02:11:13 +09:00
parent 956ea81f63
commit 282c8cc2f4
20 changed files with 789 additions and 464 deletions

View File

@ -42,11 +42,14 @@ lib/mini-picrin: FORCE
lib/libpicrin.a: FORCE
$(MAKE) -C lib libpicrin.a
ext: lib/ext/eval.c
ext: lib/ext/eval.c lib/ext/error.c
lib/ext/eval.c: piclib/eval.scm
bin/picrin-bootstrap -c eval_rom piclib/eval.scm | bin/picrin-bootstrap tools/mkeval.scm > lib/ext/eval.c
lib/ext/error.c: piclib/error.scm
bin/picrin-bootstrap -c error_rom piclib/error.scm | bin/picrin-bootstrap tools/mkerror.scm > lib/ext/error.c
picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) ext lib/libpicrin.a
$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libpicrin.a $(LDFLAGS)

View File

@ -5,7 +5,6 @@ LIBPICRIN_SRCS = \
char.c\
data.c\
dict.c\
error.c\
gc.c\
number.c\
pair.c\
@ -22,7 +21,8 @@ LIBPICRIN_SRCS = \
ext/eval.c\
ext/read.c\
ext/write.c\
ext/file.c
ext/file.c\
ext/error.c
LIBPICRIN_OBJS = \
$(LIBPICRIN_SRCS:.c=.o)

View File

@ -1,311 +0,0 @@
/**
* See Copyright Notice in picrin.h
*/
#include "picrin.h"
#include "object.h"
#include "state.h"
void
pic_panic(pic_state *pic, const char *msg)
{
if (pic->panicf) {
pic->panicf(pic, msg);
}
#if PIC_USE_LIBC
abort();
#endif
PIC_UNREACHABLE();
}
void
pic_warnf(pic_state *pic, const char *fmt, ...)
{
va_list ap;
pic_value err;
va_start(ap, fmt);
err = pic_vstrf_value(pic, fmt, ap);
va_end(ap);
pic_fprintf(pic, pic_stderr(pic), "warn: %s\n", pic_str(pic, err, NULL));
}
#define pic_exc(pic) pic_ref(pic, "current-exception-handlers")
#if PIC_USE_CALLCC
PIC_JMPBUF *
pic_prepare_try(pic_state *pic)
{
struct context *cxt = pic_malloc(pic, sizeof(struct context));
cxt->pc = NULL;
cxt->fp = NULL;
cxt->sp = NULL;
cxt->irep = NULL;
cxt->conts = pic_nil_value(pic);
cxt->prev = pic->cxt;
pic->cxt = cxt;
return &cxt->jmp;
}
static pic_value
native_exception_handler(pic_state *pic)
{
pic_value err;
pic_get_args(pic, "o", &err);
pic_call(pic, pic_closure_ref(pic, 0), 1, err);
PIC_UNREACHABLE();
}
void
pic_enter_try(pic_state *pic)
{
pic_value cont, handler;
pic_value var, env;
pic->cxt->ai = pic->ai;
/* call/cc */
cont = pic_make_cont(pic, pic_invalid_value(pic));
handler = pic_lambda(pic, native_exception_handler, 1, cont);
/* with-exception-handler */
var = pic_exc(pic);
env = pic_make_attr(pic);
pic_attr_set(pic, env, var, pic_cons(pic, handler, pic_call(pic, var, 0)));
pic->dyn_env = pic_cons(pic, env, pic->dyn_env);
pic_leave(pic, pic->cxt->ai);
}
void
pic_exit_try(pic_state *pic)
{
struct context *cxt = pic->cxt;
pic_value c, it;
pic->dyn_env = pic_cdr(pic, pic->dyn_env);
pic_for_each (c, cxt->conts, it) {
proc_ptr(pic, c)->env->regs[0] = pic_false_value(pic);
}
pic->cxt = cxt->prev;
pic_free(pic, cxt);
/* don't rewind ai here */
}
pic_value
pic_abort_try(pic_state *pic)
{
struct context *cxt = pic->cxt;
pic_value c, it;
pic_value err = cxt->sp->regs[1];
pic_for_each (c, cxt->conts, it) {
proc_ptr(pic, c)->env->regs[0] = pic_false_value(pic);
}
pic->cxt = cxt->prev;
pic_free(pic, cxt);
pic_protect(pic, err);
return err;
}
#else
PIC_JMPBUF *pic_prepare_try(pic_state *PIC_UNUSED(pic)) { return NULL; }
void pic_enter_try(pic_state *PIC_UNUSED(pic)) { }
void pic_exit_try(pic_state *PIC_UNUSED(pic)) { }
pic_value pic_abort_try(pic_state *PIC_UNUSED(pic)) { PIC_UNREACHABLE(); }
#endif
pic_value
pic_make_error(pic_state *pic, const char *type, const char *msg, pic_value irrs)
{
struct error *e;
pic_value ty = pic_intern_cstr(pic, type);
e = (struct error *)pic_obj_alloc(pic, PIC_TYPE_ERROR);
e->type = sym_ptr(pic, ty);
e->msg = str_ptr(pic, pic_cstr_value(pic, msg));
e->irrs = irrs;
return obj_value(pic, e);
}
static pic_value
with_exception_handlers(pic_state *pic, pic_value handlers, pic_value thunk)
{
pic_value var, env, r;
var = pic_exc(pic);
env = pic_make_attr(pic);
pic_attr_set(pic, env, var, handlers);
pic->dyn_env = pic_cons(pic, env, pic->dyn_env);
r = pic_call(pic, thunk, 0);
pic->dyn_env = pic_cdr(pic, pic->dyn_env);
return r;
}
static pic_value
on_raise(pic_state *pic)
{
pic_value handler, err, val;
bool continuable;
pic_get_args(pic, "");
handler = pic_closure_ref(pic, 0);
err = pic_closure_ref(pic, 1);
continuable = pic_bool(pic, pic_closure_ref(pic, 2));
val = pic_call(pic, handler, 1, err);
if (! continuable) {
pic_error(pic, "handler returned", 2, handler, err);
}
return val;
}
pic_value
pic_raise_continuable(pic_state *pic, pic_value err)
{
pic_value handlers, var = pic_exc(pic), thunk;
handlers = pic_call(pic, var, 0);
if (pic_nil_p(pic, handlers)) {
pic_panic(pic, "no exception handler");
}
thunk = pic_lambda(pic, on_raise, 3, pic_car(pic, handlers), err, pic_true_value(pic));
return with_exception_handlers(pic, pic_cdr(pic, handlers), thunk);
}
void
pic_raise(pic_state *pic, pic_value err)
{
pic_value handlers, var = pic_exc(pic), thunk;
handlers = pic_call(pic, var, 0);
if (pic_nil_p(pic, handlers)) {
pic_panic(pic, "no exception handler");
}
thunk = pic_lambda(pic, on_raise, 3, pic_car(pic, handlers), err, pic_false_value(pic));
with_exception_handlers(pic, pic_cdr(pic, handlers), thunk);
PIC_UNREACHABLE();
}
void
pic_error(pic_state *pic, const char *msg, int n, ...)
{
va_list ap;
pic_value irrs;
va_start(ap, n);
irrs = pic_vlist(pic, n, ap);
va_end(ap);
pic_raise(pic, pic_make_error(pic, "", msg, irrs));
}
static pic_value
pic_error_with_exception_handler(pic_state *pic)
{
pic_value handler, thunk;
pic_value handlers, exc = pic_exc(pic);
pic_get_args(pic, "ll", &handler, &thunk);
handlers = pic_call(pic, exc, 0);
return with_exception_handlers(pic, pic_cons(pic, handler, handlers), thunk);
}
static pic_value
pic_error_raise(pic_state *pic)
{
pic_value v;
pic_get_args(pic, "o", &v);
pic_raise(pic, v);
}
static pic_value
pic_error_raise_continuable(pic_state *pic)
{
pic_value v;
pic_get_args(pic, "o", &v);
return pic_raise_continuable(pic, v);
}
static pic_value
pic_error_error(pic_state *pic)
{
const char *cstr;
int argc;
pic_value *argv;
pic_get_args(pic, "z*", &cstr, &argc, &argv);
pic_raise(pic, pic_make_error(pic, "", cstr, pic_make_list(pic, argc, argv)));
}
static pic_value
pic_error_error_object_p(pic_state *pic)
{
pic_value v;
pic_get_args(pic, "o", &v);
return pic_bool_value(pic, pic_error_p(pic, v));
}
static pic_value
pic_error_error_object_message(pic_state *pic)
{
pic_value e;
pic_get_args(pic, "o", &e);
TYPE_CHECK(pic, e, error);
return obj_value(pic, error_ptr(pic, e)->msg);
}
static pic_value
pic_error_error_object_irritants(pic_state *pic)
{
pic_value e;
pic_get_args(pic, "o", &e);
TYPE_CHECK(pic, e, error);
return error_ptr(pic, e)->irrs;
}
static pic_value
pic_error_error_object_type(pic_state *pic)
{
pic_value e;
pic_get_args(pic, "o", &e);
TYPE_CHECK(pic, e, error);
return obj_value(pic, error_ptr(pic, e)->type);
}
void
pic_init_error(pic_state *pic)
{
pic_defvar(pic, "current-exception-handlers", pic_nil_value(pic));
pic_defun(pic, "with-exception-handler", pic_error_with_exception_handler);
pic_defun(pic, "raise", pic_error_raise);
pic_defun(pic, "raise-continuable", pic_error_raise_continuable);
pic_defun(pic, "error", pic_error_error);
pic_defun(pic, "error-object?", pic_error_error_object_p);
pic_defun(pic, "error-object-message", pic_error_error_object_message);
pic_defun(pic, "error-object-irritants", pic_error_error_object_irritants);
pic_defun(pic, "error-object-type", pic_error_error_object_type);
}

409
lib/ext/error.c Normal file
View File

@ -0,0 +1,409 @@
/**
* See Copyright Notice in picrin.h
*/
#include "picrin.h"
#include "../object.h"
#include "../state.h"
#if PIC_USE_ERROR
# define pic_exc(pic) pic_ref(pic, "current-exception-handlers")
PIC_JMPBUF *
pic_prepare_try(pic_state *pic)
{
struct context *cxt = pic_malloc(pic, sizeof(struct context));
cxt->pc = NULL;
cxt->fp = NULL;
cxt->sp = NULL;
cxt->irep = NULL;
cxt->conts = pic_nil_value(pic);
cxt->prev = pic->cxt;
pic->cxt = cxt;
return &cxt->jmp;
}
static pic_value
native_exception_handler(pic_state *pic)
{
pic_value err;
pic_get_args(pic, "o", &err);
pic_call(pic, pic_closure_ref(pic, 0), 1, err);
PIC_UNREACHABLE();
}
void
pic_enter_try(pic_state *pic)
{
pic_value cont, handler;
pic_value var, env;
pic->cxt->ai = pic->ai;
/* call/cc */
cont = pic_make_cont(pic, pic_invalid_value(pic));
handler = pic_lambda(pic, native_exception_handler, 1, cont);
/* with-exception-handler */
var = pic_exc(pic);
env = pic_make_attr(pic);
pic_attr_set(pic, env, var, pic_cons(pic, handler, pic_call(pic, var, 0)));
pic->dyn_env = pic_cons(pic, env, pic->dyn_env);
pic_leave(pic, pic->cxt->ai);
}
void
pic_exit_try(pic_state *pic)
{
struct context *cxt = pic->cxt;
pic_value c, it;
pic->dyn_env = pic_cdr(pic, pic->dyn_env);
pic_for_each (c, cxt->conts, it) {
proc_ptr(pic, c)->env->regs[0] = pic_false_value(pic);
}
pic->cxt = cxt->prev;
pic_free(pic, cxt);
/* don't rewind ai here */
}
pic_value
pic_abort_try(pic_state *pic)
{
struct context *cxt = pic->cxt;
pic_value c, it;
pic_value err = cxt->sp->regs[1];
pic_for_each (c, cxt->conts, it) {
proc_ptr(pic, c)->env->regs[0] = pic_false_value(pic);
}
pic->cxt = cxt->prev;
pic_free(pic, cxt);
pic_protect(pic, err);
return err;
}
#endif
#if PIC_USE_ERROR
static const unsigned char error_rom[] = {
0x03, 0x01, 0x00, 0x04, 0x02, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x05,
0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x02, 0x00, 0x00,
0x02, 0x01, 0x01, 0x06, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x04, 0x01,
0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x6c, 0x69,
0x73, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00,
0x02, 0x01, 0x02, 0x01, 0x00, 0x04, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00,
0x02, 0x0e, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x6b, 0x65, 0x2d, 0x70, 0x61,
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x00, 0x06, 0x00, 0x00, 0x04,
0x01, 0x01, 0x01, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x00, 0x04,
0x0b, 0x0b, 0x48, 0x00, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x00, 0x63,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x78, 0x63, 0x65, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72,
0x73, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x72, 0x61, 0x69, 0x73, 0x65,
0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x72, 0x61, 0x69, 0x73, 0x65, 0x2d,
0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x00,
0x02, 0x16, 0x00, 0x00, 0x00, 0x77, 0x69, 0x74, 0x68, 0x2d, 0x65, 0x78,
0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x68, 0x61, 0x6e, 0x64,
0x6c, 0x65, 0x72, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x6b,
0x65, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f,
0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3f, 0x00, 0x02, 0x16,
0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x2d, 0x69, 0x72, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x74,
0x73, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72,
0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x74, 0x79,
0x70, 0x65, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f,
0x72, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x70, 0x6c,
0x61, 0x79, 0x00, 0x04, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x02, 0x00,
0x00, 0x07, 0x00, 0x01, 0x02, 0x00, 0x01, 0x07, 0x00, 0x02, 0x02, 0x00,
0x02, 0x07, 0x00, 0x03, 0x02, 0x00, 0x03, 0x07, 0x00, 0x04, 0x02, 0x00,
0x04, 0x07, 0x00, 0x05, 0x02, 0x00, 0x05, 0x07, 0x00, 0x06, 0x02, 0x00,
0x06, 0x07, 0x00, 0x07, 0x02, 0x00, 0x07, 0x07, 0x00, 0x08, 0x02, 0x00,
0x08, 0x07, 0x00, 0x09, 0x02, 0x00, 0x09, 0x02, 0x01, 0x0a, 0x06, 0x02,
0x0a, 0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00,
0x02, 0x1a, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x2d, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x68,
0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x06, 0x00, 0x00, 0x02,
0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x00, 0x01,
0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02,
0x0e, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x6b, 0x65, 0x2d, 0x61, 0x74, 0x74,
0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x01, 0x01, 0x01, 0x00, 0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00,
0x02, 0x1b, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x2d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76,
0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00,
0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x05, 0x01, 0x00, 0x11, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x01, 0x02, 0x01, 0x04, 0x02, 0x01,
0x01, 0x04, 0x03, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00, 0x05, 0x01, 0x01,
0x10, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e,
0x73, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x02,
0x04, 0x03, 0x00, 0x03, 0x01, 0x03, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c,
0x00, 0x00, 0x00, 0x02, 0x1b, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x2d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x2d,
0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x00,
0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02,
0x01, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00,
0x00, 0x00, 0x63, 0x64, 0x72, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00,
0x04, 0x02, 0x05, 0x02, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c,
0x00, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x2d, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x06,
0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01,
0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
0x00, 0x63, 0x61, 0x72, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04,
0x02, 0x07, 0x02, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x04, 0x02, 0x0a,
0x02, 0x01, 0x02, 0x01, 0x00, 0x05, 0x01, 0x02, 0x0f, 0x00, 0x00, 0x00,
0x02, 0x05, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x01,
0x10, 0x00, 0x00, 0x00, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x20,
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x00, 0x06, 0x00, 0x00,
0x02, 0x01, 0x00, 0x03, 0x02, 0x01, 0x04, 0x03, 0x0b, 0x02, 0x01, 0x03,
0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x04, 0x01, 0x07, 0x01, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00,
0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x1b, 0x00, 0x00, 0x00,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x64, 0x79, 0x6e, 0x61,
0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02,
0x08, 0x03, 0x01, 0x02, 0x01, 0x00, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x00,
0x00, 0x04, 0x00, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02,
0x00, 0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00,
0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x78, 0x63,
0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c,
0x65, 0x72, 0x73, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01,
0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00,
0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x00, 0x00, 0x00,
0x6d, 0x61, 0x6b, 0x65, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x65, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01,
0x00, 0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x1b, 0x00, 0x00,
0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x64, 0x79, 0x6e,
0x61, 0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e,
0x6d, 0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01,
0x01, 0x01, 0x00, 0x05, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00,
0x00, 0x04, 0x01, 0x02, 0x01, 0x04, 0x02, 0x01, 0x01, 0x04, 0x03, 0x00,
0x01, 0x01, 0x03, 0x03, 0x00, 0x05, 0x01, 0x01, 0x10, 0x00, 0x00, 0x00,
0x02, 0x04, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x73, 0x00, 0x06, 0x00,
0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x02, 0x04, 0x03, 0x00, 0x03,
0x01, 0x03, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02,
0x1b, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d,
0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76, 0x69,
0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02,
0x01, 0x00, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01,
0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x63, 0x64,
0x72, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x05, 0x02,
0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02,
0x1a, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d,
0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x68, 0x61,
0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x01,
0x0c, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x63, 0x61, 0x72,
0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x07, 0x02, 0x01,
0x02, 0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x01, 0x02, 0x01, 0x00, 0x04, 0x02, 0x0a, 0x02, 0x01, 0x02, 0x01,
0x00, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04,
0x01, 0x06, 0x01, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x04,
0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x1b, 0x00, 0x00, 0x00, 0x63,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x64, 0x79, 0x6e, 0x61, 0x6d,
0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65,
0x6e, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x07,
0x03, 0x01, 0x02, 0x01, 0x00, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x04, 0x00, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00,
0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x00,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x78, 0x63, 0x65,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65,
0x72, 0x73, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01,
0x00, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04,
0x01, 0x01, 0x01, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x03,
0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x00, 0x00, 0x00, 0x6d,
0x61, 0x6b, 0x65, 0x2d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
0x65, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
0x03, 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x02, 0x1b, 0x00, 0x00, 0x00,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x64, 0x79, 0x6e, 0x61,
0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01,
0x01, 0x00, 0x05, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x04, 0x01, 0x02, 0x01, 0x04, 0x02, 0x01, 0x01, 0x04, 0x03, 0x00, 0x01,
0x01, 0x03, 0x03, 0x00, 0x05, 0x01, 0x01, 0x10, 0x00, 0x00, 0x00, 0x02,
0x04, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x73, 0x00, 0x06, 0x00, 0x00,
0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x02, 0x04, 0x03, 0x00, 0x03, 0x01,
0x03, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x1b,
0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x64,
0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76, 0x69, 0x72,
0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x00, 0x05, 0x01, 0x01,
0x10, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e,
0x73, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x07, 0x02,
0x04, 0x03, 0x05, 0x02, 0x01, 0x03, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c,
0x00, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x2d, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x06,
0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01,
0x00, 0x03, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x09, 0x03,
0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x01, 0x05, 0x01, 0x04, 0x02, 0x00,
0x01, 0x01, 0x02, 0x02, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00,
0x02, 0x1b, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
0x2d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x2d, 0x65, 0x6e, 0x76,
0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x06, 0x00, 0x00,
0x02, 0x01, 0x00, 0x04, 0x02, 0x06, 0x03, 0x01, 0x02, 0x01, 0x00, 0x03,
0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x01, 0x04, 0x01,
0x01, 0x02, 0x01, 0x01, 0x04, 0x00, 0x06, 0x01, 0x01, 0x14, 0x00, 0x00,
0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72,
0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x02, 0x04,
0x03, 0x00, 0x03, 0x04, 0x04, 0x00, 0x04, 0x01, 0x04, 0x01, 0x00, 0x05,
0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0x6d,
0x61, 0x6b, 0x65, 0x2d, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x00, 0x02,
0x0c, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x00, 0x06, 0x00, 0x00, 0x04, 0x01, 0x01, 0x01,
0x03, 0x02, 0x01, 0x04, 0x03, 0x00, 0x01, 0x01, 0x03, 0x02, 0x00, 0x04,
0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x72,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x3f, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x04, 0x02, 0x00, 0x02, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x01,
0x1c, 0x00, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0x72, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x04, 0x00, 0x00,
0x01, 0x08, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04,
0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x00, 0x01, 0x01, 0x0a, 0x01, 0x01,
0x01, 0x01, 0x00, 0x05, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x02, 0x03,
0x00, 0x00, 0x00, 0x65, 0x71, 0x3f, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
0x00, 0x06, 0x00, 0x00, 0x04, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00, 0x01,
0x03, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00,
0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72,
0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3f, 0x00, 0x06, 0x00, 0x00,
0x02, 0x01, 0x00, 0x04, 0x02, 0x00, 0x02, 0x01, 0x02, 0x01, 0x00, 0x06,
0x01, 0x04, 0x27, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x72,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x2d, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x00,
0x02, 0x05, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x01,
0x14, 0x00, 0x00, 0x00, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 0x74,
0x79, 0x70, 0x65, 0x20, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68,
0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d,
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x04, 0x00, 0x00, 0x01, 0x08,
0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x01,
0x02, 0x01, 0x02, 0x06, 0x00, 0x01, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02,
0x02, 0x04, 0x03, 0x01, 0x02, 0x03, 0x04, 0x03, 0x01, 0x04, 0x01, 0x00,
0x05, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00,
0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2d, 0x72, 0x65, 0x66, 0x00, 0x06,
0x00, 0x00, 0x04, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00, 0x01, 0x0d, 0x03,
0x02, 0x01, 0x03, 0x02, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00,
0x02, 0x0d, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x3f, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x04, 0x02, 0x00, 0x02, 0x01, 0x02, 0x01, 0x00, 0x06, 0x01, 0x04,
0x27, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x72, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x2d, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x00, 0x02, 0x05,
0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x01, 0x14, 0x00,
0x00, 0x00, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x79, 0x70,
0x65, 0x20, 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x02,
0x0c, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x00, 0x04, 0x00, 0x00, 0x01, 0x08, 0x00, 0x10,
0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x01, 0x02, 0x01,
0x02, 0x06, 0x00, 0x01, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, 0x04,
0x03, 0x01, 0x02, 0x03, 0x04, 0x03, 0x01, 0x04, 0x01, 0x00, 0x05, 0x00,
0x01, 0x10, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x76, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x2d, 0x72, 0x65, 0x66, 0x00, 0x06, 0x00, 0x00,
0x04, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00, 0x01, 0x0d, 0x03, 0x01, 0x01,
0x03, 0x02, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x0d,
0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x3f, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04,
0x02, 0x00, 0x02, 0x01, 0x02, 0x01, 0x00, 0x06, 0x01, 0x04, 0x27, 0x00,
0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x72, 0x65, 0x63, 0x6f, 0x72,
0x64, 0x2d, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x00, 0x02, 0x05, 0x00, 0x00,
0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00,
0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20,
0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x02, 0x0c, 0x00,
0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x00, 0x04, 0x00, 0x00, 0x01, 0x08, 0x00, 0x10, 0x00, 0x06,
0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x01, 0x02, 0x01, 0x02, 0x06,
0x00, 0x01, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02, 0x02, 0x04, 0x03, 0x01,
0x02, 0x03, 0x04, 0x03, 0x01, 0x04, 0x01, 0x00, 0x05, 0x00, 0x01, 0x10,
0x00, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x76, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x2d, 0x72, 0x65, 0x66, 0x00, 0x06, 0x00, 0x00, 0x04, 0x01,
0x02, 0x01, 0x04, 0x02, 0x00, 0x01, 0x0d, 0x03, 0x00, 0x01, 0x03, 0x02,
0x01, 0x06, 0x01, 0x01, 0x12, 0x00, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00,
0x00, 0x6d, 0x61, 0x6b, 0x65, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d,
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x0a, 0x02, 0x04, 0x03, 0x00, 0x02, 0x04, 0x04, 0x00, 0x03, 0x01,
0x04, 0x01, 0x00, 0x04, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x05,
0x00, 0x00, 0x00, 0x72, 0x61, 0x69, 0x73, 0x65, 0x00, 0x06, 0x00, 0x00,
0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00,
0x03, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02,
0x01, 0x00, 0x01, 0x01, 0x02, 0x01, 0x03, 0x02, 0x00, 0x08, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x04,
0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x6e,
0x75, 0x6c, 0x6c, 0x3f, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04,
0x02, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x04, 0x00, 0x02, 0x1e, 0x00,
0x00, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x63, 0x75, 0x72, 0x72, 0x65,
0x6e, 0x74, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x70, 0x6f, 0x72,
0x74, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x63, 0x61, 0x72, 0x00, 0x04,
0x00, 0x00, 0x01, 0x08, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x00, 0x04, 0x01,
0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x01, 0x04, 0x01, 0x01, 0x01, 0x04,
0x02, 0x02, 0x03, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x00, 0x0d, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x01, 0x01, 0x01, 0x04, 0x02, 0x00,
0x01, 0x01, 0x02, 0x02, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00,
0x02, 0x0d, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x3f, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x04, 0x02, 0x02, 0x02, 0x01, 0x02, 0x01, 0x00, 0x06, 0x01, 0x01,
0x26, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x61, 0x70, 0x70,
0x6c, 0x79, 0x00, 0x04, 0x00, 0x00, 0x01, 0x08, 0x00, 0x0d, 0x00, 0x02,
0x00, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x04,
0x01, 0x01, 0x01, 0x04, 0x02, 0x04, 0x02, 0x04, 0x03, 0x03, 0x02, 0x04,
0x04, 0x01, 0x02, 0x01, 0x04, 0x01, 0x00, 0x03, 0x02, 0x00, 0x08, 0x00,
0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00,
0x04, 0x02, 0x05, 0x02, 0x01, 0x02, 0x01, 0x00, 0x04, 0x01, 0x01, 0x1c,
0x00, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f,
0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x74, 0x79, 0x70,
0x65, 0x00, 0x04, 0x00, 0x00, 0x01, 0x08, 0x00, 0x10, 0x00, 0x06, 0x00,
0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x06, 0x02, 0x01, 0x02, 0x04, 0x00,
0x01, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x00, 0x05, 0x01, 0x00, 0x11,
0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x02, 0x02, 0x01, 0x00, 0x04, 0x02,
0x00, 0x01, 0x04, 0x03, 0x05, 0x02, 0x01, 0x03, 0x01, 0x00, 0x05, 0x00,
0x01, 0x11, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x00,
0x04, 0x00, 0x09, 0x02, 0x04, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x04,
0x03, 0x06, 0x02, 0x01, 0x03, 0x01, 0x00, 0x05, 0x01, 0x01, 0x10, 0x00,
0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72,
0x3a, 0x20, 0x22, 0x00, 0x04, 0x00, 0x06, 0x02, 0x02, 0x01, 0x00, 0x03,
0x02, 0x00, 0x04, 0x03, 0x03, 0x02, 0x01, 0x03, 0x01, 0x00, 0x04, 0x01,
0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01,
0x00, 0x04, 0x02, 0x06, 0x02, 0x01, 0x02, 0x01, 0x00, 0x05, 0x01, 0x00,
0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x02, 0x02, 0x01, 0x00, 0x04,
0x02, 0x00, 0x01, 0x04, 0x03, 0x05, 0x02, 0x01, 0x03, 0x01, 0x00, 0x04,
0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x22,
0x00, 0x04, 0x00, 0x09, 0x02, 0x02, 0x01, 0x00, 0x03, 0x02, 0x00, 0x01,
0x02, 0x01, 0x00, 0x04, 0x01, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x16,
0x00, 0x00, 0x00, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x6f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x2d, 0x69, 0x72, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x74,
0x73, 0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x02, 0x09, 0x02,
0x01, 0x02, 0x01, 0x00, 0x05, 0x02, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x02,
0x08, 0x00, 0x00, 0x00, 0x66, 0x6f, 0x72, 0x2d, 0x65, 0x61, 0x63, 0x68,
0x00, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x01, 0x04, 0x03,
0x00, 0x01, 0x01, 0x03, 0x01, 0x00, 0x05, 0x00, 0x01, 0x11, 0x00, 0x00,
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0c, 0x02,
0x04, 0x01, 0x07, 0x01, 0x03, 0x02, 0x00, 0x04, 0x03, 0x09, 0x02, 0x01,
0x03, 0x02, 0x00, 0x05, 0x01, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x01,
0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x02, 0x02, 0x01, 0x00,
0x03, 0x02, 0x00, 0x04, 0x03, 0x09, 0x02, 0x01, 0x03, 0x01, 0x00, 0x05,
0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x77,
0x72, 0x69, 0x74, 0x65, 0x00, 0x06, 0x00, 0x00, 0x04, 0x01, 0x01, 0x01,
0x04, 0x02, 0x01, 0x02, 0x04, 0x03, 0x0a, 0x02, 0x01, 0x03, 0x01, 0x00,
0x03, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00,
0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x04, 0x00, 0x00, 0x01,
0x07, 0x00, 0x00, 0x04, 0x00, 0x02, 0x01, 0x0c, 0x01, 0x01, 0x01,
};
#endif
void
pic_init_error(pic_state *PIC_UNUSED(pic))
{
#if PIC_USE_ERROR
pic_call(pic, pic_deserialize(pic, pic_blob_value(pic, error_rom, sizeof error_rom)), 0);
#endif
}

View File

@ -75,13 +75,24 @@ pic_fopen(pic_state *pic, FILE *fp, const char *mode) {
}
}
#if !PIC_USE_ERROR
# define file_error pic_error
#else
PIC_NORETURN static void
file_error(pic_state *pic, const char *msg, const char *fname)
file_error(pic_state *pic, const char *msg, int n, ...)
{
pic_value fn = pic_cstr_value(pic, fname);
va_list ap;
pic_value e, irrs;
pic_raise(pic, pic_make_error(pic, "file", msg, pic_list(pic, 1, fn)));
va_start(ap, n);
irrs = pic_vlist(pic, n, ap);
va_end(ap);
e = pic_funcall(pic, "make-error-object", 3, pic_intern_lit(pic, "file"), pic_cstr_value(pic, msg), irrs);
pic_funcall(pic, "raise", 1, e);
PIC_UNREACHABLE();
}
#endif
pic_value
pic_file_open_input_file(pic_state *pic)
@ -92,7 +103,7 @@ pic_file_open_input_file(pic_state *pic)
pic_get_args(pic, "z", &fname);
if ((fp = fopen(fname, "r")) == NULL) {
file_error(pic, "could not open file", fname);
file_error(pic, "could not open file", 1, pic_cstr_value(pic, fname));
}
return pic_fopen(pic, fp, "r");
}
@ -106,7 +117,7 @@ pic_file_open_output_file(pic_state *pic)
pic_get_args(pic, "z", &fname);
if ((fp = fopen(fname, "w")) == NULL) {
file_error(pic, "could not open file", fname);
file_error(pic, "could not open file", 1, pic_cstr_value(pic, fname));
}
return pic_fopen(pic, fp, "w");
}
@ -134,7 +145,7 @@ pic_file_delete(pic_state *pic)
pic_get_args(pic, "z", &fname);
if (remove(fname) != 0) {
file_error(pic, "file cannot be deleted", fname);
file_error(pic, "file cannot be deleted", 1, pic_cstr_value(pic, fname));
}
return pic_undef_value(pic);
}

View File

@ -11,7 +11,7 @@ main(int argc, char *argv[])
pic_state *pic;
pic_value e, port;
pic = pic_open(pic_default_allocf, NULL);
pic = pic_open(pic_default_allocf, NULL, pic_default_panicf);
pic_try {
if (argc == 1) { /* repl */

View File

@ -30,11 +30,24 @@ static pic_reader_t reader_dispatch[256];
static pic_value read_core(pic_state *pic, pic_value port, int c, struct reader_control *p);
static pic_value read_nullable(pic_state *pic, pic_value port, int c, struct reader_control *p);
#if !PIC_USE_ERROR
# define read_error pic_error
#else
PIC_NORETURN static void
read_error(pic_state *pic, const char *msg, pic_value irritants)
read_error(pic_state *pic, const char *msg, int n, ...)
{
pic_raise(pic, pic_make_error(pic, "read", msg, irritants));
va_list ap;
pic_value e, irrs;
va_start(ap, n);
irrs = pic_vlist(pic, n, ap);
va_end(ap);
e = pic_funcall(pic, "make-error-object", 3, pic_intern_lit(pic, "read"), pic_cstr_value(pic, msg), irrs);
pic_funcall(pic, "raise", 1, e);
PIC_UNREACHABLE();
}
#endif
static int
skip(pic_state *pic, pic_value port, int c)
@ -252,7 +265,7 @@ read_uinteger(pic_state *pic, pic_value port, int c, struct reader_control *PIC_
unsigned u = 0;
if (! isdigit(c)) {
read_error(pic, "expected one or more digits", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "expected one or more digits", 1, pic_char_value(pic, c));
}
u = c - '0';
@ -268,10 +281,10 @@ read_true(pic_state *pic, pic_value port, int c, struct reader_control *PIC_UNUS
{
if ((c = peek(pic, port)) == 'r') {
if (! expect(pic, port, "rue")) {
read_error(pic, "unexpected character while reading #true", pic_nil_value(pic));
read_error(pic, "unexpected character while reading #true", 0);
}
} else if (! isdelim(c)) {
read_error(pic, "non-delimiter character given after #t", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "non-delimiter character given after #t", 1, pic_char_value(pic, c));
}
return pic_true_value(pic);
@ -282,10 +295,10 @@ read_false(pic_state *pic, pic_value port, int c, struct reader_control *PIC_UNU
{
if ((c = peek(pic, port)) == 'a') {
if (! expect(pic, port, "alse")) {
read_error(pic, "unexpected character while reading #false", pic_nil_value(pic));
read_error(pic, "unexpected character while reading #false", 0);
}
} else if (! isdelim(c)) {
read_error(pic, "non-delimiter character given after #f", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "non-delimiter character given after #f", 1, pic_char_value(pic, c));
}
return pic_false_value(pic);
@ -298,7 +311,7 @@ read_char(pic_state *pic, pic_value port, int c, struct reader_control *PIC_UNUS
if (! isdelim(peek(pic, port))) {
switch (c) {
default: read_error(pic, "unexpected character after char literal", pic_list(pic, 1, pic_char_value(pic, c)));
default: read_error(pic, "unexpected character after char literal", 1, pic_char_value(pic, c));
case 'a': c = '\a'; if (! expect(pic, port, "larm")) goto fail; break;
case 'b': c = '\b'; if (! expect(pic, port, "ackspace")) goto fail; break;
case 'd': c = 0x7F; if (! expect(pic, port, "elete")) goto fail; break;
@ -323,7 +336,7 @@ read_char(pic_state *pic, pic_value port, int c, struct reader_control *PIC_UNUS
return pic_char_value(pic, (char)c);
fail:
read_error(pic, "unexpected character while reading character literal", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "unexpected character while reading character literal", 1, pic_char_value(pic, c));
}
static pic_value
@ -386,7 +399,7 @@ read_pipe(pic_state *pic, pic_value port, int c, struct reader_control *PIC_UNUS
i = 0;
while ((HEX_BUF[i++] = (char)next(pic, port)) != ';') {
if (i >= sizeof HEX_BUF)
read_error(pic, "expected ';'", pic_list(pic, 1, pic_char_value(pic, HEX_BUF[sizeof(HEX_BUF) - 1])));
read_error(pic, "expected ';'", 1, pic_char_value(pic, HEX_BUF[sizeof(HEX_BUF) - 1]));
}
c = (char)strtol(HEX_BUF, NULL, 16);
break;
@ -420,11 +433,11 @@ read_blob(pic_state *pic, pic_value port, int c, struct reader_control *p)
}
if (nbits != 8) {
read_error(pic, "unsupported bytevector bit width", pic_list(pic, 1, pic_int_value(pic, nbits)));
read_error(pic, "unsupported bytevector bit width", 1, pic_int_value(pic, nbits));
}
if (c != '(') {
read_error(pic, "expected '(' character", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "expected '(' character", 1, pic_char_value(pic, c));
}
len = 0;
@ -433,7 +446,7 @@ read_blob(pic_state *pic, pic_value port, int c, struct reader_control *p)
while ((c = skip(pic, port, c)) != ')') {
n = read_uinteger(pic, port, c, p);
if (n < 0 || (1 << nbits) <= n) {
read_error(pic, "invalid element in bytevector literal", pic_list(pic, 1, pic_int_value(pic, n)));
read_error(pic, "invalid element in bytevector literal", 1, pic_int_value(pic, n));
}
len += 1;
dat = pic_realloc(pic, dat, len);
@ -452,12 +465,12 @@ read_undef_or_blob(pic_state *pic, pic_value port, int c, struct reader_control
{
if ((c = peek(pic, port)) == 'n') {
if (! expect(pic, port, "ndefined")) {
read_error(pic, "unexpected character while reading #undefined", pic_nil_value(pic));
read_error(pic, "unexpected character while reading #undefined", 0);
}
return pic_undef_value(pic);
}
if (! isdigit(c)) {
read_error(pic, "expect #undefined or #u8(...), but illegal character given", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "expect #undefined or #u8(...), but illegal character given", 1, pic_char_value(pic, c));
}
return read_blob(pic, port, 'u', p);
}
@ -483,7 +496,7 @@ read_pair(pic_state *pic, pic_value port, int c, struct reader_control *p)
if (pic_invalid_p(pic, read_nullable(pic, port, c, p))) {
goto closing;
}
read_error(pic, "unmatched parenthesis", pic_nil_value(pic));
read_error(pic, "unmatched parenthesis", 0);
}
return cdr;
}
@ -579,7 +592,7 @@ read_label_ref(pic_state *pic, pic_value PIC_UNUSED(port), int i, struct reader_
it = kh_get(read, h, i);
if (it == kh_end(h)) {
read_error(pic, "label of given index not defined", pic_list(pic, 1, pic_int_value(pic, i)));
read_error(pic, "label of given index not defined", 1, pic_int_value(pic, i));
}
return kh_val(h, it);
}
@ -600,13 +613,13 @@ read_label(pic_state *pic, pic_value port, int c, struct reader_control *p)
if (c == '#') {
return read_label_ref(pic, port, i, p);
}
read_error(pic, "broken label expression", pic_nil_value(pic));
read_error(pic, "broken label expression", 0);
}
static pic_value
read_unmatch(pic_state *pic, pic_value PIC_UNUSED(port), int PIC_UNUSED(c), struct reader_control *PIC_UNUSED(p))
{
read_error(pic, "unmatched parenthesis", pic_nil_value(pic));
read_error(pic, "unmatched parenthesis", 0);
}
static pic_value
@ -615,11 +628,11 @@ read_dispatch(pic_state *pic, pic_value port, int c, struct reader_control *p)
c = next(pic, port);
if (c == EOF) {
read_error(pic, "unexpected EOF", pic_nil_value(pic));
read_error(pic, "unexpected EOF", 0);
}
if (reader_dispatch[c] == NULL) {
read_error(pic, "invalid character at the seeker head", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "invalid character at the seeker head", 1, pic_char_value(pic, c));
}
return reader_dispatch[c](pic, port, c, p);
@ -631,11 +644,11 @@ read_nullable(pic_state *pic, pic_value port, int c, struct reader_control *p)
c = skip(pic, port, c);
if (c == EOF) {
read_error(pic, "unexpected EOF", pic_nil_value(pic));
read_error(pic, "unexpected EOF", 0);
}
if (reader_table[c] == NULL) {
read_error(pic, "invalid character at the seeker head", pic_list(pic, 1, pic_char_value(pic, c)));
read_error(pic, "invalid character at the seeker head", 1, pic_char_value(pic, c));
}
return reader_table[c](pic, port, c, p);
@ -708,46 +721,48 @@ reader_table_init(void)
}
static void
reader_init(pic_state *PIC_UNUSED(pic), struct reader_control *p)
destroy_reader_control(pic_state *pic, void *ptr)
{
p->typecase = CASE_DEFAULT;
kh_init(read, &p->labels);
struct reader_control *p = ptr;
kh_destroy(read, &p->labels);
pic_free(pic, ptr);
}
static void
reader_destroy(pic_state *pic, struct reader_control *p)
static struct reader_control *
make_reader_control(pic_state *pic)
{
kh_destroy(read, &p->labels);
struct reader_control *p;
static const pic_data_type t = { "pic_reader_control", destroy_reader_control };
p = pic_malloc(pic, sizeof *p);
p->typecase = CASE_DEFAULT;
kh_init(read, &p->labels);
pic_data_value(pic, p, &t);
return p;
}
static pic_value
read_value(pic_state *pic, pic_value port)
{
struct reader_control p;
size_t ai = pic_enter(pic);
struct reader_control *p = make_reader_control(pic);
size_t ai;
pic_value val;
int c;
pic_value e;
reader_init(pic, &p);
ai = pic_enter(pic);
while ((c = skip(pic, port, next(pic, port))) != EOF) {
val = read_nullable(pic, port, c, p);
pic_try {
size_t ai = pic_enter(pic);
while ((c = skip(pic, port, next(pic, port))) != EOF) {
val = read_nullable(pic, port, c, &p);
if (! pic_invalid_p(pic, val)) {
break;
}
pic_leave(pic, ai);
}
if (c == EOF) {
val = pic_eof_object(pic);
if (! pic_invalid_p(pic, val)) {
break;
}
pic_leave(pic, ai);
}
pic_catch(e) {
reader_destroy(pic, &p);
pic_raise(pic, e);
if (c == EOF) {
val = pic_eof_object(pic);
}
pic_leave(pic, ai);

View File

@ -296,33 +296,6 @@ write_record(pic_state *pic, pic_value obj, pic_value port, struct writer_contro
pic_fprintf(pic, port, ">");
}
static void
write_error(pic_state *pic, pic_value err, pic_value port, struct writer_control *p)
{
if (p->mode == WRITE_MODE) {
pic_fprintf(pic, port, "#<error %p>", obj_ptr(pic, err));
return;
}
if (! pic_error_p(pic, err)) {
pic_fprintf(pic, port, "raise: ~s", err);
} else {
struct error *e;
pic_value elem, it;
e = error_ptr(pic, err);
if (! pic_eq_p(pic, obj_value(pic, e->type), pic_intern_lit(pic, ""))) {
pic_fprintf(pic, port, "~s-", obj_value(pic, e->type));
}
pic_fprintf(pic, port, "error: \"~a\"", obj_value(pic, e->msg));
pic_for_each (elem, e->irrs, it) { /* print error irritants */
pic_fprintf(pic, port, " ~s", elem);
}
pic_fprintf(pic, port, "\n");
}
}
static const char *
typename(pic_state *pic, pic_value obj)
{
@ -356,8 +329,6 @@ typename(pic_state *pic, pic_value obj)
return "bytevector";
case PIC_TYPE_PORT:
return "port";
case PIC_TYPE_ERROR:
return "error";
case PIC_TYPE_FRAME:
return "frame";
case PIC_TYPE_IREP:
@ -441,9 +412,6 @@ write_core(pic_state *pic, pic_value obj, pic_value port, struct writer_control
case PIC_TYPE_RECORD:
write_record(pic, obj, port, p);
break;
case PIC_TYPE_ERROR:
write_error(pic, obj, port, p);
break;
default:
pic_fprintf(pic, port, "#<%s %p>", typename(pic, obj), obj_ptr(pic, obj));
break;

View File

@ -26,7 +26,6 @@ struct object {
struct proc proc;
struct frame frame;
struct port port;
struct error err;
struct irep irep;
} u;
};
@ -104,9 +103,11 @@ pic_malloc(pic_state *pic, size_t size)
{
void *ptr;
retry:
ptr = pic->allocf(pic->userdata, NULL, size);
if (ptr == NULL && size > 0) {
pic_panic(pic, "memory exhausted");
pic->panicf(pic, "out of memory", 0, NULL);
goto retry;
}
return ptr;
}
@ -114,9 +115,11 @@ pic_malloc(pic_state *pic, size_t size)
void *
pic_realloc(pic_state *pic, void *ptr, size_t size)
{
retry:
ptr = pic->allocf(pic->userdata, ptr, size);
if (ptr == NULL && size > 0) {
pic_panic(pic, "memory exhausted");
pic->panicf(pic, "out of memory", 0, NULL);
goto retry;
}
return ptr;
}
@ -127,9 +130,11 @@ pic_calloc(pic_state *pic, size_t count, size_t size)
void *ptr;
size *= count;
retry:
ptr = pic->allocf(pic->userdata, NULL, size);
if (ptr == NULL && size > 0) {
pic_panic(pic, "memory exhausted");
pic->panicf(pic, "out of memory", 0, NULL);
goto retry;
}
memset(ptr, 0, size);
return ptr;
@ -263,12 +268,6 @@ gc_mark_object(pic_state *pic, struct object *obj)
case PIC_TYPE_PORT: {
break;
}
case PIC_TYPE_ERROR: {
gc_mark_object(pic, (struct object *)obj->u.err.type);
gc_mark(pic, obj->u.err.irrs);
LOOP(obj->u.err.msg);
break;
}
case PIC_TYPE_STRING: {
break;
}
@ -434,7 +433,6 @@ gc_finalize_object(pic_state *pic, struct object *obj)
}
case PIC_TYPE_PAIR:
case PIC_TYPE_ERROR:
case PIC_TYPE_RECORD:
case PIC_TYPE_PROC_FUNC:
case PIC_TYPE_PROC_IREP:
@ -460,7 +458,6 @@ type2size(int type)
case PIC_TYPE_PORT: return sizeof(struct port);
case PIC_TYPE_PAIR: return sizeof(struct pair);
case PIC_TYPE_FRAME: return sizeof(struct frame);
case PIC_TYPE_ERROR: return sizeof(struct error);
case PIC_TYPE_RECORD: return sizeof(struct record);
case PIC_TYPE_PROC_FUNC: return sizeof(struct proc);
case PIC_TYPE_PROC_IREP: return sizeof(struct proc);
@ -669,9 +666,12 @@ pic_obj_alloc_unsafe(pic_state *pic, int type)
obj = obj_alloc(pic, type);
if (obj == NULL) {
pic_gc(pic);
retry:
obj = obj_alloc(pic, type);
if (obj == NULL)
pic_panic(pic, "GC memory exhausted");
if (obj == NULL) {
pic->panicf(pic, "out of memory", 0, NULL);
goto retry;
}
}
return obj;

View File

@ -18,6 +18,7 @@
/* #define PIC_USE_WRITE 1 */
/* #define PIC_USE_EVAL 1 */
/* #define PIC_USE_FILE 1 */
/* #define PIC_USE_ERROR 1 */
/**
* I/O configuration

View File

@ -59,7 +59,8 @@ typedef struct {
*/
typedef void *(*pic_allocf)(void *userdata, void *ptr, size_t n);
pic_state *pic_open(pic_allocf f, void *userdata);
typedef void (*pic_panicf)(pic_state *, const char *msg, int n, pic_value *args);
pic_state *pic_open(pic_allocf allocf, void *userdata, pic_panicf panicf);
void pic_close(pic_state *);
@ -291,39 +292,6 @@ pic_value pic_fmemopen(pic_state *, const char *buf, int len, const char *mode);
int pic_fgetbuf(pic_state *, pic_value port, const char **buf, int *len); /* deprecated */
/*
* error handling
*/
typedef void (*pic_panicf)(pic_state *, const char *msg);
pic_panicf pic_atpanic(pic_state *, pic_panicf f);
PIC_NORETURN void pic_panic(pic_state *, const char *msg);
pic_value pic_raise_continuable(pic_state *pic, pic_value err);
PIC_NORETURN void pic_raise(pic_state *, pic_value v);
PIC_NORETURN void pic_error(pic_state *, const char *msg, int n, ...);
#define pic_try pic_try_(PIC_GENSYM(jmp))
#define pic_try_(jmp) \
do { \
extern PIC_JMPBUF *pic_prepare_try(pic_state *); \
extern void pic_enter_try(pic_state *); \
extern void pic_exit_try(pic_state *); \
extern pic_value pic_abort_try(pic_state *); \
PIC_JMPBUF *jmp = pic_prepare_try(pic); \
if (PIC_SETJMP(*jmp) == 0) { \
pic_enter_try(pic);
#define pic_catch(e) pic_catch_(e, PIC_GENSYM(label))
#define pic_catch_(e, label) \
pic_exit_try(pic); \
} else { \
e = pic_abort_try(pic); \
goto label; \
} \
} while (0); \
if (0) \
label:
/*
* core language features
*/
@ -338,6 +306,8 @@ void pic_defvar(pic_state *, const char *name, pic_value v);
pic_value pic_funcall(pic_state *, const char *name, int n, ...);
pic_value pic_values(pic_state *, int n, ...);
pic_value pic_vvalues(pic_state *, int n, va_list);
PIC_NORETURN void pic_error(pic_state *, const char *msg, int n, ...);
PIC_NORETURN void pic_verror(pic_state *pic, const char *msg, int n, va_list ap);
/*

View File

@ -11,12 +11,36 @@ extern "C" {
#if PIC_USE_LIBC
void *pic_default_allocf(void *, void *, size_t);
void pic_default_panicf(pic_state *, const char *, int, pic_value *);
#endif
#if PIC_USE_FILE
pic_value pic_fopen(pic_state *, FILE *, const char *mode);
#endif
#if PIC_USE_ERROR
# define pic_try pic_try_(PIC_GENSYM(jmp))
# define pic_try_(jmp) \
do { \
extern PIC_JMPBUF *pic_prepare_try(pic_state *); \
extern void pic_enter_try(pic_state *); \
extern void pic_exit_try(pic_state *); \
extern pic_value pic_abort_try(pic_state *); \
PIC_JMPBUF *jmp = pic_prepare_try(pic); \
if (PIC_SETJMP(*jmp) == 0) { \
pic_enter_try(pic);
# define pic_catch(e) pic_catch_(e, PIC_GENSYM(label))
# define pic_catch_(e, label) \
pic_exit_try(pic); \
} else { \
e = pic_abort_try(pic); \
goto label; \
} \
} while (0); \
if (0) \
label:
#endif
#if defined(__cplusplus)
}
#endif

View File

@ -28,12 +28,19 @@
# define PIC_USE_FILE 1
#endif
#ifndef PIC_USE_ERROR
# define PIC_USE_ERROR 1
#endif
#if !PIC_USE_LIBC && PIC_USE_FILE
# error PIC_USE_FILE requires PIC_USE_LIBC
#endif
#if !PIC_USE_LIBC && PIC_USE_CALLCC
# error PIC_USE_CALLCC requires PIC_USE_LIBC
#endif
#if !PIC_USE_CALLCC && PIC_USE_ERROR
# error PIC_USE_ERROR requires PIC_USE_CALLCC
#endif
#if PIC_USE_CALLCC
# include <setjmp.h>

View File

@ -31,7 +31,6 @@ enum {
PIC_TYPE_RECORD = 23,
PIC_TYPE_ATTR = 24,
PIC_TYPE_PORT = 25,
PIC_TYPE_ERROR = 26,
PIC_TYPE_IREP = 27,
PIC_TYPE_FRAME = 28,
PIC_TYPE_PROC_FUNC = 29,
@ -222,7 +221,6 @@ DEFPRED(pic_false_p, PIC_TYPE_FALSE)
DEFPRED(pic_str_p, PIC_TYPE_STRING)
DEFPRED(pic_vec_p, PIC_TYPE_VECTOR)
DEFPRED(pic_blob_p, PIC_TYPE_BLOB)
DEFPRED(pic_error_p, PIC_TYPE_ERROR)
DEFPRED(pic_dict_p, PIC_TYPE_DICT)
DEFPRED(pic_attr_p, PIC_TYPE_ATTR)
DEFPRED(pic_rec_p, PIC_TYPE_RECORD)

View File

@ -152,18 +152,10 @@ struct port {
} file;
};
struct error {
OBJECT_HEADER
struct symbol *type;
struct string *msg;
pic_value irrs;
};
#define TYPENAME_int "integer"
#define TYPENAME_blob "bytevector"
#define TYPENAME_char "character"
#define TYPENAME_sym "symbol"
#define TYPENAME_error "error"
#define TYPENAME_proc "procedure"
#define TYPENAME_str "string"
#define TYPENAME_vec "vector"
@ -257,7 +249,6 @@ DEFPTR(attr, struct attr)
DEFPTR(data, struct data)
DEFPTR(proc, struct proc)
DEFPTR(port, struct port)
DEFPTR(error, struct error)
DEFPTR(rec, struct record)
DEFPTR(irep, struct irep)
#undef pic_data_p
@ -273,7 +264,6 @@ pic_value pic_make_record(pic_state *, pic_value type, pic_value datum);
pic_value pic_record_type(pic_state *pic, pic_value record);
pic_value pic_record_datum(pic_state *pic, pic_value record);
pic_value pic_make_cont(pic_state *pic, pic_value k);
pic_value pic_make_error(pic_state *, const char *type, const char *msg, pic_value irrs);
struct rope *pic_rope_incref(struct rope *);
void pic_rope_decref(pic_state *, struct rope *);

View File

@ -29,11 +29,25 @@ pic_state_global_objects(pic_state *pic)
return pic->globals;
}
static pic_value
pic_state_error(pic_state *pic)
{
const char *msg;
int argc;
pic_value *args;
pic_get_args(pic, "z*", &msg, &argc, &args);
pic->panicf(pic, msg, argc, args);
PIC_UNREACHABLE();
}
static void
pic_init_state(pic_state *pic)
{
pic_defun(pic, "features", pic_state_features);
pic_defun(pic, "global-objects", pic_state_global_objects);
pic_defun(pic, "error", pic_state_error);
pic_add_feature(pic, "picrin");
@ -128,7 +142,6 @@ pic_init_core(pic_state *pic)
pic_init_vector(pic); DONE;
pic_init_blob(pic); DONE;
pic_init_char(pic); DONE;
pic_init_error(pic); DONE;
pic_init_str(pic); DONE;
pic_init_var(pic); DONE;
pic_init_dict(pic); DONE;
@ -151,10 +164,13 @@ pic_init_core(pic_state *pic)
#if PIC_USE_EVAL
pic_init_eval(pic); DONE;
#endif
#if PIC_USE_ERROR
pic_init_error(pic); DONE;
#endif
}
pic_state *
pic_open(pic_allocf allocf, void *userdata)
pic_open(pic_allocf allocf, void *userdata, pic_panicf panicf)
{
pic_state *pic;
@ -170,6 +186,9 @@ pic_open(pic_allocf allocf, void *userdata)
/* user data */
pic->userdata = userdata;
/* panic handler */
pic->panicf = panicf;
/* context */
pic->default_cxt.ai = 0;
pic->default_cxt.pc = NULL;
@ -280,6 +299,20 @@ pic_close(pic_state *pic)
allocf(pic->userdata, pic, 0);
}
void
pic_warnf(pic_state *PIC_UNUSED(pic), const char *PIC_UNUSED(fmt), ...)
{
#if PIC_USE_FILE
va_list ap;
pic_value err;
va_start(ap, fmt);
err = pic_vstrf_value(pic, fmt, ap);
va_end(ap);
pic_fprintf(pic, pic_stderr(pic), "warn: %s\n", pic_str(pic, err, NULL));
#endif
}
pic_value
pic_global_ref(pic_state *pic, pic_value sym)
{
@ -353,3 +386,40 @@ pic_funcall(pic_state *pic, const char *name, int n, ...)
pic_leave(pic, ai);
return pic_protect(pic, r);
}
#if PIC_USE_LIBC
void
pic_default_panicf(pic_state *pic, const char *msg, int PIC_UNUSED(n), pic_value *PIC_UNUSED(args))
{
fprintf(stderr, "panic!: %s\n", msg);
abort();
}
#endif
void
pic_error(pic_state *pic, const char *msg, int n, ...)
{
va_list ap;
va_start(ap, n);
pic_verror(pic, msg, n, ap);
va_end(ap);
PIC_UNREACHABLE();
}
void
pic_verror(pic_state *pic, const char *msg, int n, va_list ap)
{
pic_value error = pic_ref(pic, "error");
int i;
pic_value *args;
args = pic_alloca(pic, sizeof(pic_value) * (n + 1));
args[0] = pic_cstr_value(pic, msg);
for (i = 0; i < n; ++i) {
args[i + 1] = va_arg(ap, pic_value);
}
pic_apply(pic, error, n + 1, args);
PIC_UNREACHABLE();
}

88
piclib/error.c Normal file
View File

@ -0,0 +1,88 @@
/**
* See Copyright Notice in picrin.h
*/
#include "picrin.h"
#include "../object.h"
#include "../state.h"
#if PIC_USE_ERROR
# define pic_exc(pic) pic_ref(pic, "current-exception-handlers")
PIC_JMPBUF *
pic_prepare_try(pic_state *pic)
{
struct context *cxt = pic_malloc(pic, sizeof(struct context));
cxt->pc = NULL;
cxt->fp = NULL;
cxt->sp = NULL;
cxt->irep = NULL;
cxt->conts = pic_nil_value(pic);
cxt->prev = pic->cxt;
pic->cxt = cxt;
return &cxt->jmp;
}
static pic_value
native_exception_handler(pic_state *pic)
{
pic_value err;
pic_get_args(pic, "o", &err);
pic_call(pic, pic_closure_ref(pic, 0), 1, err);
PIC_UNREACHABLE();
}
void
pic_enter_try(pic_state *pic)
{
pic_value cont, handler;
pic_value var, env;
pic->cxt->ai = pic->ai;
/* call/cc */
cont = pic_make_cont(pic, pic_invalid_value(pic));
handler = pic_lambda(pic, native_exception_handler, 1, cont);
/* with-exception-handler */
var = pic_exc(pic);
env = pic_make_attr(pic);
pic_attr_set(pic, env, var, pic_cons(pic, handler, pic_call(pic, var, 0)));
pic->dyn_env = pic_cons(pic, env, pic->dyn_env);
pic_leave(pic, pic->cxt->ai);
}
void
pic_exit_try(pic_state *pic)
{
struct context *cxt = pic->cxt;
pic_value c, it;
pic->dyn_env = pic_cdr(pic, pic->dyn_env);
pic_for_each (c, cxt->conts, it) {
proc_ptr(pic, c)->env->regs[0] = pic_false_value(pic);
}
pic->cxt = cxt->prev;
pic_free(pic, cxt);
/* don't rewind ai here */
}
pic_value
pic_abort_try(pic_state *pic)
{
struct context *cxt = pic->cxt;
pic_value c, it;
pic_value err = cxt->sp->regs[1];
pic_for_each (c, cxt->conts, it) {
proc_ptr(pic, c)->env->regs[0] = pic_false_value(pic);
}
pic->cxt = cxt->prev;
pic_free(pic, cxt);
pic_protect(pic, err);
return err;
}
#endif

52
piclib/error.scm Normal file
View File

@ -0,0 +1,52 @@
(begin
(define current-exception-handlers
(let ((e error))
(make-parameter (list e))))
(define (raise x)
(let ((handlers (current-exception-handlers)))
(parameterize ((current-exception-handlers (cdr handlers)))
((car handlers) x)
(error "handler returned" x))))
(define (raise-continuable x)
(let ((handlers (current-exception-handlers)))
(parameterize ((current-exception-handlers (cdr handlers)))
((car handlers) x))))
(define (with-exception-handler handler thunk)
(let ((handlers (current-exception-handlers)))
(parameterize ((current-exception-handlers (cons handler handlers)))
(thunk))))
(define-record-type error-object
(make-error-object type message irritants)
error-object?
(type error-object-type)
(message error-object-message)
(irritants error-object-irritants))
(set! error
(lambda (message . irritants)
(raise (make-error-object #f message irritants))))
(set! display
(let ((d display))
(lambda (x . port)
(let ((port (if (null? port) (current-error-port) (car port))))
(if (error-object? x)
(let ()
(when (error-object-type x)
(d (error-object-type x) port)
(d "-" port))
(d "error: \"" port)
(d (error-object-message x) port)
(d "\"")
(for-each
(lambda (x)
(d " " port)
(write x port))
(error-object-irritants x))
(d "\n" port))
(apply d x port)))))))

View File

@ -28,7 +28,7 @@ main(int argc, char *argv[], char **envp)
pic_value e;
int status;
pic = pic_open(pic_default_allocf, NULL);
pic = pic_open(pic_default_allocf, NULL, pic_default_panicf);
picrin_argc = argc;
picrin_argv = argv;

30
tools/mkerror.scm Normal file
View File

@ -0,0 +1,30 @@
(let ((port (open-input-file "piclib/error.c")))
(let loop ()
(let ((c (read-u8 port)))
(unless (eof-object? c)
(write-u8 c)
(loop)))))
(for-each
display
`("\n"
"#if PIC_USE_ERROR\n"
"static "))
(let loop ()
(let ((c (read-u8)))
(unless (eof-object? c)
(write-u8 c)
(loop))))
(for-each
display
`("#endif\n"
"\n"
"void\n"
"pic_init_error(pic_state *PIC_UNUSED(pic))\n"
"{\n"
"#if PIC_USE_ERROR\n"
" pic_call(pic, pic_deserialize(pic, pic_blob_value(pic, error_rom, sizeof error_rom)), 0);\n"
"#endif\n"
"}\n"))