still experimenting to find a good way to represent byte codes and literal frames in the interactive mode
This commit is contained in:
parent
b9ae46afff
commit
c7e87698d0
14
bin/main.c
14
bin/main.c
@ -822,7 +822,7 @@ static int handle_dbgopt (hcl_t* hcl, const hcl_bch_t* str)
|
||||
|
||||
cm = hcl_find_bchar_in_bcstr(flt, ',');
|
||||
len = cm? (cm - flt): hcl_count_bcstr(flt);
|
||||
if (hcl_comp_bchars_bcstr (flt, len, "gc") == 0) dbgopt |= HCL_DEBUG_GC;
|
||||
if (hcl_comp_bchars_bcstr (flt, len, "gc") == 0) dbgopt |= HCL_TRAIT_DEBUG_GC;
|
||||
else if (hcl_comp_bchars_bcstr (flt, len, "bigint") == 0) dbgopt |= HCL_DEBUG_BIGINT;
|
||||
else
|
||||
{
|
||||
@ -1082,8 +1082,8 @@ int main (int argc, char* argv[])
|
||||
{
|
||||
hcl_bitmask_t trait = 0;
|
||||
|
||||
/*trait |= HCL_NOGC;*/
|
||||
trait |= HCL_AWAIT_PROCS;
|
||||
/*trait |= HCL_TRAIT_NOGC;*/
|
||||
trait |= HCL_TRAIT_AWAIT_PROCS;
|
||||
hcl_setoption (hcl, HCL_TRAIT, &trait);
|
||||
|
||||
/* disable GC logs */
|
||||
@ -1160,6 +1160,14 @@ hcl_logufmt (hcl, HCL_LOG_WARN, fmt, ustr, 0x6789);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (xtn->reader_istty)
|
||||
{
|
||||
hcl_bitmask_t trait;
|
||||
hcl_getoption (hcl, HCL_TRAIT, &trait);
|
||||
trait |= HCL_TRAIT_INTERACTIVE;
|
||||
hcl_setoption (hcl, HCL_TRAIT, &trait);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
hcl_oop_t obj;
|
||||
|
109
lib/comp.c
109
lib/comp.c
@ -33,7 +33,7 @@ enum
|
||||
};
|
||||
|
||||
#define TV_BUFFER_ALIGN 256
|
||||
#define BLK_TMPRCNT_BUFFER_ALIGN 128
|
||||
#define BLK_INFO_BUFFER_ALIGN 128
|
||||
|
||||
#define EMIT_BYTE_INSTRUCTION(hcl,code) \
|
||||
do { if (emit_byte_instruction(hcl,code) <= -1) return -1; } while(0)
|
||||
@ -43,31 +43,26 @@ enum
|
||||
|
||||
/* --------------------------------------------
|
||||
|
||||
// literal frame is not fully a stack
|
||||
// new literal frame => current litera count + 1
|
||||
// back one new literal frame => current literal frame index - 1
|
||||
|
||||
<--- code/literal frame #0
|
||||
(defun plus(x y) <--- code/literal frame #1
|
||||
(defun plus(x y)
|
||||
(printf "plus %d %d\n" x y)
|
||||
(defun minus(x y) <--- code/literal frame #2
|
||||
(defun minus(x y)
|
||||
(printf "minus %d %d\n" x y)
|
||||
(- x y)
|
||||
)
|
||||
(+ x y) <--- code/literal frame #1
|
||||
(+ x y)
|
||||
)
|
||||
<--- code/literal frame #0
|
||||
|
||||
(defun dummy(q) <--- code/literal frame #3
|
||||
(defun dummy(q)
|
||||
(printf "%s\n" q)
|
||||
)
|
||||
<--- code/literal frame #0
|
||||
|
||||
(plus 10 20)
|
||||
<---- minus is now available
|
||||
|
||||
(minus 10 1)
|
||||
|
||||
literals -->
|
||||
//
|
||||
// characeter 'A'
|
||||
// "string"
|
||||
@ -78,67 +73,6 @@ enum
|
||||
|
||||
------------------------------ */
|
||||
|
||||
static int acquire_ccl (hcl_t* hcl)
|
||||
{
|
||||
hcl_ccl_t* ccl;
|
||||
|
||||
if (hcl->ccl.len >= hcl->ccl.capa)
|
||||
{
|
||||
hcl_ccl_t* tmp;
|
||||
|
||||
tmp = hcl_reallocmem(hcl, hcl->ccl.ptr, hcl->ccl.capa + 32);
|
||||
if (HCL_UNLIKELY(!tmp)) return -1;
|
||||
|
||||
hcl->ccl.capa += 32;
|
||||
}
|
||||
|
||||
ccl = &hcl->ccl.ptr[hcl->ccl.len];
|
||||
HCL_MEMSET (ccl, 0, SIZEOF(*ccl));
|
||||
ccl->pindex = hcl->ccl.index;
|
||||
hcl->ccl.index = hcl->ccl.len++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int release_ccl (hcl_t* hcl)
|
||||
{
|
||||
hcl->ccl.index = hcl->ccl.ptr[hcl->ccl.index].pindex;
|
||||
}
|
||||
|
||||
static void destroy_ccls (hcl_t* hcl)
|
||||
{
|
||||
while (hcl->ccl.len > 0)
|
||||
{
|
||||
hcl_ccl_t* ccl = &hcl->ccl.ptr[--hcl->ccl.len];
|
||||
|
||||
if (ccl->bc.ptr)
|
||||
{
|
||||
hcl_freemem (hcl, ccl->bc.ptr);
|
||||
ccl->bc.ptr = HCL_NULL;
|
||||
ccl->bc.capa = 0;
|
||||
ccl->bc.len = 0;
|
||||
}
|
||||
|
||||
if (ccl->lit.ptr)
|
||||
{
|
||||
while (ccl->lit.len > 0)
|
||||
{
|
||||
hcl_clv_t* clv = &ccl->lit.ptr[--ccl->lit.len];
|
||||
hcl_freemem (hcl, clv);
|
||||
}
|
||||
hcl_freemem (hcl, ccl->lit.ptr);
|
||||
ccl->lit.ptr = HCL_NULL;
|
||||
ccl->lit.capa = 0;
|
||||
ccl->lit.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hcl_freemem (hcl, hcl->ccl.ptr);
|
||||
hcl->ccl.ptr = HCL_NULL;
|
||||
hcl->ccl.capa = 0;
|
||||
hcl->ccl.len = 0;
|
||||
hcl->ccl.index = 0;
|
||||
}
|
||||
|
||||
static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index)
|
||||
{
|
||||
hcl_oow_t capa, i;
|
||||
@ -168,6 +102,8 @@ static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index)
|
||||
}
|
||||
|
||||
*index = hcl->code.lit.len;
|
||||
if (hcl->option.trait & HCL_TRAIT_INTERACTIVE) *index -= hcl->c->blk.info[hcl->c->blk.depth].litbase;
|
||||
|
||||
((hcl_oop_oop_t)hcl->code.lit.arr)->slot[hcl->code.lit.len++] = obj;
|
||||
return 0;
|
||||
}
|
||||
@ -225,24 +161,25 @@ static int find_temporary_variable_backward (hcl_t* hcl, hcl_oop_t name, hcl_oow
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_count)
|
||||
static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_count, hcl_oow_t lit_base)
|
||||
{
|
||||
HCL_ASSERT (hcl, hcl->c->blk.depth >= 0);
|
||||
|
||||
if (hcl->c->blk.depth >= hcl->c->blk.tmprcnt_capa)
|
||||
if (hcl->c->blk.depth >= hcl->c->blk.info_capa)
|
||||
{
|
||||
hcl_oow_t* tmp;
|
||||
hcl_blk_info_t* tmp;
|
||||
hcl_oow_t newcapa;
|
||||
|
||||
newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_TMPRCNT_BUFFER_ALIGN);
|
||||
tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.tmprcnt, newcapa * HCL_SIZEOF(*tmp));
|
||||
newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_INFO_BUFFER_ALIGN);
|
||||
tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.info, newcapa * HCL_SIZEOF(*tmp));
|
||||
if (!tmp) return -1;
|
||||
|
||||
hcl->c->blk.tmprcnt_capa = newcapa;
|
||||
hcl->c->blk.tmprcnt = tmp;
|
||||
hcl->c->blk.info_capa = newcapa;
|
||||
hcl->c->blk.info = tmp;
|
||||
}
|
||||
|
||||
hcl->c->blk.tmprcnt[hcl->c->blk.depth] = tmpr_count;
|
||||
hcl->c->blk.info[hcl->c->blk.depth].tmprcnt = tmpr_count;
|
||||
hcl->c->blk.info[hcl->c->blk.depth].litbase = lit_base;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1123,7 +1060,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src, int defun)
|
||||
return -1;
|
||||
}
|
||||
hcl->c->blk.depth++;
|
||||
if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size) <= -1) return -1;
|
||||
if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size, hcl->code.lit.len) <= -1) return -1;
|
||||
|
||||
/* use the accumulated number of temporaries so far when generating
|
||||
* the make_block instruction. at context activation time, the actual
|
||||
@ -1627,14 +1564,14 @@ static int emit_indexed_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t
|
||||
|
||||
/* if a temporary variable is accessed inside a block,
|
||||
* use a special instruction to indicate it */
|
||||
HCL_ASSERT (hcl, index < hcl->c->blk.tmprcnt[hcl->c->blk.depth]);
|
||||
HCL_ASSERT (hcl, index < hcl->c->blk.info[hcl->c->blk.depth].tmprcnt);
|
||||
for (i = hcl->c->blk.depth; i > 0; i--) /* excluded the top level -- TODO: change this code depending on global variable handling */
|
||||
{
|
||||
if (index >= hcl->c->blk.tmprcnt[i - 1])
|
||||
if (index >= hcl->c->blk.info[i - 1].tmprcnt)
|
||||
{
|
||||
hcl_oow_t ctx_offset, index_in_ctx;
|
||||
ctx_offset = hcl->c->blk.depth - i;
|
||||
index_in_ctx = index - hcl->c->blk.tmprcnt[i - 1];
|
||||
index_in_ctx = index - hcl->c->blk.info[i - 1].tmprcnt;
|
||||
/* ctx_offset 0 means the current context.
|
||||
* 1 means current->home.
|
||||
* 2 means current->home->home.
|
||||
@ -2564,7 +2501,7 @@ static HCL_INLINE int emit_lambda (hcl_t* hcl)
|
||||
jip = HCL_OOP_TO_SMOOI(cf->operand);
|
||||
|
||||
hcl->c->blk.depth--;
|
||||
hcl->c->tv.size = hcl->c->blk.tmprcnt[hcl->c->blk.depth];
|
||||
hcl->c->tv.size = hcl->c->blk.info[hcl->c->blk.depth].tmprcnt;
|
||||
|
||||
/* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */
|
||||
block_code_size = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1);
|
||||
@ -2682,7 +2619,7 @@ int hcl_compile (hcl_t* hcl, hcl_oop_t obj)
|
||||
|
||||
/* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */
|
||||
hcl->c->blk.depth++;
|
||||
if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size) <= -1) return -1;
|
||||
if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size, 0) <= -1) return -1;
|
||||
|
||||
PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj);
|
||||
|
||||
|
@ -2216,7 +2216,7 @@ static int execute (hcl_t* hcl)
|
||||
/* the stack contains the final return value so the stack pointer must be 0. */
|
||||
HCL_ASSERT (hcl, hcl->sp == 0);
|
||||
|
||||
if (hcl->option.trait & HCL_AWAIT_PROCS)
|
||||
if (hcl->option.trait & HCL_TRAIT_AWAIT_PROCS)
|
||||
terminate_process (hcl, hcl->processor->active);
|
||||
else
|
||||
goto done;
|
||||
@ -2280,6 +2280,9 @@ static int execute (hcl_t* hcl)
|
||||
|
||||
|
||||
#if 0
|
||||
if (hcl->option.trait & HCL_TRAIT_INTERACTIVE)
|
||||
{
|
||||
|
||||
/* the MAKE_BLOCK instruction is followed by the long JUMP_FORWARD_X instruction.
|
||||
* i can decode the instruction and get the size of instructions
|
||||
* of the block context */
|
||||
@ -2293,6 +2296,8 @@ static int execute (hcl_t* hcl)
|
||||
#endif
|
||||
|
||||
HCL_DEBUG1(hcl, "**** MAKE BLOCK joff = %zu\n", joff);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -228,6 +228,13 @@ struct hcl_cframe_t
|
||||
|
||||
typedef struct hcl_cframe_t hcl_cframe_t;
|
||||
|
||||
struct hcl_blk_info_t
|
||||
{
|
||||
hcl_oow_t tmprcnt;
|
||||
hcl_oow_t litbase;
|
||||
};
|
||||
typedef struct hcl_blk_info_t hcl_blk_info_t;
|
||||
|
||||
struct hcl_compiler_t
|
||||
{
|
||||
/* output handler */
|
||||
@ -305,8 +312,8 @@ struct hcl_compiler_t
|
||||
struct
|
||||
{
|
||||
hcl_ooi_t depth;
|
||||
hcl_oow_t* tmprcnt;
|
||||
hcl_oow_t tmprcnt_capa;
|
||||
hcl_blk_info_t* info;
|
||||
hcl_oow_t info_capa;
|
||||
} blk; /* lambda block */
|
||||
};
|
||||
#endif
|
||||
|
@ -748,7 +748,7 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_
|
||||
|
||||
hcl_getoption (proto->hcl, HCL_TRAIT, &trait);
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC;
|
||||
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_TRAIT_DEBUG_GC;
|
||||
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
|
||||
#endif
|
||||
hcl_setoption (proto->hcl, HCL_TRAIT, &trait);
|
||||
@ -1677,7 +1677,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
||||
hcl_setcmgr (server->dummy_hcl, hcl_server_getcmgr(server));
|
||||
hcl_getoption (server->dummy_hcl, HCL_TRAIT, &trait);
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC;
|
||||
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_TRAIT_DEBUG_GC;
|
||||
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
|
||||
#endif
|
||||
hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait);
|
||||
@ -2357,7 +2357,7 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
|
||||
|
||||
hcl_getoption (server->dummy_hcl, HCL_TRAIT, &trait);
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC;
|
||||
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_TRAIT_DEBUG_GC;
|
||||
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
|
||||
#endif
|
||||
hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait);
|
||||
|
47
lib/hcl.h
47
lib/hcl.h
@ -183,16 +183,18 @@ typedef enum hcl_option_dflval_t hcl_option_dflval_t;
|
||||
enum hcl_trait_t
|
||||
{
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
HCL_DEBUG_GC = (1u << 0),
|
||||
HCL_TRAIT_DEBUG_GC = (1u << 0),
|
||||
HCL_DEBUG_BIGINT = (1u << 1),
|
||||
#endif
|
||||
|
||||
HCL_TRAIT_INTERACTIVE = (1u << 7),
|
||||
|
||||
/* perform no garbage collection when the heap is full.
|
||||
* you still can use hcl_gc() explicitly. */
|
||||
HCL_NOGC = (1u << 8),
|
||||
HCL_TRAIT_NOGC = (1u << 8),
|
||||
|
||||
/* wait for running process when exiting from the main method */
|
||||
HCL_AWAIT_PROCS = (1u << 9)
|
||||
HCL_TRAIT_AWAIT_PROCS = (1u << 9)
|
||||
};
|
||||
typedef enum hcl_trait_t hcl_trait_t;
|
||||
|
||||
@ -1091,35 +1093,6 @@ typedef struct hcl_compiler_t hcl_compiler_t;
|
||||
|
||||
#define HCL_ERRMSG_CAPA (2048)
|
||||
|
||||
typedef struct hcl_clv_t hcl_clv_t;
|
||||
struct hcl_clv_t /* literal value in compiler */
|
||||
{
|
||||
|
||||
int type; /* int, string, byte string, character, etc */
|
||||
hcl_oow_t size;
|
||||
/* data is placed here */
|
||||
};
|
||||
|
||||
typedef struct hcl_ccl_t hcl_ccl_t;
|
||||
struct hcl_ccl_t /* code and literal in compiler */
|
||||
{
|
||||
struct
|
||||
{
|
||||
hcl_uint8_t* ptr;
|
||||
hcl_oow_t capa;
|
||||
hcl_oow_t len;
|
||||
} bc;
|
||||
|
||||
struct
|
||||
{
|
||||
hcl_clv_t* ptr;
|
||||
hcl_oow_t capa;
|
||||
hcl_oow_t len;
|
||||
} lit;
|
||||
|
||||
hcl_oow_t pindex;
|
||||
};
|
||||
|
||||
struct hcl_t
|
||||
{
|
||||
hcl_oow_t _instsize;
|
||||
@ -1270,14 +1243,6 @@ struct hcl_t
|
||||
} xbuf; /* buffer to support sprintf */
|
||||
} sprintf;
|
||||
|
||||
struct
|
||||
{
|
||||
hcl_ccl_t* ptr;
|
||||
hcl_oow_t capa;
|
||||
hcl_oow_t len;
|
||||
hcl_oow_t index;
|
||||
} ccl;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
@ -1598,7 +1563,7 @@ HCL_EXPORT void hcl_deregcb (
|
||||
|
||||
/**
|
||||
* The hcl_gc() function performs garbage collection.
|
||||
* It is not affected by #HCL_NOGC.
|
||||
* It is not affected by #HCL_TRAIT_NOGC.
|
||||
*/
|
||||
HCL_EXPORT void hcl_gc (
|
||||
hcl_t* hcl
|
||||
|
@ -31,11 +31,11 @@ void* hcl_allocbytes (hcl_t* hcl, hcl_oow_t size)
|
||||
hcl_uint8_t* ptr;
|
||||
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
if ((hcl->option.trait & HCL_DEBUG_GC) && !(hcl->option.trait & HCL_NOGC)) hcl_gc (hcl);
|
||||
if ((hcl->option.trait & HCL_TRAIT_DEBUG_GC) && !(hcl->option.trait & HCL_TRAIT_NOGC)) hcl_gc (hcl);
|
||||
#endif
|
||||
|
||||
ptr = (hcl_uint8_t*)hcl_allocheapmem(hcl, hcl->curheap, size);
|
||||
if (!ptr && hcl->errnum == HCL_EOOMEM && !(hcl->option.trait & HCL_NOGC))
|
||||
if (!ptr && hcl->errnum == HCL_EOOMEM && !(hcl->option.trait & HCL_TRAIT_NOGC))
|
||||
{
|
||||
hcl_gc (hcl);
|
||||
HCL_LOG4 (hcl, HCL_LOG_GC | HCL_LOG_INFO,
|
||||
|
@ -2262,11 +2262,11 @@ static void fini_compiler (hcl_t* hcl)
|
||||
hcl->c->tv.capa = 0;
|
||||
}
|
||||
|
||||
if (hcl->c->blk.tmprcnt)
|
||||
if (hcl->c->blk.info)
|
||||
{
|
||||
hcl_freemem (hcl, hcl->c->blk.tmprcnt);
|
||||
hcl->c->blk.tmprcnt = HCL_NULL;
|
||||
hcl->c->blk.tmprcnt_capa = 0;
|
||||
hcl_freemem (hcl, hcl->c->blk.info);
|
||||
hcl->c->blk.info = HCL_NULL;
|
||||
hcl->c->blk.info_capa = 0;
|
||||
hcl->c->blk.depth = -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user