aboutsummaryrefslogtreecommitdiff
path: root/miscutils/bc.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-24 00:50:32 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-24 00:50:32 +0100
commitad0bd381e97214c6c978f5214bcd328bfea4b3da (patch)
tree74a169a96098056a28bc9359a48659f7b2cd5369 /miscutils/bc.c
parent9471bd46603d9f61c76d672b0a679c2b9446c3cf (diff)
downloadbusybox-w32-ad0bd381e97214c6c978f5214bcd328bfea4b3da.tar.gz
busybox-w32-ad0bd381e97214c6c978f5214bcd328bfea4b3da.tar.bz2
busybox-w32-ad0bd381e97214c6c978f5214bcd328bfea4b3da.zip
bc: for "dc only" remove handling of LAST, move OBASE enums up to IBASE
function old new delta dc_LEX_to_INST - 82 +82 bc_parse_pushNUM - 62 +62 zbc_program_num 981 978 -3 bc_result_free 46 43 -3 zbc_program_binOpPrep 305 300 -5 static.msg 24 12 -12 zbc_program_exec 4013 3994 -19 zdc_parse_expr 583 507 -76 dc_parse_insts 83 - -83 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 0/6 up/down: 144/-201) Total: -57 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r--miscutils/bc.c157
1 files changed, 82 insertions, 75 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index a7b8aa4bb..85eeb6743 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -141,7 +141,7 @@
141//usage:#define dc_full_usage "\n" 141//usage:#define dc_full_usage "\n"
142//usage: "\nTiny RPN calculator. Operations:" 142//usage: "\nTiny RPN calculator. Operations:"
143//usage: "\n+, -, *, /, %, ~, ^," IF_NOT_FEATURE_DC_SMALL(" |,") 143//usage: "\n+, -, *, /, %, ~, ^," IF_NOT_FEATURE_DC_SMALL(" |,")
144//usage: "\np - print top of the stack (without popping)" 144//usage: "\np - print top of the stack without popping"
145//usage: "\nf - print entire stack" 145//usage: "\nf - print entire stack"
146//usage: "\nk - pop the value and set the precision" 146//usage: "\nk - pop the value and set the precision"
147//usage: "\ni - pop the value and set input radix" 147//usage: "\ni - pop the value and set input radix"
@@ -286,14 +286,14 @@ typedef enum BcInst {
286 BC_INST_VAR, 286 BC_INST_VAR,
287 BC_INST_ARRAY_ELEM, 287 BC_INST_ARRAY_ELEM,
288 BC_INST_ARRAY, 288 BC_INST_ARRAY,
289
290 BC_INST_SCALE_FUNC, 289 BC_INST_SCALE_FUNC,
291 BC_INST_IBASE, 290
292 BC_INST_SCALE, 291 BC_INST_IBASE, // order of these constans should match other enums
293 BC_INST_LAST, 292 BC_INST_OBASE, // order of these constans should match other enums
293 BC_INST_SCALE, // order of these constans should match other enums
294 IF_BC(BC_INST_LAST,) // order of these constans should match other enums
294 BC_INST_LENGTH, 295 BC_INST_LENGTH,
295 BC_INST_READ, 296 BC_INST_READ,
296 BC_INST_OBASE,
297 BC_INST_SQRT, 297 BC_INST_SQRT,
298 298
299 BC_INST_PRINT, 299 BC_INST_PRINT,
@@ -365,12 +365,12 @@ typedef enum BcResultType {
365 BC_RESULT_STR, 365 BC_RESULT_STR,
366 366
367 //code uses "inst - BC_INST_IBASE + BC_RESULT_IBASE" construct, 367 //code uses "inst - BC_INST_IBASE + BC_RESULT_IBASE" construct,
368 BC_RESULT_IBASE, // relative order should match for: BC_INST_IBASE 368 BC_RESULT_IBASE, // relative order should match for: BC_INST_IBASE
369 BC_RESULT_SCALE, // relative order should match for: BC_INST_SCALE 369 BC_RESULT_OBASE, // relative order should match for: BC_INST_OBASE
370 BC_RESULT_LAST, // relative order should match for: BC_INST_LAST 370 BC_RESULT_SCALE, // relative order should match for: BC_INST_SCALE
371 IF_BC(BC_RESULT_LAST,) // relative order should match for: BC_INST_LAST
371 BC_RESULT_CONSTANT, 372 BC_RESULT_CONSTANT,
372 BC_RESULT_ONE, 373 BC_RESULT_ONE,
373 BC_RESULT_OBASE, // relative order should match for: BC_INST_OBASE
374} BcResultType; 374} BcResultType;
375 375
376typedef union BcResultData { 376typedef union BcResultData {
@@ -453,12 +453,12 @@ typedef enum BcLexType {
453 BC_LEX_KEY_FOR, 453 BC_LEX_KEY_FOR,
454 BC_LEX_KEY_HALT, 454 BC_LEX_KEY_HALT,
455 // code uses "type - BC_LEX_KEY_IBASE + BC_INST_IBASE" construct, 455 // code uses "type - BC_LEX_KEY_IBASE + BC_INST_IBASE" construct,
456 BC_LEX_KEY_IBASE, // relative order should match for: BC_INST_IBASE 456 BC_LEX_KEY_IBASE, // relative order should match for: BC_INST_IBASE
457 BC_LEX_KEY_OBASE, // relative order should match for: BC_INST_OBASE
457 BC_LEX_KEY_IF, 458 BC_LEX_KEY_IF,
458 BC_LEX_KEY_LAST, // relative order should match for: BC_INST_LAST 459 IF_BC(BC_LEX_KEY_LAST,) // relative order should match for: BC_INST_LAST
459 BC_LEX_KEY_LENGTH, 460 BC_LEX_KEY_LENGTH,
460 BC_LEX_KEY_LIMITS, 461 BC_LEX_KEY_LIMITS,
461 BC_LEX_KEY_OBASE, // relative order should match for: BC_INST_OBASE
462 BC_LEX_KEY_PRINT, 462 BC_LEX_KEY_PRINT,
463 BC_LEX_KEY_QUIT, 463 BC_LEX_KEY_QUIT,
464 BC_LEX_KEY_READ, 464 BC_LEX_KEY_READ,
@@ -487,11 +487,11 @@ typedef enum BcLexType {
487 487
488 // code uses "t - BC_LEX_STORE_IBASE + BC_INST_IBASE" construct, 488 // code uses "t - BC_LEX_STORE_IBASE + BC_INST_IBASE" construct,
489 BC_LEX_STORE_IBASE, // relative order should match for: BC_INST_IBASE 489 BC_LEX_STORE_IBASE, // relative order should match for: BC_INST_IBASE
490 BC_LEX_STORE_OBASE, // relative order should match for: BC_INST_OBASE
490 BC_LEX_STORE_SCALE, // relative order should match for: BC_INST_SCALE 491 BC_LEX_STORE_SCALE, // relative order should match for: BC_INST_SCALE
491 BC_LEX_LOAD, 492 BC_LEX_LOAD,
492 BC_LEX_LOAD_POP, 493 BC_LEX_LOAD_POP,
493 BC_LEX_STORE_PUSH, 494 BC_LEX_STORE_PUSH,
494 BC_LEX_STORE_OBASE, // relative order should match for: BC_INST_OBASE
495 BC_LEX_PRINT_POP, 495 BC_LEX_PRINT_POP,
496 BC_LEX_NQUIT, 496 BC_LEX_NQUIT,
497 BC_LEX_SCALE_FACTOR, 497 BC_LEX_SCALE_FACTOR,
@@ -513,11 +513,11 @@ static const struct BcLexKeyword bc_lex_kws[20] = {
513 BC_LEX_KW_ENTRY("for" , 1), // 5 513 BC_LEX_KW_ENTRY("for" , 1), // 5
514 BC_LEX_KW_ENTRY("halt" , 0), // 6 514 BC_LEX_KW_ENTRY("halt" , 0), // 6
515 BC_LEX_KW_ENTRY("ibase" , 1), // 7 515 BC_LEX_KW_ENTRY("ibase" , 1), // 7
516 BC_LEX_KW_ENTRY("if" , 1), // 8 516 BC_LEX_KW_ENTRY("obase" , 1), // 8
517 BC_LEX_KW_ENTRY("last" , 0), // 9 517 BC_LEX_KW_ENTRY("if" , 1), // 9
518 BC_LEX_KW_ENTRY("length" , 1), // 10 518 BC_LEX_KW_ENTRY("last" , 0), // 10
519 BC_LEX_KW_ENTRY("limits" , 0), // 11 519 BC_LEX_KW_ENTRY("length" , 1), // 11
520 BC_LEX_KW_ENTRY("obase" , 1), // 12 520 BC_LEX_KW_ENTRY("limits" , 0), // 12
521 BC_LEX_KW_ENTRY("print" , 0), // 13 521 BC_LEX_KW_ENTRY("print" , 0), // 13
522 BC_LEX_KW_ENTRY("quit" , 1), // 14 522 BC_LEX_KW_ENTRY("quit" , 1), // 14
523 BC_LEX_KW_ENTRY("read" , 0), // 15 523 BC_LEX_KW_ENTRY("read" , 0), // 15
@@ -527,10 +527,10 @@ static const struct BcLexKeyword bc_lex_kws[20] = {
527 BC_LEX_KW_ENTRY("while" , 1), // 19 527 BC_LEX_KW_ENTRY("while" , 1), // 19
528}; 528};
529#undef BC_LEX_KW_ENTRY 529#undef BC_LEX_KW_ENTRY
530#define STRING_if (bc_lex_kws[8].name8)
531#define STRING_else (bc_lex_kws[4].name8) 530#define STRING_else (bc_lex_kws[4].name8)
532#define STRING_while (bc_lex_kws[19].name8)
533#define STRING_for (bc_lex_kws[5].name8) 531#define STRING_for (bc_lex_kws[5].name8)
532#define STRING_if (bc_lex_kws[9].name8)
533#define STRING_while (bc_lex_kws[19].name8)
534enum { 534enum {
535 POSIX_KWORD_MASK = 0 535 POSIX_KWORD_MASK = 0
536 | (1 << 0) // 0 536 | (1 << 0) // 0
@@ -542,10 +542,10 @@ enum {
542 | (0 << 6) // 6 542 | (0 << 6) // 6
543 | (1 << 7) // 7 543 | (1 << 7) // 7
544 | (1 << 8) // 8 544 | (1 << 8) // 8
545 | (0 << 9) // 9 545 | (1 << 9) // 9
546 | (1 << 10) // 10 546 | (0 << 10) // 10
547 | (0 << 11) // 11 547 | (1 << 11) // 11
548 | (1 << 12) // 12 548 | (0 << 12) // 12
549 | (0 << 13) // 13 549 | (0 << 13) // 13
550 | (1 << 14) // 14 550 | (1 << 14) // 14
551 | (0 << 15) // 15 551 | (0 << 15) // 15
@@ -560,19 +560,19 @@ enum {
560// true if the token is valid in an expression, false otherwise. 560// true if the token is valid in an expression, false otherwise.
561// Used to figure out when expr parsing should stop *without error message* 561// Used to figure out when expr parsing should stop *without error message*
562// - 0 element indicates this condition. 1 means "this token is to be eaten 562// - 0 element indicates this condition. 1 means "this token is to be eaten
563// as part of the expression", token can them still be determined to be invalid 563// as part of the expression", it can then still be determined to be invalid
564// by later processing. 564// by later processing.
565enum { 565enum {
566#define EXBITS(a,b,c,d,e,f,g,h) \ 566#define EXBITS(a,b,c,d,e,f,g,h) \
567 ((uint64_t)((a << 0)+(b << 1)+(c << 2)+(d << 3)+(e << 4)+(f << 5)+(g << 6)+(h << 7))) 567 ((uint64_t)((a << 0)+(b << 1)+(c << 2)+(d << 3)+(e << 4)+(f << 5)+(g << 6)+(h << 7)))
568 BC_PARSE_EXPRS_BITS = 0 568 BC_PARSE_EXPRS_BITS = 0 // corresponding BC_LEX_xyz:
569 + (EXBITS(0,0,1,1,1,1,1,1) << (0*8)) // 0: eof inval ++ -- - ^ * / 569 + (EXBITS(0,0,1,1,1,1,1,1) << (0*8)) // 0: eof inval ++ -- - ^ * /
570 + (EXBITS(1,1,1,1,1,1,1,1) << (1*8)) // 8: % + - == <= >= != < 570 + (EXBITS(1,1,1,1,1,1,1,1) << (1*8)) // 8: % + - == <= >= != <
571 + (EXBITS(1,1,1,1,1,1,1,1) << (2*8)) // 16: > ! || && ^= *= /= %= 571 + (EXBITS(1,1,1,1,1,1,1,1) << (2*8)) // 16: > ! || && ^= *= /= %=
572 + (EXBITS(1,1,1,0,0,1,1,0) << (3*8)) // 24: += -= = NL WS ( ) [ 572 + (EXBITS(1,1,1,0,0,1,1,0) << (3*8)) // 24: += -= = NL WS ( ) [
573 + (EXBITS(0,0,0,0,0,0,1,1) << (4*8)) // 32: , ] { ; } STR NAME NUM 573 + (EXBITS(0,0,0,0,0,0,1,1) << (4*8)) // 32: , ] { ; } STR NAME NUM
574 + (EXBITS(0,0,0,0,0,0,0,1) << (5*8)) // 40: auto break cont define else for halt ibase 574 + (EXBITS(0,0,0,0,0,0,0,1) << (5*8)) // 40: auto break cont define else for halt ibase
575 + (EXBITS(0,1,1,1,1,0,0,1) << (6*8)) // 48: if last len limits obase print quit read - bug, why "limits" is allowed? 575 + (EXBITS(1,0,1,1,1,0,0,1) << (6*8)) // 48: obase if last len limits print quit read - bug, why "limits" is allowed?
576 + (EXBITS(0,1,1,0,0,0,0,0) << (7*8)) // 56: return scale sqrt while 576 + (EXBITS(0,1,1,0,0,0,0,0) << (7*8)) // 56: return scale sqrt while
577#undef EXBITS 577#undef EXBITS
578}; 578};
@@ -615,30 +615,30 @@ static const uint8_t bc_parse_ops[] = {
615#if ENABLE_DC 615#if ENABLE_DC
616static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1 616static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1
617int8_t 617int8_t
618dc_parse_insts[] = { 618dc_LEX_to_INST[] = { // (so many INVALIDs b/c dc parser does not generate these LEXs) // corresponding BC_LEX_xyz:
619 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE, 619 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE, // EOF INVALID OP_INC OP_DEC
620 BC_INST_INVALID, BC_INST_POWER, BC_INST_MULTIPLY, BC_INST_DIVIDE, 620 BC_INST_INVALID, BC_INST_POWER, BC_INST_MULTIPLY, BC_INST_DIVIDE, // NEG OP_POWER OP_MULTIPLY OP_DIVIDE
621 BC_INST_MODULUS, BC_INST_PLUS, BC_INST_MINUS, 621 BC_INST_MODULUS, BC_INST_PLUS, BC_INST_MINUS, // OP_MODULUS OP_PLUS OP_MINUS
622 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, 622 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, // OP_REL_EQ OP_REL_LE OP_REL_GE OP_REL_NE
623 BC_INST_INVALID, BC_INST_INVALID, 623 BC_INST_INVALID, BC_INST_INVALID, // OP_REL_LT OP_REL_GT
624 BC_INST_BOOL_NOT, BC_INST_INVALID, BC_INST_INVALID, 624 BC_INST_BOOL_NOT, BC_INST_INVALID, BC_INST_INVALID, // OP_BOOL_NOT OP_BOOL_OR OP_BOOL_AND
625 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, 625 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, // OP_ASSIGN_POWER OP_ASSIGN_MULTIPLY OP_ASSIGN_DIVIDE OP_ASSIGN_MODULUS
626 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, 626 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, // OP_ASSIGN_PLUS OP_ASSIGN_MINUS OP_ASSIGN
627 BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GT, BC_INST_INVALID, 627 BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GT, BC_INST_INVALID, // NLINE WHITESPACE LPAREN RPAREN
628 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE, 628 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_REL_GE, // LBRACKET COMMA RBRACKET LBRACE
629 BC_INST_INVALID, BC_INST_INVALID, 629 BC_INST_INVALID, BC_INST_INVALID, // SCOLON RBRACE
630 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, 630 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, // STR NAME NUMBER
631 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, 631 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, // KEY_AUTO KEY_BREAK KEY_CONTINUE KEY_DEFINE
632 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_IBASE, 632 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_IBASE, // KEY_ELSE KEY_FOR KEY_HALT KEY_IBASE
633 BC_INST_INVALID, BC_INST_INVALID, BC_INST_LENGTH, BC_INST_INVALID, 633 BC_INST_OBASE, BC_INST_INVALID, IF_BC(BC_INST_INVALID,) BC_INST_LENGTH,//KEY_OBASE KEY_IF KEY_LAST(bc) KEY_LENGTH
634 BC_INST_OBASE, BC_INST_PRINT, BC_INST_QUIT, BC_INST_INVALID, 634 BC_INST_INVALID, BC_INST_PRINT, BC_INST_QUIT, BC_INST_INVALID, // KEY_LIMITS KEY_PRINT KEY_QUIT KEY_READ
635 BC_INST_INVALID, BC_INST_SCALE, BC_INST_SQRT, BC_INST_INVALID, 635 BC_INST_INVALID, BC_INST_SCALE, BC_INST_SQRT, BC_INST_INVALID, // KEY_RETURN KEY_SCALE KEY_SQRT KEY_WHILE
636 BC_INST_REL_EQ, BC_INST_MODEXP, BC_INST_DIVMOD, BC_INST_INVALID, 636 BC_INST_REL_EQ, BC_INST_MODEXP, BC_INST_DIVMOD, BC_INST_INVALID, // EQ_NO_REG OP_MODEXP OP_DIVMOD COLON
637 BC_INST_INVALID, BC_INST_EXECUTE, BC_INST_PRINT_STACK, BC_INST_CLEAR_STACK, 637 BC_INST_INVALID, BC_INST_EXECUTE, BC_INST_PRINT_STACK, BC_INST_CLEAR_STACK, //ELSE EXECUTE PRINT_STACK CLEAR_STACK
638 BC_INST_STACK_LEN, BC_INST_DUPLICATE, BC_INST_SWAP, BC_INST_POP, 638 BC_INST_STACK_LEN, BC_INST_DUPLICATE, BC_INST_SWAP, BC_INST_POP, // STACK_LEVEL DUPLICATE SWAP POP
639 BC_INST_ASCIIFY, BC_INST_PRINT_STREAM, BC_INST_INVALID, BC_INST_INVALID, 639 BC_INST_ASCIIFY, BC_INST_PRINT_STREAM, BC_INST_INVALID, BC_INST_INVALID, //ASCIIFY PRINT_STREAM STORE_IBASE STORE_OBASE
640 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, 640 BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, BC_INST_INVALID, // STORE_SCALE LOAD LOAD_POP STORE_PUSH
641 BC_INST_PRINT, BC_INST_NQUIT, BC_INST_SCALE_FUNC, 641 BC_INST_PRINT, BC_INST_NQUIT, BC_INST_SCALE_FUNC, // PRINT_POP NQUIT SCALE_FACTOR
642}; 642};
643#endif // ENABLE_DC 643#endif // ENABLE_DC
644 644
@@ -2667,7 +2667,7 @@ static void dc_result_copy(BcResult *d, BcResult *src)
2667 d->d.id.name = xstrdup(src->d.id.name); 2667 d->d.id.name = xstrdup(src->d.id.name);
2668 break; 2668 break;
2669 case BC_RESULT_CONSTANT: 2669 case BC_RESULT_CONSTANT:
2670 case BC_RESULT_LAST: 2670 IF_BC(case BC_RESULT_LAST:)
2671 case BC_RESULT_ONE: 2671 case BC_RESULT_ONE:
2672 case BC_RESULT_STR: 2672 case BC_RESULT_STR:
2673 memcpy(&d->d.n, &src->d.n, sizeof(BcNum)); 2673 memcpy(&d->d.n, &src->d.n, sizeof(BcNum));
@@ -4919,11 +4919,13 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t)
4919 case BC_LEX_OP_REL_NE: 4919 case BC_LEX_OP_REL_NE:
4920 case BC_LEX_OP_REL_LT: 4920 case BC_LEX_OP_REL_LT:
4921 case BC_LEX_OP_REL_GT: 4921 case BC_LEX_OP_REL_GT:
4922 dbg_lex("%s:%d LEX_OP_REL_xyz", __func__, __LINE__);
4922 s = zdc_parse_cond(p, t - BC_LEX_OP_REL_EQ + BC_INST_REL_EQ); 4923 s = zdc_parse_cond(p, t - BC_LEX_OP_REL_EQ + BC_INST_REL_EQ);
4923 get_token = false; 4924 get_token = false;
4924 break; 4925 break;
4925 case BC_LEX_SCOLON: 4926 case BC_LEX_SCOLON:
4926 case BC_LEX_COLON: 4927 case BC_LEX_COLON:
4928 dbg_lex("%s:%d LEX_[S]COLON", __func__, __LINE__);
4927 s = zdc_parse_mem(p, BC_INST_ARRAY_ELEM, true, t == BC_LEX_COLON); 4929 s = zdc_parse_mem(p, BC_INST_ARRAY_ELEM, true, t == BC_LEX_COLON);
4928 break; 4930 break;
4929 case BC_LEX_STR: 4931 case BC_LEX_STR:
@@ -4931,34 +4933,39 @@ static BC_STATUS zdc_parse_token(BcParse *p, BcLexType t)
4931 dc_parse_string(p); 4933 dc_parse_string(p);
4932 break; 4934 break;
4933 case BC_LEX_NEG: 4935 case BC_LEX_NEG:
4936 dbg_lex("%s:%d LEX_NEG", __func__, __LINE__);
4937 s = zbc_lex_next(&p->l);
4938 if (s) RETURN_STATUS(s);
4939 if (p->l.t.t != BC_LEX_NUMBER)
4940 RETURN_STATUS(bc_error_bad_token());
4941 bc_parse_pushNUM(p);
4942 bc_parse_push(p, BC_INST_NEG);
4943 break;
4934 case BC_LEX_NUMBER: 4944 case BC_LEX_NUMBER:
4935 dbg_lex("%s:%d LEX_NEG/NUMBER", __func__, __LINE__); 4945 dbg_lex("%s:%d LEX_NUMBER", __func__, __LINE__);
4936 if (t == BC_LEX_NEG) {
4937 s = zbc_lex_next(&p->l);
4938 if (s) RETURN_STATUS(s);
4939 if (p->l.t.t != BC_LEX_NUMBER)
4940 RETURN_STATUS(bc_error_bad_token());
4941 }
4942 bc_parse_pushNUM(p); 4946 bc_parse_pushNUM(p);
4943 if (t == BC_LEX_NEG) bc_parse_push(p, BC_INST_NEG);
4944 break; 4947 break;
4945 case BC_LEX_KEY_READ: 4948 case BC_LEX_KEY_READ:
4949 dbg_lex("%s:%d LEX_KEY_READ", __func__, __LINE__);
4946 bc_parse_push(p, BC_INST_READ); 4950 bc_parse_push(p, BC_INST_READ);
4947 break; 4951 break;
4948 case BC_LEX_OP_ASSIGN: 4952 case BC_LEX_OP_ASSIGN:
4949 case BC_LEX_STORE_PUSH: 4953 case BC_LEX_STORE_PUSH:
4954 dbg_lex("%s:%d LEX_OP_ASSIGN/STORE_PUSH", __func__, __LINE__);
4950 assign = t == BC_LEX_OP_ASSIGN; 4955 assign = t == BC_LEX_OP_ASSIGN;
4951 inst = assign ? BC_INST_VAR : BC_INST_PUSH_TO_VAR; 4956 inst = assign ? BC_INST_VAR : BC_INST_PUSH_TO_VAR;
4952 s = zdc_parse_mem(p, inst, true, assign); 4957 s = zdc_parse_mem(p, inst, true, assign);
4953 break; 4958 break;
4954 case BC_LEX_LOAD: 4959 case BC_LEX_LOAD:
4955 case BC_LEX_LOAD_POP: 4960 case BC_LEX_LOAD_POP:
4961 dbg_lex("%s:%d LEX_OP_LOAD[_POP]", __func__, __LINE__);
4956 inst = t == BC_LEX_LOAD_POP ? BC_INST_PUSH_VAR : BC_INST_LOAD; 4962 inst = t == BC_LEX_LOAD_POP ? BC_INST_PUSH_VAR : BC_INST_LOAD;
4957 s = zdc_parse_mem(p, inst, true, false); 4963 s = zdc_parse_mem(p, inst, true, false);
4958 break; 4964 break;
4959 case BC_LEX_STORE_IBASE: 4965 case BC_LEX_STORE_IBASE:
4960 case BC_LEX_STORE_SCALE: 4966 case BC_LEX_STORE_SCALE:
4961 case BC_LEX_STORE_OBASE: 4967 case BC_LEX_STORE_OBASE:
4968 dbg_lex("%s:%d LEX_OP_STORE_I/OBASE/SCALE", __func__, __LINE__);
4962 inst = t - BC_LEX_STORE_IBASE + BC_INST_IBASE; 4969 inst = t - BC_LEX_STORE_IBASE + BC_INST_IBASE;
4963 s = zdc_parse_mem(p, inst, false, true); 4970 s = zdc_parse_mem(p, inst, false, true);
4964 break; 4971 break;
@@ -4979,7 +4986,7 @@ static BC_STATUS zdc_parse_expr(BcParse *p)
4979 BcInst inst; 4986 BcInst inst;
4980 BcStatus s; 4987 BcStatus s;
4981 4988
4982 inst = dc_parse_insts[p->l.t.t]; 4989 inst = dc_LEX_to_INST[p->l.t.t];
4983 if (inst != BC_INST_INVALID) { 4990 if (inst != BC_INST_INVALID) {
4984 bc_parse_push(p, inst); 4991 bc_parse_push(p, inst);
4985 s = zbc_lex_next(&p->l); 4992 s = zbc_lex_next(&p->l);
@@ -5086,9 +5093,11 @@ static BC_STATUS zbc_program_num(BcResult *r, BcNum **num, bool hex)
5086 *num = &G.prog.one; 5093 *num = &G.prog.one;
5087 break; 5094 break;
5088#endif 5095#endif
5096#if SANITY_CHECKS
5089 default: 5097 default:
5090 // Testing the theory that dc does not reach LAST/ONE 5098 // Testing the theory that dc does not reach LAST/ONE
5091 bb_error_msg_and_die("BUG:%d", r->t); 5099 bb_error_msg_and_die("BUG:%d", r->t);
5100#endif
5092 } 5101 }
5093 5102
5094 RETURN_STATUS(BC_STATUS_SUCCESS); 5103 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -5750,11 +5759,8 @@ static BC_STATUS zbc_program_assign(char inst)
5750 if (ib || sc || left->t == BC_RESULT_OBASE) { 5759 if (ib || sc || left->t == BC_RESULT_OBASE) {
5751 static const char *const msg[] = { 5760 static const char *const msg[] = {
5752 "bad ibase; must be [2,16]", //BC_RESULT_IBASE 5761 "bad ibase; must be [2,16]", //BC_RESULT_IBASE
5753 "bad scale; must be [0,"BC_MAX_SCALE_STR"]", //BC_RESULT_SCALE
5754 NULL, //can't happen //BC_RESULT_LAST
5755 NULL, //can't happen //BC_RESULT_CONSTANT
5756 NULL, //can't happen //BC_RESULT_ONE
5757 "bad obase; must be [2,"BC_MAX_OBASE_STR"]", //BC_RESULT_OBASE 5762 "bad obase; must be [2,"BC_MAX_OBASE_STR"]", //BC_RESULT_OBASE
5763 "bad scale; must be [0,"BC_MAX_SCALE_STR"]", //BC_RESULT_SCALE
5758 }; 5764 };
5759 size_t *ptr; 5765 size_t *ptr;
5760 size_t max; 5766 size_t max;
@@ -6474,16 +6480,17 @@ static BC_STATUS zbc_program_exec(void)
6474 dbg_exec("BC_INST_ARRAY[_ELEM]:"); 6480 dbg_exec("BC_INST_ARRAY[_ELEM]:");
6475 s = zbc_program_pushArray(code, &ip->inst_idx, inst); 6481 s = zbc_program_pushArray(code, &ip->inst_idx, inst);
6476 break; 6482 break;
6483#if ENABLE_BC
6477 case BC_INST_LAST: 6484 case BC_INST_LAST:
6478//TODO: this can't happen on dc, right?
6479 dbg_exec("BC_INST_LAST:"); 6485 dbg_exec("BC_INST_LAST:");
6480 r.t = BC_RESULT_LAST; 6486 r.t = BC_RESULT_LAST;
6481 bc_vec_push(&G.prog.results, &r); 6487 bc_vec_push(&G.prog.results, &r);
6482 break; 6488 break;
6489#endif
6483 case BC_INST_IBASE: 6490 case BC_INST_IBASE:
6484 case BC_INST_SCALE:
6485 case BC_INST_OBASE: 6491 case BC_INST_OBASE:
6486 dbg_exec("BC_INST_internalvar:"); 6492 case BC_INST_SCALE:
6493 dbg_exec("BC_INST_internalvar(%d):", inst - BC_INST_IBASE);
6487 bc_program_pushGlobal(inst); 6494 bc_program_pushGlobal(inst);
6488 break; 6495 break;
6489 case BC_INST_SCALE_FUNC: 6496 case BC_INST_SCALE_FUNC: