simplified the logic to show the prompt in interactive mode.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
improved the EOF handling code
This commit is contained in:
parent
65d64f7c5f
commit
9b42b989fa
82
bin/main.c
82
bin/main.c
@ -111,7 +111,7 @@ struct xtn_t
|
|||||||
hcl_oow_t len;
|
hcl_oow_t len;
|
||||||
hcl_oow_t pos;
|
hcl_oow_t pos;
|
||||||
int eof;
|
int eof;
|
||||||
int ongoing;
|
hcl_oow_t ncompexprs; /* number of compiled expressions */
|
||||||
} feed;
|
} feed;
|
||||||
/*hcl_oop_t sym_errstr;*/
|
/*hcl_oop_t sym_errstr;*/
|
||||||
};
|
};
|
||||||
@ -524,43 +524,22 @@ static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj)
|
|||||||
* if a single line or continued lines contain multiple expressions,
|
* if a single line or continued lines contain multiple expressions,
|
||||||
* execution is delayed until the last expression is compiled. */
|
* execution is delayed until the last expression is compiled. */
|
||||||
|
|
||||||
if (!xtn->feed.ongoing)
|
if (xtn->feed.ncompexprs <= 0)
|
||||||
{
|
{
|
||||||
/* the first expression in the current user input line.
|
/* the first expression in the current user input line.
|
||||||
* arrange to clear byte-codes before compiling the expression. */
|
* arrange to clear byte-codes before compiling the expression. */
|
||||||
flags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK;
|
flags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK;
|
||||||
xtn->feed.ongoing = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hcl_compile(hcl, obj, flags) <= -1)
|
if (hcl_compile(hcl, obj, flags) <= -1)
|
||||||
{
|
{
|
||||||
print_error(hcl, "failed to compile");
|
print_error(hcl, "failed to compile");
|
||||||
xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */
|
xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */
|
||||||
show_prompt (hcl, 0);
|
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hcl_oow_t i;
|
xtn->feed.ncompexprs++;
|
||||||
|
|
||||||
for (i = xtn->feed.pos; i < xtn->feed.len; i++)
|
|
||||||
{
|
|
||||||
/* this loop is kind of weird. it is to check the current feed buffer is left with
|
|
||||||
* spaces only and to execute the compiled bytecodes so far if the check is true.
|
|
||||||
* the check is performed because a single line of the user input can have multiple
|
|
||||||
* expressions joined with a semicolon or contains trailing spaces. */
|
|
||||||
if (!hcl_is_bch_space(xtn->feed.buf[i])) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= xtn->feed.len || xtn->feed.pos >= xtn->feed.len)
|
|
||||||
{
|
|
||||||
/* nothing more to feed */
|
|
||||||
execute_in_interactive_mode (hcl);
|
|
||||||
xtn->feed.ongoing = 0;
|
|
||||||
show_prompt (hcl, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -590,12 +569,13 @@ static int get_line (hcl_t* hcl, xtn_t* xtn, FILE* fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xtn->feed.eof = 1;
|
xtn->feed.eof = 1;
|
||||||
|
if (xtn->feed.len <= 0) return 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TOTO: buffer check... */
|
|
||||||
xtn->feed.buf[xtn->feed.len++] = (hcl_bch_t)(unsigned int)ch;
|
xtn->feed.buf[xtn->feed.len++] = (hcl_bch_t)(unsigned int)ch;
|
||||||
if (ch == '\n') break;
|
if (ch == '\n' || xtn->feed.len >= HCL_COUNTOF(xtn->feed.buf)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -647,23 +627,12 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose)
|
|||||||
hcl_oow_t pos;
|
hcl_oow_t pos;
|
||||||
hcl_oow_t len;
|
hcl_oow_t len;
|
||||||
|
|
||||||
/* read a while line regardless of the actual expression */
|
/* read a line regardless of the actual expression */
|
||||||
n = get_line(hcl, xtn, fp);
|
n = get_line(hcl, xtn, fp);
|
||||||
if (n <= -1) goto oops;
|
if (n <= -1) goto oops;
|
||||||
if (n == 0) break;
|
if (n == 0) break;
|
||||||
|
|
||||||
/* feed the line */
|
/* feed the line */
|
||||||
#if 0
|
|
||||||
while (xtn->feed.pos < xtn->feed.len)
|
|
||||||
{
|
|
||||||
hcl_bch_t c = xtn->feed.buf[xtn->feed.pos++];
|
|
||||||
if (hcl_feedbchars(hcl, &c, 1) <= -1)
|
|
||||||
{
|
|
||||||
print_error (hcl, "failed to feed");
|
|
||||||
show_prompt (hcl, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
pos = xtn->feed.pos;
|
pos = xtn->feed.pos;
|
||||||
/* do this before calling hcl_feedbchars() so that the callback sees the updated value */
|
/* do this before calling hcl_feedbchars() so that the callback sees the updated value */
|
||||||
xtn->feed.pos = xtn->feed.len;
|
xtn->feed.pos = xtn->feed.len;
|
||||||
@ -671,39 +640,21 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose)
|
|||||||
if (hcl_feedbchars(hcl, &xtn->feed.buf[pos], len) <= -1)
|
if (hcl_feedbchars(hcl, &xtn->feed.buf[pos], len) <= -1)
|
||||||
{
|
{
|
||||||
print_error (hcl, "failed to feed");
|
print_error (hcl, "failed to feed");
|
||||||
show_prompt (hcl, 0);
|
if (len > 0) show_prompt (hcl, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* a := (1 + 2 ##askldfjasldkfjasd
|
/* TODO: check if this works when HCL_TRAIT_LANG_ENABLE_EOL is not set */
|
||||||
); b := (2 + 3
|
if (!hcl_feedpending(hcl))
|
||||||
// TODO: how to know if 'b := (2 + 3' is still not completely compiled?.
|
|
||||||
|
|
||||||
|
|
||||||
just new lines..
|
|
||||||
or lines with comments only...
|
|
||||||
+ 1 2 <-- prohibited binary operator + <--- don't look right...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (xtn->feed.ongoing && hcl_getbclen(hcl) > 0 && !hcl_feedpending(hcl))
|
|
||||||
{
|
{
|
||||||
execute_in_interactive_mode (hcl);
|
if (xtn->feed.ncompexprs > 0 && hcl_getbclen(hcl) > 0)
|
||||||
xtn->feed.ongoing = 0;
|
{
|
||||||
if (len > 0) show_prompt (hcl, 0);
|
execute_in_interactive_mode (hcl);
|
||||||
}
|
xtn->feed.ncompexprs = 0;
|
||||||
else if (len > 0)
|
}
|
||||||
{
|
show_prompt (hcl, 0);
|
||||||
if (!xtn->feed.ongoing && !hcl_feedpending(hcl))
|
|
||||||
show_prompt (hcl, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* eof reached */
|
|
||||||
hcl_logbfmt (hcl, HCL_LOG_STDOUT, "\n");
|
|
||||||
if (hcl_feedpending(hcl)) print_error (hcl, "sudden end of input");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -727,6 +678,7 @@ or lines with comments only...
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hcl_logbfmt (hcl, HCL_LOG_STDOUT, "\n");
|
||||||
if (hcl_endfeed(hcl) <= -1)
|
if (hcl_endfeed(hcl) <= -1)
|
||||||
{
|
{
|
||||||
feed_error:
|
feed_error:
|
||||||
|
38
lib/read.c
38
lib/read.c
@ -1250,6 +1250,7 @@ static int feed_process_token (hcl_t* hcl)
|
|||||||
hcl_frd_t* frd = &hcl->c->feed.rd;
|
hcl_frd_t* frd = &hcl->c->feed.rd;
|
||||||
hcl_loc_t* list_loc = HCL_NULL;
|
hcl_loc_t* list_loc = HCL_NULL;
|
||||||
int rbrace_again = 0;
|
int rbrace_again = 0;
|
||||||
|
int oops_ret = -1;
|
||||||
/* TODO: frd->obj and frd->list_loc can become local variables in this function.. */
|
/* TODO: frd->obj and frd->list_loc can become local variables in this function.. */
|
||||||
|
|
||||||
/* this function composes an s-expression non-recursively
|
/* this function composes an s-expression non-recursively
|
||||||
@ -1293,7 +1294,15 @@ static int feed_process_token (hcl_t* hcl)
|
|||||||
goto oops;
|
goto oops;
|
||||||
|
|
||||||
case HCL_TOK_EOF:
|
case HCL_TOK_EOF:
|
||||||
hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
if (hcl_feedpending(hcl))
|
||||||
|
{
|
||||||
|
hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* ugly hacking to return success intead while performing clean-up */
|
||||||
|
oops_ret = 0;
|
||||||
|
}
|
||||||
goto oops;
|
goto oops;
|
||||||
|
|
||||||
case HCL_TOK_INCLUDE:
|
case HCL_TOK_INCLUDE:
|
||||||
@ -1754,7 +1763,7 @@ static int feed_process_token (hcl_t* hcl)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frd->obj) goto oops; /* TODO: this doesn't have to be check if jump has been made to auto_xlist... so restructure the flow */
|
if (!frd->obj) goto oops; /* TODO: this doesn't have to be checked if jump has been made to auto_xlist... so restructure the flow */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* check if the element is read for a quoted list */
|
/* check if the element is read for a quoted list */
|
||||||
@ -1812,6 +1821,7 @@ ok:
|
|||||||
list_loc = HCL_NULL;
|
list_loc = HCL_NULL;
|
||||||
goto rbrace_ok;
|
goto rbrace_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
@ -1825,7 +1835,7 @@ oops:
|
|||||||
/* clean up the reader stack for a list */
|
/* clean up the reader stack for a list */
|
||||||
feed_clean_up_reader_stack (hcl);
|
feed_clean_up_reader_stack (hcl);
|
||||||
feed_continue (hcl, HCL_FLX_START);
|
feed_continue (hcl, HCL_FLX_START);
|
||||||
return -1;
|
return oops_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
@ -1880,8 +1890,8 @@ static delim_token_t delim_token_tab[] =
|
|||||||
{ ":>", 2, HCL_TOK_COLONGT },
|
{ ":>", 2, HCL_TOK_COLONGT },
|
||||||
{ ":<", 2, HCL_TOK_COLONLT },
|
{ ":<", 2, HCL_TOK_COLONLT },
|
||||||
{ ":*", 2, HCL_TOK_COLONSTAR }, /* class instantiation method */
|
{ ":*", 2, HCL_TOK_COLONSTAR }, /* class instantiation method */
|
||||||
{ "::", 2, HCL_TOK_DBLCOLONS },
|
{ "::", 2, HCL_TOK_DBLCOLONS }, /* superclass, class variables, class methods */
|
||||||
{ ":::", 3, HCL_TOK_TRPCOLONS }, /* superclass, class variables, class methods */
|
{ ":::", 3, HCL_TOK_TRPCOLONS },
|
||||||
|
|
||||||
{ ";", 1, HCL_TOK_SEMICOLON }
|
{ ";", 1, HCL_TOK_SEMICOLON }
|
||||||
};
|
};
|
||||||
@ -3223,7 +3233,7 @@ int hcl_endfeed (hcl_t* hcl)
|
|||||||
|
|
||||||
int hcl_feedpending (hcl_t* hcl)
|
int hcl_feedpending (hcl_t* hcl)
|
||||||
{
|
{
|
||||||
return hcl->c->r.st != HCL_NULL;
|
return !(hcl->c->r.st == HCL_NULL && FLX_STATE(hcl) == HCL_FLX_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len)
|
int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len)
|
||||||
@ -3277,21 +3287,7 @@ int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len)
|
|||||||
for (i = 0; i < 1;) /* weird loop in case feed_char() returns 0 */
|
for (i = 0; i < 1;) /* weird loop in case feed_char() returns 0 */
|
||||||
{
|
{
|
||||||
x = feed_char(hcl, HCL_OOCI_EOF);
|
x = feed_char(hcl, HCL_OOCI_EOF);
|
||||||
if (x <= -1)
|
if (x <= -1) goto oops;
|
||||||
{
|
|
||||||
int exp_level = !(hcl->option.trait & HCL_TRAIT_LANG_ENABLE_EOL); /* 0 if EOL is on, 1 if EOL is off */
|
|
||||||
if (hcl->c->feed.rd.level <= exp_level && HCL_ERRNUM(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
|
|
||||||
{
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i += x;
|
i += x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user