2 /************************************************************************
4 * Code is modified from the code for Gnuplot by Zou Maorong
7 * G N U P L O T -- internal.c
8 * Copyright (C) 1986, 1987 Thomas Williams, Colin Kelley
9 * You may use this code as you wish if credit is given and this message
12 /****************************************************************************/
19 extern BOOLEAN undefined
;
22 struct value
*pop(), *complex(), *integer();
23 double magnitude(), angle(), real();
24 struct value stack
[STACK_DEPTH
];
25 int s_p
= -1; /* stack pointer */
27 /*************************************************************/
34 /*************************************************************/
36 check_stack() /* make sure stack's empty */
39 (void)fprintf(STDERRR
,"\nwarning: internal error--stack not empty!\n");
42 /*************************************************************/
49 int_error("stack underflow",NO_CARET
);
55 /*************************************************************/
61 if (s_p
== STACK_DEPTH
- 1)
62 int_error("stack overflow",NO_CARET
);
67 /*************************************************************/
69 #define ERR_VAR "undefined variable: "
71 union argument
*x
; /* contains pointer to value to push; */
73 static char err_str
[sizeof(ERR_VAR
) + MAX_ID_LEN
] = ERR_VAR
;
74 struct udvt_entry
*udv
;
77 if (udv
->udv_undef
) /* undefined */
79 (void) strcpy(&err_str
[sizeof(ERR_VAR
) - 1], udv
->udv_name
);
80 int_error(err_str
,NO_CARET
);
82 push(&(udv
->udv_value
));
85 /*************************************************************/
93 /*************************************************************/
98 push(&(x
->udf_arg
->dummy_value
));
101 /*************************************************************/
106 push(&(x
->udf_arg
->dummy_value1
));
109 /*************************************************************/
114 push(&(x
->udf_arg
->dummy_value2
));
117 /*************************************************************/
122 push(&(x
->udf_arg
->dummy_value3
));
125 /*************************************************************/
127 #define ERR_FUN "undefined function: "
128 f_call(x
) /* execute a udf */
131 static char err_str
[sizeof(ERR_FUN
) + MAX_ID_LEN
] = ERR_FUN
;
132 register struct udft_entry
*udf
;
135 if (!udf
->at
) /* undefined */
137 (void) strcpy(&err_str
[sizeof(ERR_FUN
) - 1],
139 int_error(err_str
,NO_CARET
);
142 (void) pop(&(udf
->dummy_value3
));
144 (void) pop(&(udf
->dummy_value2
));
146 (void) pop(&(udf
->dummy_value1
));
147 (void) pop(&(udf
->dummy_value
));
151 /*************************************************************/
157 int_error("non-integer passed to boolean operator",NO_CARET
);
160 /*************************************************************/
166 push(integer(&a
,!a
.v
.int_val
) );
169 /*************************************************************/
175 push( integer(&a
,~a
.v
.int_val
) );
178 /*************************************************************/
181 { /* converts top-of-stack to boolean */
182 int_check(&top_of_stack
);
183 top_of_stack
.v
.int_val
= !!top_of_stack
.v
.int_val
;
186 /*************************************************************/
193 push( integer(&a
,a
.v
.int_val
|| b
.v
.int_val
) );
196 /*************************************************************/
203 push( integer(&a
,a
.v
.int_val
&& b
.v
.int_val
) );
206 /*************************************************************/
213 push( integer(&a
,a
.v
.int_val
| b
.v
.int_val
) );
216 /*************************************************************/
223 push( integer(&a
,a
.v
.int_val
^ b
.v
.int_val
) );
226 /*************************************************************/
233 push( integer(&a
,a
.v
.int_val
& b
.v
.int_val
) );
236 /*************************************************************/
244 a
.v
.int_val
= -a
.v
.int_val
;
255 /*************************************************************/
257 f_eq() /* note: floating point equality is rare because of roundoff error! */
268 result
= (a
.v
.int_val
==
272 result
= (a
.v
.int_val
==
273 b
.v
.cmplx_val
.real
&&
274 b
.v
.cmplx_val
.imag
== 0.0);
281 result
= (b
.v
.int_val
== a
.v
.cmplx_val
.real
&&
282 a
.v
.cmplx_val
.imag
== 0.0);
285 result
= (a
.v
.cmplx_val
.real
==
286 b
.v
.cmplx_val
.real
&&
291 push(integer(&a
,result
));
294 /*************************************************************/
308 result
= (a
.v
.int_val
!=
312 result
= (a
.v
.int_val
!=
313 b
.v
.cmplx_val
.real
||
314 b
.v
.cmplx_val
.imag
!= 0.0);
321 result
= (b
.v
.int_val
!=
322 a
.v
.cmplx_val
.real
||
323 a
.v
.cmplx_val
.imag
!= 0.0);
326 result
= (a
.v
.cmplx_val
.real
!=
327 b
.v
.cmplx_val
.real
||
328 a
.v
.cmplx_val
.imag
!=
332 push(integer(&a
,result
));
335 /*************************************************************/
349 result
= (a
.v
.int_val
>
353 result
= (a
.v
.int_val
>
361 result
= (a
.v
.cmplx_val
.real
>
365 result
= (a
.v
.cmplx_val
.real
>
369 push(integer(&a
,result
));
372 /*************************************************************/
386 result
= (a
.v
.int_val
<
390 result
= (a
.v
.int_val
<
398 result
= (a
.v
.cmplx_val
.real
<
402 result
= (a
.v
.cmplx_val
.real
<
406 push(integer(&a
,result
));
409 /*************************************************************/
423 result
= (a
.v
.int_val
>=
427 result
= (a
.v
.int_val
>=
435 result
= (a
.v
.cmplx_val
.real
>=
439 result
= (a
.v
.cmplx_val
.real
>=
443 push(integer(&a
,result
));
446 /*************************************************************/
460 result
= (a
.v
.int_val
<=
464 result
= (a
.v
.int_val
<=
472 result
= (a
.v
.cmplx_val
.real
<=
476 result
= (a
.v
.cmplx_val
.real
<=
480 push(integer(&a
,result
));
483 /*************************************************************/
487 struct value a
, b
, result
;
496 (void) integer(&result
,a
.v
.int_val
+
500 (void) complex(&result
,a
.v
.int_val
+
509 (void) complex(&result
,b
.v
.int_val
+
514 (void) complex(&result
,a
.v
.cmplx_val
.real
+
523 /*************************************************************/
527 struct value a
, b
, result
;
529 (void) pop(&a
); /* now do a - b */
536 (void) integer(&result
,a
.v
.int_val
-
540 (void) complex(&result
,a
.v
.int_val
-
542 -b
.v
.cmplx_val
.imag
);
549 (void) complex(&result
,a
.v
.cmplx_val
.real
-
554 (void) complex(&result
,a
.v
.cmplx_val
.real
-
563 /************************************************************/
567 struct value a
, b
, result
;
569 (void) pop(&a
); /* now do a*b */
577 (void) integer(&result
,a
.v
.int_val
*
581 (void) complex(&result
,a
.v
.int_val
*
591 (void) complex(&result
,b
.v
.int_val
*
597 (void) complex(&result
,a
.v
.cmplx_val
.real
*
610 /************************************************************/
614 struct value a
, b
, result
;
615 register double square
;
617 (void) pop(&a
); /* now do a/b */
626 (void) integer(&result
,a
.v
.int_val
/
630 (void) integer(&result
,0);
635 square
= b
.v
.cmplx_val
.real
*
640 (void) complex(&result
,a
.v
.int_val
*
641 b
.v
.cmplx_val
.real
/square
,
643 b
.v
.cmplx_val
.imag
/square
);
646 (void) complex(&result
,0.0,0.0);
657 (void) complex(&result
,a
.v
.cmplx_val
.real
/
663 (void) complex(&result
,0.0,0.0);
668 square
= b
.v
.cmplx_val
.real
*
673 (void) complex(&result
,(a
.v
.cmplx_val
.real
*
676 b
.v
.cmplx_val
.imag
)/square
,
684 (void) complex(&result
,0.0,0.0);
692 /************************************************************/
698 (void) pop(&a
); /* now do a%b */
700 if (a
.type
!= INT
|| b
.type
!= INT
)
701 int_error("can only mod ints",NO_CARET
);
703 push(integer(&a
,a
.v
.int_val
% b
.v
.int_val
));
710 /************************************************************/
714 struct value a
, b
, result
;
715 register int i
, t
, count
;
716 register double mag
, ang
;
718 (void) pop(&a
); /* now find a**b */
726 count
= abs(b
.v
.int_val
);
728 for(i
= 0; i
< count
; i
++)
730 if (b
.v
.int_val
>= 0)
731 (void) integer(&result
,t
);
733 (void) complex(&result
,1.0/t
,0.0);
737 pow(magnitude(&a
),fabs(b
.v
.cmplx_val
.real
));
738 if (b
.v
.cmplx_val
.real
< 0.0)
740 ang
= angle(&a
)*b
.v
.cmplx_val
.real
+
742 (void) complex(&result
,mag
*cos(ang
),
750 if (a
.v
.cmplx_val
.imag
== 0.0)
752 mag
= pow(a
.v
.cmplx_val
.real
,(double)abs(b
.v
.int_val
));
755 (void) complex(&result
,mag
,0.0);
759 /* not so good, but...! */
760 mag
= pow(magnitude(&a
),(double)abs(b
.v
.int_val
));
763 ang
= angle(&a
)*b
.v
.int_val
;
764 (void) complex(&result
,mag
*cos(ang
),
769 mag
= pow(magnitude(&a
),fabs(b
.v
.cmplx_val
.real
));
770 if (b
.v
.cmplx_val
.real
< 0.0)
772 ang
= angle(&a
)*b
.v
.cmplx_val
.real
+ b
.v
.cmplx_val
.imag
;
773 (void) complex(&result
,mag
*cos(ang
),
780 /************************************************************/
788 (void) pop(&a
); /* find a! (factorial) */
794 for (i
= a
.v
.int_val
; i
> 1; i
--) /*fpe's should catch overflows*/
798 int_error("factorial (!) argument must be an integer",
802 push(complex(&a
,val
,0.0));
805 /************************************************************/
813 /************************************************************/
819 int_check(&top_of_stack
);
820 if (top_of_stack
.v
.int_val
) /* non-zero */
823 return 1; /* no jump */
826 return(x
->j_arg
); /* leave the argument on TOS */
829 /************************************************************/
835 int_check(&top_of_stack
);
836 if (top_of_stack
.v
.int_val
) /* non-zero */
837 return(x
->j_arg
); /* leave the argument on TOS */
841 return 1; /* no jump */
845 /************************************************************/
854 return(1); /* no jump; fall through to TRUE code */
856 return(x
->j_arg
); /* go jump to FALSE code */
858 /****************************************************************************/