removed hcl_read() and related code
This commit is contained in:
parent
bf989e848b
commit
206df863cf
87
bin/main.c
87
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);
|
||||
|
@ -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
|
||||
|
373
lib/read.c
373
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:
|
||||
|
Loading…
Reference in New Issue
Block a user