simplify writer_control

This commit is contained in:
Yuichi Nishiwaki 2016-02-21 16:04:34 +09:00
parent 07e7785241
commit f1ef21be23
1 changed files with 47 additions and 61 deletions

View File

@ -12,8 +12,6 @@ KHASH_DEFINE2(l, void *, int, 1, kh_ptr_hash_func, kh_ptr_hash_equal)
KHASH_DEFINE2(v, void *, int, 0, kh_ptr_hash_func, kh_ptr_hash_equal) KHASH_DEFINE2(v, void *, int, 0, kh_ptr_hash_func, kh_ptr_hash_equal)
struct writer_control { struct writer_control {
pic_state *pic;
xFILE *file;
int mode; int mode;
int op; int op;
khash_t(l) labels; /* object -> int */ khash_t(l) labels; /* object -> int */
@ -29,10 +27,8 @@ struct writer_control {
#define OP_WRITE_SIMPLE 3 #define OP_WRITE_SIMPLE 3
static void static void
writer_control_init(struct writer_control *p, pic_state *pic, xFILE *file, int mode, int op) writer_control_init(struct writer_control *p, int mode, int op)
{ {
p->pic = pic;
p->file = file;
p->mode = mode; p->mode = mode;
p->op = op; p->op = op;
p->cnt = 0; p->cnt = 0;
@ -41,9 +37,8 @@ writer_control_init(struct writer_control *p, pic_state *pic, xFILE *file, int m
} }
static void static void
writer_control_destroy(struct writer_control *p) writer_control_destroy(pic_state *pic, struct writer_control *p)
{ {
pic_state *pic = p->pic;
kh_destroy(l, &p->labels); kh_destroy(l, &p->labels);
kh_destroy(v, &p->visited); kh_destroy(v, &p->visited);
} }
@ -67,9 +62,11 @@ write_blob(pic_state *pic, pic_value blob, xFILE *file)
} }
static void static void
write_char(pic_state *pic, char c, xFILE *file, int mode) write_char(pic_state *pic, pic_value ch, xFILE *file, struct writer_control *p)
{ {
if (mode == DISPLAY_MODE) { char c = pic_char(pic, ch);
if (p->mode == DISPLAY_MODE) {
xfputc(pic, c, file); xfputc(pic, c, file);
return; return;
} }
@ -87,12 +84,12 @@ write_char(pic_state *pic, char c, xFILE *file, int mode)
} }
static void static void
write_str(pic_state *pic, pic_value str, xFILE *file, int mode) write_str(pic_state *pic, pic_value str, xFILE *file, struct writer_control *p)
{ {
int i; int i;
const char *cstr = pic_str(pic, str); const char *cstr = pic_str(pic, str);
if (mode == DISPLAY_MODE) { if (p->mode == DISPLAY_MODE) {
xfprintf(pic, file, "%s", pic_str(pic, str)); xfprintf(pic, file, "%s", pic_str(pic, str));
return; return;
} }
@ -120,18 +117,17 @@ write_float(pic_state *pic, double f, xFILE *file)
} }
} }
static void write_core(struct writer_control *p, pic_value); static void write_core(pic_state *, pic_value, xFILE *, struct writer_control *);
static void static void
write_pair_help(struct writer_control *p, pic_value pair) write_pair_help(pic_state *pic, pic_value pair, xFILE *file, struct writer_control *p)
{ {
pic_state *pic = p->pic;
khash_t(l) *lh = &p->labels; khash_t(l) *lh = &p->labels;
khash_t(v) *vh = &p->visited; khash_t(v) *vh = &p->visited;
int it; int it;
int ret; int ret;
write_core(p, pic_car(pic, pair)); write_core(pic, pic_car(pic, pair), file, p);
if (pic_nil_p(pic, pic_cdr(pic, pair))) { if (pic_nil_p(pic, pic_cdr(pic, pair))) {
return; return;
@ -140,20 +136,20 @@ write_pair_help(struct writer_control *p, pic_value pair)
/* shared objects */ /* shared objects */
if ((it = kh_get(l, lh, pic_obj_ptr(pic_cdr(pic, pair)))) != kh_end(lh) && kh_val(lh, it) != -1) { if ((it = kh_get(l, lh, pic_obj_ptr(pic_cdr(pic, pair)))) != kh_end(lh) && kh_val(lh, it) != -1) {
xfprintf(pic, p->file, " . "); xfprintf(pic, file, " . ");
kh_put(v, vh, pic_obj_ptr(pic_cdr(pic, pair)), &ret); kh_put(v, vh, pic_obj_ptr(pic_cdr(pic, pair)), &ret);
if (ret == 0) { /* if exists */ if (ret == 0) { /* if exists */
xfprintf(pic, p->file, "#%d#", kh_val(lh, it)); xfprintf(pic, file, "#%d#", kh_val(lh, it));
return; return;
} }
xfprintf(pic, p->file, "#%d=", kh_val(lh, it)); xfprintf(pic, file, "#%d=", kh_val(lh, it));
} }
else { else {
xfprintf(pic, p->file, " "); xfprintf(pic, file, " ");
} }
write_pair_help(p, pic_cdr(pic, pair)); write_pair_help(pic, pic_cdr(pic, pair), file, p);
if (p->op == OP_WRITE) { if (p->op == OP_WRITE) {
if ((it = kh_get(l, lh, pic_obj_ptr(pic_cdr(pic, pair)))) != kh_end(lh) && kh_val(lh, it) != -1) { if ((it = kh_get(l, lh, pic_obj_ptr(pic_cdr(pic, pair)))) != kh_end(lh) && kh_val(lh, it) != -1) {
@ -164,78 +160,74 @@ write_pair_help(struct writer_control *p, pic_value pair)
return; return;
} }
else { else {
xfprintf(pic, p->file, " . "); xfprintf(pic, file, " . ");
write_core(p, pic_cdr(pic, pair)); write_core(pic, pic_cdr(pic, pair), file, p);
} }
} }
#define EQ(sym, lit) (strcmp(pic_str(pic, pic_sym_name(pic, sym)), lit) == 0) #define EQ(sym, lit) (strcmp(pic_str(pic, pic_sym_name(pic, sym)), lit) == 0)
static void static void
write_pair(struct writer_control *p, pic_value pair) write_pair(pic_state *pic, pic_value pair, xFILE *file, struct writer_control *p)
{ {
pic_state *pic = p->pic;
xFILE *file = p->file;
pic_value tag; pic_value tag;
if (pic_pair_p(pic, pic_cdr(pic, pair)) && pic_nil_p(pic, pic_cddr(pic, pair)) && pic_sym_p(pic, pic_car(pic, pair))) { if (pic_pair_p(pic, pic_cdr(pic, pair)) && pic_nil_p(pic, pic_cddr(pic, pair)) && pic_sym_p(pic, pic_car(pic, pair))) {
tag = pic_car(pic, pair); tag = pic_car(pic, pair);
if (EQ(tag, "quote")) { if (EQ(tag, "quote")) {
xfprintf(pic, file, "'"); xfprintf(pic, file, "'");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "unquote")) { else if (EQ(tag, "unquote")) {
xfprintf(pic, file, ","); xfprintf(pic, file, ",");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "unquote-splicing")) { else if (EQ(tag, "unquote-splicing")) {
xfprintf(pic, file, ",@"); xfprintf(pic, file, ",@");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "quasiquote")) { else if (EQ(tag, "quasiquote")) {
xfprintf(pic, file, "`"); xfprintf(pic, file, "`");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "syntax-quote")) { else if (EQ(tag, "syntax-quote")) {
xfprintf(pic, file, "#'"); xfprintf(pic, file, "#'");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "syntax-unquote")) { else if (EQ(tag, "syntax-unquote")) {
xfprintf(pic, file, "#,"); xfprintf(pic, file, "#,");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "syntax-unquote-splicing")) { else if (EQ(tag, "syntax-unquote-splicing")) {
xfprintf(pic, file, "#,@"); xfprintf(pic, file, "#,@");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
else if (EQ(tag, "syntax-quasiquote")) { else if (EQ(tag, "syntax-quasiquote")) {
xfprintf(pic, file, "#`"); xfprintf(pic, file, "#`");
write_core(p, pic_cadr(pic, pair)); write_core(pic, pic_cadr(pic, pair), file, p);
return; return;
} }
} }
xfprintf(pic, file, "("); xfprintf(pic, file, "(");
write_pair_help(p, pair); write_pair_help(pic, pair, file, p);
xfprintf(pic, file, ")"); xfprintf(pic, file, ")");
} }
static void static void
write_vec(struct writer_control *p, pic_value vec) write_vec(pic_state *pic, pic_value vec, xFILE *file, struct writer_control *p)
{ {
pic_state *pic = p->pic;
xFILE *file = p->file;
int i, len = pic_vec_len(pic, vec); int i, len = pic_vec_len(pic, vec);
xfprintf(pic, file, "#("); xfprintf(pic, file, "#(");
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
write_core(p, pic_vec_ref(pic, vec, i)); write_core(pic, pic_vec_ref(pic, vec, i), file, p);
if (i + 1 < len) { if (i + 1 < len) {
xfprintf(pic, file, " "); xfprintf(pic, file, " ");
} }
@ -244,28 +236,24 @@ write_vec(struct writer_control *p, pic_value vec)
} }
static void static void
write_dict(struct writer_control *p, pic_value dict) write_dict(pic_state *pic, pic_value dict, xFILE *file, struct writer_control *p)
{ {
pic_state *pic = p->pic;
xFILE *file = p->file;
pic_value key, val; pic_value key, val;
int it = 0; int it = 0;
xfprintf(pic, file, "#.(dictionary"); xfprintf(pic, file, "#.(dictionary");
while (pic_dict_next(pic, dict, &it, &key, &val)) { while (pic_dict_next(pic, dict, &it, &key, &val)) {
xfprintf(pic, file, " '%s ", pic_str(pic, pic_sym_name(pic, key))); xfprintf(pic, file, " '%s ", pic_str(pic, pic_sym_name(pic, key)));
write_core(p, val); write_core(pic, val, file, p);
} }
xfprintf(pic, file, ")"); xfprintf(pic, file, ")");
} }
static void static void
write_core(struct writer_control *p, pic_value obj) write_core(pic_state *pic, pic_value obj, xFILE *file, struct writer_control *p)
{ {
pic_state *pic = p->pic;
khash_t(l) *lh = &p->labels; khash_t(l) *lh = &p->labels;
khash_t(v) *vh = &p->visited; khash_t(v) *vh = &p->visited;
xFILE *file = p->file;
int it; int it;
int ret; int ret;
@ -311,19 +299,19 @@ write_core(struct writer_control *p, pic_value obj)
write_blob(pic, obj, file); write_blob(pic, obj, file);
break; break;
case PIC_TYPE_CHAR: case PIC_TYPE_CHAR:
write_char(pic, pic_char(pic, obj), file, p->mode); write_char(pic, obj, file, p);
break; break;
case PIC_TYPE_STRING: case PIC_TYPE_STRING:
write_str(pic, obj, file, p->mode); write_str(pic, obj, file, p);
break; break;
case PIC_TYPE_PAIR: case PIC_TYPE_PAIR:
write_pair(p, obj); write_pair(pic, obj, file, p);
break; break;
case PIC_TYPE_VECTOR: case PIC_TYPE_VECTOR:
write_vec(p, obj); write_vec(pic, obj, file, p);
break; break;
case PIC_TYPE_DICT: case PIC_TYPE_DICT:
write_dict(p, obj); write_dict(pic, obj, file, p);
break; break;
default: default:
xfprintf(pic, file, "#<%s %p>", pic_typename(pic, pic_type(pic, obj)), pic_obj_ptr(obj)); xfprintf(pic, file, "#<%s %p>", pic_typename(pic, pic_type(pic, obj)), pic_obj_ptr(obj));
@ -339,10 +327,8 @@ write_core(struct writer_control *p, pic_value obj)
} }
static void static void
traverse(struct writer_control *p, pic_value obj) traverse(pic_state *pic, pic_value obj, struct writer_control *p)
{ {
pic_state *pic = p->pic;
if (p->op == OP_WRITE_SIMPLE) { if (p->op == OP_WRITE_SIMPLE) {
return; return;
} }
@ -362,20 +348,20 @@ traverse(struct writer_control *p, pic_value obj)
if (pic_pair_p(pic, obj)) { if (pic_pair_p(pic, obj)) {
/* pair */ /* pair */
traverse(p, pic_car(pic, obj)); traverse(pic, pic_car(pic, obj), p);
traverse(p, pic_cdr(pic, obj)); traverse(pic, pic_cdr(pic, obj), p);
} else if (pic_vec_p(pic, obj)) { } else if (pic_vec_p(pic, obj)) {
/* vector */ /* vector */
int i, len = pic_vec_len(pic, obj); int i, len = pic_vec_len(pic, obj);
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
traverse(p, pic_vec_ref(pic, obj, i)); traverse(pic, pic_vec_ref(pic, obj, i), p);
} }
} else { } else {
/* dictionary */ /* dictionary */
int it = 0; int it = 0;
pic_value val; pic_value val;
while (pic_dict_next(pic, obj, &it, NULL, &val)) { while (pic_dict_next(pic, obj, &it, NULL, &val)) {
traverse(p, val); traverse(pic, val, p);
} }
} }
@ -401,13 +387,13 @@ write(pic_state *pic, pic_value obj, xFILE *file, int mode, int op)
{ {
struct writer_control p; struct writer_control p;
writer_control_init(&p, pic, file, mode, op); writer_control_init(&p, mode, op);
traverse(&p, obj); traverse(pic, obj, &p);
write_core(&p, obj); write_core(pic, obj, file, &p);
writer_control_destroy(&p); writer_control_destroy(pic, &p);
} }