diff options
-rw-r--r-- | include/usage.h | 7 | ||||
-rw-r--r-- | miscutils/dc.c | 35 |
2 files changed, 40 insertions, 2 deletions
diff --git a/include/usage.h b/include/usage.h index 5b357a2..2ebf9ad 100644 --- a/include/usage.h +++ b/include/usage.h @@ -245,7 +245,12 @@ #define dc_full_usage \ "This is a Tiny RPN calculator that understands the\n" \ "following operations: +, -, /, *, and, or, not, eor.\n" \ - "i.e., 'dc 2 2 add' -> 4, and 'dc 8 8 \\* 2 2 + /' -> 16" + "i.e., 'dc 2 2 add' -> 4, and 'dc 8 8 \\* 2 2 + /' -> 16" \ + "p - Prints the value on the top of the stack, without altering the stack.\n" \ + "f - Prints the entire contents of the stack without altering anything.\n" \ + "o - Pops the value off the top of the stack and uses it to set the output radix.\n" \ + " Only 10 and 16 are supported.\n" + #define dc_example_usage \ "$ dc 2 2 +\n" \ "4\n" \ diff --git a/miscutils/dc.c b/miscutils/dc.c index f9020b3..c7b43ea 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -11,6 +11,7 @@ static double stack[100]; static unsigned int pointer; +static unsigned char base; static void push(double a) { @@ -70,9 +71,38 @@ static void not(void) push(~(unsigned int) pop()); } +static void set_output_base(void) +{ + base=(unsigned char)pop(); + if ((base != 10) && (base != 16)) { + fprintf(stderr, "Error: base = %d is not supported.\n", base); + base=10; + } +} + +static void print_base(double print) +{ + if (base == 16) + printf("%x\n", (unsigned int)print); + else + printf("%g\n", print); +} + +static void print_stack_no_pop(void) +{ + unsigned int i=pointer; + while (i) + print_base(stack[--i]); +} + +static void print_no_pop(void) +{ + print_base(stack[pointer-1]); +} + static void print(void) { - printf("%g\n", pop()); + print_base(pop()); } struct op { @@ -93,6 +123,9 @@ static const struct op operators[] = { {"or", or}, {"not", not}, {"eor", eor}, + {"p", print_no_pop}, + {"f", print_stack_no_pop}, + {"o", set_output_base}, {0, 0} }; |