diff options
-rw-r--r-- | miscutils/bc.c | 226 |
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 | ||
619 | struct BcProgram; | 619 | struct BcProgram; |
620 | 620 | ||
621 | typedef BcStatus (*BcParseParse)(struct BcParse *) FAST_FUNC; | 621 | typedef BC_STATUS (*BcParseParse)(struct BcParse *) FAST_FUNC; |
622 | 622 | ||
623 | typedef struct BcParse { | 623 | typedef 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. |
1370 | static BcStatus bc_read_line(BcVec *vec) | 1370 | static 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 | ||
3035 | static BcStatus bc_lex_string(BcLex *l) | 3031 | static 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 | ||
3064 | static void bc_lex_assign(BcLex *l, BcLexType with, BcLexType without) | 3064 | static 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 | ||
3488 | static BcStatus bc_parse_text(BcParse *p, const char *text) | 3489 | static 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. |
3525 | static void bc_parse_reset(BcParse *p) | 3530 | static 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 | ||
3653 | static BcStatus bc_parse_params(BcParse *p, uint8_t flags) | 3658 | static 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 | ||
3682 | static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags) | 3689 | static 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 | ||
3714 | err: | 3720 | err: |
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 | ||
3719 | static BcStatus bc_parse_name(BcParse *p, BcInst *type, uint8_t flags) | 3728 | static 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 | ||
3774 | err: | 3773 | err: |
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 | ||
3779 | static BC_STATUS zbc_parse_read(BcParse *p) | 3781 | static 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 | ||
3799 | static BcStatus bc_parse_builtin(BcParse *p, BcLexType type, uint8_t flags, | 3801 | static 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 | ||
3824 | static BcStatus bc_parse_scale(BcParse *p, BcInst *type, uint8_t flags) | 3829 | static 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 | ||
3851 | static BcStatus bc_parse_incdec(BcParse *p, BcInst *prev, bool *paren_expr, | 3860 | static 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 | ||
3921 | static BC_STATUS zbc_parse_minus(BcParse *p, BcInst *prev, size_t ops_bgn, | 3920 | static 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 | ||
4637 | static FAST_FUNC BcStatus bc_parse_parse(BcParse *p) | 4636 | static 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 |
4659 | static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags, BcParseNext next) | 4661 | static 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 | ||
4932 | static void bc_parse_init(BcParse *p, size_t func) | 4934 | static 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 | ||
4937 | static BC_STATUS zbc_parse_expression(BcParse *p, uint8_t flags) | 4939 | static 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 | ||
5138 | static FAST_FUNC BcStatus dc_parse_parse(BcParse *p) | 5140 | static 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 | ||
5155 | static void dc_parse_init(BcParse *p, size_t func) | 5160 | static 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 | ||
5388 | static BcStatus bc_program_read(void) | 5390 | static 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 | ||
5443 | static size_t bc_program_index(char *code, size_t *bgn) | 5448 | static 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 | ||
7003 | static BcStatus bc_vm_process(const char *text) | 7005 | static 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(); |