qse/ase/lsp/mem.c

645 lines
15 KiB
C
Raw Normal View History

2005-09-18 11:34:35 +00:00
/*
2006-10-26 09:31:28 +00:00
* $Id: mem.c,v 1.16 2006-10-26 09:31:28 bacon Exp $
2005-09-18 11:34:35 +00:00
*/
2006-10-24 04:22:40 +00:00
#include <ase/lsp/lsp_i.h>
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
ase_lsp_mem_t* ase_lsp_openmem (
ase_lsp_t* lsp, ase_size_t ubound, ase_size_t ubound_inc)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem;
ase_size_t i;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* allocate memory */
mem = (ase_lsp_mem_t*) ASE_LSP_MALLOC (lsp, ase_sizeof(ase_lsp_mem_t));
2006-10-24 04:22:40 +00:00
if (mem == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
ASE_LSP_MEMSET (lsp, mem, 0, ase_sizeof(ase_lsp_mem_t));
mem->lsp = lsp;
/* create a new root environment frame */
2006-10-26 08:17:38 +00:00
mem->frame = ase_lsp_newframe (lsp);
2006-10-24 15:31:35 +00:00
if (mem->frame == ASE_NULL)
{
ASE_LSP_FREE (lsp, mem);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
mem->root_frame = mem->frame;
2006-10-24 04:22:40 +00:00
mem->brooding_frame = ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* create an array to hold temporary objects */
2006-10-26 08:17:38 +00:00
/*
mem->temp_arr = ase_lsp_arr_new (512);
if (mem->temp_arr == ASE_NULL)
2006-10-24 15:31:35 +00:00
{
2006-10-26 08:17:38 +00:00
ase_lsp_freeframe (lsp, mem->frame);
2006-10-24 15:31:35 +00:00
ASE_LSP_FREE (lsp, mem);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
2006-10-26 08:17:38 +00:00
*/
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* initialize object allocation list */
2005-09-18 11:34:35 +00:00
mem->ubound = ubound;
mem->ubound_inc = ubound_inc;
mem->count = 0;
2006-10-24 15:31:35 +00:00
for (i = 0; i < ASE_LSP_TYPE_COUNT; i++)
{
2006-10-24 04:22:40 +00:00
mem->used[i] = ASE_NULL;
mem->free[i] = ASE_NULL;
2005-09-18 11:34:35 +00:00
}
2006-10-24 04:22:40 +00:00
mem->locked = ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* when "ubound" is too small, the garbage collection can
* be performed while making the common objects. */
2006-10-24 04:22:40 +00:00
mem->nil = ASE_NULL;
mem->t = ASE_NULL;
mem->quote = ASE_NULL;
mem->lambda = ASE_NULL;
mem->macro = ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* initialize common object pointers */
2006-10-25 13:42:31 +00:00
mem->nil = ase_lsp_makenil (mem);
mem->t = ase_lsp_maketrue (mem);
mem->quote = ase_lsp_makesymobj (mem, ASE_T("quote"), 5);
mem->lambda = ase_lsp_makesymobj (mem, ASE_T("lambda"), 6);
mem->macro = ase_lsp_makesymobj (mem, ASE_T("macro"), 5);
2006-10-24 04:22:40 +00:00
if (mem->nil == ASE_NULL ||
mem->t == ASE_NULL ||
mem->quote == ASE_NULL ||
mem->lambda == ASE_NULL ||
2006-10-24 15:31:35 +00:00
mem->macro == ASE_NULL)
{
2006-10-24 04:22:40 +00:00
ase_lsp_dispose_all (mem);
2006-10-26 08:17:38 +00:00
/*ase_lsp_arr_free (mem->temp_arr);*/
ase_lsp_freeframe (lsp, mem->frame);
2006-10-24 15:31:35 +00:00
ASE_LSP_FREE (lsp, mem);
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
return mem;
}
2006-10-24 15:31:35 +00:00
void ase_lsp_closemem (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 15:31:35 +00:00
/* dispose of the allocated objects */
2006-10-24 04:22:40 +00:00
ase_lsp_dispose_all (mem);
2005-09-18 11:34:35 +00:00
2006-10-26 08:17:38 +00:00
/* dispose of the temporary object arrs */
/*ase_lsp_arr_free (mem->temp_arr);*/
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* dispose of environment frames */
2006-10-26 08:17:38 +00:00
ase_lsp_freeframe (mem->lsp, mem->frame);
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
/* free the memory */
ASE_LSP_FREE (mem->lsp, mem);
2005-09-18 11:34:35 +00:00
}
2006-10-24 04:22:40 +00:00
static int __add_prim (ase_lsp_mem_t* mem,
const ase_char_t* name, ase_size_t len, ase_lsp_prim_t prim)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* n, * p;
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
n = ase_lsp_makesymobj (mem, name, len);
2006-10-24 04:22:40 +00:00
if (n == ASE_NULL) return -1;
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
ase_lsp_lockobj (mem->lsp, n);
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
p = ase_lsp_makeprim (mem, prim);
2006-10-24 04:22:40 +00:00
if (p == ASE_NULL) return -1;
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
ase_lsp_unlockobj (mem->lsp, n);
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
if (ase_lsp_setfunc(mem, n, p) == ASE_NULL) return -1;
2005-09-18 11:34:35 +00:00
return 0;
}
2006-10-24 04:22:40 +00:00
int ase_lsp_add_builtin_prims (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
#define ADD_PRIM(mem,name,len,prim) \
2005-09-19 03:05:37 +00:00
if (__add_prim(mem,name,len,prim) == -1) return -1;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ADD_PRIM (mem, ASE_T("abort"), 5, ase_lsp_prim_abort);
ADD_PRIM (mem, ASE_T("eval"), 4, ase_lsp_prim_eval);
ADD_PRIM (mem, ASE_T("prog1"), 5, ase_lsp_prim_prog1);
ADD_PRIM (mem, ASE_T("progn"), 5, ase_lsp_prim_progn);
ADD_PRIM (mem, ASE_T("gc"), 2, ase_lsp_prim_gc);
ADD_PRIM (mem, ASE_T("cond"), 4, ase_lsp_prim_cond);
ADD_PRIM (mem, ASE_T("if"), 2, ase_lsp_prim_if);
ADD_PRIM (mem, ASE_T("while"), 5, ase_lsp_prim_while);
ADD_PRIM (mem, ASE_T("car"), 3, ase_lsp_prim_car);
ADD_PRIM (mem, ASE_T("cdr"), 3, ase_lsp_prim_cdr);
ADD_PRIM (mem, ASE_T("cons"), 4, ase_lsp_prim_cons);
ADD_PRIM (mem, ASE_T("set"), 3, ase_lsp_prim_set);
ADD_PRIM (mem, ASE_T("setq"), 4, ase_lsp_prim_setq);
ADD_PRIM (mem, ASE_T("quote"), 5, ase_lsp_prim_quote);
ADD_PRIM (mem, ASE_T("defun"), 5, ase_lsp_prim_defun);
ADD_PRIM (mem, ASE_T("demac"), 5, ase_lsp_prim_demac);
ADD_PRIM (mem, ASE_T("let"), 3, ase_lsp_prim_let);
ADD_PRIM (mem, ASE_T("let*"), 4, ase_lsp_prim_letx);
ADD_PRIM (mem, ASE_T(">"), 1, ase_lsp_prim_gt);
ADD_PRIM (mem, ASE_T("<"), 1, ase_lsp_prim_lt);
ADD_PRIM (mem, ASE_T("+"), 1, ase_lsp_prim_plus);
ADD_PRIM (mem, ASE_T("-"), 1, ase_lsp_prim_minus);
2005-09-20 08:05:32 +00:00
2005-09-18 11:34:35 +00:00
return 0;
}
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* ase_lsp_alloc (ase_lsp_mem_t* mem, int type, ase_size_t size)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
if (mem->count >= mem->ubound) ase_lsp_collectgarbage (mem);
2005-09-18 11:34:35 +00:00
if (mem->count >= mem->ubound) {
mem->ubound += mem->ubound_inc;
2006-10-24 04:22:40 +00:00
if (mem->count >= mem->ubound) return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
2006-10-25 13:42:31 +00:00
obj = (ase_lsp_obj_t*) ASE_LSP_MALLOC (mem->lsp, size);
if (obj == ASE_NULL)
{
2006-10-24 15:31:35 +00:00
ase_lsp_collectgarbage (mem);
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
obj = (ase_lsp_obj_t*) ASE_LSP_MALLOC (mem->lsp, size);
2006-10-24 04:22:40 +00:00
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
2006-10-24 04:22:40 +00:00
ASE_LSP_TYPE(obj) = type;
ASE_LSP_SIZE(obj) = size;
ASE_LSP_MARK(obj) = 0;
ASE_LSP_LOCK(obj) = 0;
2005-09-18 11:34:35 +00:00
2006-10-26 08:17:38 +00:00
/* insert the object at the head of the used list */
2006-10-24 04:22:40 +00:00
ASE_LSP_LINK(obj) = mem->used[type];
2005-09-18 11:34:35 +00:00
mem->used[type] = obj;
mem->count++;
2005-09-19 12:04:00 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint1 (ASE_T("mem->count: %u\n"), mem->count);
2005-09-19 12:04:00 +00:00
#endif
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-24 15:31:35 +00:00
void ase_lsp_dispose (
ase_lsp_mem_t* mem, ase_lsp_obj_t* prev, ase_lsp_obj_t* obj)
2005-09-18 11:34:35 +00:00
{
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (mem->lsp, obj != ASE_NULL);
ASE_LSP_ASSERT (mem->lsp, mem->count > 0);
2005-09-18 11:34:35 +00:00
// TODO: push the object to the free list for more
// efficient memory management
2006-10-24 04:22:40 +00:00
if (prev == ASE_NULL)
mem->used[ASE_LSP_TYPE(obj)] = ASE_LSP_LINK(obj);
else ASE_LSP_LINK(prev) = ASE_LSP_LINK(obj);
2005-09-18 11:34:35 +00:00
mem->count--;
2005-09-20 11:19:15 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint1 (ASE_T("mem->count: %u\n"), mem->count);
2005-09-20 11:19:15 +00:00
#endif
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
ASE_LSP_FREE (mem->lsp, obj);
2005-09-18 11:34:35 +00:00
}
2006-10-24 04:22:40 +00:00
void ase_lsp_dispose_all (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj, * next;
ase_size_t i;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
for (i = 0; i < ASE_LSP_TYPE_COUNT; i++)
{
2005-09-18 11:34:35 +00:00
obj = mem->used[i];
2006-10-24 15:31:35 +00:00
while (obj != ASE_NULL)
{
2006-10-24 04:22:40 +00:00
next = ASE_LSP_LINK(obj);
ase_lsp_dispose (mem, ASE_NULL, obj);
2005-09-18 11:34:35 +00:00
obj = next;
}
}
}
2006-10-25 13:42:31 +00:00
static void __mark_obj (ase_lsp_t* lsp, ase_lsp_obj_t* obj)
2005-09-18 11:34:35 +00:00
{
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (lsp, obj != ASE_NULL);
2005-09-18 11:34:35 +00:00
// TODO:....
// can it be recursive?
2006-10-24 04:22:40 +00:00
if (ASE_LSP_MARK(obj) != 0) return;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_MARK(obj) = 1;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
if (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_CONS)
{
2006-10-25 13:42:31 +00:00
__mark_obj (lsp, ASE_LSP_CAR(obj));
__mark_obj (lsp, ASE_LSP_CDR(obj));
2005-09-18 11:34:35 +00:00
}
2006-10-24 15:31:35 +00:00
else if (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_FUNC)
{
2006-10-25 13:42:31 +00:00
__mark_obj (lsp, ASE_LSP_FFORMAL(obj));
__mark_obj (lsp, ASE_LSP_FBODY(obj));
2005-09-18 11:34:35 +00:00
}
2006-10-24 15:31:35 +00:00
else if (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_MACRO)
{
2006-10-25 13:42:31 +00:00
__mark_obj (lsp, ASE_LSP_MFORMAL(obj));
__mark_obj (lsp, ASE_LSP_MBODY(obj));
2005-09-18 11:34:35 +00:00
}
}
/*
2006-10-25 13:42:31 +00:00
* ase_lsp_lockobj and ase_lsp_unlockallobjs are just called by ase_lsp_read.
2005-09-18 11:34:35 +00:00
*/
2006-10-25 13:42:31 +00:00
void ase_lsp_lockobj (ase_lsp_t* lsp, ase_lsp_obj_t* obj)
2005-09-18 11:34:35 +00:00
{
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (lsp, obj != ASE_NULL);
2006-10-24 04:22:40 +00:00
ASE_LSP_LOCK(obj) = 1;
//ASE_LSP_MARK(obj) = 1;
2005-09-18 11:34:35 +00:00
}
2006-10-25 13:42:31 +00:00
void ase_lsp_unlockobj (ase_lsp_t* lsp, ase_lsp_obj_t* obj)
2005-09-18 11:34:35 +00:00
{
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (lsp, obj != ASE_NULL);
2006-10-24 04:22:40 +00:00
ASE_LSP_LOCK(obj) = 0;
2005-09-18 11:34:35 +00:00
}
2006-10-25 13:42:31 +00:00
void ase_lsp_unlockallobjs (ase_lsp_t* lsp, ase_lsp_obj_t* obj)
2005-09-18 11:34:35 +00:00
{
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (lsp, obj != ASE_NULL);
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_LOCK(obj) = 0;
2005-09-18 11:34:35 +00:00
2006-10-24 15:31:35 +00:00
if (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_CONS)
{
2006-10-25 13:42:31 +00:00
ase_lsp_unlockallobjs (lsp, ASE_LSP_CAR(obj));
ase_lsp_unlockallobjs (lsp, ASE_LSP_CDR(obj));
2005-09-18 11:34:35 +00:00
}
2006-10-24 15:31:35 +00:00
else if (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_FUNC)
{
2006-10-25 13:42:31 +00:00
ase_lsp_unlockallobjs (lsp, ASE_LSP_FFORMAL(obj));
ase_lsp_unlockallobjs (lsp, ASE_LSP_FBODY(obj));
2005-09-18 11:34:35 +00:00
}
2006-10-24 15:31:35 +00:00
else if (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_MACRO)
{
2006-10-25 13:42:31 +00:00
ase_lsp_unlockallobjs (lsp, ASE_LSP_MFORMAL(obj));
ase_lsp_unlockallobjs (lsp, ASE_LSP_MBODY(obj));
2005-09-18 11:34:35 +00:00
}
}
2006-10-24 15:31:35 +00:00
static void ase_lsp_markobjsinuse (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_frame_t* frame;
ase_lsp_assoc_t* assoc;
2006-10-26 08:17:38 +00:00
/*ase_lsp_arr_t* arr;*/
/*ase_size_t i;*/
2005-09-18 11:34:35 +00:00
2005-09-20 11:19:15 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint0 (ASE_T("marking environment frames\n"));
2005-09-20 11:19:15 +00:00
#endif
2006-10-24 15:31:35 +00:00
/* mark objects in the environment frames */
2005-09-18 11:34:35 +00:00
frame = mem->frame;
2006-10-24 15:31:35 +00:00
while (frame != ASE_NULL)
{
2005-09-18 11:34:35 +00:00
assoc = frame->assoc;
2006-10-24 15:31:35 +00:00
while (assoc != ASE_NULL)
{
2006-10-25 13:42:31 +00:00
__mark_obj (mem->lsp, assoc->name);
2005-09-20 11:19:15 +00:00
2006-10-24 04:22:40 +00:00
if (assoc->value != ASE_NULL)
2006-10-25 13:42:31 +00:00
__mark_obj (mem->lsp, assoc->value);
2006-10-24 04:22:40 +00:00
if (assoc->func != ASE_NULL)
2006-10-25 13:42:31 +00:00
__mark_obj (mem->lsp, assoc->func);
2005-09-20 11:19:15 +00:00
2005-09-18 11:34:35 +00:00
assoc = assoc->link;
}
frame = frame->link;
}
2005-09-20 11:19:15 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint0 (ASE_T("marking interim frames\n"));
2005-09-20 11:19:15 +00:00
#endif
2005-09-18 11:34:35 +00:00
// mark objects in the interim frames
frame = mem->brooding_frame;
2006-10-24 04:22:40 +00:00
while (frame != ASE_NULL) {
2005-09-18 11:34:35 +00:00
assoc = frame->assoc;
2006-10-24 04:22:40 +00:00
while (assoc != ASE_NULL) {
2006-10-25 13:42:31 +00:00
__mark_obj (mem->lsp, assoc->name);
2005-09-20 11:19:15 +00:00
2006-10-24 04:22:40 +00:00
if (assoc->value != ASE_NULL)
2006-10-25 13:42:31 +00:00
__mark_obj (mem->lsp, assoc->value);
2006-10-24 04:22:40 +00:00
if (assoc->func != ASE_NULL)
2006-10-25 13:42:31 +00:00
__mark_obj (mem->lsp, assoc->func);
2005-09-20 11:19:15 +00:00
2005-09-18 11:34:35 +00:00
assoc = assoc->link;
}
frame = frame->link;
}
/*
2006-10-24 04:22:40 +00:00
ase_dprint0 (ASE_T("marking the locked object\n"));
2006-10-25 13:42:31 +00:00
if (mem->locked != ASE_NULL) __mark_obj (mem->lsp, mem->locked);
2005-09-18 11:34:35 +00:00
*/
2005-09-20 11:19:15 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint0 (ASE_T("marking termporary objects\n"));
2005-09-20 11:19:15 +00:00
#endif
2006-10-26 08:17:38 +00:00
/*
arr = mem->temp_arr;
for (i = 0; i < arr->size; i++)
2006-10-25 13:42:31 +00:00
{
2006-10-26 08:17:38 +00:00
__mark_obj (mem->lsp, arr->buffer[i]);
2005-09-18 11:34:35 +00:00
}
2006-10-26 08:17:38 +00:00
*/
2005-09-18 11:34:35 +00:00
2005-09-20 11:19:15 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint0 (ASE_T("marking builtin objects\n"));
2005-09-20 11:19:15 +00:00
#endif
2005-09-18 11:34:35 +00:00
// mark common objects
2006-10-25 13:42:31 +00:00
if (mem->t != ASE_NULL) __mark_obj (mem->lsp, mem->t);
if (mem->nil != ASE_NULL) __mark_obj (mem->lsp, mem->nil);
if (mem->quote != ASE_NULL) __mark_obj (mem->lsp, mem->quote);
if (mem->lambda != ASE_NULL) __mark_obj (mem->lsp, mem->lambda);
if (mem->macro != ASE_NULL) __mark_obj (mem->lsp, mem->macro);
2005-09-18 11:34:35 +00:00
}
2006-10-24 15:31:35 +00:00
static void ase_lsp_sweepunmarkedobjs (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj, * prev, * next;
ase_size_t i;
2005-09-18 11:34:35 +00:00
// scan all the allocated objects and get rid of unused objects
2006-10-24 04:22:40 +00:00
for (i = 0; i < ASE_LSP_TYPE_COUNT; i++) {
//for (i = ASE_LSP_TYPE_COUNT; i > 0; /*i--*/) {
prev = ASE_NULL;
2005-09-18 11:34:35 +00:00
obj = mem->used[i];
//obj = mem->used[--i];
2005-09-20 11:19:15 +00:00
#if 0
2006-10-24 04:22:40 +00:00
ase_dprint1 (ASE_T("sweeping objects of type: %u\n"), i);
2005-09-20 11:19:15 +00:00
#endif
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
while (obj != ASE_NULL) {
next = ASE_LSP_LINK(obj);
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
if (ASE_LSP_LOCK(obj) == 0 && ASE_LSP_MARK(obj) == 0) {
2005-09-18 11:34:35 +00:00
// dispose of unused objects
2006-10-24 04:22:40 +00:00
ase_lsp_dispose (mem, prev, obj);
2005-09-18 11:34:35 +00:00
}
else {
// unmark the object in use
2006-10-24 04:22:40 +00:00
ASE_LSP_MARK(obj) = 0;
2005-09-18 11:34:35 +00:00
prev = obj;
}
obj = next;
}
}
}
2006-10-24 15:31:35 +00:00
void ase_lsp_collectgarbage (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 15:31:35 +00:00
ase_lsp_markobjsinuse (mem);
ase_lsp_sweepunmarkedobjs (mem);
2005-09-18 11:34:35 +00:00
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makenil (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
if (mem->nil != ASE_NULL) return mem->nil;
2006-10-25 13:42:31 +00:00
mem->nil = ase_lsp_alloc (
mem, ASE_LSP_OBJ_NIL, ase_sizeof(ase_lsp_obj_nil_t));
2005-09-18 11:34:35 +00:00
return mem->nil;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_maketrue (ase_lsp_mem_t* mem)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
if (mem->t != ASE_NULL) return mem->t;
2006-10-25 13:42:31 +00:00
mem->t = ase_lsp_alloc (
mem, ASE_LSP_OBJ_TRUE, ase_sizeof(ase_lsp_obj_true_t));
2005-09-18 11:34:35 +00:00
return mem->t;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makeintobj (ase_lsp_mem_t* mem, ase_long_t value)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
obj = ase_lsp_alloc (mem,
ASE_LSP_OBJ_INT, ase_sizeof(ase_lsp_obj_int_t));
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_IVALUE(obj) = value;
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makerealobj (ase_lsp_mem_t* mem, ase_real_t value)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
obj = ase_lsp_alloc (mem,
ASE_LSP_OBJ_REAL, ase_sizeof(ase_lsp_obj_real_t));
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_RVALUE(obj) = value;
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makesymobj (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, const ase_char_t* str, ase_size_t len)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
// look for a sysmbol with the given name
2006-10-25 13:42:31 +00:00
obj = mem->used[ASE_LSP_OBJ_SYM];
while (obj != ASE_NULL)
{
2005-09-18 11:34:35 +00:00
// if there is a symbol with the same name, it is just used.
2006-10-25 13:42:31 +00:00
if (ase_lsp_strxncmp (
2006-10-26 08:17:38 +00:00
ASE_LSP_SYMPTR(obj),
2006-10-25 13:42:31 +00:00
ASE_LSP_SYMLEN(obj), str, len) == 0) return obj;
2006-10-24 04:22:40 +00:00
obj = ASE_LSP_LINK(obj);
2005-09-18 11:34:35 +00:00
}
// no such symbol found. create a new one
2006-10-25 13:42:31 +00:00
obj = ase_lsp_alloc (mem, ASE_LSP_OBJ_SYM,
ase_sizeof(ase_lsp_obj_sym_t)+(len + 1)*ase_sizeof(ase_char_t));
2006-10-24 04:22:40 +00:00
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
// fill in the symbol buffer
2006-10-26 08:17:38 +00:00
ase_lsp_strncpy (ASE_LSP_SYMPTR(obj), str, len);
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makestrobj (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, const ase_char_t* str, ase_size_t len)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
// allocate memory for the string
2006-10-25 13:42:31 +00:00
obj = ase_lsp_alloc (mem, ASE_LSP_OBJ_STR,
ase_sizeof(ase_lsp_obj_str_t)+(len + 1)*ase_sizeof(ase_char_t));
2006-10-24 04:22:40 +00:00
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
// fill in the string buffer
2006-10-26 08:17:38 +00:00
ase_lsp_strncpy (ASE_LSP_STRPTR(obj), str, len);
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makecons (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, ase_lsp_obj_t* car, ase_lsp_obj_t* cdr)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
obj = ase_lsp_alloc (mem, ASE_LSP_OBJ_CONS, ase_sizeof(ase_lsp_obj_cons_t));
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_CAR(obj) = car;
ASE_LSP_CDR(obj) = cdr;
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makefunc (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, ase_lsp_obj_t* formal, ase_lsp_obj_t* body)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
obj = ase_lsp_alloc (mem, ASE_LSP_OBJ_FUNC, ase_sizeof(ase_lsp_obj_func_t));
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_FFORMAL(obj) = formal;
ASE_LSP_FBODY(obj) = body;
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makemacro (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, ase_lsp_obj_t* formal, ase_lsp_obj_t* body)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
obj = ase_lsp_alloc (mem, ASE_LSP_OBJ_MACRO, ase_sizeof(ase_lsp_obj_macro_t));
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
ASE_LSP_MFORMAL(obj) = formal;
ASE_LSP_MBODY(obj) = body;
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-25 13:42:31 +00:00
ase_lsp_obj_t* ase_lsp_makeprim (ase_lsp_mem_t* mem, void* impl)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_obj_t* obj;
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
obj = ase_lsp_alloc (
mem, ASE_LSP_OBJ_PRIM, ase_sizeof(ase_lsp_obj_prim_t));
2006-10-24 04:22:40 +00:00
if (obj == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
/*ASE_LSP_PRIM(obj) = (ase_lsp_prim_t)impl;*/
((ase_lsp_obj_prim_t*)obj)->impl = impl;
2005-09-18 11:34:35 +00:00
return obj;
}
2006-10-24 04:22:40 +00:00
ase_lsp_assoc_t* ase_lsp_lookup (ase_lsp_mem_t* mem, ase_lsp_obj_t* name)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_frame_t* frame;
ase_lsp_assoc_t* assoc;
2005-09-18 11:34:35 +00:00
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (mem->lsp, ASE_LSP_TYPE(name) == ASE_LSP_OBJ_SYM);
2005-09-18 11:34:35 +00:00
frame = mem->frame;
2006-10-25 13:42:31 +00:00
while (frame != ASE_NULL)
{
2006-10-26 08:17:38 +00:00
assoc = ase_lsp_lookupinframe (mem->lsp, frame, name);
2006-10-24 04:22:40 +00:00
if (assoc != ASE_NULL) return assoc;
2005-09-18 11:34:35 +00:00
frame = frame->link;
}
2006-10-24 04:22:40 +00:00
return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
2006-10-25 13:42:31 +00:00
ase_lsp_assoc_t* ase_lsp_setvalue (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, ase_lsp_obj_t* name, ase_lsp_obj_t* value)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_assoc_t* assoc;
2005-09-18 11:34:35 +00:00
2006-10-24 04:22:40 +00:00
assoc = ase_lsp_lookup (mem, name);
2006-10-25 13:42:31 +00:00
if (assoc == ASE_NULL)
{
2006-10-26 08:17:38 +00:00
assoc = ase_lsp_insertvalueintoframe (
mem->lsp, mem->root_frame, name, value);
2006-10-24 04:22:40 +00:00
if (assoc == ASE_NULL) return ASE_NULL;
2005-09-18 11:34:35 +00:00
}
else assoc->value = value;
return assoc;
}
2006-10-25 13:42:31 +00:00
ase_lsp_assoc_t* ase_lsp_setfunc (
2006-10-24 04:22:40 +00:00
ase_lsp_mem_t* mem, ase_lsp_obj_t* name, ase_lsp_obj_t* func)
2005-09-20 09:17:06 +00:00
{
2006-10-24 04:22:40 +00:00
ase_lsp_assoc_t* assoc;
2005-09-20 09:17:06 +00:00
2006-10-24 04:22:40 +00:00
assoc = ase_lsp_lookup (mem, name);
2006-10-25 13:42:31 +00:00
if (assoc == ASE_NULL)
{
2006-10-26 08:17:38 +00:00
assoc = ase_lsp_insertfuncintoframe (
mem->lsp, mem->root_frame, name, func);
2006-10-24 04:22:40 +00:00
if (assoc == ASE_NULL) return ASE_NULL;
2005-09-20 09:17:06 +00:00
}
else assoc->func = func;
return assoc;
}
2006-10-24 04:22:40 +00:00
ase_size_t ase_lsp_cons_len (ase_lsp_mem_t* mem, ase_lsp_obj_t* obj)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_size_t count;
2005-09-18 11:34:35 +00:00
2006-10-26 09:31:28 +00:00
ASE_LSP_ASSERT (mem->lsp,
2006-10-25 13:42:31 +00:00
obj == mem->nil || ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_CONS);
2005-09-18 11:34:35 +00:00
count = 0;
//while (obj != mem->nil) {
2006-10-25 13:42:31 +00:00
while (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_CONS)
{
2005-09-18 11:34:35 +00:00
count++;
2006-10-24 04:22:40 +00:00
obj = ASE_LSP_CDR(obj);
2005-09-18 11:34:35 +00:00
}
return count;
}
2006-10-25 13:42:31 +00:00
int ase_lsp_probeargs (ase_lsp_mem_t* mem, ase_lsp_obj_t* obj, ase_size_t* len)
2005-09-18 11:34:35 +00:00
{
2006-10-24 04:22:40 +00:00
ase_size_t count = 0;
2005-09-18 11:34:35 +00:00
2006-10-25 13:42:31 +00:00
while (ASE_LSP_TYPE(obj) == ASE_LSP_OBJ_CONS)
{
2005-09-18 11:34:35 +00:00
count++;
2006-10-24 04:22:40 +00:00
obj = ASE_LSP_CDR(obj);
2005-09-18 11:34:35 +00:00
}
if (obj != mem->nil) return -1;
*len = count;
return 0;
}