diff options
| author | phil <phil@NetBSD.org> | 1997-04-29 00:34:25 +0000 |
|---|---|---|
| committer | phil <phil@NetBSD.org> | 1997-04-29 00:34:25 +0000 |
| commit | bc4e66aef97f86fd61dc4cd478f6564b0b3857b3 (patch) | |
| tree | 32b08a693b1a9045e32f00e5b1542f8fc92f24db /gnu/usr.bin/dc/stack.c | |
| parent | f18cfec654719ae1e1ce6725d7b6fd8834919d6a (diff) | |
Complete import of bc-1.04 by updating dc.
Diffstat (limited to 'gnu/usr.bin/dc/stack.c')
| -rw-r--r-- | gnu/usr.bin/dc/stack.c | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/gnu/usr.bin/dc/stack.c b/gnu/usr.bin/dc/stack.c index 6e3f9abff9b..c8cd195af35 100644 --- a/gnu/usr.bin/dc/stack.c +++ b/gnu/usr.bin/dc/stack.c @@ -1,7 +1,7 @@ /* * implement stack functions for dc * - * Copyright (C) 1994 Free Software Foundation, Inc. + * Copyright (C) 1994, 1997 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -105,6 +105,49 @@ dc_binop DC_DECLARG((op, kscale)) } /* check that there are two numbers on top of the stack, + * then call op with the popped numbers. Construct two dc_data + * values from the dc_num's returned by op and push them + * on the stack. + * If the op call doesn't return DC_SUCCESS, then leave the stack + * unmodified. + */ +void +dc_binop2 DC_DECLARG((op, kscale)) + int (*op)DC_PROTO((dc_num, dc_num, int, dc_num *, dc_num *)) DC_DECLSEP + int kscale DC_DECLEND +{ + dc_data a; + dc_data b; + dc_data r1; + dc_data r2; + + if (!dc_stack || !dc_stack->link){ + Empty_Stack; + return; + } + if (dc_stack->value.dc_type!=DC_NUMBER + || dc_stack->link->value.dc_type!=DC_NUMBER){ + fprintf(stderr, "%s: non-numeric value\n", progname); + return; + } + (void)dc_pop(&b); + (void)dc_pop(&a); + if ((*op)(a.v.number, b.v.number, kscale, + &r1.v.number, &r2.v.number) == DC_SUCCESS){ + r1.dc_type = DC_NUMBER; + dc_push(r1); + r2.dc_type = DC_NUMBER; + dc_push(r2); + dc_free_num(&a.v.number); + dc_free_num(&b.v.number); + }else{ + /* op failed; restore the stack */ + dc_push(a); + dc_push(b); + } +} + +/* check that there are two numbers on top of the stack, * then call dc_compare with the popped numbers. * Return negative, zero, or positive based on the ordering * of the two numbers. @@ -133,6 +176,51 @@ dc_cmpop DC_DECLVOID() return result; } +/* check that there are three numbers on top of the stack, + * then call op with the popped numbers. Construct a dc_data + * value from the dc_num returned by op and push it + * on the stack. + * If the op call doesn't return DC_SUCCESS, then leave the stack + * unmodified. + */ +void +dc_triop DC_DECLARG((op, kscale)) + int (*op)DC_PROTO((dc_num, dc_num, dc_num, int, dc_num *)) DC_DECLSEP + int kscale DC_DECLEND +{ + dc_data a; + dc_data b; + dc_data c; + dc_data r; + + if (!dc_stack || !dc_stack->link || !dc_stack->link->link){ + Empty_Stack; + return; + } + if (dc_stack->value.dc_type!=DC_NUMBER + || dc_stack->link->value.dc_type!=DC_NUMBER + || dc_stack->link->link->value.dc_type!=DC_NUMBER){ + fprintf(stderr, "%s: non-numeric value\n", progname); + return; + } + (void)dc_pop(&c); + (void)dc_pop(&b); + (void)dc_pop(&a); + if ((*op)(a.v.number, b.v.number, c.v.number, + kscale, &r.v.number) == DC_SUCCESS){ + r.dc_type = DC_NUMBER; + dc_push(r); + dc_free_num(&a.v.number); + dc_free_num(&b.v.number); + dc_free_num(&c.v.number); + }else{ + /* op failed; restore the stack */ + dc_push(a); + dc_push(b); + dc_push(c); + } +} + /* initialize the register stacks to their initial values */ void |
