summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/dc/stack.c
diff options
context:
space:
mode:
authorphil <phil@NetBSD.org>1997-04-29 00:34:25 +0000
committerphil <phil@NetBSD.org>1997-04-29 00:34:25 +0000
commitbc4e66aef97f86fd61dc4cd478f6564b0b3857b3 (patch)
tree32b08a693b1a9045e32f00e5b1542f8fc92f24db /gnu/usr.bin/dc/stack.c
parentf18cfec654719ae1e1ce6725d7b6fd8834919d6a (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.c90
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