aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c98
1 files changed, 33 insertions, 65 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 4d252cc97..29007d828 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2828,18 +2828,6 @@ static void bc_lex_file(BcLex *l)
2828 l->newline = false; 2828 l->newline = false;
2829} 2829}
2830 2830
2831IF_BC(static BC_STATUS zbc_lex_token(BcLex *l);)
2832IF_DC(static BC_STATUS zdc_lex_token(BcLex *l);)
2833
2834static BC_STATUS zcommon_lex_token(BcLex *l)
2835{
2836 if (IS_BC) {
2837 IF_BC(RETURN_STATUS(zbc_lex_token(l));)
2838 }
2839 IF_DC(RETURN_STATUS(zdc_lex_token(l));)
2840}
2841#define zcommon_lex_token(...) (zcommon_lex_token(__VA_ARGS__) COMMA_SUCCESS)
2842
2843static bool bc_lex_more_input(BcLex *l) 2831static bool bc_lex_more_input(BcLex *l)
2844{ 2832{
2845 size_t str; 2833 size_t str;
@@ -2912,6 +2900,9 @@ static bool bc_lex_more_input(BcLex *l)
2912 return l->len != 0; 2900 return l->len != 0;
2913} 2901}
2914 2902
2903IF_BC(static BC_STATUS zbc_lex_token(BcLex *l);)
2904IF_DC(static BC_STATUS zdc_lex_token(BcLex *l);)
2905
2915static BC_STATUS zbc_lex_next(BcLex *l) 2906static BC_STATUS zbc_lex_next(BcLex *l)
2916{ 2907{
2917 BcStatus s; 2908 BcStatus s;
@@ -2941,7 +2932,11 @@ static BC_STATUS zbc_lex_next(BcLex *l)
2941 dbg_lex("next string to parse:'%.*s'", 2932 dbg_lex("next string to parse:'%.*s'",
2942 (int)(strchrnul(l->buf + l->i, '\n') - (l->buf + l->i)), 2933 (int)(strchrnul(l->buf + l->i, '\n') - (l->buf + l->i)),
2943 l->buf + l->i); 2934 l->buf + l->i);
2944 s = zcommon_lex_token(l); 2935 if (IS_BC) {
2936 IF_BC(s = zbc_lex_token(l));
2937 } else {
2938 IF_DC(s = zdc_lex_token(l));
2939 }
2945 } while (!s && l->t.t == BC_LEX_WHITESPACE); 2940 } while (!s && l->t.t == BC_LEX_WHITESPACE);
2946 dbg_lex("l->t.t from string:%d", l->t.t); 2941 dbg_lex("l->t.t from string:%d", l->t.t);
2947 2942
@@ -3571,24 +3566,6 @@ static void bc_parse_pushNUM(BcParse *p)
3571 bc_parse_pushIndex(p, idx); 3566 bc_parse_pushIndex(p, idx);
3572} 3567}
3573 3568
3574IF_BC(static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p);)
3575IF_DC(static BC_STATUS zdc_parse_parse(BcParse *p);)
3576
3577// "Parse" half of "parse,execute,repeat" main loop
3578static BC_STATUS zcommon_parse(BcParse *p)
3579{
3580 if (IS_BC) {
3581// FIXME: "eating" of stmt delemiters is coded inconsistently
3582// (sometimes zbc_parse_stmt() eats the delimiter, sometimes don't),
3583// which causes bugs such as "print 1 print 2" erroneously accepted,
3584// or "print 1 else 2" detecting parse error only after executing
3585// "print 1" part.
3586 IF_BC(RETURN_STATUS(zbc_parse_stmt_or_funcdef(p));)
3587 }
3588 IF_DC(RETURN_STATUS(zdc_parse_parse(p));)
3589}
3590#define zcommon_parse(...) (zcommon_parse(__VA_ARGS__) COMMA_SUCCESS)
3591
3592static BC_STATUS zbc_parse_text_init(BcParse *p, const char *text) 3569static BC_STATUS zbc_parse_text_init(BcParse *p, const char *text)
3593{ 3570{
3594 p->func = bc_program_func(p->fidx); 3571 p->func = bc_program_func(p->fidx);
@@ -3612,15 +3589,13 @@ static void bc_program_reset(void)
3612 ip->inst_idx = f->code.len; 3589 ip->inst_idx = f->code.len;
3613} 3590}
3614 3591
3615// Called when zbc/zdc_parse_parse() detects a failure, 3592// Called when parsing code detects a failure,
3616// resets parsing structures. 3593// resets parsing structures.
3617static void bc_parse_reset(BcParse *p) 3594static void bc_parse_reset(BcParse *p)
3618{ 3595{
3619 if (p->fidx != BC_PROG_MAIN) { 3596 if (p->fidx != BC_PROG_MAIN) {
3620 bc_vec_pop_all(&p->func->code); 3597 bc_func_free(p->func);
3621 IF_BC(bc_vec_pop_all(&p->func->labels);) 3598 bc_func_init(p->func);
3622 IF_BC(bc_vec_pop_all(&p->func->autos);)
3623 IF_BC(p->func->nparams = 0;)
3624 3599
3625 p->fidx = BC_PROG_MAIN; 3600 p->fidx = BC_PROG_MAIN;
3626 p->func = bc_program_func_BC_PROG_MAIN(); 3601 p->func = bc_program_func_BC_PROG_MAIN();
@@ -4592,11 +4567,6 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(BcParse *p, bool auto_allowed)
4592 break; 4567 break;
4593 } 4568 }
4594 4569
4595 if (s || G_interrupt) {
4596 bc_parse_reset(p);
4597 s = BC_STATUS_FAILURE;
4598 }
4599
4600 dbg_lex_done("%s:%d done", __func__, __LINE__); 4570 dbg_lex_done("%s:%d done", __func__, __LINE__);
4601 RETURN_STATUS(s); 4571 RETURN_STATUS(s);
4602} 4572}
@@ -4980,13 +4950,13 @@ static BC_STATUS zdc_parse_expr(BcParse *p)
4980{ 4950{
4981 BcLexType t; 4951 BcLexType t;
4982 4952
4983 dbg_lex_enter("%s:%d entered G.prs.l.t.t:%d", __func__, __LINE__, G.prs.l.t.t); 4953 dbg_lex_enter("%s:%d entered, p->l.t.t:%d", __func__, __LINE__, p->l.t.t);
4984 for (;;) { 4954 for (;;) {
4985 BcInst inst; 4955 BcInst inst;
4986 BcStatus s; 4956 BcStatus s;
4987 4957
4988 t = p->l.t.t; 4958 t = p->l.t.t;
4989 dbg_lex("%s:%d G.prs.l.t.t:%d", __func__, __LINE__, G.prs.l.t.t); 4959 dbg_lex("%s:%d p->l.t.t:%d", __func__, __LINE__, p->l.t.t);
4990 if (t == BC_LEX_EOF) break; 4960 if (t == BC_LEX_EOF) break;
4991 4961
4992 inst = dc_parse_insts[t]; 4962 inst = dc_parse_insts[t];
@@ -5006,26 +4976,6 @@ static BC_STATUS zdc_parse_expr(BcParse *p)
5006} 4976}
5007#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS) 4977#define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__) COMMA_SUCCESS)
5008 4978
5009static BC_STATUS zdc_parse_parse(BcParse *p)
5010{
5011 BcStatus s;
5012
5013 dbg_lex_enter("%s:%d entered", __func__, __LINE__);
5014 if (p->l.t.t == BC_LEX_EOF)
5015 s = bc_error("end of file");
5016 else
5017 s = zdc_parse_expr(p);
5018
5019 if (s || G_interrupt) {
5020 bc_parse_reset(p);
5021 s = BC_STATUS_FAILURE;
5022 }
5023
5024 dbg_lex_done("%s:%d done", __func__, __LINE__);
5025 RETURN_STATUS(s);
5026}
5027#define zdc_parse_parse(...) (zdc_parse_parse(__VA_ARGS__) COMMA_SUCCESS)
5028
5029#endif // ENABLE_DC 4979#endif // ENABLE_DC
5030 4980
5031static BcVec* bc_program_search(char *id, bool var) 4981static BcVec* bc_program_search(char *id, bool var)
@@ -6687,8 +6637,26 @@ static BC_STATUS zbc_vm_process(const char *text)
6687 6637
6688 while (G.prs.l.t.t != BC_LEX_EOF) { 6638 while (G.prs.l.t.t != BC_LEX_EOF) {
6689 dbg_lex("%s:%d G.prs.l.t.t:%d, parsing...", __func__, __LINE__, G.prs.l.t.t); 6639 dbg_lex("%s:%d G.prs.l.t.t:%d, parsing...", __func__, __LINE__, G.prs.l.t.t);
6690 s = zcommon_parse(&G.prs); 6640 if (IS_BC) {
6691 if (s) RETURN_STATUS(s); 6641// FIXME: "eating" of stmt delemiters is coded inconsistently
6642// (sometimes zbc_parse_stmt() eats the delimiter, sometimes don't),
6643// which causes bugs such as "print 1 print 2" erroneously accepted,
6644// or "print 1 else 2" detecting parse error only after executing
6645// "print 1" part.
6646 IF_BC(s = zbc_parse_stmt_or_funcdef(&G.prs));
6647 } else {
6648#if ENABLE_DC
6649 if (G.prs.l.t.t == BC_LEX_EOF)
6650 s = bc_error("end of file");
6651 else
6652 s = zdc_parse_expr(&G.prs);
6653#endif
6654 }
6655 if (s || G_interrupt) {
6656 bc_parse_reset(&G.prs); // includes bc_program_reset()
6657 RETURN_STATUS(BC_STATUS_FAILURE);
6658 }
6659
6692 dbg_lex("%s:%d executing...", __func__, __LINE__); 6660 dbg_lex("%s:%d executing...", __func__, __LINE__);
6693 s = zbc_program_exec(); 6661 s = zbc_program_exec();
6694 if (s) { 6662 if (s) {