bc: fix interactive read()
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
2638454464
commit
53e569c06b
@ -6753,6 +6753,7 @@ static BC_STATUS zbc_vm_process(const char *text)
|
|||||||
s = zbc_parse_text_init(&G.prs, text); // does the first zbc_lex_next()
|
s = zbc_parse_text_init(&G.prs, text); // does the first zbc_lex_next()
|
||||||
if (s) RETURN_STATUS(s);
|
if (s) RETURN_STATUS(s);
|
||||||
|
|
||||||
|
IF_BC(check_eof:)
|
||||||
while (G.prs.l.lex != XC_LEX_EOF) {
|
while (G.prs.l.lex != XC_LEX_EOF) {
|
||||||
BcInstPtr *ip;
|
BcInstPtr *ip;
|
||||||
BcFunc *f;
|
BcFunc *f;
|
||||||
@ -6760,23 +6761,25 @@ static BC_STATUS zbc_vm_process(const char *text)
|
|||||||
dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex);
|
dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex);
|
||||||
if (IS_BC) {
|
if (IS_BC) {
|
||||||
#if ENABLE_BC
|
#if ENABLE_BC
|
||||||
|
if (G.prs.l.lex == BC_LEX_SCOLON
|
||||||
|
|| G.prs.l.lex == XC_LEX_NLINE
|
||||||
|
) {
|
||||||
|
s = zbc_lex_next(&G.prs.l);
|
||||||
|
if (s) goto err;
|
||||||
|
goto check_eof;
|
||||||
|
}
|
||||||
|
|
||||||
s = zbc_parse_stmt_or_funcdef(&G.prs);
|
s = zbc_parse_stmt_or_funcdef(&G.prs);
|
||||||
if (s) goto err;
|
if (s) goto err;
|
||||||
|
|
||||||
// Check that next token is not bogus, and skip over
|
// Check that next token is a correct stmt delimiter -
|
||||||
// stmt delimiter(s) - newlines and semicolons
|
// disallows "print 1 print 2" and such.
|
||||||
s = 1; // s == 1 on first iteration only
|
|
||||||
for (;;) {
|
|
||||||
if (G.prs.l.lex == XC_LEX_EOF)
|
|
||||||
goto execute; // this goto avoids resetting 's' to zero
|
|
||||||
if (G.prs.l.lex != BC_LEX_SCOLON
|
if (G.prs.l.lex != BC_LEX_SCOLON
|
||||||
&& G.prs.l.lex != XC_LEX_NLINE
|
&& G.prs.l.lex != XC_LEX_NLINE
|
||||||
|
&& G.prs.l.lex != XC_LEX_EOF
|
||||||
) {
|
) {
|
||||||
const char *err_at;
|
const char *err_at;
|
||||||
// Not newline and not semicolon
|
//TODO: commonalize for other parse errors:
|
||||||
if (s == 0) // saw at least one NL/semicolon before it?
|
|
||||||
break; // yes, good
|
|
||||||
//TODO: commolalize for other parse errors:
|
|
||||||
err_at = G.prs.l.lex_next_at ? G.prs.l.lex_next_at : "UNKNOWN";
|
err_at = G.prs.l.lex_next_at ? G.prs.l.lex_next_at : "UNKNOWN";
|
||||||
bc_error_fmt("bad statement terminator at '%.*s'",
|
bc_error_fmt("bad statement terminator at '%.*s'",
|
||||||
(int)(strchrnul(err_at, '\n') - err_at),
|
(int)(strchrnul(err_at, '\n') - err_at),
|
||||||
@ -6784,10 +6787,8 @@ static BC_STATUS zbc_vm_process(const char *text)
|
|||||||
);
|
);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
// NL or semicolon: skip it, set s = 0, repeat
|
// The above logic is fragile. Check these examples:
|
||||||
s = zbc_lex_next(&G.prs.l);
|
// - interative read() still works
|
||||||
if (s) goto err;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if ENABLE_DC
|
#if ENABLE_DC
|
||||||
@ -6807,7 +6808,7 @@ static BC_STATUS zbc_vm_process(const char *text)
|
|||||||
bc_parse_reset(&G.prs); // includes bc_program_reset()
|
bc_parse_reset(&G.prs); // includes bc_program_reset()
|
||||||
RETURN_STATUS(BC_STATUS_FAILURE);
|
RETURN_STATUS(BC_STATUS_FAILURE);
|
||||||
}
|
}
|
||||||
IF_BC(execute:)
|
|
||||||
dbg_lex("%s:%d executing...", __func__, __LINE__);
|
dbg_lex("%s:%d executing...", __func__, __LINE__);
|
||||||
s = zbc_program_exec();
|
s = zbc_program_exec();
|
||||||
if (s) {
|
if (s) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user