don't use size_t for index

This commit is contained in:
Yuichi Nishiwaki 2016-02-27 00:44:32 +09:00
parent 22d339c2f7
commit a14d3a62c4
1 changed files with 29 additions and 46 deletions

View File

@ -9,15 +9,15 @@
struct chunk { struct chunk {
char *str; char *str;
int refcnt; int refcnt;
size_t len; int len;
char buf[1]; char buf[1];
}; };
struct rope { struct rope {
int refcnt; int refcnt;
size_t weight; int weight;
struct chunk *chunk; struct chunk *chunk;
size_t offset; int offset;
struct rope *left, *right; struct rope *left, *right;
}; };
@ -26,9 +26,8 @@ struct rope {
} while (0) } while (0)
#define CHUNK_DECREF(c) do { \ #define CHUNK_DECREF(c) do { \
struct chunk *c_ = (c); \ if (! --(c)->refcnt) { \
if (! --c_->refcnt) { \ pic_free(pic, (c)); \
pic_free(pic, c_); \
} \ } \
} while (0) } while (0)
@ -52,7 +51,7 @@ pic_rope_decref(pic_state *pic, struct rope *x) {
} }
static struct chunk * static struct chunk *
pic_make_chunk(pic_state *pic, const char *str, size_t len) make_chunk(pic_state *pic, const char *str, int len)
{ {
struct chunk *c; struct chunk *c;
@ -67,7 +66,7 @@ pic_make_chunk(pic_state *pic, const char *str, size_t len)
} }
static struct chunk * static struct chunk *
pic_make_chunk_lit(pic_state *pic, const char *str, size_t len) make_chunk_lit(pic_state *pic, const char *str, int len)
{ {
struct chunk *c; struct chunk *c;
@ -80,7 +79,7 @@ pic_make_chunk_lit(pic_state *pic, const char *str, size_t len)
} }
static struct rope * static struct rope *
pic_make_rope(pic_state *pic, struct chunk *c) make_rope(pic_state *pic, struct chunk *c)
{ {
struct rope *x; struct rope *x;
@ -96,7 +95,7 @@ pic_make_rope(pic_state *pic, struct chunk *c)
} }
static pic_value static pic_value
pic_make_str(pic_state *pic, struct rope *rope) make_str(pic_state *pic, struct rope *rope)
{ {
struct string *str; struct string *str;
@ -106,29 +105,6 @@ pic_make_str(pic_state *pic, struct rope *rope)
return pic_obj_value(str); return pic_obj_value(str);
} }
static size_t
rope_len(struct rope *x)
{
return x->weight;
}
static char
rope_at(struct rope *x, size_t i)
{
while (i < x->weight) {
if (x->chunk) {
return x->chunk->str[x->offset + i];
}
if (i < x->left->weight) {
x = x->left;
} else {
i -= x->left->weight;
x = x->right;
}
}
return -1;
}
static struct rope * static struct rope *
rope_cat(pic_state *pic, struct rope *x, struct rope *y) rope_cat(pic_state *pic, struct rope *x, struct rope *y)
{ {
@ -149,7 +125,7 @@ rope_cat(pic_state *pic, struct rope *x, struct rope *y)
} }
static struct rope * static struct rope *
rope_sub(pic_state *pic, struct rope *x, size_t i, size_t j) rope_sub(pic_state *pic, struct rope *x, int i, int j)
{ {
assert(i <= j); assert(i <= j);
assert(j <= x->weight); assert(j <= x->weight);
@ -196,7 +172,7 @@ rope_sub(pic_state *pic, struct rope *x, size_t i, size_t j)
} }
static void static void
flatten(pic_state *pic, struct rope *x, struct chunk *c, size_t offset) flatten(pic_state *pic, struct rope *x, struct chunk *c, int offset)
{ {
if (x->chunk) { if (x->chunk) {
memcpy(c->str + offset, x->chunk->str + x->offset, x->weight); memcpy(c->str + offset, x->chunk->str + x->offset, x->weight);
@ -253,44 +229,51 @@ pic_str_value(pic_state *pic, const char *str, int len)
struct chunk *c; struct chunk *c;
if (len > 0) { if (len > 0) {
c = pic_make_chunk(pic, str, len); c = make_chunk(pic, str, len);
} else { } else {
if (len == 0) { if (len == 0) {
str = ""; str = "";
} }
c = pic_make_chunk_lit(pic, str, -len); c = make_chunk_lit(pic, str, -len);
} }
return pic_make_str(pic, pic_make_rope(pic, c)); return make_str(pic, make_rope(pic, c));
} }
int int
pic_str_len(pic_state *PIC_UNUSED(pic), pic_value str) pic_str_len(pic_state *PIC_UNUSED(pic), pic_value str)
{ {
return rope_len(pic_str_ptr(pic, str)->rope); return pic_str_ptr(pic, str)->rope->weight;
} }
char char
pic_str_ref(pic_state *pic, pic_value str, int i) pic_str_ref(pic_state *pic, pic_value str, int i)
{ {
int c; struct rope *rope = pic_str_ptr(pic, str)->rope;
c = rope_at(pic_str_ptr(pic, str)->rope, i); while (i < rope->weight) {
if (c == -1) { if (rope->chunk) {
pic_error(pic, "index out of range", 1, pic_int_value(pic, i)); return rope->chunk->str[rope->offset + i];
}
if (i < rope->left->weight) {
rope = rope->left;
} else {
i -= rope->left->weight;
rope = rope->right;
}
} }
return (char)c; PIC_UNREACHABLE();
} }
pic_value pic_value
pic_str_cat(pic_state *pic, pic_value a, pic_value b) pic_str_cat(pic_state *pic, pic_value a, pic_value b)
{ {
return pic_make_str(pic, rope_cat(pic, pic_str_ptr(pic, a)->rope, pic_str_ptr(pic, b)->rope)); return make_str(pic, rope_cat(pic, pic_str_ptr(pic, a)->rope, pic_str_ptr(pic, b)->rope));
} }
pic_value pic_value
pic_str_sub(pic_state *pic, pic_value str, int s, int e) pic_str_sub(pic_state *pic, pic_value str, int s, int e)
{ {
return pic_make_str(pic, rope_sub(pic, pic_str_ptr(pic, str)->rope, s, e)); return make_str(pic, rope_sub(pic, pic_str_ptr(pic, str)->rope, s, e));
} }
int int