upgrade xvect.h

This commit is contained in:
Yuichi Nishiwaki 2014-09-14 01:08:37 +09:00
parent b20a97ed9f
commit 09e56c2c35
2 changed files with 157 additions and 41 deletions

View File

@ -198,13 +198,13 @@ lookup_scope(analyze_scope *scope, pic_sym sym)
size_t i;
/* args */
for (i = 0; i < scope->args.size; ++i) {
for (i = 0; i < xv_size(&scope->args); ++i) {
arg = xv_get(&scope->args, i);
if (*arg == sym)
return true;
}
/* locals */
for (i = 0; i < scope->locals.size; ++i) {
for (i = 0; i < xv_size(&scope->locals); ++i) {
local = xv_get(&scope->locals, i);
if (*local == sym)
return true;
@ -218,13 +218,13 @@ capture_var(analyze_scope *scope, pic_sym sym)
pic_sym *var;
size_t i;
for (i = 0; i < scope->captures.size; ++i) {
for (i = 0; i < xv_size(&scope->captures); ++i) {
var = xv_get(&scope->captures, i);
if (*var == sym) {
break;
}
}
if (i == scope->captures.size) {
if (i == xv_size(&scope->captures)) {
xv_push(&scope->captures, &sym);
}
}
@ -384,7 +384,7 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
size_t i;
args = pic_nil_value();
for (i = scope->args.size; i > 0; --i) {
for (i = xv_size(&scope->args); i > 0; --i) {
var = xv_get(&scope->args, i - 1);
pic_push(pic, pic_sym_value(*var), args);
}
@ -399,13 +399,13 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
analyze_deferred(state);
locals = pic_nil_value();
for (i = scope->locals.size; i > 0; --i) {
for (i = xv_size(&scope->locals); i > 0; --i) {
var = xv_get(&scope->locals, i - 1);
pic_push(pic, pic_sym_value(*var), locals);
}
captures = pic_nil_value();
for (i = scope->captures.size; i > 0; --i) {
for (i = xv_size(&scope->captures); i > 0; --i) {
var = xv_get(&scope->captures, i - 1);
pic_push(pic, pic_sym_value(*var), captures);
}
@ -940,21 +940,21 @@ create_activation(codegen_context *cxt)
xh_init_int(&regs, sizeof(size_t));
offset = 1;
for (i = 0; i < cxt->args.size; ++i) {
for (i = 0; i < xv_size(&cxt->args); ++i) {
var = xv_get(&cxt->args, i);
n = i + offset;
xh_put_int(&regs, *var, &n);
}
offset += i;
for (i = 0; i < cxt->locals.size; ++i) {
for (i = 0; i < xv_size(&cxt->locals); ++i) {
var = xv_get(&cxt->locals, i);
n = i + offset;
xh_put_int(&regs, *var, &n);
}
for (i = 0; i < cxt->captures.size; ++i) {
for (i = 0; i < xv_size(&cxt->captures); ++i) {
var = xv_get(&cxt->captures, i);
if ((n = xh_val(xh_get_int(&regs, *var), size_t)) <= cxt->args.size || (cxt->varg && n == cxt->args.size + 1)) {
if ((n = xh_val(xh_get_int(&regs, *var), size_t)) <= xv_size(&cxt->args) || (cxt->varg && n == xv_size(&cxt->args) + 1)) {
/* copy arguments to capture variable area */
cxt->code[cxt->clen].insn = OP_LREF;
cxt->code[cxt->clen].u.i = n;
@ -1031,9 +1031,9 @@ pop_codegen_context(codegen_state *state)
irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
irep->name = state->cxt->name;
irep->varg = state->cxt->varg;
irep->argc = state->cxt->args.size + 1;
irep->localc = state->cxt->locals.size;
irep->capturec = state->cxt->captures.size;
irep->argc = xv_size(&state->cxt->args) + 1;
irep->localc = xv_size(&state->cxt->locals);
irep->capturec = xv_size(&state->cxt->captures);
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
irep->clen = state->cxt->clen;
irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen);
@ -1065,7 +1065,7 @@ index_capture(codegen_state *state, pic_sym sym, int depth)
cxt = cxt->up;
}
for (i = 0; i < cxt->captures.size; ++i) {
for (i = 0; i < xv_size(&cxt->captures); ++i) {
var = xv_get(&cxt->captures, i);
if (*var == sym)
return i;
@ -1081,13 +1081,13 @@ index_local(codegen_state *state, pic_sym sym)
pic_sym *var;
offset = 1;
for (i = 0; i < cxt->args.size; ++i) {
for (i = 0; i < xv_size(&cxt->args); ++i) {
var = xv_get(&cxt->args, i);
if (*var == sym)
return i + offset;
}
offset += i;
for (i = 0; i < cxt->locals.size; ++i) {
for (i = 0; i < xv_size(&cxt->locals); ++i) {
var = xv_get(&cxt->locals, i);
if (*var == sym)
return i + offset;
@ -1128,7 +1128,7 @@ codegen(codegen_state *state, pic_value obj)
name = pic_sym(pic_list_ref(pic, obj, 1));
if ((i = index_capture(state, name, 0)) != -1) {
cxt->code[cxt->clen].insn = OP_LREF;
cxt->code[cxt->clen].u.i = i + cxt->args.size + cxt->locals.size + 1;
cxt->code[cxt->clen].u.i = i + xv_size(&cxt->args) + xv_size(&cxt->locals) + 1;
cxt->clen++;
return;
}
@ -1174,7 +1174,7 @@ codegen(codegen_state *state, pic_value obj)
name = pic_sym(pic_list_ref(pic, var, 1));
if ((i = index_capture(state, name, 0)) != -1) {
cxt->code[cxt->clen].insn = OP_LSET;
cxt->code[cxt->clen].u.i = i + cxt->args.size + cxt->locals.size + 1;
cxt->code[cxt->clen].u.i = i + xv_size(&cxt->args) + xv_size(&cxt->locals) + 1;
cxt->clen++;
cxt->code[cxt->clen].insn = OP_PUSHNONE;
cxt->clen++;

View File

@ -2,40 +2,52 @@
#define XVECT_H__
/*
* Copyright (c) 2014 by Yuichi Nishiwaki <yuichi@idyll.jp>
* Copyright (c) 2014 by Yuichi Nishiwaki <yuichi@idylls.jp>
*/
#if defined(__cplusplus)
extern "C" {
#endif
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef struct xvect {
char *data;
size_t size, capa, width;
size_t size, mask, head, tail, width;
} xvect;
static inline void xv_init(xvect *, size_t);
static inline void xv_destroy(xvect *);
static inline size_t xv_size(xvect *);
static inline void xv_reserve(xvect *, size_t);
static inline void xv_shrink(xvect *, size_t);
static inline void *xv_get(xvect *, size_t);
static inline void xv_set(xvect *, size_t, void *);
static inline void xv_push(xvect *, void *);
static inline void *xv_peek(xvect *);
static inline void *xv_pop(xvect *);
static inline void *xv_shift(xvect *);
static inline void xv_unshift(xvect *, void *);
static inline void xv_splice(xvect *, size_t, size_t);
static inline void xv_insert(xvect *, size_t, void *);
static inline void
xv_init(xvect *x, size_t width)
{
x->data = NULL;
x->size = 0;
x->capa = 0;
x->width = width;
x->size = 0;
x->mask = -1;
x->head = 0;
x->tail = 0;
}
static inline void
@ -44,44 +56,148 @@ xv_destroy(xvect *x)
free(x->data);
}
static inline void
xv_reserve(xvect *x, size_t newcapa)
static inline size_t
xv_size(xvect *x)
{
x->data = realloc(x->data, newcapa * x->width);
x->capa = newcapa;
return x->tail < x->head
? x->tail + x->size - x->head
: x->tail - x->head;
}
static inline size_t
xv_round2(size_t x)
{
x -= 1;
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
x |= (x >> 32);
x++;
return x;
}
static inline void
xv_rotate(xvect *x)
{
if (x->tail < x->head) {
char buf[x->size * x->width];
/* perform rotation */
memcpy(buf, x->data, sizeof buf);
memcpy(x->data, buf + x->head * x->width, (x->size - x->head) * x->width);
memcpy(x->data + (x->size - x->head) * x->width, buf, x->tail * x->width);
x->tail = x->size - x->head + x->tail;
x->head = 0;
}
}
static inline void
xv_adjust(xvect *x, size_t size)
{
size = xv_round2(size);
if (size != x->size) {
xv_rotate(x);
x->data = realloc(x->data, size * x->width);
x->size = size;
x->mask = size - 1;
}
}
static inline void
xv_reserve(xvect *x, size_t mincapa)
{
if (x->size < mincapa + 1) {
xv_adjust(x, mincapa + 1); /* capa == size - 1 */
}
}
static inline void
xv_shrink(xvect *x, size_t maxcapa)
{
if (x->size > maxcapa + 1) {
xv_adjust(x, maxcapa + 1); /* capa == size - 1 */
}
}
static inline void *
xv_get(xvect *x, size_t i)
{
return x->data + i * x->width;
assert(i < xv_size(x));
return x->data + ((x->head + i) & x->mask) * x->width;
}
static inline void
xv_set(xvect *x, size_t i, void *src)
{
memcpy(x->data + i * x->width, src, x->width);
memcpy(xv_get(x, i), src, x->width);
}
static inline void
xv_push(xvect *x, void *src)
{
if (x->capa <= x->size + 1) {
xv_reserve(x, x->size * 2 + 1);
}
xv_set(x, x->size++, src);
}
static inline void *
xv_peek(xvect *x)
{
return xv_get(x, x->size);
xv_reserve(x, xv_size(x) + 1);
x->tail = (x->tail + 1) & x->mask;
xv_set(x, xv_size(x) - 1, src);
}
static inline void *
xv_pop(xvect *x)
{
return xv_get(x, --x->size);
void *dat;
assert(xv_size(x) >= 1);
dat = xv_get(x, xv_size(x) - 1);
x->tail = (x->tail - 1) & x->mask;
return dat;
}
static inline void *
xv_shift(xvect *x)
{
void *dat;
assert(xv_size(x) >= 1);
dat = xv_get(x, 0);
x->head = (x->head + 1) & x->mask;
return dat;
}
static inline void
xv_unshift(xvect *x, void *src)
{
xv_reserve(x, xv_size(x) + 1);
x->head = (x->head - 1) & x->mask;
xv_set(x, 0, src);
}
static inline void
xv_splice(xvect *x, size_t i, size_t j)
{
assert(i <= j && j < xv_size(x));
xv_rotate(x);
memmove(xv_get(x, i), xv_get(x, j), (xv_size(x) - j) * x->width);
x->tail = (x->tail - j + i) & x->mask;
}
static inline void
xv_insert(xvect *x, size_t i, void *src)
{
assert(i <= xv_size(x));
xv_reserve(x, xv_size(x) + 1);
xv_rotate(x);
x->tail = (x->tail + 1) & x->mask;
if (xv_size(x) - 1 != i) {
memmove(xv_get(x, i + 1), xv_get(x, i), (xv_size(x) - 1 - i) * x->width);
}
xv_set(x, i, src);
}
#if defined(__cplusplus)