upgrade xvect.h
This commit is contained in:
parent
b20a97ed9f
commit
09e56c2c35
38
codegen.c
38
codegen.c
|
@ -198,13 +198,13 @@ lookup_scope(analyze_scope *scope, pic_sym sym)
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* args */
|
/* args */
|
||||||
for (i = 0; i < scope->args.size; ++i) {
|
for (i = 0; i < xv_size(&scope->args); ++i) {
|
||||||
arg = xv_get(&scope->args, i);
|
arg = xv_get(&scope->args, i);
|
||||||
if (*arg == sym)
|
if (*arg == sym)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* locals */
|
/* locals */
|
||||||
for (i = 0; i < scope->locals.size; ++i) {
|
for (i = 0; i < xv_size(&scope->locals); ++i) {
|
||||||
local = xv_get(&scope->locals, i);
|
local = xv_get(&scope->locals, i);
|
||||||
if (*local == sym)
|
if (*local == sym)
|
||||||
return true;
|
return true;
|
||||||
|
@ -218,13 +218,13 @@ capture_var(analyze_scope *scope, pic_sym sym)
|
||||||
pic_sym *var;
|
pic_sym *var;
|
||||||
size_t i;
|
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);
|
var = xv_get(&scope->captures, i);
|
||||||
if (*var == sym) {
|
if (*var == sym) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == scope->captures.size) {
|
if (i == xv_size(&scope->captures)) {
|
||||||
xv_push(&scope->captures, &sym);
|
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;
|
size_t i;
|
||||||
|
|
||||||
args = pic_nil_value();
|
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);
|
var = xv_get(&scope->args, i - 1);
|
||||||
pic_push(pic, pic_sym_value(*var), args);
|
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);
|
analyze_deferred(state);
|
||||||
|
|
||||||
locals = pic_nil_value();
|
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);
|
var = xv_get(&scope->locals, i - 1);
|
||||||
pic_push(pic, pic_sym_value(*var), locals);
|
pic_push(pic, pic_sym_value(*var), locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
captures = pic_nil_value();
|
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);
|
var = xv_get(&scope->captures, i - 1);
|
||||||
pic_push(pic, pic_sym_value(*var), captures);
|
pic_push(pic, pic_sym_value(*var), captures);
|
||||||
}
|
}
|
||||||
|
@ -940,21 +940,21 @@ create_activation(codegen_context *cxt)
|
||||||
xh_init_int(®s, sizeof(size_t));
|
xh_init_int(®s, sizeof(size_t));
|
||||||
|
|
||||||
offset = 1;
|
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);
|
var = xv_get(&cxt->args, i);
|
||||||
n = i + offset;
|
n = i + offset;
|
||||||
xh_put_int(®s, *var, &n);
|
xh_put_int(®s, *var, &n);
|
||||||
}
|
}
|
||||||
offset += i;
|
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);
|
var = xv_get(&cxt->locals, i);
|
||||||
n = i + offset;
|
n = i + offset;
|
||||||
xh_put_int(®s, *var, &n);
|
xh_put_int(®s, *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);
|
var = xv_get(&cxt->captures, i);
|
||||||
if ((n = xh_val(xh_get_int(®s, *var), size_t)) <= cxt->args.size || (cxt->varg && n == cxt->args.size + 1)) {
|
if ((n = xh_val(xh_get_int(®s, *var), size_t)) <= xv_size(&cxt->args) || (cxt->varg && n == xv_size(&cxt->args) + 1)) {
|
||||||
/* copy arguments to capture variable area */
|
/* copy arguments to capture variable area */
|
||||||
cxt->code[cxt->clen].insn = OP_LREF;
|
cxt->code[cxt->clen].insn = OP_LREF;
|
||||||
cxt->code[cxt->clen].u.i = n;
|
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 = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
|
||||||
irep->name = state->cxt->name;
|
irep->name = state->cxt->name;
|
||||||
irep->varg = state->cxt->varg;
|
irep->varg = state->cxt->varg;
|
||||||
irep->argc = state->cxt->args.size + 1;
|
irep->argc = xv_size(&state->cxt->args) + 1;
|
||||||
irep->localc = state->cxt->locals.size;
|
irep->localc = xv_size(&state->cxt->locals);
|
||||||
irep->capturec = state->cxt->captures.size;
|
irep->capturec = xv_size(&state->cxt->captures);
|
||||||
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
|
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
|
||||||
irep->clen = state->cxt->clen;
|
irep->clen = state->cxt->clen;
|
||||||
irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen);
|
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;
|
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);
|
var = xv_get(&cxt->captures, i);
|
||||||
if (*var == sym)
|
if (*var == sym)
|
||||||
return i;
|
return i;
|
||||||
|
@ -1081,13 +1081,13 @@ index_local(codegen_state *state, pic_sym sym)
|
||||||
pic_sym *var;
|
pic_sym *var;
|
||||||
|
|
||||||
offset = 1;
|
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);
|
var = xv_get(&cxt->args, i);
|
||||||
if (*var == sym)
|
if (*var == sym)
|
||||||
return i + offset;
|
return i + offset;
|
||||||
}
|
}
|
||||||
offset += i;
|
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);
|
var = xv_get(&cxt->locals, i);
|
||||||
if (*var == sym)
|
if (*var == sym)
|
||||||
return i + offset;
|
return i + offset;
|
||||||
|
@ -1128,7 +1128,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
name = pic_sym(pic_list_ref(pic, obj, 1));
|
name = pic_sym(pic_list_ref(pic, obj, 1));
|
||||||
if ((i = index_capture(state, name, 0)) != -1) {
|
if ((i = index_capture(state, name, 0)) != -1) {
|
||||||
cxt->code[cxt->clen].insn = OP_LREF;
|
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++;
|
cxt->clen++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1174,7 +1174,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
name = pic_sym(pic_list_ref(pic, var, 1));
|
name = pic_sym(pic_list_ref(pic, var, 1));
|
||||||
if ((i = index_capture(state, name, 0)) != -1) {
|
if ((i = index_capture(state, name, 0)) != -1) {
|
||||||
cxt->code[cxt->clen].insn = OP_LSET;
|
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->clen++;
|
||||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
||||||
cxt->clen++;
|
cxt->clen++;
|
||||||
|
|
|
@ -2,40 +2,52 @@
|
||||||
#define XVECT_H__
|
#define XVECT_H__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 by Yuichi Nishiwaki <yuichi@idyll.jp>
|
* Copyright (c) 2014 by Yuichi Nishiwaki <yuichi@idylls.jp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
typedef struct xvect {
|
typedef struct xvect {
|
||||||
char *data;
|
char *data;
|
||||||
size_t size, capa, width;
|
size_t size, mask, head, tail, width;
|
||||||
} xvect;
|
} xvect;
|
||||||
|
|
||||||
static inline void xv_init(xvect *, size_t);
|
static inline void xv_init(xvect *, size_t);
|
||||||
static inline void xv_destroy(xvect *);
|
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_reserve(xvect *, size_t);
|
||||||
|
static inline void xv_shrink(xvect *, size_t);
|
||||||
|
|
||||||
static inline void *xv_get(xvect *, size_t);
|
static inline void *xv_get(xvect *, size_t);
|
||||||
static inline void xv_set(xvect *, size_t, void *);
|
static inline void xv_set(xvect *, size_t, void *);
|
||||||
|
|
||||||
static inline void xv_push(xvect *, void *);
|
static inline void xv_push(xvect *, void *);
|
||||||
static inline void *xv_peek(xvect *);
|
|
||||||
static inline void *xv_pop(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
|
static inline void
|
||||||
xv_init(xvect *x, size_t width)
|
xv_init(xvect *x, size_t width)
|
||||||
{
|
{
|
||||||
x->data = NULL;
|
x->data = NULL;
|
||||||
x->size = 0;
|
|
||||||
x->capa = 0;
|
|
||||||
x->width = width;
|
x->width = width;
|
||||||
|
x->size = 0;
|
||||||
|
x->mask = -1;
|
||||||
|
x->head = 0;
|
||||||
|
x->tail = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -44,44 +56,148 @@ xv_destroy(xvect *x)
|
||||||
free(x->data);
|
free(x->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline size_t
|
||||||
xv_reserve(xvect *x, size_t newcapa)
|
xv_size(xvect *x)
|
||||||
{
|
{
|
||||||
x->data = realloc(x->data, newcapa * x->width);
|
return x->tail < x->head
|
||||||
x->capa = newcapa;
|
? 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 *
|
static inline void *
|
||||||
xv_get(xvect *x, size_t i)
|
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
|
static inline void
|
||||||
xv_set(xvect *x, size_t i, void *src)
|
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
|
static inline void
|
||||||
xv_push(xvect *x, void *src)
|
xv_push(xvect *x, void *src)
|
||||||
{
|
{
|
||||||
if (x->capa <= x->size + 1) {
|
xv_reserve(x, xv_size(x) + 1);
|
||||||
xv_reserve(x, x->size * 2 + 1);
|
x->tail = (x->tail + 1) & x->mask;
|
||||||
}
|
xv_set(x, xv_size(x) - 1, src);
|
||||||
xv_set(x, x->size++, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
xv_peek(xvect *x)
|
|
||||||
{
|
|
||||||
return xv_get(x, x->size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
xv_pop(xvect *x)
|
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)
|
#if defined(__cplusplus)
|
||||||
|
|
Loading…
Reference in New Issue