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 lib/libpicrin.a: FORCE
$(MAKE) -C lib libpicrin.a $(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 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 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 picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) ext lib/libpicrin.a
$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libpicrin.a $(LDFLAGS) $(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libpicrin.a $(LDFLAGS)

View File

@ -5,7 +5,6 @@ LIBPICRIN_SRCS = \
char.c\ char.c\
data.c\ data.c\
dict.c\ dict.c\
error.c\
gc.c\ gc.c\
number.c\ number.c\
pair.c\ pair.c\
@ -22,7 +21,8 @@ LIBPICRIN_SRCS = \
ext/eval.c\ ext/eval.c\
ext/read.c\ ext/read.c\
ext/write.c\ ext/write.c\
ext/file.c ext/file.c\
ext/error.c
LIBPICRIN_OBJS = \ LIBPICRIN_OBJS = \
$(LIBPICRIN_SRCS:.c=.o) $(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 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_value
pic_file_open_input_file(pic_state *pic) 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); pic_get_args(pic, "z", &fname);
if ((fp = fopen(fname, "r")) == NULL) { 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"); return pic_fopen(pic, fp, "r");
} }
@ -106,7 +117,7 @@ pic_file_open_output_file(pic_state *pic)
pic_get_args(pic, "z", &fname); pic_get_args(pic, "z", &fname);
if ((fp = fopen(fname, "w")) == NULL) { 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"); return pic_fopen(pic, fp, "w");
} }
@ -134,7 +145,7 @@ pic_file_delete(pic_state *pic)
pic_get_args(pic, "z", &fname); pic_get_args(pic, "z", &fname);
if (remove(fname) != 0) { 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); return pic_undef_value(pic);
} }

View File

