aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c140
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
6652static BcStatus bc_program_exec(void) 6652static 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