diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-15 20:06:59 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-15 20:06:59 +0100 |
commit | 99b37623356a1555359df1c011d4a6732918a5c4 (patch) | |
tree | e12312d1068e991b51f0b078b24169501f973337 | |
parent | fd51e0c4d22825282f3e38be0655db36b3e716d2 (diff) | |
download | busybox-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.c | 107 | ||||
-rwxr-xr-x | testsuite/bc.tests | 20 |
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 |
173 | static unsigned lex_indent; | 174 | static 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 | |||
195 | typedef enum BcStatus { | 202 | typedef 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 | ||
669 | static 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 | |||
683 | static 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 | ||
3490 | IF_BC(static BC_STATUS zbc_parse_parse(BcParse *p);) | 3518 | IF_BC(static BC_STATUS zbc_parse_stmt_or_funcdef(BcParse *p);) |
3491 | IF_DC(static BC_STATUS zdc_parse_parse(BcParse *p);) | 3519 | IF_DC(static BC_STATUS zdc_parse_parse(BcParse *p);) |
3492 | 3520 | ||
3493 | static BC_STATUS zcommon_parse(BcParse *p) | 3521 | static 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 | ||
4106 | static 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 | |||
4119 | static void bc_parse_noElse(BcParse *p) | 4136 | static 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 | ||
4660 | static BC_STATUS zbc_parse_parse(BcParse *p) | 4679 | static 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 | ||
4967 | static 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) | |||
5190 | static BC_STATUS zcommon_parse_expr(BcParse *p, uint8_t flags) | 5201 | static 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 | ||
29 | testing "bc if 0 else" \ | ||
30 | "bc" \ | ||
31 | "2\n9\n" \ | ||
32 | "" "if (0) 1 else 2; 9" | ||
33 | |||
34 | testing "bc if 1 else" \ | ||
35 | "bc" \ | ||
36 | "1\n9\n" \ | ||
37 | "" "if (1) 1 else 2; 9" | ||
38 | |||
39 | testing "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 | |||
44 | testing "bc if 0 else if 1" \ | ||
45 | "bc" \ | ||
46 | "2\n9\n" \ | ||
47 | "" "if (0) 1 else if (1) 2; 9" | ||
48 | |||
29 | tar xJf bc_large.tar.xz | 49 | tar xJf bc_large.tar.xz |
30 | 50 | ||
31 | for f in bc*.bc; do | 51 | for f in bc*.bc; do |