@ -11,7 +11,7 @@ main(int argc, char *argv[])
pic_state *pic; pic_state *pic;
pic_value e, port; pic_value e, port;
pic = pic_open(pic_default_allocf, NULL); pic = pic_open(pic_default_allocf, NULL, pic_default_panicf);
pic_try { pic_try {
if (argc == 1) { /* repl */ 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_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); 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 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 static int
skip(pic_state *pic, pic_value port, int c) 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; unsigned u = 0;
if (! isdigit(c)) { 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'; 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 ((c = peek(pic, port)) == 'r') {
if (! expect(pic, port, "rue")) { 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)) { } 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); 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 ((c = peek(pic, port)) == 'a') {
if (! expect(pic, port, "alse")) { 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)) { } 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); 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))) { if (! isdelim(peek(pic, port))) {
switch (c) { 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 'a': c = '\a'; if (! expect(pic, port, "larm")) goto fail; break;
case 'b': c = '\b'; if (! expect(pic, port, "ackspace")) 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; 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); return pic_char_value(pic, (char)c);
fail: 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 static pic_value
@ -386,7 +399,7 @@ read_pipe(pic_state *pic, pic_value port, int c, struct reader_control *PIC_UNUS
i = 0; i = 0;
while ((HEX_BUF[i++] = (char)next(pic, port)) != ';') { while ((HEX_BUF[i++] = (char)next(pic, port)) != ';') {
if (i >= sizeof HEX_BUF) 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); c = (char)strtol(HEX_BUF, NULL, 16);
break; break;
@ -420,11 +433,11 @@ read_blob(pic_state *pic, pic_value port, int c, struct reader_control *p)
} }
if (nbits != 8) { 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 != '(') { 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; 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)) != ')') { while ((c = skip(pic, port, c)) != ')') {
n = read_uinteger(pic, port, c, p); n = read_uinteger(pic, port, c, p);
if (n < 0 || (1 << nbits) <= n) { 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; len += 1;
dat = pic_realloc(pic, dat, len); 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 ((c = peek(pic, port)) == 'n') {
if (! expect(pic, port, "ndefined")) { 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); return pic_undef_value(pic);
} }
if (! isdigit(c)) { 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); 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))) { if (pic_invalid_p(pic, read_nullable(pic, port, c, p))) {
goto closing; goto closing;
} }
read_error(pic, "unmatched parenthesis", pic_nil_value(pic)); read_error(pic, "unmatched parenthesis", 0);
} }
return cdr; 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); it = kh_get(read, h, i);
if (it == kh_end(h)) { 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); 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 == '#') { if (c == '#') {
return read_label_ref(pic, port, i, p); 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 static pic_value
read_unmatch(pic_state *pic, pic_value PIC_UNUSED(port), int PIC_UNUSED(c), struct reader_control *PIC_UNUSED(p)) 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 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); c = next(pic, port);
if (c == EOF) { if (c == EOF) {
read_error(pic, "unexpected EOF", pic_nil_value(pic)); read_error(pic, "unexpected EOF", 0);
} }
if (reader_dispatch[c] == NULL) { 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); 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); c = skip(pic, port, c);
if (c == EOF) { if (c == EOF) {
read_error(pic, "unexpected EOF", pic_nil_value(pic)); read_error(pic, "unexpected EOF", 0);
} }
if (reader_table[c] == NULL) { 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); return reader_table[c](pic, port, c, p);
@ -708,46 +721,48 @@ reader_table_init(void)
} }
static 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; struct reader_control *p = ptr;
kh_init(read, &p->labels);
kh_destroy(read, &p->labels);
pic_free(pic, ptr);
} }
static void static struct reader_control *
reader_destroy(pic_state *pic, struct reader_control *p) 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 static pic_value
read_value(pic_state *pic, pic_value port) read_value(pic_state *pic, pic_value port)
{ {
struct reader_control p; struct reader_control *p = make_reader_control(pic);
size_t ai = pic_enter(pic); size_t ai;
pic_value val; pic_value val;
int c; 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 { if (! pic_invalid_p(pic, val)) {
size_t ai = pic_enter(pic); break;
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);
} }
pic_leave(pic, ai);
} }
pic_catch(e) { if (c == EOF) {
reader_destroy(pic, &p); val = pic_eof_object(pic);
pic_raise(pic, e);
} }
pic_leave(pic, ai); 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, ">"); 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 * static const char *
typename(pic_state *pic, pic_value obj) typename(pic_state *pic, pic_value obj)
{ {
@ -356,8 +329,6 @@ typename(pic_state *pic, pic_value obj)
return "bytevector"; return "bytevector";
case PIC_TYPE_PORT: case PIC_TYPE_PORT:
return "port"; return "port";
case PIC_TYPE_ERROR:
return "error";
case PIC_TYPE_FRAME: case PIC_TYPE_FRAME:
return "frame"; return "frame";
case PIC_TYPE_IREP: 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: case PIC_TYPE_RECORD:
write_record(pic, obj, port, p); write_record(pic, obj, port, p);
break; break;
case PIC_TYPE_ERROR:
write_error(pic, obj, port, p);
break;
default: default:
pic_fprintf(pic, port, "#<%s %p>", typename(pic, obj), obj_ptr(pic, obj)); pic_fprintf(pic, port, "#<%s %p>", typename(pic, obj), obj_ptr(pic, obj));
break; break;

View File

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

View File

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

View File

@ -59,7 +59,8 @@ typedef struct {
*/ */
typedef void *(*pic_allocf)(void *userdata, void *ptr, size_t n); 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 *); 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 */ 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 * 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_funcall(pic_state *, const char *name, int n, ...);
pic_value pic_values(pic_state *, int n, ...); pic_value pic_values(pic_state *, int n, ...);
pic_value pic_vvalues(pic_state *, int n, va_list); 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 #if PIC_USE_LIBC
void *pic_default_allocf(void *, void *, size_t); void *pic_default_allocf(void *, void *, size_t);
void pic_default_panicf(pic_state *, const char *, int, pic_value *);
#endif #endif
#if PIC_USE_FILE #if PIC_USE_FILE
pic_value pic_fopen(pic_state *, FILE *, const char *mode); pic_value pic_fopen(pic_state *, FILE *, const char *mode);
#endif #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) #if defined(__cplusplus)
} }
#endif #endif

View File

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

View File

@ -31,7 +31,6 @@ enum {
PIC_TYPE_RECORD = 23, PIC_TYPE_RECORD = 23,
PIC_TYPE_ATTR = 24, PIC_TYPE_ATTR = 24,
PIC_TYPE_PORT = 25, PIC_TYPE_PORT = 25,
PIC_TYPE_ERROR = 26,
PIC_TYPE_IREP = 27, PIC_TYPE_IREP = 27,
PIC_TYPE_FRAME = 28, PIC_TYPE_FRAME = 28,
PIC_TYPE_PROC_FUNC = 29, 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_str_p, PIC_TYPE_STRING)
DEFPRED(pic_vec_p, PIC_TYPE_VECTOR) DEFPRED(pic_vec_p, PIC_TYPE_VECTOR)
DEFPRED(pic_blob_p, PIC_TYPE_BLOB) DEFPRED(pic_blob_p, PIC_TYPE_BLOB)
DEFPRED(pic_error_p, PIC_TYPE_ERROR)
DEFPRED(pic_dict_p, PIC_TYPE_DICT) DEFPRED(pic_dict_p, PIC_TYPE_DICT)
DEFPRED(pic_attr_p, PIC_TYPE_ATTR) DEFPRED(pic_attr_p, PIC_TYPE_ATTR)
DEFPRED(pic_rec_p, PIC_TYPE_RECORD) DEFPRED(pic_rec_p, PIC_TYPE_RECORD)

