From 25e19d4f007dc51194f6d21bcedd5900991cb8a5 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Fri, 19 Feb 2016 21:56:45 +0900 Subject: [PATCH] struct pic_vector * -> pic_value --- extlib/benz/bool.c | 13 +- extlib/benz/eval.c | 71 ++++----- extlib/benz/include/picrin.h | 10 +- extlib/benz/include/picrin/compat.h | 18 +++ extlib/benz/include/picrin/object.h | 15 +- extlib/benz/proc.c | 4 +- extlib/benz/read.c | 17 +-- extlib/benz/vector.c | 219 +++++++++++++++------------- extlib/benz/write.c | 18 +-- 9 files changed, 214 insertions(+), 171 deletions(-) diff --git a/extlib/benz/bool.c b/extlib/benz/bool.c index 19c856cb..c5d47823 100644 --- a/extlib/benz/bool.c +++ b/extlib/benz/bool.c @@ -158,17 +158,16 @@ internal_equal_p(pic_state *pic, pic_value x, pic_value y, int depth, khash_t(m) goto LOOP; /* tail-call optimization */ } case PIC_TYPE_VECTOR: { - int i; - struct pic_vector *u, *v; + int i, xlen, ylen; - u = pic_vec_ptr(x); - v = pic_vec_ptr(y); + xlen = pic_vec_len(pic, x); + ylen = pic_vec_len(pic, y); - if (u->len != v->len) { + if (xlen != ylen) { return false; } - for (i = 0; i < u->len; ++i) { - if (! internal_equal_p(pic, u->data[i], v->data[i], depth + 1, h)) + for (i = 0; i < xlen; ++i) { + if (! internal_equal_p(pic, pic_vec_ref(pic, x, i), pic_vec_ref(pic, y, i), depth + 1, h)) return false; } return true; diff --git a/extlib/benz/eval.c b/extlib/benz/eval.c index 264c3272..64160c7f 100644 --- a/extlib/benz/eval.c +++ b/extlib/benz/eval.c @@ -217,7 +217,7 @@ analyze_lambda(pic_state *pic, analyze_scope *up, pic_value form) analyze_scope s, *scope = &s; pic_value formals, body; pic_value rest = pic_undef_value(pic); - pic_vec *args, *locals, *captures; + pic_value args, locals, captures; int i, j; khiter_t it; @@ -232,7 +232,7 @@ analyze_lambda(pic_state *pic, analyze_scope *up, pic_value form) args = pic_make_vec(pic, kh_size(&scope->args), NULL); for (i = 0; pic_pair_p(pic, formals); formals = pic_cdr(pic, formals), i++) { - args->data[i] = pic_car(pic, formals); + pic_vec_set(pic, args, i, pic_car(pic, formals)); } if (scope->rest != NULL) { @@ -242,26 +242,26 @@ analyze_lambda(pic_state *pic, analyze_scope *up, pic_value form) locals = pic_make_vec(pic, kh_size(&scope->locals), NULL); j = 0; if (scope->rest != NULL) { - locals->data[j++] = pic_obj_value(scope->rest); + pic_vec_set(pic, locals, j++, pic_obj_value(scope->rest)); } for (it = kh_begin(&scope->locals); it < kh_end(&scope->locals); ++it) { if (kh_exist(&scope->locals, it)) { if (scope->rest != NULL && kh_key(&scope->locals, it) == scope->rest) continue; - locals->data[j++] = pic_obj_value(kh_key(&scope->locals, it)); + pic_vec_set(pic, locals, j++, pic_obj_value(kh_key(&scope->locals, it))); } } captures = pic_make_vec(pic, kh_size(&scope->captures), NULL); for (it = kh_begin(&scope->captures), j = 0; it < kh_end(&scope->captures); ++it) { if (kh_exist(&scope->captures, it)) { - captures->data[j++] = pic_obj_value(kh_key(&scope->captures, it)); + pic_vec_set(pic, captures, j++, pic_obj_value(kh_key(&scope->captures, it))); } } analyzer_scope_destroy(pic, scope); - return pic_list(pic, 6, pic_obj_value(pic->sLAMBDA), rest, pic_obj_value(args), pic_obj_value(locals), pic_obj_value(captures), body); + return pic_list(pic, 6, pic_obj_value(pic->sLAMBDA), rest, args, locals, captures, body); } static pic_value @@ -360,7 +360,7 @@ pic_analyze(pic_state *pic, pic_value obj) typedef struct codegen_context { /* rest args variable is counted as a local */ pic_sym *rest; - pic_vec *args, *locals, *captures; + pic_value args, locals, captures; /* actual bit code sequence */ pic_code *code; size_t clen, ccapa; @@ -381,7 +381,7 @@ typedef struct codegen_context { static void create_activation(pic_state *, codegen_context *); static void -codegen_context_init(pic_state *pic, codegen_context *cxt, codegen_context *up, pic_sym *rest, pic_vec *args, pic_vec *locals, pic_vec *captures) +codegen_context_init(pic_state *pic, codegen_context *cxt, codegen_context *up, pic_sym *rest, pic_value args, pic_value locals, pic_value captures) { cxt->up = up; cxt->rest = rest; @@ -422,9 +422,9 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) irep = pic_malloc(pic, sizeof(struct pic_irep)); irep->refc = 1; irep->varg = cxt->rest != NULL; - irep->argc = (int)cxt->args->len + 1; - irep->localc = (int)cxt->locals->len; - irep->capturec = (int)cxt->captures->len; + irep->argc = pic_vec_len(pic, cxt->args) + 1; + irep->localc = pic_vec_len(pic, cxt->locals); + irep->capturec = pic_vec_len(pic, cxt->captures); irep->code = pic_realloc(pic, cxt->code, sizeof(pic_code) * cxt->clen); irep->irep = pic_realloc(pic, cxt->irep, sizeof(struct pic_irep *) * cxt->ilen); irep->ints = pic_realloc(pic, cxt->ints, sizeof(int) * cxt->klen); @@ -481,7 +481,7 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) #define emit_ret(pic, cxt, tailpos) if (tailpos) emit_n(pic, cxt, OP_RET) static int -index_capture(codegen_context *cxt, pic_sym *sym, int depth) +index_capture(pic_state *pic, codegen_context *cxt, pic_sym *sym, int depth) { int i; @@ -489,26 +489,26 @@ index_capture(codegen_context *cxt, pic_sym *sym, int depth) cxt = cxt->up; } - for (i = 0; i < cxt->captures->len; ++i) { - if (pic_sym_ptr(cxt->captures->data[i]) == sym) + for (i = 0; i < pic_vec_len(pic, cxt->captures); ++i) { + if (pic_sym_ptr(pic_vec_ref(pic, cxt->captures, i)) == sym) return i; } return -1; } static int -index_local(codegen_context *cxt, pic_sym *sym) +index_local(pic_state *pic, codegen_context *cxt, pic_sym *sym) { int i, offset; offset = 1; - for (i = 0; i < cxt->args->len; ++i) { - if (pic_sym_ptr(cxt->args->data[i]) == sym) + for (i = 0; i < pic_vec_len(pic, cxt->args); ++i) { + if (pic_sym_ptr(pic_vec_ref(pic, cxt->args, i)) == sym) return i + offset; } offset += i; - for (i = 0; i < cxt->locals->len; ++i) { - if (pic_sym_ptr(cxt->locals->data[i]) == sym) + for (i = 0; i < pic_vec_len(pic, cxt->locals); ++i) { + if (pic_sym_ptr(pic_vec_ref(pic, cxt->locals, i)) == sym) return i + offset; } return -1; @@ -531,10 +531,11 @@ create_activation(pic_state *pic, codegen_context *cxt) { int i, n; - for (i = 0; i < cxt->captures->len; ++i) { - n = index_local(cxt, pic_sym_ptr(cxt->captures->data[i])); + for (i = 0; i < pic_vec_len(pic, cxt->captures); ++i) { + pic_sym *sym = pic_sym_ptr(pic_vec_ref(pic, cxt->captures, i)); + n = index_local(pic, cxt, sym); assert(n != -1); - if (n <= cxt->args->len || cxt->rest == pic_sym_ptr(cxt->captures->data[i])) { + if (n <= pic_vec_len(pic, cxt->args) || cxt->rest == sym) { /* copy arguments to capture variable area */ emit_i(pic, cxt, OP_LREF, n); } else { @@ -565,7 +566,7 @@ codegen_ref(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos) depth = pic_int(pic, pic_list_ref(pic, obj, 1)); name = pic_sym_ptr(pic_list_ref(pic, obj, 2)); - emit_r(pic, cxt, OP_CREF, depth, index_capture(cxt, name, depth)); + emit_r(pic, cxt, OP_CREF, depth, index_capture(pic, cxt, name, depth)); emit_ret(pic, cxt, tailpos); } else if (sym == LREF) { @@ -573,11 +574,11 @@ codegen_ref(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos) int i; name = pic_sym_ptr(pic_list_ref(pic, obj, 1)); - if ((i = index_capture(cxt, name, 0)) != -1) { - emit_i(pic, cxt, OP_LREF, i + (int)cxt->args->len + (int)cxt->locals->len + 1); + if ((i = index_capture(pic, cxt, name, 0)) != -1) { + emit_i(pic, cxt, OP_LREF, i + pic_vec_len(pic, cxt->args) + pic_vec_len(pic, cxt->locals) + 1); emit_ret(pic, cxt, tailpos); } else { - emit_i(pic, cxt, OP_LREF, index_local(cxt, name)); + emit_i(pic, cxt, OP_LREF, index_local(pic, cxt, name)); emit_ret(pic, cxt, tailpos); } } @@ -607,7 +608,7 @@ codegen_set(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos) depth = pic_int(pic, pic_list_ref(pic, var, 1)); name = pic_sym_ptr(pic_list_ref(pic, var, 2)); - emit_r(pic, cxt, OP_CSET, depth, index_capture(cxt, name, depth)); + emit_r(pic, cxt, OP_CSET, depth, index_capture(pic, cxt, name, depth)); emit_ret(pic, cxt, tailpos); } else if (type == LREF) { @@ -615,11 +616,11 @@ codegen_set(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos) int i; name = pic_sym_ptr(pic_list_ref(pic, var, 1)); - if ((i = index_capture(cxt, name, 0)) != -1) { - emit_i(pic, cxt, OP_LSET, i + (int)cxt->args->len + (int)cxt->locals->len + 1); + if ((i = index_capture(pic, cxt, name, 0)) != -1) { + emit_i(pic, cxt, OP_LSET, i + pic_vec_len(pic, cxt->args) + pic_vec_len(pic, cxt->locals) + 1); emit_ret(pic, cxt, tailpos); } else { - emit_i(pic, cxt, OP_LSET, index_local(cxt, name)); + emit_i(pic, cxt, OP_LSET, index_local(pic, cxt, name)); emit_ret(pic, cxt, tailpos); } } @@ -631,7 +632,7 @@ codegen_lambda(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos codegen_context c, *inner_cxt = &c; pic_value rest_opt, body; pic_sym *rest = NULL; - pic_vec *args, *locals, *captures; + pic_value args, locals, captures; check_irep_size(pic, cxt); @@ -640,9 +641,9 @@ codegen_lambda(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos if (pic_sym_p(pic, rest_opt)) { rest = pic_sym_ptr(rest_opt); } - args = pic_vec_ptr(pic_list_ref(pic, obj, 2)); - locals = pic_vec_ptr(pic_list_ref(pic, obj, 3)); - captures = pic_vec_ptr(pic_list_ref(pic, obj, 4)); + args = pic_list_ref(pic, obj, 2); + locals = pic_list_ref(pic, obj, 3); + captures = pic_list_ref(pic, obj, 4); body = pic_list_ref(pic, obj, 5); /* emit irep */ @@ -818,7 +819,7 @@ codegen(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos) static struct pic_irep * pic_codegen(pic_state *pic, pic_value obj) { - pic_vec *empty = pic_make_vec(pic, 0, NULL); + pic_value empty = pic_make_vec(pic, 0, NULL); codegen_context c, *cxt = &c; codegen_context_init(pic, cxt, NULL, NULL, empty, empty, empty); diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index b2421e3b..b1483dd3 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -55,7 +55,6 @@ struct pic_object; struct pic_symbol; struct pic_pair; struct pic_string; -struct pic_vector; struct pic_blob; struct pic_proc; struct pic_port; @@ -66,7 +65,6 @@ struct pic_data; typedef struct pic_symbol pic_sym; typedef struct pic_id pic_id; typedef struct pic_pair pic_pair; -typedef struct pic_vector pic_vec; typedef void *(*pic_allocf)(void *userdata, void *ptr, size_t n); @@ -235,10 +233,10 @@ pic_value pic_reverse(pic_state *, pic_value list); pic_value pic_append(pic_state *, pic_value xs, pic_value ys); /* vector */ -pic_vec *pic_make_vec(pic_state *, int, pic_value *); -pic_value pic_vec_ref(pic_state *, pic_vec *, int); -void pic_vec_set(pic_state *, pic_vec *, int, pic_value); -int pic_vec_len(pic_state *, pic_vec *); +pic_value pic_make_vec(pic_state *, int n, pic_value *argv); +pic_value pic_vec_ref(pic_state *, pic_value vec, int i); +void pic_vec_set(pic_state *, pic_value vec, int i, pic_value v); +int pic_vec_len(pic_state *, pic_value vec); /* dictionary */ pic_value pic_make_dict(pic_state *); diff --git a/extlib/benz/include/picrin/compat.h b/extlib/benz/include/picrin/compat.h index 8f2bb886..ba4d964e 100644 --- a/extlib/benz/include/picrin/compat.h +++ b/extlib/benz/include/picrin/compat.h @@ -203,6 +203,24 @@ memcpy(void *dst, const void *src, size_t n) return d; } +PIC_INLINE void * +memmove(void *dst, const void *src, size_t n) +{ + const char *s = src; + char *d = dst; + + if (d <= s || d >= s + n) { + memcpy(dst, src, n); + } else { + s += n; + d += n; + while (n-- > 0) { + *--d = *--s; + } + } + return d; +} + PIC_INLINE char * strcpy(char *dst, const char *src) { diff --git a/extlib/benz/include/picrin/object.h b/extlib/benz/include/picrin/object.h index 4f5ddfe9..08acd36c 100644 --- a/extlib/benz/include/picrin/object.h +++ b/extlib/benz/include/picrin/object.h @@ -120,13 +120,13 @@ struct pic_port { xFILE *file; }; +#define pic_vec_ptr(pic, o) ((struct pic_vector *)pic_obj_ptr(o)) #define pic_dict_ptr(pic, v) ((struct pic_dict *)pic_obj_ptr(v)) #define pic_sym_ptr(v) ((pic_sym *)pic_obj_ptr(v)) #define pic_id_ptr(v) ((pic_id *)pic_obj_ptr(v)) #define pic_pair_ptr(o) ((struct pic_pair *)pic_obj_ptr(o)) #define pic_blob_ptr(v) ((struct pic_blob *)pic_obj_ptr(v)) #define pic_str_ptr(o) ((struct pic_string *)pic_obj_ptr(o)) -#define pic_vec_ptr(o) ((struct pic_vector *)pic_obj_ptr(o)) #define pic_weak_ptr(v) ((struct pic_weak *)pic_obj_ptr(v)) #define pic_data_ptr(o) ((struct pic_data *)pic_obj_ptr(o)) #define pic_context_ptr(o) ((struct pic_context *)pic_obj_ptr(o)) @@ -143,6 +143,19 @@ struct pic_port { struct pic_object *pic_obj_alloc(pic_state *, size_t, int type); +#define VALID_INDEX(pic, len, i) do { \ + if (i < 0 || len <= i) pic_errorf(pic, "index out of range: %d", i); \ + } while (0) +#define VALID_RANGE(pic, len, s, e) do { \ + if (s < 0 || len < s) pic_errorf(pic, "invalid start index: %d", s); \ + if (e < s || len < e) pic_errorf(pic, "invalid end index: %d", e); \ + } while (0) +#define VALID_ATRANGE(pic, tolen, at, fromlen, s, e) do { \ + VALID_INDEX(pic, tolen, at); \ + VALID_RANGE(pic, fromlen, s, e); \ + if (tolen - at < e - s) pic_errorf(pic, "invalid range"); \ + } while (0) + pic_id *pic_make_identifier(pic_state *, pic_id *, struct pic_env *); struct pic_proc *pic_make_proc(pic_state *, pic_func_t, int, pic_value *); struct pic_proc *pic_make_proc_irep(pic_state *, struct pic_irep *, struct pic_context *); diff --git a/extlib/benz/proc.c b/extlib/benz/proc.c index b3a8970e..712c26db 100644 --- a/extlib/benz/proc.c +++ b/extlib/benz/proc.c @@ -21,7 +21,7 @@ * c char * char * z char ** c string * m pic_sym ** symbol - * v pic_vec ** vector object + * v pic_value * vector object * s struct pic_str ** string object * b struct pic_blob ** bytevector object * l struct pic_proc ** lambda object @@ -148,7 +148,6 @@ pic_get_args(pic_state *pic, const char *format, ...) VAL_CASE(c, type, ctype, pic_## type ##_ptr(v)) PTR_CASE('m', sym, pic_sym *) - PTR_CASE('v', vec, pic_vec *) PTR_CASE('s', str, struct pic_string *) PTR_CASE('b', blob, struct pic_blob *) PTR_CASE('l', proc, struct pic_proc *) @@ -158,6 +157,7 @@ pic_get_args(pic_state *pic, const char *format, ...) #define OBJ_CASE(c, type) VAL_CASE(c, type, pic_value, v) + OBJ_CASE('v', vec) OBJ_CASE('d', dict) default: diff --git a/extlib/benz/read.c b/extlib/benz/read.c index 88e636b2..2a7c99e5 100644 --- a/extlib/benz/read.c +++ b/extlib/benz/read.c @@ -590,8 +590,7 @@ read_pair(pic_state *pic, xFILE *file, int c) static pic_value read_vector(pic_state *pic, xFILE *file, int c) { - pic_value list, it, elem; - pic_vec *vec; + pic_value list, it, elem, vec; int i = 0; list = read(pic, file, c); @@ -599,10 +598,10 @@ read_vector(pic_state *pic, xFILE *file, int c) vec = pic_make_vec(pic, pic_length(pic, list), NULL); pic_for_each (elem, list, it) { - vec->data[i++] = elem; + pic_vec_set(pic, vec, i++, elem); } - return pic_obj_value(vec); + return vec; } static pic_value @@ -639,13 +638,13 @@ read_label_set(pic_state *pic, xFILE *file, int i) } if (vect) { - pic_vec *tmp; + pic_value tmp; - kh_val(h, it) = val = pic_obj_value(pic_make_vec(pic, 0, NULL)); + kh_val(h, it) = val = pic_make_vec(pic, 0, NULL); - tmp = pic_vec_ptr(read(pic, file, c)); - PIC_SWAP(pic_value *, tmp->data, pic_vec_ptr(val)->data); - PIC_SWAP(int, tmp->len, pic_vec_ptr(val)->len); + tmp = read(pic, file, c); + PIC_SWAP(pic_value *, pic_vec_ptr(pic, tmp)->data, pic_vec_ptr(pic, val)->data); + PIC_SWAP(int, pic_vec_ptr(pic, tmp)->len, pic_vec_ptr(pic, val)->len); return val; } diff --git a/extlib/benz/vector.c b/extlib/benz/vector.c index 339a346b..da75cd9c 100644 --- a/extlib/benz/vector.c +++ b/extlib/benz/vector.c @@ -5,7 +5,7 @@ #include "picrin.h" #include "picrin/object.h" -struct pic_vector * +pic_value pic_make_vec(pic_state *pic, int len, pic_value *argv) { struct pic_vector *vec; @@ -21,7 +21,25 @@ pic_make_vec(pic_state *pic, int len, pic_value *argv) } else { memcpy(vec->data, argv, sizeof(pic_value) * len); } - return vec; + return pic_obj_value(vec); +} + +pic_value +pic_vec_ref(pic_state PIC_UNUSED(*pic), pic_value vec, int k) +{ + return pic_vec_ptr(pic, vec)->data[k]; +} + +void +pic_vec_set(pic_state PIC_UNUSED(*pic), pic_value vec, int k, pic_value val) +{ + pic_vec_ptr(pic, vec)->data[k] = val; +} + +int +pic_vec_len(pic_state PIC_UNUSED(*pic), pic_value vec) +{ + return pic_vec_ptr(pic, vec)->len; } static pic_value @@ -39,100 +57,92 @@ pic_vec_vector(pic_state *pic) { int argc; pic_value *argv; - pic_vec *vec; pic_get_args(pic, "*", &argc, &argv); - vec = pic_make_vec(pic, argc, argv); - - return pic_obj_value(vec); + return pic_make_vec(pic, argc, argv); } static pic_value pic_vec_make_vector(pic_state *pic) { - pic_value v; + pic_value vec, init; int n, k, i; - struct pic_vector *vec; - n = pic_get_args(pic, "i|o", &k, &v); + n = pic_get_args(pic, "i|o", &k, &init); + + if (k < 0) { + pic_errorf(pic, "make-vector: negative length given %d", k); + } vec = pic_make_vec(pic, k, NULL); if (n == 2) { for (i = 0; i < k; ++i) { - vec->data[i] = v; + pic_vec_set(pic, vec, i, init); } } - return pic_obj_value(vec); + return vec; } static pic_value pic_vec_vector_length(pic_state *pic) { - struct pic_vector *v; + pic_value v; pic_get_args(pic, "v", &v); - return pic_int_value(pic, v->len); + return pic_int_value(pic, pic_vec_len(pic, v)); } static pic_value pic_vec_vector_ref(pic_state *pic) { - struct pic_vector *v; + pic_value v; int k; pic_get_args(pic, "vi", &v, &k); - if (v->len <= k) { - pic_errorf(pic, "vector-ref: index out of range"); - } - return v->data[k]; + VALID_INDEX(pic, pic_vec_len(pic, v), k); + + return pic_vec_ref(pic, v, k); } static pic_value pic_vec_vector_set(pic_state *pic) { - struct pic_vector *v; + pic_value v, o; int k; - pic_value o; pic_get_args(pic, "vio", &v, &k, &o); - if (v->len <= k) { - pic_errorf(pic, "vector-set!: index out of range"); - } - v->data[k] = o; + VALID_INDEX(pic, pic_vec_len(pic, v), k); + + pic_vec_set(pic, v, k, o); + return pic_undef_value(pic); } static pic_value pic_vec_vector_copy_i(pic_state *pic) { - pic_vec *to, *from; - int n, at, start, end; + pic_value to, from; + int n, at, start, end, tolen, fromlen; n = pic_get_args(pic, "viv|ii", &to, &at, &from, &start, &end); + tolen = pic_vec_len(pic, to); + fromlen = pic_vec_len(pic, from); + switch (n) { case 3: start = 0; case 4: - end = from->len; + end = fromlen; } - if (to == from && (start <= at && at < end)) { - /* copy in reversed order */ - at += end - start; - while (start < end) { - to->data[--at] = from->data[--end]; - } - return pic_undef_value(pic); - } + VALID_ATRANGE(pic, tolen, at, fromlen, start, end); - while (start < end) { - to->data[at++] = from->data[start++]; - } + memmove(pic_vec_ptr(pic, to)->data + at, pic_vec_ptr(pic, from)->data + start, sizeof(pic_value) * (end - start)); return pic_undef_value(pic); } @@ -140,73 +150,72 @@ pic_vec_vector_copy_i(pic_state *pic) static pic_value pic_vec_vector_copy(pic_state *pic) { - pic_vec *from, *to; - int n, start, end; + pic_value from; + int n, start, end, fromlen; n = pic_get_args(pic, "v|ii", &from, &start, &end); + fromlen = pic_vec_len(pic, from); + switch (n) { case 1: start = 0; case 2: - end = from->len; + end = fromlen; } - if (end < start) { - pic_errorf(pic, "vector-copy: end index must not be less than start index"); - } + VALID_RANGE(pic, fromlen, start, end); - to = pic_make_vec(pic, end - start, from->data + start); - - return pic_obj_value(to); + return pic_make_vec(pic, end - start, pic_vec_ptr(pic, from)->data + start); } static pic_value pic_vec_vector_append(pic_state *pic) { - pic_value *argv; - int argc, i, j, len; - pic_vec *vec; + pic_value *argv, vec; + int argc, i, len; pic_get_args(pic, "*", &argc, &argv); len = 0; for (i = 0; i < argc; ++i) { pic_assert_type(pic, argv[i], vec); - len += pic_vec_ptr(argv[i])->len; + len += pic_vec_len(pic, argv[i]); } vec = pic_make_vec(pic, len, NULL); len = 0; for (i = 0; i < argc; ++i) { - for (j = 0; j < pic_vec_ptr(argv[i])->len; ++j) { - vec->data[len + j] = pic_vec_ptr(argv[i])->data[j]; - } - len += pic_vec_ptr(argv[i])->len; + int l = pic_vec_len(pic, argv[i]); + memcpy(pic_vec_ptr(pic, vec)->data + len, pic_vec_ptr(pic, argv[i])->data, sizeof(pic_value) * l); + len += l; } - return pic_obj_value(vec); + return vec; } static pic_value pic_vec_vector_fill_i(pic_state *pic) { - pic_vec *vec; - pic_value obj; - int n, start, end; + pic_value vec, obj; + int n, start, end, len; n = pic_get_args(pic, "vo|ii", &vec, &obj, &start, &end); + len = pic_vec_len(pic, vec); + switch (n) { case 2: start = 0; case 3: - end = vec->len; + end = len; } + VALID_RANGE(pic, len, start, end); + while (start < end) { - vec->data[start++] = obj; + pic_vec_set(pic, vec, start++, obj); } return pic_undef_value(pic); @@ -217,18 +226,20 @@ pic_vec_vector_map(pic_state *pic) { struct pic_proc *proc; int argc, i, len, j; - pic_value *argv, vals; - pic_vec *vec; + pic_value *argv, vec, vals; pic_get_args(pic, "l*", &proc, &argc, &argv); + if (argc == 0) { + pic_errorf(pic, "vector-map: wrong number of arguments (1 for at least 2)"); + } + len = INT_MAX; for (i = 0; i < argc; ++i) { + int l; pic_assert_type(pic, argv[i], vec); - - len = len < pic_vec_ptr(argv[i])->len - ? len - : pic_vec_ptr(argv[i])->len; + l = pic_vec_len(pic, argv[i]); + len = len < l ? len : l; } vec = pic_make_vec(pic, len, NULL); @@ -236,12 +247,12 @@ pic_vec_vector_map(pic_state *pic) for (i = 0; i < len; ++i) { vals = pic_nil_value(pic); for (j = 0; j < argc; ++j) { - pic_push(pic, pic_vec_ptr(argv[j])->data[i], vals); + pic_push(pic, pic_vec_ref(pic, argv[j], i), vals); } - vec->data[i] = pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals); + pic_vec_set(pic, vec, i, pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals)); } - return pic_obj_value(vec); + return vec; } static pic_value @@ -253,19 +264,22 @@ pic_vec_vector_for_each(pic_state *pic) pic_get_args(pic, "l*", &proc, &argc, &argv); + if (argc == 0) { + pic_errorf(pic, "vector-for-each: wrong number of arguments (1 for at least 2)"); + } + len = INT_MAX; for (i = 0; i < argc; ++i) { + int l; pic_assert_type(pic, argv[i], vec); - - len = len < pic_vec_ptr(argv[i])->len - ? len - : pic_vec_ptr(argv[i])->len; + l = pic_vec_len(pic, argv[i]); + len = len < l ? len : l; } for (i = 0; i < len; ++i) { vals = pic_nil_value(pic); for (j = 0; j < argc; ++j) { - pic_push(pic, pic_vec_ptr(argv[j])->data[i], vals); + pic_push(pic, pic_vec_ref(pic, argv[j], i), vals); } pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals); } @@ -276,41 +290,43 @@ pic_vec_vector_for_each(pic_state *pic) static pic_value pic_vec_list_to_vector(pic_state *pic) { - struct pic_vector *vec; - pic_value list, e, it, *data; + pic_value list, vec, e, it; + int len, i = 0; pic_get_args(pic, "o", &list); - vec = pic_make_vec(pic, pic_length(pic, list), NULL); - - data = vec->data; + len = pic_length(pic, list); + vec = pic_make_vec(pic, len, NULL); pic_for_each (e, list, it) { - *data++ = e; + pic_vec_set(pic, vec, i++, e); } - return pic_obj_value(vec); + return vec; } static pic_value pic_vec_vector_to_list(pic_state *pic) { - struct pic_vector *vec; + pic_value vec; pic_value list; - int n, start, end, i; + int n, start, end, i, len; n = pic_get_args(pic, "v|ii", &vec, &start, &end); + len = pic_vec_len(pic, vec); + switch (n) { case 1: start = 0; case 2: - end = vec->len; + end = len; } - list = pic_nil_value(pic); + VALID_RANGE(pic, len, start, end); + list = pic_nil_value(pic); for (i = start; i < end; ++i) { - pic_push(pic, vec->data[i], list); + pic_push(pic, pic_vec_ref(pic, vec, i), list); } return pic_reverse(pic, list); } @@ -318,30 +334,31 @@ pic_vec_vector_to_list(pic_state *pic) static pic_value pic_vec_vector_to_string(pic_state *pic) { - pic_vec *vec; + pic_value vec, t; char *buf; - int n, start, end, i; + int n, start, end, i, len; struct pic_string *str; n = pic_get_args(pic, "v|ii", &vec, &start, &end); + len = pic_vec_len(pic, vec); + switch (n) { case 1: start = 0; case 2: - end = vec->len; + end = len; } - if (end < start) { - pic_errorf(pic, "vector->string: end index must not be less than start index"); - } + VALID_RANGE(pic, len, start, end); buf = pic_malloc(pic, end - start); - for (i = start; i < end; ++i) { - pic_assert_type(pic, vec->data[i], char); + t = pic_vec_ref(pic, vec, i); - buf[i - start] = pic_char(pic, vec->data[i]); + pic_assert_type(pic, t, char); + + buf[i - start] = pic_char(pic, t); } str = pic_str_value(pic, buf, end - start); @@ -355,7 +372,7 @@ pic_vec_string_to_vector(pic_state *pic) { struct pic_string *str; int n, start, end, i; - pic_vec *vec; + pic_value vec; n = pic_get_args(pic, "s|ii", &str, &start, &end); @@ -366,16 +383,14 @@ pic_vec_string_to_vector(pic_state *pic) end = pic_str_len(pic, str); } - if (end < start) { - pic_errorf(pic, "string->vector: end index must not be less than start index"); - } + VALID_RANGE(pic, pic_str_len(pic, str), start, end); vec = pic_make_vec(pic, end - start, NULL); for (i = 0; i < end - start; ++i) { - vec->data[i] = pic_char_value(pic, pic_str_ref(pic, str, i + start)); + pic_vec_set(pic, vec, i, pic_char_value(pic, pic_str_ref(pic, str, i + start))); } - return pic_obj_value(vec); + return vec; } void diff --git a/extlib/benz/write.c b/extlib/benz/write.c index c80b7fc3..a65dc804 100644 --- a/extlib/benz/write.c +++ b/extlib/benz/write.c @@ -221,16 +221,16 @@ write_pair(struct writer_control *p, struct pic_pair *pair) } static void -write_vec(struct writer_control *p, pic_vec *vec) +write_vec(struct writer_control *p, pic_value vec) { pic_state *pic = p->pic; xFILE *file = p->file; - int i; + int i, len = pic_vec_len(pic, vec); xfprintf(pic, file, "#("); - for (i = 0; i < vec->len; ++i) { - write_core(p, vec->data[i]); - if (i + 1 < vec->len) { + for (i = 0; i < len; ++i) { + write_core(p, pic_vec_ref(pic, vec, i)); + if (i + 1 < len) { xfprintf(pic, file, " "); } } @@ -315,7 +315,7 @@ write_core(struct writer_control *p, pic_value obj) write_pair(p, pic_pair_ptr(obj)); break; case PIC_TYPE_VECTOR: - write_vec(p, pic_vec_ptr(obj)); + write_vec(p, obj); break; case PIC_TYPE_DICT: write_dict(p, obj); @@ -361,9 +361,9 @@ traverse(struct writer_control *p, pic_value obj) traverse(p, pic_cdr(pic, obj)); } else if (pic_vec_p(pic, obj)) { /* vector */ - int i; - for (i = 0; i < pic_vec_ptr(obj)->len; ++i) { - traverse(p, pic_vec_ptr(obj)->data[i]); + int i, len = pic_vec_len(pic, obj); + for (i = 0; i < len; ++i) { + traverse(p, pic_vec_ref(pic, obj, i)); } } else { /* dictionary */