diff --git a/bin/main.c b/bin/main.c index a27976c..fce8a19 100644 --- a/bin/main.c +++ b/bin/main.c @@ -435,75 +435,6 @@ static hcl_oop_t execute_in_batch_mode (hcl_t* hcl, int verbose) return retv; } -static int main_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose) -{ - while (1) - { - hcl_cnode_t* obj; - int n; - -/* -static int count = 0; -if (count %5 == 0) hcl_reset (hcl); -count++; -*/ - obj = hcl_read(hcl); - if (!obj) - { - if (hcl->errnum == HCL_EFINIS) - { - /* end of input */ - break; - } - else if (hcl->errnum == HCL_ESYNERR) - { - print_synerr (hcl); - if (hcl_isstdreadertty(hcl) && hcl_getsynerrnum(hcl) != HCL_SYNERR_EOF) - { - /* TODO: drain remaining data in the reader including the actual input stream and buffered data in hcl */ - continue; - } - } - else - { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot read object - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); - } - goto oops; - } - - if (verbose) hcl_prbfmt (hcl, "\n"); /* flush the output buffer by hcl_print above */ - n = hcl_compile(hcl, obj, cflags); - hcl_freecnode (hcl, obj); /* not needed any more */ - - if (n <= -1) - { - if (hcl->errnum == HCL_ESYNERR) - { - print_synerr (hcl); - } - else - { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot compile object - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); - } - /* carry on? */ - - if (!hcl_isstdreadertty(hcl)) goto oops; - } - else if (hcl_isstdreadertty(hcl)) - { - /* interactive mode */ - execute_in_interactive_mode (hcl); - } - } - - if (!hcl_isstdreadertty(hcl) && hcl_getbclen(hcl) > 0) execute_in_batch_mode (hcl, verbose); - - return 0; - -oops: - return -1; -} - 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; @@ -568,7 +499,7 @@ int main (int argc, char* argv[]) }; static hcl_bopt_t opt = { - "l:xv", + "l:v", lopt }; @@ -576,7 +507,7 @@ int main (int argc, char* argv[]) hcl_oow_t heapsize = DEFAULT_HEAPSIZE; int cflags; int verbose = 0; - int experimental = 0; + /*int experimental = 0;*/ #if defined(HCL_BUILD_DEBUG) const char* dbgopt = HCL_NULL; @@ -600,9 +531,9 @@ int main (int argc, char* argv[]) logopt = opt.arg; break; - case 'x': + /*case 'x': experimental = 1; - break; + break;*/ case 'v': verbose = 1; @@ -744,15 +675,7 @@ int main (int argc, char* argv[]) cflags = 0; if (hcl_isstdreadertty(hcl)) cflags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK; - if (experimental) - { - /* this is to test the feed-based reader */ - if (feed_loop(hcl, xtn, cflags, verbose) <= -1) goto oops; - } - else - { - if (main_loop(hcl, xtn, cflags, verbose) <= -1) goto oops; - } + if (feed_loop(hcl, xtn, cflags, verbose) <= -1) goto oops; set_signal_to_default (SIGINT); hcl_close (hcl); diff --git a/lib/hcl.h b/lib/hcl.h index 27317b3..eae527b 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -2261,10 +2261,6 @@ HCL_EXPORT void hcl_flushio ( hcl_t* hcl ); -HCL_EXPORT hcl_cnode_t* hcl_read ( - hcl_t* hcl -); - HCL_EXPORT int hcl_print ( hcl_t* hcl, hcl_oop_t obj diff --git a/lib/read.c b/lib/read.c index 472e47b..9f1de4d 100644 --- a/lib/read.c +++ b/lib/read.c @@ -1857,379 +1857,6 @@ oops: return HCL_NULL; } -static hcl_cnode_t* read_object (hcl_t* hcl) -{ - /* this function read an s-expression non-recursively - * by manipulating its own stack. */ - - int level = 0, flagv = 0; - hcl_cnode_t* obj = HCL_NULL; - - while (1) - { - redo: - switch (TOKEN_TYPE(hcl)) - { - default: - hcl_setsynerr (hcl, HCL_SYNERR_ILTOK, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - - case HCL_IOTOK_EOF: - hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - - case HCL_IOTOK_INCLUDE: - /* TODO: should i limit where #include can be specified? - * disallow it inside a list literal or an array literal? */ - GET_TOKEN_WITH_GOTO (hcl, oops); - if (TOKEN_TYPE(hcl) != HCL_IOTOK_STRLIT) - { - hcl_setsynerr (hcl, HCL_SYNERR_STRING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } - if (begin_include(hcl) <= -1) goto oops; - goto redo; - - case HCL_IOTOK_LBRACK: /* [] */ - flagv = DATA_LIST; - LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_ARRAY); - goto start_list; - - case HCL_IOTOK_BAPAREN: /* #[ */ - flagv = DATA_LIST; - LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_BYTEARRAY); - goto start_list; - - case HCL_IOTOK_LBRACE: /* { */ - flagv = DATA_LIST; - LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_DIC); - goto start_list; - - case HCL_IOTOK_QLPAREN: /* #( */ - flagv = DATA_LIST; - LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_QLIST); - goto start_list; - - case HCL_IOTOK_LPARCOLON: /* (: */ - flagv = 0; - LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_MLIST); - goto start_list; - - case HCL_IOTOK_LPAREN: /* ( */ - flagv = 0; - LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_XLIST); - start_list: - if (level >= HCL_TYPE_MAX(int)) - { - /* the nesting level has become too deep */ - hcl_setsynerr (hcl, HCL_SYNERR_NESTING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } - - /* push some data to simulate recursion into - * a list literal or an array literal */ - if (enter_list(hcl, TOKEN_LOC(hcl), flagv) <= -1) goto oops; - level++; - - /* read the next token */ - GET_TOKEN_WITH_GOTO (hcl, oops); - goto redo; - - case HCL_IOTOK_DOT: - if (level <= 0 || !can_dot_list(hcl)) - { - /* cannot have a period: - * 1. at the top level - not inside () - * 2. at the beginning of a list - * 3. inside an array, byte-array, dictionary, xlist */ - hcl_setsynerr (hcl, HCL_SYNERR_DOTBANNED, TOKEN_LOC(hcl), HCL_NULL); - goto oops; - } - - GET_TOKEN_WITH_GOTO (hcl, oops); - goto redo; - - case HCL_IOTOK_COLON: - if (level <= 0 || !can_colon_list(hcl)) - { - hcl_setsynerr (hcl, HCL_SYNERR_COLONBANNED, TOKEN_LOC(hcl), HCL_NULL); - goto oops; - } - - GET_TOKEN_WITH_GOTO (hcl, oops); - goto redo; - - case HCL_IOTOK_COMMA: - if (level <= 0 || !can_comma_list(hcl)) - { - hcl_setsynerr (hcl, HCL_SYNERR_COMMABANNED, TOKEN_LOC(hcl), HCL_NULL); - goto oops; - } - - GET_TOKEN_WITH_GOTO (hcl, oops); - goto redo; - - case HCL_IOTOK_RPAREN: /* xlist (), qlist #() */ - case HCL_IOTOK_RBRACK: /* bytearray #[], array[] */ - case HCL_IOTOK_RBRACE: /* dictionary {} */ - { - static struct - { - int closer; - hcl_synerrnum_t synerr; - } req[] = - { - { HCL_IOTOK_RPAREN, HCL_SYNERR_RPAREN }, /* XLIST ( ) */ - { HCL_IOTOK_RPAREN, HCL_SYNERR_RPAREN }, /* MLIST (: ) */ - { HCL_IOTOK_RBRACK, HCL_SYNERR_RBRACK }, /* ARRAY [ ] */ - { HCL_IOTOK_RBRACK, HCL_SYNERR_RBRACK }, /* BYTEARRAY #[ ] */ - { HCL_IOTOK_RBRACE, HCL_SYNERR_RBRACE }, /* DIC { } */ - { HCL_IOTOK_RPAREN, HCL_SYNERR_RPAREN } /* QLIST #( ) */ - }; - - int oldflagv; - int concode; - - if (level <= 0) - { - hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL); - goto oops; - } - - concode = LIST_FLAG_GET_CONCODE(flagv); - - if (req[concode].closer != TOKEN_TYPE(hcl)) - { - hcl_setsynerr (hcl, req[concode].synerr, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } - -#if 0 - if ((flagv & QUOTED) || level <= 0) - { - /* the right parenthesis can never appear while - * 'quoted' is true. 'quoted' is set to false when - * entering a normal list. 'quoted' is set to true - * when entering a quoted list. a quoted list does - * not have an explicit right parenthesis. - * so the right parenthesis can only pair up with - * the left parenthesis for the normal list. - * - * For example, '(1 2 3 ') 5 6) - * - * this condition is triggerred when the first ) is - * met after the second quote. - * - * also it is illegal to have the right parenthesis - * with no opening(left) parenthesis, which is - * indicated by level<=0. - */ - hcl_setsynerr (hcl, HCL_SYNERR_LPAREN, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } -#endif - obj = leave_list(hcl, &flagv, &oldflagv); - - level--; - break; - } - - case HCL_IOTOK_VBAR: - if (hcl->c->r.st && (hcl->c->r.st->flagv & DATA_LIST)) - { - hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } - obj = read_vlist(hcl); - break; - - case HCL_IOTOK_NIL: - obj = hcl_makecnodenil(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_TRUE: - obj = hcl_makecnodetrue(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_FALSE: - obj = hcl_makecnodefalse(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_SELF: - obj = hcl_makecnodeself(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_SUPER: - obj = hcl_makecnodesuper(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_ELLIPSIS: - obj = hcl_makecnodeellipsis(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_TRPCOLONS: - obj = hcl_makecnodetrpcolons(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_DCSTAR: - obj = hcl_makecnodedcstar(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_SMPTRLIT: - { - hcl_oow_t i; - hcl_oow_t v = 0; - - HCL_ASSERT (hcl, TOKEN_NAME_LEN(hcl) >= 3); - for (i = 2; i < TOKEN_NAME_LEN(hcl); i++) - { - HCL_ASSERT (hcl, is_xdigitchar(TOKEN_NAME_CHAR(hcl, i))); - v = v * 16 + CHAR_TO_NUM(TOKEN_NAME_CHAR(hcl, i), 16); - } - - if (!HCL_IN_SMPTR_RANGE(v)) - { - hcl_setsynerr (hcl, HCL_SYNERR_SMPTRLIT, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } - - obj = hcl_makecnodesmptrlit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl), v); - break; - } - - case HCL_IOTOK_ERRLIT: - { - hcl_oow_t i; - hcl_ooi_t v = 0; - - HCL_ASSERT (hcl, TOKEN_NAME_LEN(hcl) >= 3); - for (i = 2; i < TOKEN_NAME_LEN(hcl); i++) - { - HCL_ASSERT (hcl, is_digitchar(TOKEN_NAME_CHAR(hcl, i))); - v = v * 10 + CHAR_TO_NUM(TOKEN_NAME_CHAR(hcl, i), 10); - - if (v > HCL_ERROR_MAX) - { - hcl_setsynerr (hcl, HCL_SYNERR_ERRLIT, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - goto oops; - } - } - - obj = hcl_makecnodeerrlit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl), v); - break; - } - - case HCL_IOTOK_CHARLIT: - obj = hcl_makecnodecharlit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl), TOKEN_NAME_CHAR(hcl, 0)); - break; - - case HCL_IOTOK_NUMLIT: - obj = hcl_makecnodenumlit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_RADNUMLIT: - obj = hcl_makecnoderadnumlit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_FPDECLIT: - obj = hcl_makecnodefpdeclit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - /* - case HCL_IOTOK_REAL: - obj = hcl_makerealnum(hcl, HCL_IOTOK_RVAL(hcl)); - break; - */ - - case HCL_IOTOK_STRLIT: - obj = hcl_makecnodestrlit(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_IDENT: - obj = hcl_makecnodesymbol(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - case HCL_IOTOK_IDENT_DOTTED: - obj = hcl_makecnodedsymbol(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - break; - - } - - if (!obj) goto oops; - -#if 0 - /* check if the element is read for a quoted list */ - while (flagv & QUOTED) - { - int oldflagv; - - HCL_ASSERT (hcl, level > 0); - - /* if so, append the element read into the quote list */ - if (chain_to_list(hcl, obj) <= -1) goto oops; - - /* exit out of the quoted list. the quoted list can have one element only. */ - obj = leave_list(hcl, &flagv, &oldflagv); - - /* one level up toward the top */ - level--; - } -#endif - - /* check if we are at the top level */ - if (level <= 0) break; /* yes */ - - /* if not, append the element read into the current list. - * if we are not at the top level, we must be in a list */ - if (chain_to_list(hcl, obj) <= -1) goto oops; - - /* because it has been chained to the list, it belongs to the current stack top. - * mark that obj is not stand-alone by nullifying it. without this, if a jump - * is made to oops, the momory block pointed to by obj may get freed twice. */ - obj = HCL_NULL; - - clear_comma_colon_flag (hcl); - - /* read the next token */ - GET_TOKEN_WITH_GOTO (hcl, oops); - } - - /* upon exit, we must be at the top level */ - HCL_ASSERT (hcl, level == 0); - - HCL_ASSERT (hcl, hcl->c->r.st == HCL_NULL); - HCL_ASSERT (hcl, obj != HCL_NULL); - return obj; - -oops: - if (obj) hcl_freecnode (hcl, obj); - - /* clean up the reader stack for a list */ - while (hcl->c->r.st) - { - hcl_rstl_t* rstl; - - rstl = hcl->c->r.st; - hcl->c->r.st = rstl->prev; - if (rstl->head) hcl_freecnode (hcl, rstl->head); - hcl_freemem (hcl, rstl); - } - - return HCL_NULL; -} - -hcl_cnode_t* hcl_read (hcl_t* hcl) -{ - HCL_ASSERT (hcl, hcl->c && hcl->c->reader); - if (get_token(hcl) <= -1) return HCL_NULL; - if (TOKEN_TYPE(hcl) == HCL_IOTOK_EOF) - { - hcl_seterrnum (hcl, HCL_EFINIS); - return HCL_NULL; - } - return read_object(hcl); -} - /* ------------------------------------------------------------------------ */ /* TODO: