diff options
-rw-r--r-- | miscutils/bc.c | 140 |
1 files changed, 19 insertions, 121 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 3f57f4df8..9f44f83f5 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -6651,8 +6651,6 @@ static void bc_program_addFunc(char *name, size_t *idx) | |||
6651 | 6651 | ||
6652 | static BcStatus bc_program_exec(void) | 6652 | static BcStatus bc_program_exec(void) |
6653 | { | 6653 | { |
6654 | BcStatus s = BC_STATUS_SUCCESS; | ||
6655 | size_t idx; | ||
6656 | BcResult r, *ptr; | 6654 | BcResult r, *ptr; |
6657 | BcNum *num; | 6655 | BcNum *num; |
6658 | BcInstPtr *ip = bc_vec_top(&G.prog.stack); | 6656 | BcInstPtr *ip = bc_vec_top(&G.prog.stack); |
@@ -6660,58 +6658,41 @@ static BcStatus bc_program_exec(void) | |||
6660 | char *code = func->code.v; | 6658 | char *code = func->code.v; |
6661 | bool cond = false; | 6659 | bool cond = false; |
6662 | 6660 | ||
6663 | while (!s && ip->idx < func->code.len) { | 6661 | while (ip->idx < func->code.len) { |
6664 | 6662 | BcStatus s; | |
6665 | char inst = code[(ip->idx)++]; | 6663 | char inst = code[(ip->idx)++]; |
6666 | 6664 | ||
6667 | switch (inst) { | 6665 | switch (inst) { |
6668 | |||
6669 | #if ENABLE_BC | 6666 | #if ENABLE_BC |
6670 | case BC_INST_JUMP_ZERO: | 6667 | case BC_INST_JUMP_ZERO: |
6671 | { | ||
6672 | s = bc_program_prep(&ptr, &num); | 6668 | s = bc_program_prep(&ptr, &num); |
6673 | if (s) return s; | 6669 | if (s) return s; |
6674 | cond = !bc_num_cmp(num, &G.prog.zero); | 6670 | cond = !bc_num_cmp(num, &G.prog.zero); |
6675 | bc_vec_pop(&G.prog.results); | 6671 | bc_vec_pop(&G.prog.results); |
6676 | } | 6672 | // Fallthrough. |
6677 | // Fallthrough. | 6673 | case BC_INST_JUMP: { |
6678 | case BC_INST_JUMP: | ||
6679 | { | ||
6680 | size_t *addr; | 6674 | size_t *addr; |
6681 | idx = bc_program_index(code, &ip->idx); | 6675 | size_t idx = bc_program_index(code, &ip->idx); |
6682 | addr = bc_vec_item(&func->labels, idx); | 6676 | addr = bc_vec_item(&func->labels, idx); |
6683 | if (inst == BC_INST_JUMP || cond) ip->idx = *addr; | 6677 | if (inst == BC_INST_JUMP || cond) ip->idx = *addr; |
6684 | break; | 6678 | break; |
6685 | } | 6679 | } |
6686 | |||
6687 | case BC_INST_CALL: | 6680 | case BC_INST_CALL: |
6688 | { | ||
6689 | s = bc_program_call(code, &ip->idx); | 6681 | s = bc_program_call(code, &ip->idx); |
6690 | break; | 6682 | break; |
6691 | } | ||
6692 | |||
6693 | case BC_INST_INC_PRE: | 6683 | case BC_INST_INC_PRE: |
6694 | case BC_INST_DEC_PRE: | 6684 | case BC_INST_DEC_PRE: |
6695 | case BC_INST_INC_POST: | 6685 | case BC_INST_INC_POST: |
6696 | case BC_INST_DEC_POST: | 6686 | case BC_INST_DEC_POST: |
6697 | { | ||
6698 | s = bc_program_incdec(inst); | 6687 | s = bc_program_incdec(inst); |
6699 | break; | 6688 | break; |
6700 | } | ||
6701 | |||
6702 | case BC_INST_HALT: | 6689 | case BC_INST_HALT: |
6703 | { | ||
6704 | QUIT_OR_RETURN_TO_MAIN; | 6690 | QUIT_OR_RETURN_TO_MAIN; |
6705 | break; | 6691 | break; |
6706 | } | ||
6707 | |||
6708 | case BC_INST_RET: | 6692 | case BC_INST_RET: |
6709 | case BC_INST_RET0: | 6693 | case BC_INST_RET0: |
6710 | { | ||
6711 | s = bc_program_return(inst); | 6694 | s = bc_program_return(inst); |
6712 | break; | 6695 | break; |
6713 | } | ||
6714 | |||
6715 | case BC_INST_BOOL_OR: | 6696 | case BC_INST_BOOL_OR: |
6716 | case BC_INST_BOOL_AND: | 6697 | case BC_INST_BOOL_AND: |
6717 | #endif // ENABLE_BC | 6698 | #endif // ENABLE_BC |
@@ -6721,121 +6702,77 @@ static BcStatus bc_program_exec(void) | |||
6721 | case BC_INST_REL_NE: | 6702 | case BC_INST_REL_NE: |
6722 | case BC_INST_REL_LT: | 6703 | case BC_INST_REL_LT: |
6723 | case BC_INST_REL_GT: | 6704 | case BC_INST_REL_GT: |
6724 | { | ||
6725 | s = bc_program_logical(inst); | 6705 | s = bc_program_logical(inst); |
6726 | break; | 6706 | break; |
6727 | } | ||
6728 | |||
6729 | case BC_INST_READ: | 6707 | case BC_INST_READ: |
6730 | { | ||
6731 | s = bc_program_read(); | 6708 | s = bc_program_read(); |
6732 | break; | 6709 | break; |
6733 | } | ||
6734 | |||
6735 | case BC_INST_VAR: | 6710 | case BC_INST_VAR: |
6736 | { | ||
6737 | s = bc_program_pushVar(code, &ip->idx, false, false); | 6711 | s = bc_program_pushVar(code, &ip->idx, false, false); |
6738 | break; | 6712 | break; |
6739 | } | ||
6740 | |||
6741 | case BC_INST_ARRAY_ELEM: | 6713 | case BC_INST_ARRAY_ELEM: |
6742 | case BC_INST_ARRAY: | 6714 | case BC_INST_ARRAY: |
6743 | { | ||
6744 | s = bc_program_pushArray(code, &ip->idx, inst); | 6715 | s = bc_program_pushArray(code, &ip->idx, inst); |
6745 | break; | 6716 | break; |
6746 | } | ||
6747 | |||
6748 | case BC_INST_LAST: | 6717 | case BC_INST_LAST: |
6749 | { | ||
6750 | r.t = BC_RESULT_LAST; | 6718 | r.t = BC_RESULT_LAST; |
6751 | bc_vec_push(&G.prog.results, &r); | 6719 | bc_vec_push(&G.prog.results, &r); |
6752 | break; | 6720 | break; |
6753 | } | ||
6754 | |||
6755 | case BC_INST_IBASE: | 6721 | case BC_INST_IBASE: |
6756 | case BC_INST_SCALE: | 6722 | case BC_INST_SCALE: |
6757 | case BC_INST_OBASE: | 6723 | case BC_INST_OBASE: |
6758 | { | ||
6759 | bc_program_pushGlobal(inst); | 6724 | bc_program_pushGlobal(inst); |
6760 | break; | 6725 | break; |
6761 | } | ||
6762 | |||
6763 | case BC_INST_SCALE_FUNC: | 6726 | case BC_INST_SCALE_FUNC: |
6764 | case BC_INST_LENGTH: | 6727 | case BC_INST_LENGTH: |
6765 | case BC_INST_SQRT: | 6728 | case BC_INST_SQRT: |
6766 | { | ||
6767 | s = bc_program_builtin(inst); | 6729 | s = bc_program_builtin(inst); |
6768 | break; | 6730 | break; |
6769 | } | ||
6770 | |||
6771 | case BC_INST_NUM: | 6731 | case BC_INST_NUM: |
6772 | { | ||
6773 | r.t = BC_RESULT_CONSTANT; | 6732 | r.t = BC_RESULT_CONSTANT; |
6774 | r.d.id.idx = bc_program_index(code, &ip->idx); | 6733 | r.d.id.idx = bc_program_index(code, &ip->idx); |
6775 | bc_vec_push(&G.prog.results, &r); | 6734 | bc_vec_push(&G.prog.results, &r); |
6776 | break; | 6735 | break; |
6777 | } | ||
6778 | |||
6779 | case BC_INST_POP: | 6736 | case BC_INST_POP: |
6780 | { | ||
6781 | if (!BC_PROG_STACK(&G.prog.results, 1)) | 6737 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6782 | s = bc_error_stack_has_too_few_elements(); | 6738 | s = bc_error_stack_has_too_few_elements(); |
6783 | else | 6739 | else |
6784 | bc_vec_pop(&G.prog.results); | 6740 | bc_vec_pop(&G.prog.results); |
6785 | break; | 6741 | break; |
6786 | } | ||
6787 | |||
6788 | case BC_INST_POP_EXEC: | 6742 | case BC_INST_POP_EXEC: |
6789 | { | ||
6790 | bc_vec_pop(&G.prog.stack); | 6743 | bc_vec_pop(&G.prog.stack); |
6791 | break; | 6744 | break; |
6792 | } | ||
6793 | |||
6794 | case BC_INST_PRINT: | 6745 | case BC_INST_PRINT: |
6795 | case BC_INST_PRINT_POP: | 6746 | case BC_INST_PRINT_POP: |
6796 | case BC_INST_PRINT_STR: | 6747 | case BC_INST_PRINT_STR: |
6797 | { | ||
6798 | s = bc_program_print(inst, 0); | 6748 | s = bc_program_print(inst, 0); |
6799 | break; | 6749 | break; |
6800 | } | ||
6801 | |||
6802 | case BC_INST_STR: | 6750 | case BC_INST_STR: |
6803 | { | ||
6804 | r.t = BC_RESULT_STR; | 6751 | r.t = BC_RESULT_STR; |
6805 | r.d.id.idx = bc_program_index(code, &ip->idx); | 6752 | r.d.id.idx = bc_program_index(code, &ip->idx); |
6806 | bc_vec_push(&G.prog.results, &r); | 6753 | bc_vec_push(&G.prog.results, &r); |
6807 | break; | 6754 | break; |
6808 | } | ||
6809 | |||
6810 | case BC_INST_POWER: | 6755 | case BC_INST_POWER: |
6811 | case BC_INST_MULTIPLY: | 6756 | case BC_INST_MULTIPLY: |
6812 | case BC_INST_DIVIDE: | 6757 | case BC_INST_DIVIDE: |
6813 | case BC_INST_MODULUS: | 6758 | case BC_INST_MODULUS: |
6814 | case BC_INST_PLUS: | 6759 | case BC_INST_PLUS: |
6815 | case BC_INST_MINUS: | 6760 | case BC_INST_MINUS: |
6816 | { | ||
6817 | s = bc_program_op(inst); | 6761 | s = bc_program_op(inst); |
6818 | break; | 6762 | break; |
6819 | } | ||
6820 | |||
6821 | case BC_INST_BOOL_NOT: | 6763 | case BC_INST_BOOL_NOT: |
6822 | { | ||
6823 | s = bc_program_prep(&ptr, &num); | 6764 | s = bc_program_prep(&ptr, &num); |
6824 | if (s) return s; | 6765 | if (s) return s; |
6825 | |||
6826 | bc_num_init(&r.d.n, BC_NUM_DEF_SIZE); | 6766 | bc_num_init(&r.d.n, BC_NUM_DEF_SIZE); |
6827 | (!bc_num_cmp(num, &G.prog.zero) ? bc_num_one : bc_num_zero)(&r.d.n); | 6767 | if (!bc_num_cmp(num, &G.prog.zero)) |
6768 | bc_num_one(&r.d.n); | ||
6769 | else | ||
6770 | bc_num_zero(&r.d.n); | ||
6828 | bc_program_retire(&r, BC_RESULT_TEMP); | 6771 | bc_program_retire(&r, BC_RESULT_TEMP); |
6829 | |||
6830 | break; | 6772 | break; |
6831 | } | ||
6832 | |||
6833 | case BC_INST_NEG: | 6773 | case BC_INST_NEG: |
6834 | { | ||
6835 | s = bc_program_negate(); | 6774 | s = bc_program_negate(); |
6836 | break; | 6775 | break; |
6837 | } | ||
6838 | |||
6839 | #if ENABLE_BC | 6776 | #if ENABLE_BC |
6840 | case BC_INST_ASSIGN_POWER: | 6777 | case BC_INST_ASSIGN_POWER: |
6841 | case BC_INST_ASSIGN_MULTIPLY: | 6778 | case BC_INST_ASSIGN_MULTIPLY: |
@@ -6845,123 +6782,84 @@ static BcStatus bc_program_exec(void) | |||
6845 | case BC_INST_ASSIGN_MINUS: | 6782 | case BC_INST_ASSIGN_MINUS: |
6846 | #endif | 6783 | #endif |
6847 | case BC_INST_ASSIGN: | 6784 | case BC_INST_ASSIGN: |
6848 | { | ||
6849 | s = bc_program_assign(inst); | 6785 | s = bc_program_assign(inst); |
6850 | break; | 6786 | break; |
6851 | } | ||
6852 | #if ENABLE_DC | 6787 | #if ENABLE_DC |
6853 | case BC_INST_MODEXP: | 6788 | case BC_INST_MODEXP: |
6854 | { | ||
6855 | s = bc_program_modexp(); | 6789 | s = bc_program_modexp(); |
6856 | break; | 6790 | break; |
6857 | } | ||
6858 | |||
6859 | case BC_INST_DIVMOD: | 6791 | case BC_INST_DIVMOD: |
6860 | { | ||
6861 | s = bc_program_divmod(); | 6792 | s = bc_program_divmod(); |
6862 | break; | 6793 | break; |
6863 | } | ||
6864 | |||
6865 | case BC_INST_EXECUTE: | 6794 | case BC_INST_EXECUTE: |
6866 | case BC_INST_EXEC_COND: | 6795 | case BC_INST_EXEC_COND: |
6867 | { | ||
6868 | cond = inst == BC_INST_EXEC_COND; | 6796 | cond = inst == BC_INST_EXEC_COND; |
6869 | s = bc_program_execStr(code, &ip->idx, cond); | 6797 | s = bc_program_execStr(code, &ip->idx, cond); |
6870 | break; | 6798 | break; |
6871 | } | 6799 | case BC_INST_PRINT_STACK: { |
6872 | 6800 | size_t idx; | |
6873 | case BC_INST_PRINT_STACK: | 6801 | for (idx = 0; idx < G.prog.results.len; ++idx) { |
6874 | { | ||
6875 | for (idx = 0; !s && idx < G.prog.results.len; ++idx) | ||
6876 | s = bc_program_print(BC_INST_PRINT, idx); | 6802 | s = bc_program_print(BC_INST_PRINT, idx); |
6803 | if (s) break; | ||
6804 | } | ||
6877 | break; | 6805 | break; |
6878 | } | 6806 | } |
6879 | |||
6880 | case BC_INST_CLEAR_STACK: | 6807 | case BC_INST_CLEAR_STACK: |
6881 | { | ||
6882 | bc_vec_pop_all(&G.prog.results); | 6808 | bc_vec_pop_all(&G.prog.results); |
6883 | break; | 6809 | break; |
6884 | } | ||
6885 | |||
6886 | case BC_INST_STACK_LEN: | 6810 | case BC_INST_STACK_LEN: |
6887 | { | ||
6888 | bc_program_stackLen(); | 6811 | bc_program_stackLen(); |
6889 | break; | 6812 | break; |
6890 | } | ||
6891 | |||
6892 | case BC_INST_DUPLICATE: | 6813 | case BC_INST_DUPLICATE: |
6893 | { | ||
6894 | if (!BC_PROG_STACK(&G.prog.results, 1)) | 6814 | if (!BC_PROG_STACK(&G.prog.results, 1)) |
6895 | return bc_error_stack_has_too_few_elements(); | 6815 | return bc_error_stack_has_too_few_elements(); |
6896 | ptr = bc_vec_top(&G.prog.results); | 6816 | ptr = bc_vec_top(&G.prog.results); |
6897 | bc_result_copy(&r, ptr); | 6817 | bc_result_copy(&r, ptr); |
6898 | bc_vec_push(&G.prog.results, &r); | 6818 | bc_vec_push(&G.prog.results, &r); |
6899 | break; | 6819 | break; |
6900 | } | 6820 | case BC_INST_SWAP: { |
6901 | |||
6902 | case BC_INST_SWAP: | ||
6903 | { | ||
6904 | BcResult *ptr2; | 6821 | BcResult *ptr2; |
6905 | |||
6906 | if (!BC_PROG_STACK(&G.prog.results, 2)) | 6822 | if (!BC_PROG_STACK(&G.prog.results, 2)) |
6907 | return bc_error_stack_has_too_few_elements(); | 6823 | return bc_error_stack_has_too_few_elements(); |
6908 | |||
6909 | ptr = bc_vec_item_rev(&G.prog.results, 0); | 6824 | ptr = bc_vec_item_rev(&G.prog.results, 0); |
6910 | ptr2 = bc_vec_item_rev(&G.prog.results, 1); | 6825 | ptr2 = bc_vec_item_rev(&G.prog.results, 1); |
6911 | memcpy(&r, ptr, sizeof(BcResult)); | 6826 | memcpy(&r, ptr, sizeof(BcResult)); |
6912 | memcpy(ptr, ptr2, sizeof(BcResult)); | 6827 | memcpy(ptr, ptr2, sizeof(BcResult)); |
6913 | memcpy(ptr2, &r, sizeof(BcResult)); | 6828 | memcpy(ptr2, &r, sizeof(BcResult)); |
6914 | |||
6915 | break; | 6829 | break; |
6916 | } | 6830 | } |
6917 | |||
6918 | case BC_INST_ASCIIFY: | 6831 | case BC_INST_ASCIIFY: |
6919 | { | ||
6920 | s = bc_program_asciify(); | 6832 | s = bc_program_asciify(); |
6921 | break; | 6833 | break; |
6922 | } | ||
6923 | |||
6924 | case BC_INST_PRINT_STREAM: | 6834 | case BC_INST_PRINT_STREAM: |
6925 | { | ||
6926 | s = bc_program_printStream(); | 6835 | s = bc_program_printStream(); |
6927 | break; | 6836 | break; |
6928 | } | ||
6929 | |||
6930 | case BC_INST_LOAD: | 6837 | case BC_INST_LOAD: |
6931 | case BC_INST_PUSH_VAR: | 6838 | case BC_INST_PUSH_VAR: { |
6932 | { | ||
6933 | bool copy = inst == BC_INST_LOAD; | 6839 | bool copy = inst == BC_INST_LOAD; |
6934 | s = bc_program_pushVar(code, &ip->idx, true, copy); | 6840 | s = bc_program_pushVar(code, &ip->idx, true, copy); |
6935 | break; | 6841 | break; |
6936 | } | 6842 | } |
6937 | 6843 | case BC_INST_PUSH_TO_VAR: { | |
6938 | case BC_INST_PUSH_TO_VAR: | ||
6939 | { | ||
6940 | char *name = bc_program_name(code, &ip->idx); | 6844 | char *name = bc_program_name(code, &ip->idx); |
6941 | s = bc_program_copyToVar(name, true); | 6845 | s = bc_program_copyToVar(name, true); |
6942 | free(name); | 6846 | free(name); |
6943 | break; | 6847 | break; |
6944 | } | 6848 | } |
6945 | |||
6946 | case BC_INST_QUIT: | 6849 | case BC_INST_QUIT: |
6947 | { | ||
6948 | if (G.prog.stack.len <= 2) | 6850 | if (G.prog.stack.len <= 2) |
6949 | QUIT_OR_RETURN_TO_MAIN; | 6851 | QUIT_OR_RETURN_TO_MAIN; |
6950 | bc_vec_npop(&G.prog.stack, 2); | 6852 | bc_vec_npop(&G.prog.stack, 2); |
6951 | break; | 6853 | break; |
6952 | } | ||
6953 | |||
6954 | case BC_INST_NQUIT: | 6854 | case BC_INST_NQUIT: |
6955 | { | ||
6956 | s = bc_program_nquit(); | 6855 | s = bc_program_nquit(); |
6957 | break; | 6856 | break; |
6958 | } | ||
6959 | #endif // ENABLE_DC | 6857 | #endif // ENABLE_DC |
6960 | } | 6858 | } |
6961 | 6859 | ||
6962 | if (s || G_interrupt) { | 6860 | if (s || G_interrupt) { |
6963 | bc_program_reset(); | 6861 | bc_program_reset(); |
6964 | break; | 6862 | return s; |
6965 | } | 6863 | } |
6966 | 6864 | ||
6967 | // If the stack has changed, pointers may be invalid. | 6865 | // If the stack has changed, pointers may be invalid. |
@@ -6970,7 +6868,7 @@ static BcStatus bc_program_exec(void) | |||
6970 | code = func->code.v; | 6868 | code = func->code.v; |
6971 | } | 6869 | } |
6972 | 6870 | ||
6973 | return s; | 6871 | return BC_STATUS_SUCCESS; |
6974 | } | 6872 | } |
6975 | 6873 | ||
6976 | #if ENABLE_BC | 6874 | #if ENABLE_BC |