View File

@ -152,18 +152,10 @@ struct port {
} file; } file;
}; };
struct error {
OBJECT_HEADER
struct symbol *type;
struct string *msg;
pic_value irrs;
};
#define TYPENAME_int "integer" #define TYPENAME_int "integer"
#define TYPENAME_blob "bytevector" #define TYPENAME_blob "bytevector"
#define TYPENAME_char "character" #define TYPENAME_char "character"
#define TYPENAME_sym "symbol" #define TYPENAME_sym "symbol"
#define TYPENAME_error "error"
#define TYPENAME_proc "procedure" #define TYPENAME_proc "procedure"
#define TYPENAME_str "string" #define TYPENAME_str "string"
#define TYPENAME_vec "vector" #define TYPENAME_vec "vector"
@ -257,7 +249,6 @@ DEFPTR(attr, struct attr)
DEFPTR(data, struct data) DEFPTR(data, struct data)
DEFPTR(proc, struct proc) DEFPTR(proc, struct proc)
DEFPTR(port, struct port) DEFPTR(port, struct port)
DEFPTR(error, struct error)
DEFPTR(rec, struct record) DEFPTR(rec, struct record)
DEFPTR(irep, struct irep) DEFPTR(irep, struct irep)
#undef pic_data_p #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_type(pic_state *pic, pic_value record);
pic_value pic_record_datum(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_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 *); struct rope *pic_rope_incref(struct rope *);
void pic_rope_decref(pic_state *, 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; 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 static void
pic_init_state(pic_state *pic) pic_init_state(pic_state *pic)
{ {
pic_defun(pic, "features", pic_state_features); pic_defun(pic, "features", pic_state_features);
pic_defun(pic, "global-objects", pic_state_global_objects); pic_defun(pic, "global-objects", pic_state_global_objects);
pic_defun(pic, "error", pic_state_error);
pic_add_feature(pic, "picrin"); pic_add_feature(pic, "picrin");
@ -128,7 +142,6 @@ pic_init_core(pic_state *pic)
pic_init_vector(pic); DONE; pic_init_vector(pic); DONE;
pic_init_blob(pic); DONE; pic_init_blob(pic); DONE;
pic_init_char(pic); DONE; pic_init_char(pic); DONE;
pic_init_error(pic); DONE;
pic_init_str(pic); DONE; pic_init_str(pic); DONE;
pic_init_var(pic); DONE; pic_init_var(pic); DONE;
pic_init_dict(pic); DONE; pic_init_dict(pic); DONE;
@ -151,10 +164,13 @@ pic_init_core(pic_state *pic)
#if PIC_USE_EVAL #if PIC_USE_EVAL
pic_init_eval(pic); DONE; pic_init_eval(pic); DONE;
#endif #endif
#if PIC_USE_ERROR
pic_init_error(pic); DONE;
#endif
} }
pic_state * pic_state *
pic_open(pic_allocf allocf, void *userdata) pic_open(pic_allocf allocf, void *userdata, pic_panicf panicf)
{ {
pic_state *pic; pic_state *pic;
@ -170,6 +186,9 @@ pic_open(pic_allocf allocf, void *userdata)
/* user data */ /* user data */
pic->userdata = userdata; pic->userdata = userdata;
/* panic handler */
pic->panicf = panicf;
/* context */ /* context */
pic->default_cxt.ai = 0; pic->default_cxt.ai = 0;
pic->default_cxt.pc = NULL; pic->default_cxt.pc = NULL;
@ -280,6 +299,20 @@ pic_close(pic_state *pic)
allocf(pic->userdata, pic, 0); 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_value
pic_global_ref(pic_state *pic, pic_value sym) 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); pic_leave(pic, ai);
return pic_protect(pic, r); 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; pic_value e;
int status; int status;
pic = pic_open(pic_default_allocf, NULL); pic = pic_open(pic_default_allocf, NULL, pic_default_panicf);
picrin_argc = argc; picrin_argc = argc;
picrin_argv = argv; 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"))