From 9b42b989fa0204bb5983ac3a8862079a5110850f Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 17 Apr 2024 12:20:25 +0900 Subject: [PATCH] simplified the logic to show the prompt in interactive mode. improved the EOF handling code --- bin/main.c | 82 +++++++++++------------------------------------------- lib/read.c | 38 +++++++++++-------------- 2 files changed, 34 insertions(+), 86 deletions(-) diff --git a/bin/main.c b/bin/main.c index f34054e..ec6a824 100644 --- a/bin/main.c +++ b/bin/main.c @@ -111,7 +111,7 @@ struct xtn_t hcl_oow_t len; hcl_oow_t pos; int eof; - int ongoing; + hcl_oow_t ncompexprs; /* number of compiled expressions */ } feed; /*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, * 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. * arrange to clear byte-codes before compiling the expression. */ flags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK; - xtn->feed.ongoing = 1; } if (hcl_compile(hcl, obj, flags) <= -1) { print_error(hcl, "failed to compile"); xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */ - show_prompt (hcl, 0); } -#if 0 else { - hcl_oow_t i; - - 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); - } + xtn->feed.ncompexprs++; } -#endif return 0; } @@ -590,12 +569,13 @@ static int get_line (hcl_t* hcl, xtn_t* xtn, FILE* fp) } xtn->feed.eof = 1; + if (xtn->feed.len <= 0) return 0; + break; } - /* TOTO: buffer check... */ 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; @@ -647,23 +627,12 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) hcl_oow_t pos; 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); if (n <= -1) goto oops; if (n == 0) break; /* 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; /* do this before calling hcl_feedbchars() so that the callback sees the updated value */ 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) { print_error (hcl, "failed to feed"); - show_prompt (hcl, 0); + if (len > 0) show_prompt (hcl, 0); } else { - /* a := (1 + 2 ##askldfjasldkfjasd - ); b := (2 + 3 -// 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)) + /* TODO: check if this works when HCL_TRAIT_LANG_ENABLE_EOL is not set */ + if (!hcl_feedpending(hcl)) { - execute_in_interactive_mode (hcl); - xtn->feed.ongoing = 0; - if (len > 0) show_prompt (hcl, 0); - } - else if (len > 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"); + if (xtn->feed.ncompexprs > 0 && hcl_getbclen(hcl) > 0) + { + execute_in_interactive_mode (hcl); + xtn->feed.ncompexprs = 0; + } + show_prompt (hcl, 0); } } - #endif } } else @@ -727,6 +678,7 @@ or lines with comments only... } } + hcl_logbfmt (hcl, HCL_LOG_STDOUT, "\n"); if (hcl_endfeed(hcl) <= -1) { feed_error: diff --git a/lib/read.c b/lib/read.c index 0d82c03..5bc400d 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1250,6 +1250,7 @@ static int feed_process_token (hcl_t* hcl) hcl_frd_t* frd = &hcl->c->feed.rd; hcl_loc_t* list_loc = HCL_NULL; int rbrace_again = 0; + int oops_ret = -1; /* TODO: frd->obj and frd->list_loc can become local variables in this function.. */ /* this function composes an s-expression non-recursively @@ -1293,7 +1294,15 @@ static int feed_process_token (hcl_t* hcl) goto oops; 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; case HCL_TOK_INCLUDE: @@ -1754,7 +1763,7 @@ static int feed_process_token (hcl_t* hcl) 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 /* check if the element is read for a quoted list */ @@ -1812,6 +1821,7 @@ ok: list_loc = HCL_NULL; goto rbrace_ok; } + return 0; oops: @@ -1825,7 +1835,7 @@ oops: /* clean up the reader stack for a list */ feed_clean_up_reader_stack (hcl); 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_COLONLT }, { ":*", 2, HCL_TOK_COLONSTAR }, /* class instantiation method */ - { "::", 2, HCL_TOK_DBLCOLONS }, - { ":::", 3, HCL_TOK_TRPCOLONS }, /* superclass, class variables, class methods */ + { "::", 2, HCL_TOK_DBLCOLONS }, /* superclass, class variables, class methods */ + { ":::", 3, HCL_TOK_TRPCOLONS }, { ";", 1, HCL_TOK_SEMICOLON } }; @@ -3223,7 +3233,7 @@ int hcl_endfeed (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) @@ -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 */ { x = feed_char(hcl, HCL_OOCI_EOF); - if (x <= -1) - { - 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; - } - } + if (x <= -1) goto oops; i += x; } }