aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c226
1 files changed, 114 insertions, 112 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index f942d42ac..73c801c44 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -618,7 +618,7 @@ struct BcParse;
618 618
619struct BcProgram; 619struct BcProgram;
620 620
621typedef BcStatus (*BcParseParse)(struct BcParse *) FAST_FUNC; 621typedef BC_STATUS (*BcParseParse)(struct BcParse *) FAST_FUNC;
622 622
623typedef struct BcParse { 623typedef struct BcParse {
624 624
@@ -1364,8 +1364,8 @@ static int push_input_byte(BcVec *vec, char c)
1364 return 0; 1364 return 0;
1365} 1365}
1366 1366
1367// This is not a "z" function: can also return BC_STATUS_EOF 1367// This is not a "z" function:
1368// Can return success (0) or BC_STATUS_EOF. 1368// can return success (0) or BC_STATUS_EOF.
1369// Exits with error message if read error is detected. 1369// Exits with error message if read error is detected.
1370static BcStatus bc_read_line(BcVec *vec) 1370static BcStatus bc_read_line(BcVec *vec)
1371{ 1371{
@@ -2305,12 +2305,8 @@ static BC_STATUS zbc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
2305 else 2305 else
2306 bc_num_expand(c, req); 2306 bc_num_expand(c, req);
2307 2307
2308#if !ERRORS_ARE_FATAL
2309 s = op(ptr_a, ptr_b, c, scale);
2310#else
2311 op(ptr_a, ptr_b, c, scale);
2312 s = BC_STATUS_SUCCESS; 2308 s = BC_STATUS_SUCCESS;
2313#endif 2309 ERROR_RETURN(s =) op(ptr_a, ptr_b, c, scale);
2314 2310
2315 if (init) bc_num_free(&num2); 2311 if (init) bc_num_free(&num2);
2316 2312
@@ -3032,25 +3028,26 @@ static BC_STATUS zbc_lex_identifier(BcLex *l)
3032# define zbc_lex_identifier(...) (zbc_lex_identifier(__VA_ARGS__), BC_STATUS_SUCCESS) 3028# define zbc_lex_identifier(...) (zbc_lex_identifier(__VA_ARGS__), BC_STATUS_SUCCESS)
3033#endif 3029#endif
3034 3030
3035static BcStatus bc_lex_string(BcLex *l) 3031static BC_STATUS zbc_lex_string(BcLex *l)
3036{ 3032{
3037 size_t len, nls = 0, i = l->i; 3033 size_t len, nls = 0, i = l->i;
3038 char c; 3034 char c;
3039 3035
3040 l->t.t = BC_LEX_STR; 3036 l->t.t = BC_LEX_STR;
3041 3037
3042 for (c = l->buf[i]; c != 0 && c != '"'; c = l->buf[++i]) nls += (c == '\n'); 3038 for (c = l->buf[i]; c != 0 && c != '"'; c = l->buf[++i])
3039 nls += (c == '\n');
3043 3040
3044 if (c == '\0') { 3041 if (c == '\0') {
3045 l->i = i; 3042 l->i = i;
3046 return bc_error("string end could not be found"); 3043 RETURN_STATUS(bc_error("string end could not be found"));
3047 } 3044 }
3048 3045
3049 len = i - l->i; 3046 len = i - l->i;
3050 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. 3047 // This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
3051 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { 3048 if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
3052 if (len > BC_MAX_STRING) 3049 if (len > BC_MAX_STRING)
3053 return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"); 3050 RETURN_STATUS(("string too long: must be [1,"BC_MAX_STRING_STR"]"));
3054 } 3051 }
3055 bc_vec_string(&l->t.v, len, l->buf + l->i); 3052 bc_vec_string(&l->t.v, len, l->buf + l->i);
3056 3053
@@ -3058,8 +3055,11 @@ static BcStatus bc_lex_string(BcLex *l)
3058 l->line += nls; 3055 l->line += nls;
3059 G.err_line = l->line; 3056 G.err_line = l->line;
3060 3057
3061 return BC_STATUS_SUCCESS; 3058 RETURN_STATUS(BC_STATUS_SUCCESS);
3062} 3059}
3060#if ERRORS_ARE_FATAL
3061# define zbc_lex_string(...) (zbc_lex_string(__VA_ARGS__), BC_STATUS_SUCCESS)
3062#endif
3063 3063
3064static void bc_lex_assign(BcLex *l, BcLexType with, BcLexType without) 3064static void bc_lex_assign(BcLex *l, BcLexType with, BcLexType without)
3065{ 3065{
@@ -3132,7 +3132,7 @@ static FAST_FUNC BC_STATUS zbc_lex_token(BcLex *l)
3132 } 3132 }
3133 break; 3133 break;
3134 case '"': 3134 case '"':
3135 s = bc_lex_string(l); 3135 s = zbc_lex_string(l);
3136 break; 3136 break;
3137 case '#': 3137 case '#':
3138 s = bc_POSIX_does_not_allow("'#' script comments"); 3138 s = bc_POSIX_does_not_allow("'#' script comments");
@@ -3462,6 +3462,7 @@ static void bc_parse_pushIndex(BcParse *p, size_t idx)
3462{ 3462{
3463 unsigned char amt, i, nums[sizeof(size_t)]; 3463 unsigned char amt, i, nums[sizeof(size_t)];
3464 3464
3465///oh boy
3465 for (amt = 0; idx; ++amt) { 3466 for (amt = 0; idx; ++amt) {
3466 nums[amt] = (char) idx; 3467 nums[amt] = (char) idx;
3467 idx = (idx & ((unsigned long) ~(UCHAR_MAX))) >> sizeof(char) * CHAR_BIT; 3468 idx = (idx & ((unsigned long) ~(UCHAR_MAX))) >> sizeof(char) * CHAR_BIT;
@@ -3485,7 +3486,7 @@ static void bc_parse_number(BcParse *p, BcInst *prev, size_t *nexs)
3485 (*prev) = BC_INST_NUM; 3486 (*prev) = BC_INST_NUM;
3486} 3487}
3487 3488
3488static BcStatus bc_parse_text(BcParse *p, const char *text) 3489static BC_STATUS zbc_parse_text(BcParse *p, const char *text)
3489{ 3490{
3490 BcStatus s; 3491 BcStatus s;
3491 3492
@@ -3493,14 +3494,18 @@ static BcStatus bc_parse_text(BcParse *p, const char *text)
3493 3494
3494 if (!text[0] && !BC_PARSE_CAN_EXEC(p)) { 3495 if (!text[0] && !BC_PARSE_CAN_EXEC(p)) {
3495 p->l.t.t = BC_LEX_INVALID; 3496 p->l.t.t = BC_LEX_INVALID;
3496 s = p->parse(p); 3497 s = BC_STATUS_SUCCESS;
3497 if (s) return s; 3498 ERROR_RETURN(s =) p->parse(p);
3499 if (s) RETURN_STATUS(s);
3498 if (!BC_PARSE_CAN_EXEC(p)) 3500 if (!BC_PARSE_CAN_EXEC(p))
3499 return bc_error("file is not executable"); 3501 RETURN_STATUS(bc_error("file is not executable"));
3500 } 3502 }
3501 3503
3502 return zbc_lex_text(&p->l, text); 3504 RETURN_STATUS(zbc_lex_text(&p->l, text));
3503} 3505}
3506#if ERRORS_ARE_FATAL
3507# define zbc_parse_text(...) (zbc_parse_text(__VA_ARGS__), BC_STATUS_SUCCESS)
3508#endif
3504 3509
3505// Called when parsing or execution detects a failure, 3510// Called when parsing or execution detects a failure,
3506// resets execution structures. 3511// resets execution structures.
@@ -3520,7 +3525,7 @@ static void bc_program_reset(void)
3520#define bc_parse_updateFunc(p, f) \ 3525#define bc_parse_updateFunc(p, f) \
3521 ((p)->func = bc_program_func((p)->fidx = (f))) 3526 ((p)->func = bc_program_func((p)->fidx = (f)))
3522 3527
3523// Called when bc/dc_parse_parse() detects a failure, 3528// Called when zbc/zdc_parse_parse() detects a failure,
3524// resets parsing structures. 3529// resets parsing structures.
3525static void bc_parse_reset(BcParse *p) 3530static void bc_parse_reset(BcParse *p)
3526{ 3531{
@@ -3650,36 +3655,38 @@ static BC_STATUS zbc_parse_rightParen(BcParse *p, size_t ops_bgn, size_t *nexs)
3650# define zbc_parse_rightParen(...) (zbc_parse_rightParen(__VA_ARGS__), BC_STATUS_SUCCESS) 3655# define zbc_parse_rightParen(...) (zbc_parse_rightParen(__VA_ARGS__), BC_STATUS_SUCCESS)
3651#endif 3656#endif
3652 3657
3653static BcStatus bc_parse_params(BcParse *p, uint8_t flags) 3658static BC_STATUS zbc_parse_params(BcParse *p, uint8_t flags)
3654{ 3659{
3655 BcStatus s; 3660 BcStatus s;
3656 bool comma = false; 3661 bool comma = false;
3657 size_t nparams; 3662 size_t nparams;
3658 3663
3659 s = zbc_lex_next(&p->l); 3664 s = zbc_lex_next(&p->l);
3660 if (s) return s; 3665 if (s) RETURN_STATUS(s);
3661 3666
3662 for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) { 3667 for (nparams = 0; p->l.t.t != BC_LEX_RPAREN; ++nparams) {
3663
3664 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3668 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3665 s = zbc_parse_expr(p, flags, bc_parse_next_param); 3669 s = zbc_parse_expr(p, flags, bc_parse_next_param);
3666 if (s) return s; 3670 if (s) RETURN_STATUS(s);
3667 3671
3668 comma = p->l.t.t == BC_LEX_COMMA; 3672 comma = p->l.t.t == BC_LEX_COMMA;
3669 if (comma) { 3673 if (comma) {
3670 s = zbc_lex_next(&p->l); 3674 s = zbc_lex_next(&p->l);
3671 if (s) return s; 3675 if (s) RETURN_STATUS(s);
3672 } 3676 }
3673 } 3677 }
3674 3678
3675 if (comma) return bc_error_bad_token(); 3679 if (comma) RETURN_STATUS(bc_error_bad_token());
3676 bc_parse_push(p, BC_INST_CALL); 3680 bc_parse_push(p, BC_INST_CALL);
3677 bc_parse_pushIndex(p, nparams); 3681 bc_parse_pushIndex(p, nparams);
3678 3682
3679 return BC_STATUS_SUCCESS; 3683 RETURN_STATUS(BC_STATUS_SUCCESS);
3680} 3684}
3685#if ERRORS_ARE_FATAL
3686# define zbc_parse_params(...) (zbc_parse_params(__VA_ARGS__), BC_STATUS_SUCCESS)
3687#endif
3681 3688
3682static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags) 3689static BC_STATUS zbc_parse_call(BcParse *p, char *name, uint8_t flags)
3683{ 3690{
3684 BcStatus s; 3691 BcStatus s;
3685 BcId entry, *entry_ptr; 3692 BcId entry, *entry_ptr;
@@ -3687,7 +3694,7 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags)
3687 3694
3688 entry.name = name; 3695 entry.name = name;
3689 3696
3690 s = bc_parse_params(p, flags); 3697 s = zbc_parse_params(p, flags);
3691 if (s) goto err; 3698 if (s) goto err;
3692 3699
3693 if (p->l.t.t != BC_LEX_RPAREN) { 3700 if (p->l.t.t != BC_LEX_RPAREN) {
@@ -3702,21 +3709,23 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags)
3702 bc_parse_addFunc(p, name, &idx); 3709 bc_parse_addFunc(p, name, &idx);
3703 idx = bc_map_index(&G.prog.fn_map, &entry); 3710 idx = bc_map_index(&G.prog.fn_map, &entry);
3704 free(entry.name); 3711 free(entry.name);
3705 } 3712 } else
3706 else
3707 free(name); 3713 free(name);
3708 3714
3709 entry_ptr = bc_vec_item(&G.prog.fn_map, idx); 3715 entry_ptr = bc_vec_item(&G.prog.fn_map, idx);
3710 bc_parse_pushIndex(p, entry_ptr->idx); 3716 bc_parse_pushIndex(p, entry_ptr->idx);
3711 3717
3712 return zbc_lex_next(&p->l); 3718 RETURN_STATUS(zbc_lex_next(&p->l));
3713 3719
3714err: 3720err:
3715 free(name); 3721 free(name);
3716 return s; 3722 RETURN_STATUS(s);
3717} 3723}
3724#if ERRORS_ARE_FATAL
3725# define zbc_parse_call(...) (zbc_parse_call(__VA_ARGS__), BC_STATUS_SUCCESS)
3726#endif
3718 3727
3719static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags) 3728static BC_STATUS zbc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3720{ 3729{
3721 BcStatus s; 3730 BcStatus s;
3722 char *name; 3731 char *name;
@@ -3726,55 +3735,48 @@ static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags)
3726 if (s) goto err; 3735 if (s) goto err;
3727 3736
3728 if (p->l.t.t == BC_LEX_LBRACKET) { 3737 if (p->l.t.t == BC_LEX_LBRACKET) {
3729
3730 s = zbc_lex_next(&p->l); 3738 s = zbc_lex_next(&p->l);
3731 if (s) goto err; 3739 if (s) goto err;
3732 3740
3733 if (p->l.t.t == BC_LEX_RBRACKET) { 3741 if (p->l.t.t == BC_LEX_RBRACKET) {
3734
3735 if (!(flags & BC_PARSE_ARRAY)) { 3742 if (!(flags & BC_PARSE_ARRAY)) {
3736 s = bc_error_bad_expression(); 3743 s = bc_error_bad_expression();
3737 goto err; 3744 goto err;
3738 } 3745 }
3739
3740 *type = BC_INST_ARRAY; 3746 *type = BC_INST_ARRAY;
3741 } 3747 } else {
3742 else {
3743
3744 *type = BC_INST_ARRAY_ELEM; 3748 *type = BC_INST_ARRAY_ELEM;
3745
3746 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL); 3749 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
3747 s = zbc_parse_expr(p, flags, bc_parse_next_elem); 3750 s = zbc_parse_expr(p, flags, bc_parse_next_elem);
3748 if (s) goto err; 3751 if (s) goto err;
3749 } 3752 }
3750
3751 s = zbc_lex_next(&p->l); 3753 s = zbc_lex_next(&p->l);
3752 if (s) goto err; 3754 if (s) goto err;
3753 bc_parse_push(p, *type); 3755 bc_parse_push(p, *type);
3754 bc_parse_pushName(p, name); 3756 bc_parse_pushName(p, name);
3755 } 3757 }
3756 else if (p->l.t.t == BC_LEX_LPAREN) { 3758 else if (p->l.t.t == BC_LEX_LPAREN) {
3757
3758 if (flags & BC_PARSE_NOCALL) { 3759 if (flags & BC_PARSE_NOCALL) {
3759 s = bc_error_bad_token(); 3760 s = bc_error_bad_token();
3760 goto err; 3761 goto err;
3761 } 3762 }
3762
3763 *type = BC_INST_CALL; 3763 *type = BC_INST_CALL;
3764 s = bc_parse_call(p, name, flags); 3764 s = zbc_parse_call(p, name, flags);
3765 } 3765 } else {
3766 else {
3767 *type = BC_INST_VAR; 3766 *type = BC_INST_VAR;
3768 bc_parse_push(p, BC_INST_VAR); 3767 bc_parse_push(p, BC_INST_VAR);
3769 bc_parse_pushName(p, name); 3768 bc_parse_pushName(p, name);
3770 } 3769 }
3771 3770
3772 return s; 3771 RETURN_STATUS(s);
3773 3772
3774err: 3773err:
3775 free(name); 3774 free(name);
3776 return s; 3775 RETURN_STATUS(s);
3777} 3776}
3777#if ERRORS_ARE_FATAL
3778# define zbc_parse_name(...) (zbc_parse_name(__VA_ARGS__), BC_STATUS_SUCCESS)
3779#endif
3778 3780
3779static BC_STATUS zbc_parse_read(BcParse *p) 3781static BC_STATUS zbc_parse_read(BcParse *p)
3780{ 3782{
@@ -3796,59 +3798,66 @@ static BC_STATUS zbc_parse_read(BcParse *p)
3796# define zbc_parse_read(...) (zbc_parse_read(__VA_ARGS__), BC_STATUS_SUCCESS) 3798# define zbc_parse_read(...) (zbc_parse_read(__VA_ARGS__), BC_STATUS_SUCCESS)
3797#endif 3799#endif
3798 3800
3799static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, 3801static BC_STATUS zbc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags,
3800 BcInst *prev) 3802 BcInst *prev)
3801{ 3803{
3802 BcStatus s; 3804 BcStatus s;
3803 3805
3804 s = zbc_lex_next(&p->l); 3806 s = zbc_lex_next(&p->l);
3805 if (s) return s; 3807 if (s) RETURN_STATUS(s);
3806 if (p->l.t.t != BC_LEX_LPAREN) return bc_error_bad_token(); 3808 if (p->l.t.t != BC_LEX_LPAREN) RETURN_STATUS(bc_error_bad_token());
3807 3809
3808 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY; 3810 flags = (flags & ~(BC_PARSE_PRINT | BC_PARSE_REL)) | BC_PARSE_ARRAY;
3809 3811
3810 s = zbc_lex_next(&p->l); 3812 s = zbc_lex_next(&p->l);
3811 if (s) return s; 3813 if (s) RETURN_STATUS(s);
3812 3814
3813 s = zbc_parse_expr(p, flags, bc_parse_next_rel); 3815 s = zbc_parse_expr(p, flags, bc_parse_next_rel);
3814 if (s) return s; 3816 if (s) RETURN_STATUS(s);
3815 3817
3816 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 3818 if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token());
3817 3819
3818 *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT; 3820 *prev = (type == BC_LEX_KEY_LENGTH) ? BC_INST_LENGTH : BC_INST_SQRT;
3819 bc_parse_push(p, *prev); 3821 bc_parse_push(p, *prev);
3820 3822
3821 return zbc_lex_next(&p->l); 3823 RETURN_STATUS(zbc_lex_next(&p->l));
3822} 3824}
3825#if ERRORS_ARE_FATAL
3826# define zbc_parse_builtin(...) (zbc_parse_builtin(__VA_ARGS__), BC_STATUS_SUCCESS)
3827#endif
3823 3828
3824static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags) 3829static BC_STATUS zbc_parse_scale(BcParse *p, BcInst *type, uint8_t flags)
3825{ 3830{
3826 BcStatus s; 3831 BcStatus s;
3827 3832
3828 s = zbc_lex_next(&p->l); 3833 s = zbc_lex_next(&p->l);
3829 if (s) return s; 3834 if (s) RETURN_STATUS(s);
3830 3835
3831 if (p->l.t.t != BC_LEX_LPAREN) { 3836 if (p->l.t.t != BC_LEX_LPAREN) {
3832 *type = BC_INST_SCALE; 3837 *type = BC_INST_SCALE;
3833 bc_parse_push(p, BC_INST_SCALE); 3838 bc_parse_push(p, BC_INST_SCALE);
3834 return BC_STATUS_SUCCESS; 3839 RETURN_STATUS(BC_STATUS_SUCCESS);
3835 } 3840 }
3836 3841
3837 *type = BC_INST_SCALE_FUNC; 3842 *type = BC_INST_SCALE_FUNC;
3838 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL); 3843 flags &= ~(BC_PARSE_PRINT | BC_PARSE_REL);
3839 3844
3840 s = zbc_lex_next(&p->l); 3845 s = zbc_lex_next(&p->l);
3841 if (s) return s; 3846 if (s) RETURN_STATUS(s);
3842 3847
3843 s = zbc_parse_expr(p, flags, bc_parse_next_rel); 3848 s = zbc_parse_expr(p, flags, bc_parse_next_rel);
3844 if (s) return s; 3849 if (s) RETURN_STATUS(s);
3845 if (p->l.t.t != BC_LEX_RPAREN) return bc_error_bad_token(); 3850 if (p->l.t.t != BC_LEX_RPAREN)
3851 RETURN_STATUS(bc_error_bad_token());
3846 bc_parse_push(p, BC_INST_SCALE_FUNC); 3852 bc_parse_push(p, BC_INST_SCALE_FUNC);
3847 3853
3848 return zbc_lex_next(&p->l); 3854 RETURN_STATUS(zbc_lex_next(&p->l));
3849} 3855}
3856#if ERRORS_ARE_FATAL
3857# define zbc_parse_scale(...) (zbc_parse_scale(__VA_ARGS__), BC_STATUS_SUCCESS)
3858#endif
3850 3859
3851static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, 3860static BC_STATUS zbc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
3852 size_t *nexprs, uint8_t flags) 3861 size_t *nexprs, uint8_t flags)
3853{ 3862{
3854 BcStatus s; 3863 BcStatus s;
@@ -3865,12 +3874,11 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
3865 s = zbc_lex_next(&p->l); 3874 s = zbc_lex_next(&p->l);
3866 } 3875 }
3867 else { 3876 else {
3868
3869 *prev = inst = BC_INST_INC_PRE + (p->l.t.t != BC_LEX_OP_INC); 3877 *prev = inst = BC_INST_INC_PRE + (p->l.t.t != BC_LEX_OP_INC);
3870 *paren_expr = true; 3878 *paren_expr = true;
3871 3879
3872 s = zbc_lex_next(&p->l); 3880 s = zbc_lex_next(&p->l);
3873 if (s) return s; 3881 if (s) RETURN_STATUS(s);
3874 type = p->l.t.t; 3882 type = p->l.t.t;
3875 3883
3876 // Because we parse the next part of the expression 3884 // Because we parse the next part of the expression
@@ -3878,45 +3886,36 @@ static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr,
3878 *nexprs = *nexprs + 1; 3886 *nexprs = *nexprs + 1;
3879 3887
3880 switch (type) { 3888 switch (type) {
3881
3882 case BC_LEX_NAME: 3889 case BC_LEX_NAME:
3883 { 3890 s = zbc_parse_name(p, prev, flags | BC_PARSE_NOCALL);
3884 s = bc_parse_name(p, prev, flags | BC_PARSE_NOCALL);
3885 break; 3891 break;
3886 }
3887
3888 case BC_LEX_KEY_IBASE: 3892 case BC_LEX_KEY_IBASE:
3889 case BC_LEX_KEY_LAST: 3893 case BC_LEX_KEY_LAST:
3890 case BC_LEX_KEY_OBASE: 3894 case BC_LEX_KEY_OBASE:
3891 {
3892 bc_parse_push(p, type - BC_LEX_KEY_IBASE + BC_INST_IBASE); 3895 bc_parse_push(p, type - BC_LEX_KEY_IBASE + BC_INST_IBASE);
3893 s = zbc_lex_next(&p->l); 3896 s = zbc_lex_next(&p->l);
3894 break; 3897 break;
3895 }
3896
3897 case BC_LEX_KEY_SCALE: 3898 case BC_LEX_KEY_SCALE:
3898 {
3899 s = zbc_lex_next(&p->l); 3899 s = zbc_lex_next(&p->l);
3900 if (s) return s; 3900 if (s) RETURN_STATUS(s);
3901 if (p->l.t.t == BC_LEX_LPAREN) 3901 if (p->l.t.t == BC_LEX_LPAREN)
3902 s = bc_error_bad_token(); 3902 s = bc_error_bad_token();
3903 else 3903 else
3904 bc_parse_push(p, BC_INST_SCALE); 3904 bc_parse_push(p, BC_INST_SCALE);
3905 break; 3905 break;
3906 }
3907
3908 default: 3906 default:
3909 {
3910 s = bc_error_bad_token(); 3907 s = bc_error_bad_token();
3911 break; 3908 break;
3912 }
3913 } 3909 }
3914 3910
3915 if (!s) bc_parse_push(p, inst); 3911 if (!s) bc_parse_push(p, inst);
3916 } 3912 }
3917 3913
3918 return s; 3914 RETURN_STATUS(s);
3919} 3915}
3916#if ERRORS_ARE_FATAL
3917# define zbc_parse_incdec(...) (zbc_parse_incdec(__VA_ARGS__), BC_STATUS_SUCCESS)
3918#endif
3920 3919
3921static BC_STATUS zbc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, 3920static BC_STATUS zbc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn,
3922 bool rparen, size_t *nexprs) 3921 bool rparen, size_t *nexprs)
@@ -4634,17 +4633,17 @@ static BC_STATUS zbc_parse_stmt(BcParse *p)
4634# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS) 4633# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS)
4635#endif 4634#endif
4636 4635
4637static FAST_FUNC BcStatus bc_parse_parse(BcParse *p) 4636static FAST_FUNC BC_STATUS zbc_parse_parse(BcParse *p)
4638{ 4637{
4639 BcStatus s; 4638 BcStatus s;
4640 4639
4641 if (p->l.t.t == BC_LEX_EOF) 4640 if (p->l.t.t == BC_LEX_EOF)
4642 s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file"); 4641 s = p->flags.len > 0 ? bc_error("block end could not be found") : bc_error("end of file");
4643 else if (p->l.t.t == BC_LEX_KEY_DEFINE) { 4642 else if (p->l.t.t == BC_LEX_KEY_DEFINE) {
4644 if (!BC_PARSE_CAN_EXEC(p)) return bc_error_bad_token(); 4643 if (!BC_PARSE_CAN_EXEC(p))
4644 RETURN_STATUS(bc_error_bad_token());
4645 s = zbc_parse_func(p); 4645 s = zbc_parse_func(p);
4646 } 4646 } else
4647 else
4648 s = zbc_parse_stmt(p); 4647 s = zbc_parse_stmt(p);
4649 4648
4650 if (s || G_interrupt) { 4649 if (s || G_interrupt) {
@@ -4652,8 +4651,11 @@ static FAST_FUNC BcStatus bc_parse_parse(BcParse *p)
4652 s = BC_STATUS_FAILURE; 4651 s = BC_STATUS_FAILURE;
4653 } 4652 }
4654 4653
4655 return s; 4654 RETURN_STATUS(s);
4656} 4655}
4656#if ERRORS_ARE_FATAL
4657# define zbc_parse_parse(...) (zbc_parse_parse(__VA_ARGS__), BC_STATUS_SUCCESS)
4658#endif
4657 4659
4658// This is not a "z" function: can also return BC_STATUS_PARSE_EMPTY_EXP 4660// This is not a "z" function: can also return BC_STATUS_PARSE_EMPTY_EXP
4659static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext next) 4661static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext next)
@@ -4676,7 +4678,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4676 case BC_LEX_OP_INC: 4678 case BC_LEX_OP_INC:
4677 case BC_LEX_OP_DEC: 4679 case BC_LEX_OP_DEC:
4678 { 4680 {
4679 s = bc_parse_incdec(p, &prev, &paren_expr, &nexprs, flags); 4681 s = zbc_parse_incdec(p, &prev, &paren_expr, &nexprs, flags);
4680 rprn = get_token = bin_last = false; 4682 rprn = get_token = bin_last = false;
4681 break; 4683 break;
4682 } 4684 }
@@ -4781,7 +4783,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4781 return bc_error_bad_expression(); 4783 return bc_error_bad_expression();
4782 paren_expr = true; 4784 paren_expr = true;
4783 rprn = get_token = bin_last = false; 4785 rprn = get_token = bin_last = false;
4784 s = bc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL); 4786 s = zbc_parse_name(p, &prev, flags & ~BC_PARSE_NOCALL);
4785 ++nexprs; 4787 ++nexprs;
4786 4788
4787 break; 4789 break;
@@ -4819,7 +4821,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4819 { 4821 {
4820 if (BC_PARSE_LEAF(prev, rprn)) 4822 if (BC_PARSE_LEAF(prev, rprn))
4821 return bc_error_bad_expression(); 4823 return bc_error_bad_expression();
4822 s = bc_parse_builtin(p, t, flags, &prev); 4824 s = zbc_parse_builtin(p, t, flags, &prev);
4823 paren_expr = true; 4825 paren_expr = true;
4824 rprn = get_token = bin_last = false; 4826 rprn = get_token = bin_last = false;
4825 ++nexprs; 4827 ++nexprs;
@@ -4848,7 +4850,7 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext ne
4848 { 4850 {
4849 if (BC_PARSE_LEAF(prev, rprn)) 4851 if (BC_PARSE_LEAF(prev, rprn))
4850 return bc_error_bad_expression(); 4852 return bc_error_bad_expression();
4851 s = bc_parse_scale(p, &prev, flags); 4853 s = zbc_parse_scale(p, &prev, flags);
4852 paren_expr = true; 4854 paren_expr = true;
4853 rprn = get_token = bin_last = false; 4855 rprn = get_token = bin_last = false;
4854 ++nexprs; 4856 ++nexprs;
@@ -4931,7 +4933,7 @@ static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4931 4933
4932static void bc_parse_init(BcParse *p, size_t func) 4934static void bc_parse_init(BcParse *p, size_t func)
4933{ 4935{
4934 bc_parse_create(p, func, bc_parse_parse, zbc_lex_token); 4936 bc_parse_create(p, func, zbc_parse_parse, zbc_lex_token);
4935} 4937}
4936 4938
4937static BC_STATUS zbc_parse_expression(BcParse *p, uint8_t flags) 4939static BC_STATUS zbc_parse_expression(BcParse *p, uint8_t flags)
@@ -5135,7 +5137,7 @@ static BC_STATUS zdc_parse_expr(BcParse *p, uint8_t flags)
5135# define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS) 5137# define zdc_parse_expr(...) (zdc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
5136#endif 5138#endif
5137 5139
5138static FAST_FUNC BcStatus dc_parse_parse(BcParse *p) 5140static FAST_FUNC BC_STATUS zdc_parse_parse(BcParse *p)
5139{ 5141{
5140 BcStatus s; 5142 BcStatus s;
5141 5143
@@ -5149,12 +5151,15 @@ static FAST_FUNC BcStatus dc_parse_parse(BcParse *p)
5149 s = BC_STATUS_FAILURE; 5151 s = BC_STATUS_FAILURE;
5150 } 5152 }
5151 5153
5152 return s; 5154 RETURN_STATUS(s);
5153} 5155}
5156#if ERRORS_ARE_FATAL
5157# define zdc_parse_parse(...) (zdc_parse_parse(__VA_ARGS__), BC_STATUS_SUCCESS)
5158#endif
5154 5159
5155static void dc_parse_init(BcParse *p, size_t func) 5160static void dc_parse_init(BcParse *p, size_t func)
5156{ 5161{
5157 bc_parse_create(p, func, dc_parse_parse, zdc_lex_token); 5162 bc_parse_create(p, func, zdc_parse_parse, zdc_lex_token);
5158} 5163}
5159 5164
5160#endif // ENABLE_DC 5165#endif // ENABLE_DC
@@ -5368,10 +5373,7 @@ static BC_STATUS zbc_program_op(char inst)
5368 bc_num_init_DEF_SIZE(&res.d.n); 5373 bc_num_init_DEF_SIZE(&res.d.n);
5369 5374
5370 s = BC_STATUS_SUCCESS; 5375 s = BC_STATUS_SUCCESS;
5371#if !ERRORS_ARE_FATAL 5376 ERROR_RETURN(s =) zbc_program_ops[inst - BC_INST_POWER](n1, n2, &res.d.n, G.prog.scale);
5372 s =
5373#endif
5374 zbc_program_ops[inst - BC_INST_POWER](n1, n2, &res.d.n, G.prog.scale);
5375 if (s) goto err; 5377 if (s) goto err;
5376 bc_program_binOpRetire(&res); 5378 bc_program_binOpRetire(&res);
5377 5379
@@ -5385,7 +5387,7 @@ err:
5385# define zbc_program_op(...) (zbc_program_op(__VA_ARGS__), BC_STATUS_SUCCESS) 5387# define zbc_program_op(...) (zbc_program_op(__VA_ARGS__), BC_STATUS_SUCCESS)
5386#endif 5388#endif
5387 5389
5388static BcStatus bc_program_read(void) 5390static BC_STATUS zbc_program_read(void)
5389{ 5391{
5390 const char *sv_file; 5392 const char *sv_file;
5391 BcStatus s; 5393 BcStatus s;
@@ -5395,7 +5397,7 @@ static BcStatus bc_program_read(void)
5395 BcFunc *f; 5397 BcFunc *f;
5396 5398
5397 if (G.in_read) 5399 if (G.in_read)
5398 return bc_error_nested_read_call(); 5400 RETURN_STATUS(bc_error_nested_read_call());
5399 5401
5400 f = bc_program_func(BC_PROG_READ); 5402 f = bc_program_func(BC_PROG_READ);
5401 bc_vec_pop_all(&f->code); 5403 bc_vec_pop_all(&f->code);
@@ -5411,7 +5413,7 @@ static BcStatus bc_program_read(void)
5411 common_parse_init(&parse, BC_PROG_READ); 5413 common_parse_init(&parse, BC_PROG_READ);
5412 bc_lex_file(&parse.l); 5414 bc_lex_file(&parse.l);
5413 5415
5414 s = bc_parse_text(&parse, buf.v); 5416 s = zbc_parse_text(&parse, buf.v);
5415 if (s) goto exec_err; 5417 if (s) goto exec_err;
5416 s = zcommon_parse_expr(&parse, BC_PARSE_NOREAD); 5418 s = zcommon_parse_expr(&parse, BC_PARSE_NOREAD);
5417 if (s) goto exec_err; 5419 if (s) goto exec_err;
@@ -5437,8 +5439,11 @@ exec_err:
5437 G.in_read = 0; 5439 G.in_read = 0;
5438 G.prog.file = sv_file; 5440 G.prog.file = sv_file;
5439 bc_vec_free(&buf); 5441 bc_vec_free(&buf);
5440 return s; 5442 RETURN_STATUS(s);
5441} 5443}
5444#if ERRORS_ARE_FATAL
5445# define zbc_program_read(...) (zbc_program_read(__VA_ARGS__), BC_STATUS_SUCCESS)
5446#endif
5442 5447
5443static size_t bc_program_index(char *code, size_t *bgn) 5448static size_t bc_program_index(char *code, size_t *bgn)
5444{ 5449{
@@ -5958,10 +5963,7 @@ static BC_STATUS zbc_program_assign(char inst)
5958 bc_num_copy(l, r); 5963 bc_num_copy(l, r);
5959 else { 5964 else {
5960 s = BC_STATUS_SUCCESS; 5965 s = BC_STATUS_SUCCESS;
5961#if !ERRORS_ARE_FATAL 5966 ERROR_RETURN(s =) zbc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, G.prog.scale);
5962 s =
5963#endif
5964 zbc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, G.prog.scale);
5965 } 5967 }
5966 if (s) RETURN_STATUS(s); 5968 if (s) RETURN_STATUS(s);
5967#else 5969#else
@@ -6610,7 +6612,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
6610 6612
6611 if (f->code.len == 0) { 6613 if (f->code.len == 0) {
6612 common_parse_init(&prs, fidx); 6614 common_parse_init(&prs, fidx);
6613 s = bc_parse_text(&prs, *str); 6615 s = zbc_parse_text(&prs, *str);
6614 if (s) goto err; 6616 if (s) goto err;
6615 s = zcommon_parse_expr(&prs, BC_PARSE_NOCALL); 6617 s = zcommon_parse_expr(&prs, BC_PARSE_NOCALL);
6616 if (s) goto err; 6618 if (s) goto err;
@@ -6747,7 +6749,7 @@ static BcStatus bc_program_exec(void)
6747 s = zbc_program_logical(inst); 6749 s = zbc_program_logical(inst);
6748 break; 6750 break;
6749 case BC_INST_READ: 6751 case BC_INST_READ:
6750 s = bc_program_read(); 6752 s = zbc_program_read();
6751 break; 6753 break;
6752 case BC_INST_VAR: 6754 case BC_INST_VAR:
6753 s = zbc_program_pushVar(code, &ip->idx, false, false); 6755 s = zbc_program_pushVar(code, &ip->idx, false, false);
@@ -7002,12 +7004,12 @@ static unsigned bc_vm_envLen(const char *var)
7002 7004
7003static BcStatus bc_vm_process(const char *text) 7005static BcStatus bc_vm_process(const char *text)
7004{ 7006{
7005 BcStatus s = bc_parse_text(&G.prs, text); 7007 BcStatus s = zbc_parse_text(&G.prs, text);
7006 7008
7007 if (s) return s; 7009 if (s) return s;
7008 7010
7009 while (G.prs.l.t.t != BC_LEX_EOF) { 7011 while (G.prs.l.t.t != BC_LEX_EOF) {
7010 s = G.prs.parse(&G.prs); 7012 ERROR_RETURN(s =) G.prs.parse(&G.prs);
7011 if (s) return s; 7013 if (s) return s;
7012 } 7014 }
7013 7015
@@ -7327,11 +7329,11 @@ static BcStatus bc_vm_exec(void)
7327 // thus error checking is normally disabled. 7329 // thus error checking is normally disabled.
7328# define DEBUG_LIB 0 7330# define DEBUG_LIB 0
7329 bc_lex_file(&G.prs.l); 7331 bc_lex_file(&G.prs.l);
7330 s = bc_parse_text(&G.prs, bc_lib); 7332 s = zbc_parse_text(&G.prs, bc_lib);
7331 if (DEBUG_LIB && s) return s; 7333 if (DEBUG_LIB && s) return s;
7332 7334
7333 while (G.prs.l.t.t != BC_LEX_EOF) { 7335 while (G.prs.l.t.t != BC_LEX_EOF) {
7334 s = G.prs.parse(&G.prs); 7336 ERROR_RETURN(s =) G.prs.parse(&G.prs);
7335 if (DEBUG_LIB && s) return s; 7337 if (DEBUG_LIB && s) return s;
7336 } 7338 }
7337 s = bc_program_exec(); 7339 s = bc_program_exec();