You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
1.9 KiB
C

#ifndef linear_algebra_refstack_h
#define linear_algebra_refstack_h
#include <lua.h>
#include <lauxlib.h>
#define MAX_REF_STACK 128
struct ref_slot {
int stack_id;
int lua_id;
};
struct ref_stack {
int top;
int reftop;
lua_State *L;
struct ref_slot s[MAX_REF_STACK];
};
static inline void
refstack_init(struct ref_stack *RS, lua_State *L) {
RS->top = 0;
RS->reftop = 0;
RS->L = L;
}
static inline void
refstack_push(struct ref_stack *RS) {
++RS->top;
}
static inline void
refstack_pop(struct ref_stack *RS) {
--RS->top;
if (RS->reftop > 0) {
if (RS->s[RS->reftop-1].stack_id == RS->top) {
--RS->reftop;
}
}
}
static inline void
refstack_2_1(struct ref_stack *RS) {
refstack_pop(RS);
refstack_pop(RS);
refstack_push(RS);
}
static inline void
refstack_1_1(struct ref_stack *RS) {
refstack_pop(RS);
refstack_push(RS);
}
static inline void
refstack_pushref(struct ref_stack *RS, int lua_id) {
if (lua_id < 0) {
refstack_push(RS);
return;
}
if (RS->reftop >= MAX_REF_STACK)
luaL_error(RS->L, "ref stack overflow");
struct ref_slot *s = &RS->s[RS->reftop++];
s->stack_id = RS->top++;
s->lua_id = lua_id;
}
static inline int
refstack_topid(struct ref_stack *RS) {
if (RS->reftop > 0) {
struct ref_slot *s = &RS->s[RS->reftop-1];
if (s->stack_id == RS->top-1) {
return s->lua_id;
}
}
return -1;
}
static inline void
refstack_swap(struct ref_stack *RS) {
int top = refstack_topid(RS);
refstack_pop(RS);
int newtop = refstack_topid(RS);
refstack_pop(RS);
refstack_pushref(RS, top);
refstack_pushref(RS, newtop);
}
static inline void
refstack_dup(struct ref_stack *RS, int index) {
int i;
int lua_id = -1;
int stack_id = RS->top - index;
for (i=RS->reftop-1;i>=0;i--) {
struct ref_slot *s = &RS->s[i];
if (s->stack_id == stack_id) {
lua_id = s->lua_id;
break;
}
if (s->stack_id < stack_id)
break;
}
refstack_pushref(RS, lua_id);
}
#endif