From 3d88cc1d371a4a5ae8e1521a1e915479bca52959 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 13:26:48 +0100 Subject: dc: correct --help text before: Tiny RPN calculator. Operations: +, -, *, /, %, ~, ^, |, p - print top of the stack without popping f - print entire stack k - pop the value and set the precision i - pop the value and set input radix o - pop the value and set output radix After: Tiny RPN calculator. Operations: Arithmetic: + - * / % ^ ~ - divide with remainder | - modular exponentiation v - square root p - print top of the stack without popping f - print entire stack k - pop the value and set precision i - pop the value and set input radix o - pop the value and set output radix function old new delta packed_usage 33519 33565 +46 Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'miscutils') diff --git a/miscutils/bc.c b/miscutils/bc.c index 02a61ac49..84bbe7b14 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -138,11 +138,53 @@ //usage: //usage:#define dc_full_usage "\n" //usage: "\nTiny RPN calculator. Operations:" -//usage: "\n+, -, *, /, %, ~, ^," IF_FEATURE_DC_BIG(" |,") +//usage: "\nArithmetic: + - * / % ^" +//usage: IF_FEATURE_DC_BIG( +//usage: "\n~ - divide with remainder" +//usage: "\n| - modular exponentiation" +//usage: "\nv - square root" +//////// "\n_NNN - push neagtive number -NNN +//////// "\n[string] - push string +//////// "\nR - DC_LEX_POP pop and discard +//////// "\nc - DC_LEX_CLEAR_STACK clear stack +//////// "\nd - DC_LEX_DUPLICATE pop, push, push +//////// "\nr - DC_LEX_SWAP pop 1, pop 2, push 1, push 2 +//////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' +//////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push +//////// "\nLr - DC_LEX_LOAD_PO, pop register 'r', push +//////// "\nSr - DC_LEX_STORE_PUSH pop, push to register 'r' +//////// "\nlr - DC_LEX_LOAD read register 'r', push +//////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' +//////// "\n? - DC_LEX_READ read line and execute +//////// "\nx - DC_LEX_EXECUTE pop string and execute +//////// "\nr - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was less +//////// "\n=r - XC_LEX_OP_REL_EQ pop, pop, execute register 'r' if equal +//////// "\n!r !=r - negated forms +//////// "\ne - DC_LEX_ELSE >tef: "if greater execute 't' else execute 'f'" +//////// "\nQ - DC_LEX_NQUIT pop, "break N" from macro invocations +//////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) +//////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits +//////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) +//////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st string char +//////// "\n( - DC_LEX_LPAREN ? +//////// "\n{ - DC_LEX_LBRACE ? +//////// "\n_ - XC_LEX_NEG (not a command - starts negative number) +//////// "\nG - DC_LEX_EQ_NO_REG (? GNU dc has no such cmd) +//////// "\nN - DC_LEX_OP_BOOL_NOT (? GNU dc has no such cmd) +//////// "\nn - DC_LEX_PRINT_POP pop, print without newline +//////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes +//usage: ) //usage: "\np - print top of the stack without popping" //usage: "\nf - print entire stack" -//usage: "\nk - pop the value and set the precision" +//////// "\nz - DC_LEX_STACK_LEVEL push stack depth +//////// "\nK - DC_LEX_SCALE push precision +//////// "\nI - DC_LEX_IBASE push input radix +//////// "\nO - DC_LEX_OBASE push output radix +//usage: IF_FEATURE_DC_BIG( +//usage: "\nk - pop the value and set precision" //usage: "\ni - pop the value and set input radix" +//usage: ) //usage: "\no - pop the value and set output radix" //usage: "\nExamples: dc -e'2 2 + p' -> 4, dc -e'8 8 * 2 2 + / p' -> 16" //usage: -- cgit v1.2.3 From ace81cd46ce53e60fe702cc1ac857989207e7ac4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 14:05:28 +0100 Subject: bc/dc: fix length(0) and length(0.000nnn) result function old new delta zxc_vm_process 6464 6498 +34 Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 17 +++++++++++++---- testsuite/bc.tests | 5 +++++ testsuite/dc.tests | 5 +++++ 3 files changed, 23 insertions(+), 4 deletions(-) (limited to 'miscutils') diff --git a/miscutils/bc.c b/miscutils/bc.c index 84bbe7b14..91564099e 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -6259,13 +6259,20 @@ static unsigned long xc_program_len(BcNum *n) { size_t len = n->len; - if (n->rdx != len) return len; + if (n->rdx != len) + // length(100): rdx 0 len 3, return 3 + // length(0.01-0.01): rdx 2 len 0, return 2 + // dc: 0.01 0.01 - Zp: rdx 2 len 0, return 1 + return len != 0 ? len : (IS_BC ? n->rdx : 1); + + // length(0): return 1 + // length(0.000nnn): count nnn for (;;) { if (len == 0) break; len--; if (n->num[len] != 0) break; } - return len; + return len + 1; } static BC_STATUS zxc_program_builtin(char inst) @@ -6293,12 +6300,12 @@ static BC_STATUS zxc_program_builtin(char inst) if (inst == XC_INST_SQRT) s = zbc_num_sqrt(num, &res.d.n, G.prog.scale); #if ENABLE_BC - else if (len != 0 && opnd->t == XC_RESULT_ARRAY) { + else if (len && opnd->t == XC_RESULT_ARRAY) { bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); } #endif #if ENABLE_DC - else if (len != 0 && !BC_PROG_NUM(opnd, num)) { + else if (len && !BC_PROG_NUM(opnd, num)) { char **str; size_t idx = opnd->t == XC_RESULT_STR ? opnd->d.id.idx : num->rdx; @@ -6307,6 +6314,8 @@ static BC_STATUS zxc_program_builtin(char inst) } #endif else { +//TODO: length(.00) and scale(.00) should return 2, they return 1 and 0 now +//(don't forget to check that dc Z and X commands do not break) bc_num_ulong2num(&res.d.n, len ? xc_program_len(num) : xc_program_scale(num)); } diff --git a/testsuite/bc.tests b/testsuite/bc.tests index 179d5d2a2..1c748727a 100755 --- a/testsuite/bc.tests +++ b/testsuite/bc.tests @@ -182,6 +182,11 @@ testing "bc print 1,2,3" \ "123" \ "" "print 1,2,3" +testing "bc length" \ + "bc" \ + "1\n3\n1\n3\n3\n" \ + "" "length(0); length(100); length(0.01); length(0.00120); length(0.012-0.012);" + testing "bc { print 1 }" \ "bc" \ "1" \ diff --git a/testsuite/dc.tests b/testsuite/dc.tests index 361bc8459..ad0099354 100755 --- a/testsuite/dc.tests +++ b/testsuite/dc.tests @@ -114,6 +114,11 @@ testing "dc newline can be a register" \ "2\n9\n" \ "" "[2p]s\n[3p]l\nx\n9p" +testing "dc Z (length) for numbers" \ + "dc" \ + "1\n1\n3\n1\n3\n1\n" \ + "" "0Zp\n0.000Zp\n100Zp\n0.01Zp\n0.00120Zp\n0.0012 0.0012 - Zp\n" + for f in dc_*.dc; do r="`basename "$f" .dc`_results.txt" test -f "$r" || continue -- cgit v1.2.3 From 1a37aa7a88722f49928f6cd7851476aa4525462d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 14:48:04 +0100 Subject: dc: document what non-GNU commands do Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'miscutils') diff --git a/miscutils/bc.c b/miscutils/bc.c index 91564099e..cc48ed3fe 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -166,12 +166,12 @@ //////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) //////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits //////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) -//////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st string char -//////// "\n( - DC_LEX_LPAREN ? -//////// "\n{ - DC_LEX_LBRACE ? +//////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st char of string +//////// "\n( - DC_LEX_LPAREN (not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 +//////// "\n{ - DC_LEX_LBRACE (not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 +//////// "\nG - DC_LEX_EQ_NO_REG (not in GNU) pop, pop, if equal push 1 else push 0 +//////// "\nN - DC_LEX_OP_BOOL_NOT (not in GNU) pop, if 0 push 1 else push 0 //////// "\n_ - XC_LEX_NEG (not a command - starts negative number) -//////// "\nG - DC_LEX_EQ_NO_REG (? GNU dc has no such cmd) -//////// "\nN - DC_LEX_OP_BOOL_NOT (? GNU dc has no such cmd) //////// "\nn - DC_LEX_PRINT_POP pop, print without newline //////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes //usage: ) -- cgit v1.2.3 From 9037757c5fde77d74e24e100efd70420a51c5d95 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 17:11:55 +0100 Subject: dc: more docs in --help Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'miscutils') diff --git a/miscutils/bc.c b/miscutils/bc.c index cc48ed3fe..934a1f8ba 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -143,12 +143,13 @@ //usage: "\n~ - divide with remainder" //usage: "\n| - modular exponentiation" //usage: "\nv - square root" -//////// "\n_NNN - push neagtive number -NNN -//////// "\n[string] - push string +//////// "\nA-F - digits 10..15 +//////// "\n_NNN - push negative number -NNN +//////// "\n[string] - push string (in FreeBSD, \[, \] and \\ are escapes, not implemented here and in GNU) //////// "\nR - DC_LEX_POP pop and discard //////// "\nc - DC_LEX_CLEAR_STACK clear stack -//////// "\nd - DC_LEX_DUPLICATE pop, push, push -//////// "\nr - DC_LEX_SWAP pop 1, pop 2, push 1, push 2 +//////// "\nd - DC_LEX_DUPLICATE duplicate top-of-stack +//////// "\nr - DC_LEX_SWAP swap top-of-stack //////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' //////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push //////// "\nLr - DC_LEX_LOAD_PO, pop register 'r', push @@ -157,21 +158,21 @@ //////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' //////// "\n? - DC_LEX_READ read line and execute //////// "\nx - DC_LEX_EXECUTE pop string and execute -//////// "\nr - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was less +//////// "\nr - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was greater //////// "\n=r - XC_LEX_OP_REL_EQ pop, pop, execute register 'r' if equal -//////// "\n!r !=r - negated forms -//////// "\ne - DC_LEX_ELSE >tef: "if greater execute 't' else execute 'f'" +//////// "\n !r !=r - negated forms +//////// "\n >tef - "if greater execute register 't' else execute 'f'" //////// "\nQ - DC_LEX_NQUIT pop, "break N" from macro invocations //////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) //////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits //////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) //////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st char of string -//////// "\n( - DC_LEX_LPAREN (not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 -//////// "\n{ - DC_LEX_LBRACE (not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 -//////// "\nG - DC_LEX_EQ_NO_REG (not in GNU) pop, pop, if equal push 1 else push 0 -//////// "\nN - DC_LEX_OP_BOOL_NOT (not in GNU) pop, if 0 push 1 else push 0 -//////// "\n_ - XC_LEX_NEG (not a command - starts negative number) +//////// "\n( - DC_LEX_LPAREN (FreeBSD, not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 +//////// "\n{ - DC_LEX_LBRACE (FreeBSD, not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 +//////// "\nG - DC_LEX_EQ_NO_REG (FreeBSD, not in GNU) pop, pop, if equal push 1 else push 0 +//////// "\nN - DC_LEX_OP_BOOL_NOT (FreeBSD, not in GNU) pop, if 0 push 1 else push 0 +//////// FreeBSD also has J and M commands, used internally by bc //////// "\nn - DC_LEX_PRINT_POP pop, print without newline //////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes //usage: ) -- cgit v1.2.3 From 9b6bcfda0e11c0e73a966a77110f6c68425cff34 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2021 21:20:18 +0100 Subject: bc: typo fix in comment Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'miscutils') diff --git a/miscutils/bc.c b/miscutils/bc.c index 934a1f8ba..553d0f472 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -152,7 +152,7 @@ //////// "\nr - DC_LEX_SWAP swap top-of-stack //////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' //////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push -//////// "\nLr - DC_LEX_LOAD_PO, pop register 'r', push +//////// "\nLr - DC_LEX_LOAD_POP pop register 'r', push //////// "\nSr - DC_LEX_STORE_PUSH pop, push to register 'r' //////// "\nlr - DC_LEX_LOAD read register 'r', push //////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' -- cgit v1.2.3