some more code for the feed-based reader

This commit is contained in:
hyung-hwan 2022-07-29 11:29:47 +00:00
parent 51c3145b88
commit e6d204c766
4 changed files with 154 additions and 143 deletions

View File

@ -96,6 +96,9 @@ struct xtn_t
/*hcl_oop_t sym_errstr;*/
};
/* ========================================================================= */
static hcl_t* g_hcl = HCL_NULL;
/* ========================================================================= */
@ -426,12 +429,91 @@ static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode)
}
*/
static void gc_hcl (hcl_t* hcl)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
/*if (xtn->sym_errstr) xtn->sym_errstr = hcl_moveoop(hcl, xtn->sym_errstr);*/
}
/* ========================================================================= */
static hcl_oop_t execute_in_interactive_mode (hcl_t* hcl)
{
hcl_oop_t retv;
hcl_decode (hcl, 0, hcl_getbclen(hcl));
HCL_LOG0 (hcl, HCL_LOG_MNEMONIC, "------------------------------------------\n");
g_hcl = hcl;
/*setup_tick ();*/
retv = hcl_execute(hcl);
/* flush pending output data in the interactive mode(e.g. printf without a newline) */
hcl_flushio (hcl);
if (!retv)
{
hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot execute - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl));
}
else
{
/* print the result in the interactive mode regardless 'verbose' */
hcl_logbfmt (hcl, HCL_LOG_STDOUT, "%O\n", retv); /* TODO: show this go to the output handler?? */
/*
* print the value of ERRSTR.
hcl_oop_cons_t cons = hcl_getatsysdic(hcl, xtn->sym_errstr);
if (cons)
{
HCL_ASSERT (hcl, HCL_IS_CONS(hcl, cons));
HCL_ASSERT (hcl, HCL_CONS_CAR(cons) == xtn->sym_errstr);
hcl_print (hcl, HCL_CONS_CDR(cons));
}
*/
}
/*cancel_tick();*/
g_hcl = HCL_NULL;
return retv;
}
static hcl_oop_t execute_in_batch_mode (hcl_t* hcl, int verbose)
{
hcl_oop_t retv;
hcl_decode (hcl, 0, hcl_getbclen(hcl));
HCL_LOG2 (hcl, HCL_LOG_MNEMONIC, "BYTECODES bclen = > %zu lflen => %zu\n", hcl_getbclen(hcl), hcl_getlflen(hcl));
g_hcl = hcl;
/*setup_tick ();*/
retv = hcl_execute(hcl);
hcl_flushio (hcl);
if (!retv)
{
hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot execute - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl));
}
else if (verbose)
{
hcl_logbfmt (hcl, HCL_LOG_STDERR, "EXECUTION OK - EXITED WITH %O\n", retv);
}
/*cancel_tick();*/
g_hcl = HCL_NULL;
/*hcl_dumpsymtab (hcl);*/
return retv;
}
static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj)
{
if (hcl_compile(hcl, obj, HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK) <= -1) return -1;
execute_in_interactive_mode (hcl);
return 0;
}
/* ========================================================================= */
static int handle_logopt (hcl_t* hcl, const hcl_bch_t* logstr)
@ -565,12 +647,6 @@ static int handle_dbgopt (hcl_t* hcl, const hcl_bch_t* str)
return 0;
}
#endif
/* ========================================================================= */
static hcl_t* g_hcl = HCL_NULL;
/* ========================================================================= */
/* ========================================================================= */
@ -704,7 +780,7 @@ count++;
print_synerr (hcl);
if (xtn->reader_istty && hcl_getsynerrnum(hcl) != HCL_SYNERR_EOF)
{
/* TODO: drain remaining data in the reader including the actual inputstream and buffered data in hcl */
/* TODO: drain remaining data in the reader including the actual input stream and buffered data in hcl */
continue;
}
}
@ -736,66 +812,11 @@ count++;
else if (xtn->reader_istty)
{
/* interactive mode */
hcl_oop_t retv;
hcl_decode (hcl, 0, hcl_getbclen(hcl));
HCL_LOG0 (hcl, HCL_LOG_MNEMONIC, "------------------------------------------\n");
g_hcl = hcl;
/*setup_tick ();*/
retv = hcl_execute(hcl);
/* flush pending output data in the interactive mode(e.g. printf without a newline) */
hcl_flushio (hcl);
if (!retv)
{
hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot execute - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl));
}
else
{
/* print the result in the interactive mode regardless 'verbose' */
hcl_logbfmt (hcl, HCL_LOG_STDOUT, "%O\n", retv); /* TODO: show this go to the output handler?? */
/*
* print the value of ERRSTR.
hcl_oop_cons_t cons = hcl_getatsysdic(hcl, xtn->sym_errstr);
if (cons)
{
HCL_ASSERT (hcl, HCL_IS_CONS(hcl, cons));
HCL_ASSERT (hcl, HCL_CONS_CAR(cons) == xtn->sym_errstr);
hcl_print (hcl, HCL_CONS_CDR(cons));
}
*/
}
/*cancel_tick();*/
g_hcl = HCL_NULL;
execute_in_interactive_mode (hcl);
}
}
if (!xtn->reader_istty && hcl_getbclen(hcl) > 0)
{
hcl_oop_t retv;
hcl_decode (hcl, 0, hcl_getbclen(hcl));
HCL_LOG2 (hcl, HCL_LOG_MNEMONIC, "BYTECODES bclen = > %zu lflen => %zu\n", hcl_getbclen(hcl), hcl_getlflen(hcl));
g_hcl = hcl;
/*setup_tick ();*/
retv = hcl_execute(hcl);
if (!retv)
{
hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot execute - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl));
}
else if (verbose)
{
hcl_logbfmt (hcl, HCL_LOG_STDERR, "EXECUTION OK - EXITED WITH %O\n", retv);
}
/*cancel_tick();*/
g_hcl = HCL_NULL;
/*hcl_dumpsymtab (hcl);*/
}
if (!xtn->reader_istty && hcl_getbclen(hcl) > 0) execute_in_batch_mode (hcl, verbose);
return 0;
@ -822,7 +843,10 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose)
}
/*(setvbuf (fp, NULL, _IONBF, 0);*/
if (xtn->reader_istty) hcl_beginfeed (hcl, on_fed_cnode_in_interactive_mode); /* override the default cnode handler */
/* TODO: use the io handler attached .. */
while (1)
{
hcl_ooi_t n;
@ -854,7 +878,6 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose)
/* 'len' must remain 0 in this case */
#endif
/* the compiler must be invoked whenever feed() sees a complete object */
if (x <= -1) goto feed_error;
}
@ -884,11 +907,7 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose)
fclose (fp);
/* TODO: execute code? */
if (hcl_getbclen(hcl) > 0)
{
/* TODO: execute code... */
}
if (!xtn->reader_istty && hcl_getbclen(hcl) > 0) execute_in_batch_mode (hcl, verbose);
return 0;
@ -1025,7 +1044,7 @@ int main (int argc, char* argv[])
memset (&hclcb, 0, HCL_SIZEOF(hclcb));
hclcb.gc = gc_hcl;
hclcb.vm_startup = vm_startup;
hclcb.vm_startup = vm_startup;
hclcb.vm_cleanup = vm_cleanup;
/*hclcb.vm_checkbc = vm_checkbc;*/
hcl_regcb (hcl, &hclcb);

