aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-15 20:06:59 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-15 20:06:59 +0100
commit99b37623356a1555359df1c011d4a6732918a5c4 (patch)
treee12312d1068e991b51f0b078b24169501f973337
parentfd51e0c4d22825282f3e38be0655db36b3e716d2 (diff)
downloadbusybox-w32-99b37623356a1555359df1c011d4a6732918a5c4.tar.gz
busybox-w32-99b37623356a1555359df1c011d4a6732918a5c4.tar.bz2
busybox-w32-99b37623356a1555359df1c011d4a6732918a5c4.zip
bc: lexer debugging, added some failing test cases
function old new delta bc_parse_push_block_flag - 47 +47 zbc_parse_body 107 121 +14 zbc_num_divmod 156 150 -6 zbc_lex_number 200 192 -8 zbc_parse_endBody 264 254 -10 bc_parse_startBody 47 - -47 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 1/3 up/down: 61/-71) Total: -10 bytes text data bss dec hex filename 982596 485 7296 990377 f1ca9 busybox_old 982586 485 7296 990367 f1c9f busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c107
-rwxr-xr-xtestsuite/bc.tests20
2 files changed, 89 insertions, 38 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index aeb29a971..374279889 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -168,6 +168,7 @@
168#else 168#else
169 169
170#define DEBUG_LEXER 0 170#define DEBUG_LEXER 0
171#define DEBUG_EXEC 0
171 172
172#if DEBUG_LEXER 173#if DEBUG_LEXER
173static unsigned lex_indent; 174static unsigned lex_indent;
@@ -192,6 +193,12 @@ static unsigned lex_indent;
192# define dbg_lex_done(...) ((void)0) 193# define dbg_lex_done(...) ((void)0)
193#endif 194#endif
194 195
196#if DEBUG_EXEC
197# define dbg_exec(...) bb_error_msg(__VA_ARGS__)
198#else
199# define dbg_exec(...) ((void)0)
200#endif
201
195typedef enum BcStatus { 202typedef enum BcStatus {
196 BC_STATUS_SUCCESS = 0, 203 BC_STATUS_SUCCESS = 0,
197 BC_STATUS_FAILURE = 1, 204 BC_STATUS_FAILURE = 1,
@@ -614,6 +621,7 @@ typedef struct BcParse {
614 size_t fidx; 621 size_t fidx;
615 622
616 size_t nbraces; 623 size_t nbraces;
624//FIXME: "define w(x) { auto z; return 1; }" fails to parse
617 bool auto_part; 625 bool auto_part;
618} BcParse; 626} BcParse;
619 627
@@ -658,6 +666,26 @@ typedef struct BcProgram {
658 666
659} BcProgram; 667} BcProgram;
660 668
669static void bc_parse_push_block_flag(BcParse *p, uint8_t flags)
670{
671 size_t size;
672 uint8_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
673 flags |= (*flag_ptr & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP));
674 flags |= BC_PARSE_FLAG_BODY;
675
676 size = p->bf_top - p->bf_base;
677 p->bf_base = xrealloc(p->bf_base, size + 2);
678 p->bf_top = p->bf_base + size + 1;
679 dbg_lex("%s:%d pushed block flag lvl:%d bits:0x%02x", __func__, __LINE__, size + 1, flags);
680 *p->bf_top = flags;
681}
682
683static ALWAYS_INLINE void bc_parse_pop_block_flag(BcParse *p)
684{
685 p->bf_top--;
686 dbg_lex("%s:%d popped block flag lvl:%d bits:0x%02x", __func__, __LINE__, p->bf_top - p->bf_base, *p->bf_top);
687}
688
661#define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) n)) 689#define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) n))
662 690
663#define BC_PROG_MAIN (0) 691#define BC_PROG_MAIN (0)
@@ -3487,13 +3515,13 @@ static void bc_parse_number(BcParse *p, BcInst *prev, size_t *nexs)
3487 (*prev) = BC_INST_NUM; 3515 (*prev) = BC_INST_NUM;
3488} 3516}
3489 3517
3490IF_BC(static BC_STATUS zbc_parse_parse(BcParse *p);) 3518IF_BC(static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p);)
3491IF_DC(static BC_STATUS zdc_parse_parse(BcParse *p);) 3519IF_DC(static BC_STATUS zdc_parse_parse(BcParse *p);)
3492 3520
3493static BC_STATUS zcommon_parse(BcParse *p) 3521static BC_STATUS zcommon_parse(BcParse *p)
3494{ 3522{
3495 if (IS_BC) { 3523 if (IS_BC) {
3496 IF_BC(RETURN_STATUS(zbc_parse_parse(p));) 3524 IF_BC(RETURN_STATUS(zbc_parse_stmt_or_funcdef(p));)
3497 } 3525 }
3498 IF_DC(RETURN_STATUS(zdc_parse_parse(p));) 3526 IF_DC(RETURN_STATUS(zdc_parse_parse(p));)
3499} 3527}
@@ -4056,7 +4084,7 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4056 if (s) RETURN_STATUS(s); 4084 if (s) RETURN_STATUS(s);
4057 } 4085 }
4058 4086
4059 p->bf_top--; 4087 bc_parse_pop_block_flag(p);
4060 4088
4061 flag_ptr = BC_PARSE_TOP_FLAG_PTR(p); 4089 flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
4062 dbg_lex("%s:%d setting BC_PARSE_FLAG_IF_END bit", __func__, __LINE__); 4090 dbg_lex("%s:%d setting BC_PARSE_FLAG_IF_END bit", __func__, __LINE__);
@@ -4069,32 +4097,34 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4069 BcInstPtr *ip; 4097 BcInstPtr *ip;
4070 size_t *label; 4098 size_t *label;
4071 4099
4072 p->bf_top--;
4073
4074 ip = bc_vec_top(&p->exits); 4100 ip = bc_vec_top(&p->exits);
4075 label = bc_vec_item(&p->func->labels, ip->idx); 4101 label = bc_vec_item(&p->func->labels, ip->idx);
4102 dbg_lex("%s:%d rewriting label: %d -> %d", __func__, __LINE__, *label, p->func->code.len);
4076 *label = p->func->code.len; 4103 *label = p->func->code.len;
4077 4104
4078 bc_vec_pop(&p->exits); 4105 bc_vec_pop(&p->exits);
4106 bc_parse_pop_block_flag(p);
4079 } 4107 }
4080 else if (BC_PARSE_FUNC_INNER(p)) { 4108 else if (BC_PARSE_FUNC_INNER(p)) {
4081 bc_parse_push(p, BC_INST_RET0); 4109 bc_parse_push(p, BC_INST_RET0);
4082 bc_parse_updateFunc(p, BC_PROG_MAIN); 4110 bc_parse_updateFunc(p, BC_PROG_MAIN);
4083 p->bf_top--; 4111 bc_parse_pop_block_flag(p);
4084 } 4112 }
4085 else { 4113 else {
4086 BcInstPtr *ip = bc_vec_top(&p->exits); 4114 BcInstPtr *ip = bc_vec_top(&p->exits);
4087 size_t *label = bc_vec_top(&p->conds); 4115 size_t *label = bc_vec_top(&p->conds);
4088 4116
4117 dbg_lex("%s:%d BC_INST_JUMP to %d", __func__, __LINE__, *label);
4089 bc_parse_push(p, BC_INST_JUMP); 4118 bc_parse_push(p, BC_INST_JUMP);
4090 bc_parse_pushIndex(p, *label); 4119 bc_parse_pushIndex(p, *label);
4091 4120
4092 label = bc_vec_item(&p->func->labels, ip->idx); 4121 label = bc_vec_item(&p->func->labels, ip->idx);
4122 dbg_lex("%s:%d rewriting label: %d -> %d", __func__, __LINE__, *label, p->func->code.len);
4093 *label = p->func->code.len; 4123 *label = p->func->code.len;
4094 4124
4095 p->bf_top--;
4096 bc_vec_pop(&p->exits); 4125 bc_vec_pop(&p->exits);
4097 bc_vec_pop(&p->conds); 4126 bc_vec_pop(&p->conds);
4127 bc_parse_pop_block_flag(p);
4098 } 4128 }
4099 4129
4100 RETURN_STATUS(s); 4130 RETURN_STATUS(s);
@@ -4103,19 +4133,6 @@ static BC_STATUS zbc_parse_endBody(BcParse *p)
4103# define zbc_parse_endBody(...) (zbc_parse_endBody(__VA_ARGS__), BC_STATUS_SUCCESS) 4133# define zbc_parse_endBody(...) (zbc_parse_endBody(__VA_ARGS__), BC_STATUS_SUCCESS)
4104#endif 4134#endif
4105 4135
4106static void bc_parse_startBody(BcParse *p, uint8_t flags)
4107{
4108 size_t size;
4109 uint8_t *flag_ptr = BC_PARSE_TOP_FLAG_PTR(p);
4110 flags |= (*flag_ptr & (BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_LOOP));
4111 flags |= BC_PARSE_FLAG_BODY;
4112
4113 size = p->bf_top - p->bf_base;
4114 p->bf_base = xrealloc(p->bf_base, size + 2);
4115 p->bf_top = p->bf_base + size + 1;
4116 *p->bf_top = flags;
4117}
4118
4119static void bc_parse_noElse(BcParse *p) 4136static void bc_parse_noElse(BcParse *p)
4120{ 4137{
4121 BcInstPtr *ip; 4138 BcInstPtr *ip;
@@ -4127,6 +4144,7 @@ static void bc_parse_noElse(BcParse *p)
4127 4144
4128 ip = bc_vec_top(&p->exits); 4145 ip = bc_vec_top(&p->exits);
4129 label = bc_vec_item(&p->func->labels, ip->idx); 4146 label = bc_vec_item(&p->func->labels, ip->idx);
4147 dbg_lex("%s:%d rewriting label: %d -> %d", __func__, __LINE__, *label, p->func->code.len);
4130 *label = p->func->code.len; 4148 *label = p->func->code.len;
4131 4149
4132 bc_vec_pop(&p->exits); 4150 bc_vec_pop(&p->exits);
@@ -4158,7 +4176,7 @@ static BC_STATUS zbc_parse_if(BcParse *p)
4158 bc_parse_pushIndex(p, ip.idx); 4176 bc_parse_pushIndex(p, ip.idx);
4159 bc_vec_push(&p->exits, &ip); 4177 bc_vec_push(&p->exits, &ip);
4160 bc_vec_push(&p->func->labels, &ip.idx); 4178 bc_vec_push(&p->func->labels, &ip.idx);
4161 bc_parse_startBody(p, BC_PARSE_FLAG_IF); 4179 bc_parse_push_block_flag(p, BC_PARSE_FLAG_IF);
4162 4180
4163 dbg_lex_done("%s:%d done", __func__, __LINE__); 4181 dbg_lex_done("%s:%d done", __func__, __LINE__);
4164 RETURN_STATUS(BC_STATUS_SUCCESS); 4182 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -4178,6 +4196,7 @@ static BC_STATUS zbc_parse_else(BcParse *p)
4178 ip.idx = p->func->labels.len; 4196 ip.idx = p->func->labels.len;
4179 ip.func = ip.len = 0; 4197 ip.func = ip.len = 0;
4180 4198
4199 dbg_lex("%s:%d after if() body: BC_INST_JUMP to %d", __func__, __LINE__, ip.idx);
4181 bc_parse_push(p, BC_INST_JUMP); 4200 bc_parse_push(p, BC_INST_JUMP);
4182 bc_parse_pushIndex(p, ip.idx); 4201 bc_parse_pushIndex(p, ip.idx);
4183 4202
@@ -4186,7 +4205,7 @@ static BC_STATUS zbc_parse_else(BcParse *p)
4186 4205
4187 bc_vec_push(&p->exits, &ip); 4206 bc_vec_push(&p->exits, &ip);
4188 bc_vec_push(&p->func->labels, &ip.idx); 4207 bc_vec_push(&p->func->labels, &ip.idx);
4189 bc_parse_startBody(p, BC_PARSE_FLAG_ELSE); 4208 bc_parse_push_block_flag(p, BC_PARSE_FLAG_ELSE);
4190 4209
4191 dbg_lex_done("%s:%d done", __func__, __LINE__); 4210 dbg_lex_done("%s:%d done", __func__, __LINE__);
4192 RETURN_STATUS(zbc_lex_next(&p->l)); 4211 RETURN_STATUS(zbc_lex_next(&p->l));
@@ -4226,7 +4245,7 @@ static BC_STATUS zbc_parse_while(BcParse *p)
4226 4245
4227 bc_parse_push(p, BC_INST_JUMP_ZERO); 4246 bc_parse_push(p, BC_INST_JUMP_ZERO);
4228 bc_parse_pushIndex(p, ip.idx); 4247 bc_parse_pushIndex(p, ip.idx);
4229 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); 4248 bc_parse_push_block_flag(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
4230 4249
4231 RETURN_STATUS(BC_STATUS_SUCCESS); 4250 RETURN_STATUS(BC_STATUS_SUCCESS);
4232} 4251}
@@ -4305,7 +4324,7 @@ static BC_STATUS zbc_parse_for(BcParse *p)
4305 bc_vec_push(&p->func->labels, &ip.idx); 4324 bc_vec_push(&p->func->labels, &ip.idx);
4306 s = zbc_lex_next(&p->l); 4325 s = zbc_lex_next(&p->l);
4307 if (s) RETURN_STATUS(s); 4326 if (s) RETURN_STATUS(s);
4308 bc_parse_startBody(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER); 4327 bc_parse_push_block_flag(p, BC_PARSE_FLAG_LOOP | BC_PARSE_FLAG_LOOP_INNER);
4309 4328
4310 RETURN_STATUS(BC_STATUS_SUCCESS); 4329 RETURN_STATUS(BC_STATUS_SUCCESS);
4311} 4330}
@@ -4412,7 +4431,7 @@ static BC_STATUS zbc_parse_func(BcParse *p)
4412 if (comma) RETURN_STATUS(bc_error("bad function definition")); 4431 if (comma) RETURN_STATUS(bc_error("bad function definition"));
4413 4432
4414 flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY; 4433 flags = BC_PARSE_FLAG_FUNC | BC_PARSE_FLAG_FUNC_INNER | BC_PARSE_FLAG_BODY;
4415 bc_parse_startBody(p, flags); 4434 bc_parse_push_block_flag(p, flags);
4416 4435
4417 s = zbc_lex_next(&p->l); 4436 s = zbc_lex_next(&p->l);
4418 if (s) RETURN_STATUS(s); 4437 if (s) RETURN_STATUS(s);
@@ -4513,7 +4532,7 @@ static BC_STATUS zbc_parse_body(BcParse *p, bool brace)
4513 else { 4532 else {
4514 dbg_lex("%s:%d !BC_PARSE_FLAG_FUNC_INNER", __func__, __LINE__); 4533 dbg_lex("%s:%d !BC_PARSE_FLAG_FUNC_INNER", __func__, __LINE__);
4515 s = zbc_parse_stmt(p); 4534 s = zbc_parse_stmt(p);
4516 if (!s && !brace) s = zbc_parse_endBody(p); 4535 if (!s && !brace && !BC_PARSE_BODY(p)) s = zbc_parse_endBody(p);
4517 } 4536 }
4518 4537
4519 dbg_lex_done("%s:%d done", __func__, __LINE__); 4538 dbg_lex_done("%s:%d done", __func__, __LINE__);
@@ -4657,7 +4676,7 @@ static BC_STATUS zbc_parse_stmt(BcParse *p)
4657# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS) 4676# define zbc_parse_stmt(...) (zbc_parse_stmt(__VA_ARGS__), BC_STATUS_SUCCESS)
4658#endif 4677#endif
4659 4678
4660static BC_STATUS zbc_parse_parse(BcParse *p) 4679static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p)
4661{ 4680{
4662 BcStatus s; 4681 BcStatus s;
4663 4682
@@ -4683,7 +4702,7 @@ static BC_STATUS zbc_parse_parse(BcParse *p)
4683 RETURN_STATUS(s); 4702 RETURN_STATUS(s);
4684} 4703}
4685#if ERRORS_ARE_FATAL 4704#if ERRORS_ARE_FATAL
4686# define zbc_parse_parse(...) (zbc_parse_parse(__VA_ARGS__), BC_STATUS_SUCCESS) 4705# define zbc_parse_stmt_or_funcdef(...) (zbc_parse_stmt_or_funcdef(__VA_ARGS__), BC_STATUS_SUCCESS)
4687#endif 4706#endif
4688 4707
4689// This is not a "z" function: can also return BC_STATUS_PARSE_EMPTY_EXP 4708// This is not a "z" function: can also return BC_STATUS_PARSE_EMPTY_EXP
@@ -4964,14 +4983,6 @@ static BC_STATUS zbc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4964# define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS) 4983# define zbc_parse_expr(...) (zbc_parse_expr(__VA_ARGS__), BC_STATUS_SUCCESS)
4965#endif 4984#endif
4966 4985
4967static BC_STATUS zbc_parse_expression(BcParse *p, uint8_t flags)
4968{
4969 RETURN_STATUS(zbc_parse_expr(p, flags, bc_parse_next_read));
4970}
4971#if ERRORS_ARE_FATAL
4972# define zbc_parse_expression(...) (zbc_parse_expression(__VA_ARGS__), BC_STATUS_SUCCESS)
4973#endif
4974
4975#endif // ENABLE_BC 4986#endif // ENABLE_BC
4976 4987
4977#if ENABLE_DC 4988#if ENABLE_DC
@@ -5190,9 +5201,9 @@ static BC_STATUS zdc_parse_parse(BcParse *p)
5190static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags) 5201static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags)
5191{ 5202{
5192 if (IS_BC) { 5203 if (IS_BC) {
5193 IF_BC(RETURN_STATUS(zbc_parse_expression(p, flags));) 5204 IF_BC(RETURN_STATUS(zbc_parse_expr(p, flags, bc_parse_next_read)));
5194 } else { 5205 } else {
5195 IF_DC(RETURN_STATUS(zdc_parse_expr(p, flags));) 5206 IF_DC(RETURN_STATUS(zdc_parse_expr(p, flags)));
5196 } 5207 }
5197} 5208}
5198#if ERRORS_ARE_FATAL 5209#if ERRORS_ARE_FATAL
@@ -6720,10 +6731,12 @@ static BC_STATUS zbc_program_exec(void)
6720 BcStatus s = BC_STATUS_SUCCESS; 6731 BcStatus s = BC_STATUS_SUCCESS;
6721 char inst = code[(ip->idx)++]; 6732 char inst = code[(ip->idx)++];
6722 6733
6734 dbg_exec("inst:%d", inst);
6723 switch (inst) { 6735 switch (inst) {
6724#if ENABLE_BC 6736#if ENABLE_BC
6725 case BC_INST_JUMP_ZERO: { 6737 case BC_INST_JUMP_ZERO: {
6726 bool zero; 6738 bool zero;
6739 dbg_exec("BC_INST_JUMP_ZERO:");
6727 s = zbc_program_prep(&ptr, &num); 6740 s = zbc_program_prep(&ptr, &num);
6728 if (s) RETURN_STATUS(s); 6741 if (s) RETURN_STATUS(s);
6729 zero = (bc_num_cmp(num, &G.prog.zero) == 0); 6742 zero = (bc_num_cmp(num, &G.prog.zero) == 0);
@@ -6737,16 +6750,19 @@ static BC_STATUS zbc_program_exec(void)
6737 case BC_INST_JUMP: { 6750 case BC_INST_JUMP: {
6738 size_t idx = bc_program_index(code, &ip->idx); 6751 size_t idx = bc_program_index(code, &ip->idx);
6739 size_t *addr = bc_vec_item(&func->labels, idx); 6752 size_t *addr = bc_vec_item(&func->labels, idx);
6753 dbg_exec("BC_INST_JUMP: to %ld", (long)*addr);
6740 ip->idx = *addr; 6754 ip->idx = *addr;
6741 break; 6755 break;
6742 } 6756 }
6743 case BC_INST_CALL: 6757 case BC_INST_CALL:
6758 dbg_exec("BC_INST_CALL:");
6744 s = zbc_program_call(code, &ip->idx); 6759 s = zbc_program_call(code, &ip->idx);
6745 break; 6760 break;
6746 case BC_INST_INC_PRE: 6761 case BC_INST_INC_PRE:
6747 case BC_INST_DEC_PRE: 6762 case BC_INST_DEC_PRE:
6748 case BC_INST_INC_POST: 6763 case BC_INST_INC_POST:
6749 case BC_INST_DEC_POST: 6764 case BC_INST_DEC_POST:
6765 dbg_exec("BC_INST_INCDEC:");
6750 s = zbc_program_incdec(inst); 6766 s = zbc_program_incdec(inst);
6751 break; 6767 break;
6752 case BC_INST_HALT: 6768 case BC_INST_HALT:
@@ -6754,6 +6770,7 @@ static BC_STATUS zbc_program_exec(void)
6754 break; 6770 break;
6755 case BC_INST_RET: 6771 case BC_INST_RET:
6756 case BC_INST_RET0: 6772 case BC_INST_RET0:
6773 dbg_exec("BC_INST_RET[0]:");
6757 s = zbc_program_return(inst); 6774 s = zbc_program_return(inst);
6758 break; 6775 break;
6759 case BC_INST_BOOL_OR: 6776 case BC_INST_BOOL_OR:
@@ -6765,16 +6782,20 @@ static BC_STATUS zbc_program_exec(void)
6765 case BC_INST_REL_NE: 6782 case BC_INST_REL_NE:
6766 case BC_INST_REL_LT: 6783 case BC_INST_REL_LT:
6767 case BC_INST_REL_GT: 6784 case BC_INST_REL_GT:
6785 dbg_exec("BC_INST_BOOL:");
6768 s = zbc_program_logical(inst); 6786 s = zbc_program_logical(inst);
6769 break; 6787 break;
6770 case BC_INST_READ: 6788 case BC_INST_READ:
6789 dbg_exec("BC_INST_READ:");
6771 s = zbc_program_read(); 6790 s = zbc_program_read();
6772 break; 6791 break;
6773 case BC_INST_VAR: 6792 case BC_INST_VAR:
6793 dbg_exec("BC_INST_VAR:");
6774 s = zbc_program_pushVar(code, &ip->idx, false, false); 6794 s = zbc_program_pushVar(code, &ip->idx, false, false);
6775 break; 6795 break;
6776 case BC_INST_ARRAY_ELEM: 6796 case BC_INST_ARRAY_ELEM:
6777 case BC_INST_ARRAY: 6797 case BC_INST_ARRAY:
6798 dbg_exec("BC_INST_ARRAY[_ELEM]:");
6778 s = zbc_program_pushArray(code, &ip->idx, inst); 6799 s = zbc_program_pushArray(code, &ip->idx, inst);
6779 break; 6800 break;
6780 case BC_INST_LAST: 6801 case BC_INST_LAST:
@@ -6789,28 +6810,34 @@ static BC_STATUS zbc_program_exec(void)
6789 case BC_INST_SCALE_FUNC: 6810 case BC_INST_SCALE_FUNC:
6790 case BC_INST_LENGTH: 6811 case BC_INST_LENGTH:
6791 case BC_INST_SQRT: 6812 case BC_INST_SQRT:
6813 dbg_exec("BC_INST_builtin:");
6792 s = zbc_program_builtin(inst); 6814 s = zbc_program_builtin(inst);
6793 break; 6815 break;
6794 case BC_INST_NUM: 6816 case BC_INST_NUM:
6817 dbg_exec("BC_INST_NUM:");
6795 r.t = BC_RESULT_CONSTANT; 6818 r.t = BC_RESULT_CONSTANT;
6796 r.d.id.idx = bc_program_index(code, &ip->idx); 6819 r.d.id.idx = bc_program_index(code, &ip->idx);
6797 bc_vec_push(&G.prog.results, &r); 6820 bc_vec_push(&G.prog.results, &r);
6798 break; 6821 break;
6799 case BC_INST_POP: 6822 case BC_INST_POP:
6823 dbg_exec("BC_INST_POP:");
6800 if (!BC_PROG_STACK(&G.prog.results, 1)) 6824 if (!BC_PROG_STACK(&G.prog.results, 1))
6801 s = bc_error_stack_has_too_few_elements(); 6825 s = bc_error_stack_has_too_few_elements();
6802 else 6826 else
6803 bc_vec_pop(&G.prog.results); 6827 bc_vec_pop(&G.prog.results);
6804 break; 6828 break;
6805 case BC_INST_POP_EXEC: 6829 case BC_INST_POP_EXEC:
6830 dbg_exec("BC_INST_POP_EXEC:");
6806 bc_vec_pop(&G.prog.stack); 6831 bc_vec_pop(&G.prog.stack);
6807 break; 6832 break;
6808 case BC_INST_PRINT: 6833 case BC_INST_PRINT:
6809 case BC_INST_PRINT_POP: 6834 case BC_INST_PRINT_POP:
6810 case BC_INST_PRINT_STR: 6835 case BC_INST_PRINT_STR:
6836 dbg_exec("BC_INST_PRINTxyz:");
6811 s = zbc_program_print(inst, 0); 6837 s = zbc_program_print(inst, 0);
6812 break; 6838 break;
6813 case BC_INST_STR: 6839 case BC_INST_STR:
6840 dbg_exec("BC_INST_STR:");
6814 r.t = BC_RESULT_STR; 6841 r.t = BC_RESULT_STR;
6815 r.d.id.idx = bc_program_index(code, &ip->idx); 6842 r.d.id.idx = bc_program_index(code, &ip->idx);
6816 bc_vec_push(&G.prog.results, &r); 6843 bc_vec_push(&G.prog.results, &r);
@@ -6821,9 +6848,11 @@ static BC_STATUS zbc_program_exec(void)
6821 case BC_INST_MODULUS: 6848 case BC_INST_MODULUS:
6822 case BC_INST_PLUS: 6849 case BC_INST_PLUS:
6823 case BC_INST_MINUS: 6850 case BC_INST_MINUS:
6851 dbg_exec("BC_INST_binaryop:");
6824 s = zbc_program_op(inst); 6852 s = zbc_program_op(inst);
6825 break; 6853 break;
6826 case BC_INST_BOOL_NOT: 6854 case BC_INST_BOOL_NOT:
6855 dbg_exec("BC_INST_BOOL_NOT:");
6827 s = zbc_program_prep(&ptr, &num); 6856 s = zbc_program_prep(&ptr, &num);
6828 if (s) RETURN_STATUS(s); 6857 if (s) RETURN_STATUS(s);
6829 bc_num_init_DEF_SIZE(&r.d.n); 6858 bc_num_init_DEF_SIZE(&r.d.n);
@@ -6833,6 +6862,7 @@ static BC_STATUS zbc_program_exec(void)
6833 bc_program_retire(&r, BC_RESULT_TEMP); 6862 bc_program_retire(&r, BC_RESULT_TEMP);
6834 break; 6863 break;
6835 case BC_INST_NEG: 6864 case BC_INST_NEG:
6865 dbg_exec("BC_INST_NEG:");
6836 s = zbc_program_negate(); 6866 s = zbc_program_negate();
6837 break; 6867 break;
6838#if ENABLE_BC 6868#if ENABLE_BC
@@ -6844,6 +6874,7 @@ static BC_STATUS zbc_program_exec(void)
6844 case BC_INST_ASSIGN_MINUS: 6874 case BC_INST_ASSIGN_MINUS:
6845#endif 6875#endif
6846 case BC_INST_ASSIGN: 6876 case BC_INST_ASSIGN:
6877 dbg_exec("BC_INST_ASSIGNxyz:");
6847 s = zbc_program_assign(inst); 6878 s = zbc_program_assign(inst);
6848 break; 6879 break;
6849#if ENABLE_DC 6880#if ENABLE_DC
diff --git a/testsuite/bc.tests b/testsuite/bc.tests
index 5e8c47c0f..79ece2669 100755
--- a/testsuite/bc.tests
+++ b/testsuite/bc.tests
@@ -26,6 +26,26 @@ testing "bc string 1" \
26 "STR\n" \ 26 "STR\n" \
27 "" "\"STR\n\"" 27 "" "\"STR\n\""
28 28
29testing "bc if 0 else" \
30 "bc" \
31 "2\n9\n" \
32 "" "if (0) 1 else 2; 9"
33
34testing "bc if 1 else" \
35 "bc" \
36 "1\n9\n" \
37 "" "if (1) 1 else 2; 9"
38
39testing "bc if 1 if 1 else else" \
40 "bc" \
41 "1\n9\n" \
42 "" "if (1) if (1) 1 else 2 else 3; 9"
43
44testing "bc if 0 else if 1" \
45 "bc" \
46 "2\n9\n" \
47 "" "if (0) 1 else if (1) 2; 9"
48
29tar xJf bc_large.tar.xz 49tar xJf bc_large.tar.xz
30 50
31for f in bc*.bc; do 51for f in bc*.bc; do