diff --git a/lib/main.c b/lib/main.c index 600e21e..c9841f8 100644 --- a/lib/main.c +++ b/lib/main.c @@ -350,7 +350,6 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) return 0; } - static int read_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) { switch (cmd) @@ -1888,7 +1887,11 @@ count++; else if (hcl->errnum == HCL_ESYNERR) { print_synerr (hcl); - if (xtn->reader_istty && hcl_getsynerrnum(hcl) != HCL_SYNERR_EOF) continue; + 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 */ + continue; + } } else { diff --git a/lib/read.c b/lib/read.c index dcf701d..849cc5d 100644 --- a/lib/read.c +++ b/lib/read.c @@ -2189,10 +2189,58 @@ static int read_object (hcl_t* hcl) static int read_object_in_cli_mode (hcl_t* hcl) { +/* +( ls -laF + pwd ) -> ( (ls -laF) (pwd) ) + + + +ls -laF (pwd) -> (ls -laF ( (pwd ) ) + + +ls -laF -> (ls -laF) + + +( -> ( + ls -laF -> (ls -laF) + pwd -> (pwd) +) -> ) + + +( ( + pwd ( (pwd ( + ls -laF (ls -laF) + ) ) ) +) ) + +* SOME key test cases + ------------ +(pwd) +------------ +(pwd +) +------------ +( +pwd) +------------ +( +pwd +) +------------ +pwd (pwd) +------------ +pwd (pwd +) +* + +--------------- +pwd) -------> error + +*/ int level = 0, array_level = 0, flagv = 0; hcl_oop_t obj; int start_virtual_list = 1; - int prev_eoled = 0; + hcl_iotok_type_t prev_token_type = HCL_IOTOK_EOF; if (TOKEN_TYPE(hcl) == HCL_IOTOK_LPAREN) start_virtual_list = 0; @@ -2207,7 +2255,7 @@ HCL_DEBUG0 (hcl, "STARTING vritual list...\n"); /* push some data to simulate recursion into * a list literal or an array literal */ - if (enter_list(hcl, flagv) == HCL_NULL) return -1; + if (enter_list(hcl, flagv) == HCL_NULL) goto oops; level++; //if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++; @@ -2218,11 +2266,11 @@ HCL_DEBUG0 (hcl, "STARTING vritual list...\n"); { default: hcl_setsynerr (hcl, HCL_SYNERR_ILTOK, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - return -1; + goto oops; case HCL_IOTOK_EOF: hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - return -1; + goto oops; case HCL_IOTOK_INCLUDE: /* TODO: should i limit where #include can be specified? @@ -2231,58 +2279,47 @@ HCL_DEBUG0 (hcl, "STARTING vritual list...\n"); if (TOKEN_TYPE(hcl) != HCL_IOTOK_STRLIT) { hcl_setsynerr (hcl, HCL_SYNERR_STRING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); - return -1; + goto oops; } - if (begin_include(hcl) <= -1) return -1; + if (begin_include(hcl) <= -1) goto oops; goto redo; case HCL_IOTOK_LPAREN: /* () */ - { - /*int first = 1; - - redo_lparen:*/ flagv = 0; LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_XLIST); - SET_TOKEN_TYPE (hcl, HCL_IOTOK_EOL); /* to have get_token() to ignore immediate after ( */ /*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)); - return -1; + goto oops; } /* push some data to simulate recursion into * a list literal or an array literal */ HCL_DEBUG0 (hcl, "111 STARTING list...\n"); - if (enter_list(hcl, flagv) == HCL_NULL) return -1; + if (enter_list(hcl, flagv) == HCL_NULL) goto oops; level++; //if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++; -/* - if (first) - { - first = 0; - goto redo_lparen; - } -*/ /* read the next token */ - GET_TOKEN (hcl); start_virtual_list = 1; - goto redo; - } + goto next_token; case HCL_IOTOK_EOL: { int oldflagv; //int concode; + if (prev_token_type == HCL_IOTOK_EOL || prev_token_type == HCL_IOTOK_LPAREN) goto next_token; + if (level <= 0) { hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL); - return -1; + goto oops; } +HCL_DEBUG1 (hcl, "11 LEAVING LIST level->%d\n", (int)level); //concode = LIST_FLAG_GET_CONCODE(flagv); obj = leave_list(hcl, &flagv, &oldflagv); @@ -2298,25 +2335,44 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n"); int oldflagv; //int concode; - if (prev_eoled) + if (prev_token_type == HCL_IOTOK_LPAREN) { - /* exit #1 */ - if (level <= 0) - { - hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL); - return -1; - } + hcl_setsynerr (hcl, HCL_SYNERR_EMPTYXLIST, TOKEN_LOC(hcl), HCL_NULL); /* TODO: change error code?? */ + goto oops; + } + else if (prev_token_type == HCL_IOTOK_EOL) + { + if (level <= 1) goto unbalpbb; - //concode = LIST_FLAG_GET_CONCODE(flagv); obj = leave_list(hcl, &flagv, &oldflagv); level--; //if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--; - if (!obj) return -1; + if (!obj) goto oops; HCL_ASSERT (hcl, level > 0); - HCL_DEBUG1 (hcl, "00 ADDING TO LIST %O\n", obj); - if (chain_to_list(hcl, obj) == HCL_NULL) return -1; - clear_comma_colon_flag (hcl); + HCL_ASSERT (hcl, obj == hcl->_nil); + } + else + { + /* exit #1 */ + if (level <= 1) goto unbalpbb; + + //concode = LIST_FLAG_GET_CONCODE(flagv); +HCL_DEBUG0 (hcl, "22 LEAVING LIST\n"); + obj = leave_list(hcl, &flagv, &oldflagv); + level--; + //if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--; + + if (!obj) goto oops; + HCL_ASSERT (hcl, level > 0); + + if (obj != hcl->_nil) + { + //HCL_ASSERT (hcl, obj == hcl->_nil); + HCL_DEBUG1 (hcl, "00 ADDING TO LIST %O\n", obj); + if (chain_to_list(hcl, obj) == HCL_NULL) goto oops; + clear_comma_colon_flag (hcl); + } } /* exit #2 */ @@ -2324,17 +2380,22 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n"); { unbalpbb: hcl_setsynerr (hcl, HCL_SYNERR_UNBALPBB, TOKEN_LOC(hcl), HCL_NULL); - return -1; + goto oops; } + HCL_DEBUG1 (hcl, "33 LEAVING LIST level %d\n", level); //concode = LIST_FLAG_GET_CONCODE(flagv); - obj = leave_list(hcl, &flagv, &oldflagv); + obj = leave_list(hcl, &flagv, &oldflagv); /* this object is added to the chain after break */ level--; - level--; /* double exit??? */ //if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--; - SET_TOKEN_TYPE (hcl, HCL_IOTOK_EOL); /* to have get_token() to ignore immediate after ( */ + if (!obj) goto oops; + if (obj == hcl->_nil) + { + /* consider an input like ls (pwd ) where EOL is '\n' */ + goto next_token; + } break; } @@ -2349,7 +2410,7 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n"); break; } - if (!obj) return -1; + if (!obj) goto oops; /* check if we are at the top level */ if (level <= 0) break; /* yes */ @@ -2357,17 +2418,21 @@ HCL_DEBUG0 (hcl, "111 STARTING list...\n"); /* if not, append the element read into the current list. * if we are not at the top level, we must be in a list */ HCL_DEBUG1 (hcl, "11 ADDING TO LIST %O\n", obj); - if (chain_to_list(hcl, obj) == HCL_NULL) return -1; + if (chain_to_list(hcl, obj) == HCL_NULL) goto oops; clear_comma_colon_flag (hcl); - prev_eoled = (TOKEN_TYPE(hcl) == HCL_IOTOK_EOL); + next_token: + prev_token_type = TOKEN_TYPE(hcl); /* read the next token */ GET_TOKEN (hcl); } -done: hcl->c->r.e = obj; return 0; + +oops: + SET_TOKEN_TYPE (hcl, HCL_IOTOK_EOL); /* to make get_token() not return an immediate EOL after error */ + return -1; } static HCL_INLINE int __read (hcl_t* hcl)