View File

@ -702,17 +702,8 @@ struct hcl_compiler_t
} u;
} lx;
struct
{
int code;
/*union
{
} u;*/
} st[100];
hcl_ooi_t top;
struct hcl_frd_t rd;
hcl_on_cnode_t on_cnode;
} feed;
/* == COMPILER STACK == */

View File

@ -1459,6 +1459,8 @@ struct hcl_dbgi_t
typedef struct hcl_compiler_t hcl_compiler_t;
typedef struct hcl_cnode_t hcl_cnode_t;
typedef int (*hcl_on_cnode_t) (hcl_t* hcl, hcl_cnode_t* obj);
enum hcl_compile_flag_t
{
/* clear byte codes at the beginnign of hcl_compile() */
@ -2082,7 +2084,6 @@ HCL_EXPORT int hcl_setoption (
const void* value
);
HCL_EXPORT hcl_cb_t* hcl_regcb (
hcl_t* hcl,
hcl_cb_t* tmpl
@ -2151,9 +2152,9 @@ HCL_EXPORT void hcl_abort (
HCL_EXPORT int hcl_attachio (
hcl_t* hcl,
hcl_ioimpl_t reader,
hcl_ioimpl_t printer
hcl_t* hcl,
hcl_ioimpl_t reader,
hcl_ioimpl_t printer
);
HCL_EXPORT void hcl_detachio (
@ -2168,11 +2169,6 @@ HCL_EXPORT hcl_cnode_t* hcl_read (
hcl_t* hcl
);
HCL_EXPORT void hcl_freecnode (
hcl_t* hcl,
hcl_cnode_t* cnode
);
HCL_EXPORT int hcl_print (
hcl_t* hcl,
hcl_oop_t obj
@ -2194,6 +2190,16 @@ HCL_EXPORT hcl_ooi_t hcl_proutufmt (
#if defined(HCL_INCLUDE_COMPILER)
HCL_EXPORT void hcl_freecnode (
hcl_t* hcl,
hcl_cnode_t* cnode
);
HCL_EXPORT void hcl_beginfeed (
hcl_t* hcl,
hcl_on_cnode_t on_cnode
);
HCL_EXPORT int hcl_feed (
hcl_t* hcl,
const hcl_ooch_t* data,

View File

@ -2247,6 +2247,14 @@ hcl_cnodetoobj (hcl_t* hcl, hcl_cnode_t* x)
/* ---------------------------------------------------------------------- */
static int on_fed_cnode (hcl_t* hcl, hcl_cnode_t* obj)
{
/* the default handler for a cnode composed via feeding - just compile the object node. */
return hcl_compile(hcl, obj, 0);
}
/* ---------------------------------------------------------------------- */
static void init_feed (hcl_t* hcl)
{
HCL_MEMSET (&hcl->c->feed, 0, HCL_SIZEOF(hcl->c->feed));
@ -2256,31 +2264,11 @@ static void init_feed (hcl_t* hcl)
hcl->c->feed.lx.loc.colm = 1;
hcl->c->feed.lx.loc.file = HCL_NULL;
hcl->c->feed.top = -1;
hcl->c->feed.on_cnode = on_fed_cnode;
}
/* ------------------------------------------------------------------------ */
static int fst_push (hcl_t* hcl, int code)
{
if (hcl->c->feed.top >= HCL_COUNTOF(hcl->c->feed.st) - 1) /* TODO: use a dynamically allocated stack? */
{
hcl_seterrbfmt (hcl, HCL_EBUFFULL, "feed stack full");
return -1;
}
hcl->c->feed.top++;
HCL_MEMSET (&hcl->c->feed.st[hcl->c->feed.top], 0, HCL_SIZEOF(hcl->c->feed.st[hcl->c->feed.top]));
hcl->c->feed.st[hcl->c->feed.top].code = code;
return 0;
}
static void fst_pop (hcl_t* hcl)
{
HCL_ASSERT (hcl, hcl->c->feed.top >= 0);
hcl->c->feed.top--;
}
static int feed_begin_include (hcl_t* hcl)
{
hcl_ioinarg_t* arg;
@ -2327,11 +2315,9 @@ static int feed_end_include (hcl_t* hcl)
x = hcl->c->reader(hcl, HCL_IO_CLOSE, hcl->c->curinp);
/* if closing has failed, still destroy the
* sio structure first as normal and return
* the failure below. this way, the caller
* does not call HCL_IO_CLOSE on
* hcl->c->curinp again. */
/* if closing has failed, still destroy the sio structure
* first as normal and return the failure below. this way,
* the caller doesn't call HCL_IO_CLOSE on hcl->c->curinp again. */
cur = hcl->c->curinp;
hcl->c->curinp = hcl->c->curinp->includer;
@ -2683,7 +2669,8 @@ static int feed_process_token (hcl_t* hcl)
/* check if we are at the top frd->level */
if (frd->level <= 0)
{
// TOOD: callback with frd->obj in case it's complete
int n;
hcl_cb_t* cb;
/* upon exit, we must be at the top level */
HCL_ASSERT (hcl, frd->level == 0);
@ -2692,14 +2679,10 @@ static int feed_process_token (hcl_t* hcl)
HCL_ASSERT (hcl, hcl->c->r.st == HCL_NULL);
HCL_ASSERT (hcl, frd->obj != HCL_NULL);
/* TODO: error handling, etc */
hcl_compile(hcl, frd->obj, HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK); /* flags 0 if non-interactive */
hcl_freecnode (hcl, frd->obj); /* not needed any more */
frd->obj = HCL_NULL;
hcl_decode (hcl, 0, hcl_getbclen(hcl));
hcl_execute (hcl);
hcl_flushio (hcl);
n = hcl->c->feed.on_cnode(hcl, frd->obj);
hcl_freecnode (hcl, frd->obj); /* not needed any more */
frd->obj = HCL_NULL;
if (n <= -1) goto oops;
}
else
{
@ -2715,7 +2698,6 @@ hcl_flushio (hcl);
clear_comma_colon_flag (hcl);
}
ok:
return 0;
@ -2949,16 +2931,10 @@ static int flx_start (hcl_t* hcl, hcl_ooci_t c)
switch (c)
{
case HCL_OOCI_EOF:
{
int n;
#if 0
n = end_include(hcl);
if (n <= -1) return -1;
if (n >= 1) goto retry;
#endif
/* only EOF of the top-level stream is supposed to be fed in.
* the internal logic discard EOFs of included streams */
FEED_WRAP_UP_WITH_CHARS (hcl, vocas[VOCA_EOF].str, vocas[VOCA_EOF].len, HCL_IOTOK_EOF);
goto consumed;
}
case ';':
FEED_CONTINUE_WITH_CHAR (hcl, c, HCL_FLX_COMMENT);
@ -3706,7 +3682,6 @@ static int feed_char (hcl_t* hcl, hcl_ooci_t c)
static int feed_from_included (hcl_t* hcl)
{
int x;
hcl_ooch_t lc;
HCL_ASSERT (hcl, hcl->c->curinp != HCL_NULL && hcl->c->curinp != &hcl->c->inarg);
@ -3721,7 +3696,7 @@ static int feed_from_included (hcl_t* hcl)
if (hcl->c->curinp->xlen <= 0)
{
/* got EOF */
/* got EOF from an included stream */
#if 0
x = feed_char(hcl, HCL_OOCI_EOF); /* TODO: or call feed_end_include? */
if (x <= -1) return -1;
@ -3735,17 +3710,18 @@ static int feed_from_included (hcl_t* hcl)
hcl->c->curinp->b.len = hcl->c->curinp->xlen;
}
lc = hcl->c->curinp->buf[hcl->c->curinp->b.pos];
x = feed_char(hcl, lc);
x = feed_char(hcl, hcl->c->curinp->buf[hcl->c->curinp->b.pos]);
if (x <= -1) return -1;
hcl->c->curinp->b.pos += x;
if (hcl->c->feed.rd.do_include_file)
{
/* perform delayed file inclusion. the token buffer must remain unchanged
* since do_include_file has been set to true in feed_process_token(). */
/* feed_process_token(), called for the "filename" token for the #include
* directive, sets hcl->c->feed.rd.do_include_file to 1 instead of attepmting
* to include the file. the file inclusion is attempted here after the return
* value of feed_char() is used to advance the hcl->c->curinp->b.pos pointer. */
hcl->c->feed.rd.do_include_file = 0; /* clear this regardless of inclusion result */
if (feed_begin_include(hcl) <= -1) return -1;
hcl->c->feed.rd.do_include_file = 0;
}
}
while (hcl->c->curinp != &hcl->c->inarg);
@ -3753,6 +3729,11 @@ static int feed_from_included (hcl_t* hcl)
return 0;
}
void hcl_beginfeed (hcl_t* hcl, hcl_on_cnode_t on_cnode)
{
hcl->c->feed.on_cnode = on_cnode;
}
int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len)
{
/* TODO: need to return the number of processed characters?
@ -3761,6 +3742,7 @@ int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len)
hcl_oow_t i;
int x;
if (data)
{
for (i = 0; i < len; )
@ -3800,10 +3782,23 @@ int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len)
}
else
{
for (i = 0; i < 1;)
for (i = 0; i < 1;) /* weird loop in case feed_char() returns 0 */
{
x = feed_char(hcl, HCL_OOCI_EOF);
if (x <= -1) return -1;
if (x <= -1)
{
if (hcl->c->feed.rd.level <= 0 && hcl_geterrnum(hcl) == HCL_ESYNERR && hcl_getsynerrnum(hcl) == HCL_SYNERR_EOF)
{
/* convert this EOF error to success as the caller knows EOF in the feed mode.
* the caller can safely stop feeding after gettting success from hcl_feed(hcl, HCL_NULL, 0);
* in the feed mode, this function doesn't set HCL_EFINIS. */
x = 1;
}
else
{
return -1;
}
}
i += x;
}
}