8 typedef void (*operator_call
)(calc_number_t
*, calc_number_t
*, calc_number_t
*);
17 static stack_node_t
*stack
;
18 static stack_node_t temp
;
19 static BOOL percent_mode
;
21 static void rpn_add_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
22 static void rpn_sub_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
23 static void rpn_mul_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
24 static void rpn_div_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
25 static void rpn_mod_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
26 static void rpn_pow_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
27 static void rpn_sqr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
28 static void rpn_and_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
29 static void rpn_or_f (calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
30 static void rpn_xor_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
31 static void rpn_shl_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
32 static void rpn_shr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
34 /* Integer mode calculations */
35 static void rpn_add_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
36 static void rpn_sub_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
37 static void rpn_mul_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
38 static void rpn_div_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
39 static void rpn_mod_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
40 static void rpn_and_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
41 static void rpn_or_i (calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
42 static void rpn_xor_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
43 static void rpn_shl_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
44 static void rpn_shr_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
46 /* Percentage mode calculations */
47 static void rpn_add_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
48 static void rpn_sub_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
49 static void rpn_mul_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
50 static void rpn_div_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
52 static const calc_operator_t operator_list
[] = {
53 { 0, NULL
, NULL
, NULL
, }, // RPN_OPERATOR_PARENT
54 { 0, NULL
, NULL
, NULL
, }, // RPN_OPERATOR_PERCENT
55 { 0, NULL
, NULL
, NULL
, }, // RPN_OPERATOR_EQUAL
56 { 1, rpn_or_f
, rpn_or_i
, NULL
, }, // RPN_OPERATOR_OR
57 { 2, rpn_xor_f
, rpn_xor_i
, NULL
, }, // RPN_OPERATOR_XOR
58 { 3, rpn_and_f
, rpn_and_i
, NULL
, }, // RPN_OPERATOR_AND
59 { 4, rpn_shl_f
, rpn_shl_i
, NULL
, }, // RPN_OPERATOR_LSH
60 { 4, rpn_shr_f
, rpn_shr_i
, NULL
, }, // RPN_OPERATOR_RSH
61 { 5, rpn_add_f
, rpn_add_i
, rpn_add_p
, }, // RPN_OPERATOR_ADD
62 { 5, rpn_sub_f
, rpn_sub_i
, rpn_sub_p
, }, // RPN_OPERATOR_SUB
63 { 6, rpn_mul_f
, rpn_mul_i
, rpn_mul_p
, }, // RPN_OPERATOR_MULT
64 { 6, rpn_div_f
, rpn_div_i
, rpn_div_p
, }, // RPN_OPERATOR_DIV
65 { 6, rpn_mod_f
, rpn_mod_i
, NULL
, }, // RPN_OPERATOR_MOD
66 { 7, rpn_pow_f
, NULL
, NULL
, }, // RPN_OPERATOR_POW
67 { 7, rpn_sqr_f
, NULL
, NULL
, }, // RPN_OPERATOR_SQR
70 static stack_node_t
*pop(void)
82 static int is_stack_empty(void)
84 return (stack
== NULL
);
87 static void push(stack_node_t
*op
)
89 stack_node_t
*z
= (stack_node_t
*)malloc(sizeof(stack_node_t
));
96 static unsigned int get_prec(unsigned int opc)
100 for (x=0; x<SIZEOF(operator_list); x++)
101 if (operator_list[x].opc == opc) break;
102 return operator_list[x].prec;
105 /* Real mode calculations */
106 static void rpn_add_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
111 static void rpn_sub_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
116 static void rpn_mul_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
121 static void rpn_div_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
129 static void rpn_mod_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
137 r
->f
= a
->f
- (t
* b
->f
);
141 static void rpn_and_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
143 calc_number_t ai
, bi
;
145 ai
.i
= logic_dbl2int(a
);
146 bi
.i
= logic_dbl2int(b
);
148 r
->f
= (long double)(ai
.i
& bi
.i
);
151 static void rpn_or_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
153 calc_number_t ai
, bi
;
155 ai
.i
= logic_dbl2int(a
);
156 bi
.i
= logic_dbl2int(b
);
158 r
->f
= (long double)(ai
.i
| bi
.i
);
161 static void rpn_xor_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
163 calc_number_t ai
, bi
;
165 ai
.i
= logic_dbl2int(a
);
166 bi
.i
= logic_dbl2int(b
);
168 r
->f
= (long double)(ai
.i
^ bi
.i
);
171 static void rpn_shl_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
177 r
->f
= a
->f
* pow(2., n
.f
);
180 static void rpn_shr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
186 r
->f
= a
->f
/ pow(2., n
.f
);
189 static void rpn_pow_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
191 r
->f
= pow(a
->f
, b
->f
);
192 if (_finite(r
->f
) == 0 || _isnan(r
->f
))
196 static void rpn_sqr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
201 r
->f
= pow(a
->f
, 1./b
->f
);
202 if (_finite(r
->f
) == 0 || _isnan(r
->f
))
207 /* Integer mode calculations */
208 static void rpn_add_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
213 static void rpn_sub_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
218 static void rpn_mul_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
223 static void rpn_div_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
231 static void rpn_mod_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
239 static void rpn_and_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
244 static void rpn_or_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
249 static void rpn_xor_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
254 static void rpn_shl_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
259 static void rpn_shr_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
264 /* Percent mode calculations */
265 static void rpn_add_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
267 r
->f
= a
->f
* (1. + b
->f
/100.);
270 static void rpn_sub_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
272 r
->f
= a
->f
* (1. - b
->f
/100.);
275 static void rpn_mul_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
277 r
->f
= a
->f
* b
->f
/ 100.;
280 static void rpn_div_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
285 r
->f
= a
->f
* 100. / b
->f
;
288 void run_operator(calc_node_t
*result
,
291 unsigned int operation
)
293 calc_number_t da
, db
, dc
;
294 DWORD base
= calc
.base
;
298 if (a
->base
== IDC_RADIO_DEC
&& b
->base
!= IDC_RADIO_DEC
) {
299 db
.f
= logic_int2dbl(&b
->number
);
300 base
= IDC_RADIO_DEC
;
302 if (a
->base
!= IDC_RADIO_DEC
&& b
->base
== IDC_RADIO_DEC
) {
303 da
.f
= logic_int2dbl(&a
->number
);
304 base
= IDC_RADIO_DEC
;
307 if (base
== IDC_RADIO_DEC
) {
309 percent_mode
= FALSE
;
310 operator_list
[operation
].op_p(&dc
, &da
, &db
);
312 operator_list
[operation
].op_f(&dc
, &da
, &db
);
313 if (_finite(dc
.f
) == 0)
316 operator_list
[operation
].op_i(&dc
, &da
, &db
);
317 /* apply final limitator to result */
321 if (a
->base
== IDC_RADIO_DEC
&& b
->base
!= IDC_RADIO_DEC
) {
322 result
->number
.i
= logic_dbl2int(&dc
);
323 apply_int_mask(&result
->number
);
325 if (a
->base
!= IDC_RADIO_DEC
&& b
->base
== IDC_RADIO_DEC
)
326 result
->number
.f
= dc
.f
;
331 static void evalStack(calc_number_t
*number
)
333 stack_node_t
*op
, ip
;
338 prec
= operator_list
[ip
.node
.operation
].prec
;
339 while (!is_stack_empty()) {
342 if (prec
<= operator_list
[op
->node
.operation
].prec
) {
343 if (op
->node
.operation
== RPN_OPERATOR_PARENT
) continue;
345 calc
.prev
= ip
.node
.number
;
346 run_operator(&ip
.node
, &op
->node
, &ip
.node
, op
->node
.operation
);
357 if(ip
.node
.operation
!= RPN_OPERATOR_EQUAL
&& ip
.node
.operation
!= RPN_OPERATOR_PERCENT
)
360 calc
.prev_operator
= op
->node
.operation
;
362 *number
= ip
.node
.number
;
365 int exec_infix2postfix(calc_number_t
*number
, unsigned int func
)
369 if (is_stack_empty() && func
== RPN_OPERATOR_EQUAL
) {
370 /* if a number has been entered with exponential */
371 /* notation, I may update it with normal mode */
377 if (func
== RPN_OPERATOR_PERCENT
)
380 tmp
.node
.number
= *number
;
381 tmp
.node
.base
= calc
.base
;
382 tmp
.node
.operation
= func
;
387 if (func
== RPN_OPERATOR_NONE
)
390 if (func
!= RPN_OPERATOR_PARENT
) {
391 calc
.last_operator
= func
;
397 void exec_change_infix(void)
399 stack_node_t
*op
= stack
;
403 if (op
->node
.operation
== RPN_OPERATOR_PARENT
||
404 op
->node
.operation
== RPN_OPERATOR_PERCENT
||
405 op
->node
.operation
== RPN_OPERATOR_EQUAL
)
407 /* remove the head, it will be re-inserted with new operator */
411 void exec_closeparent(calc_number_t
*number
)
413 stack_node_t
*op
, ip
;
415 ip
.node
.number
= *number
;
416 ip
.node
.base
= calc
.base
;
417 while (!is_stack_empty()) {
420 if (op
->node
.operation
== RPN_OPERATOR_PARENT
)
423 run_operator(&ip
.node
, &op
->node
, &ip
.node
, op
->node
.operation
);
429 *number
= ip
.node
.number
;
432 int eval_parent_count(void)
434 stack_node_t
*s
= stack
;
438 if (s
->node
.operation
== RPN_OPERATOR_PARENT
)
440 s
= (stack_node_t
*)(s
->next
);
447 while (!is_stack_empty())
449 /* clear prev and last typed operators */
451 calc
.last_operator
= 0;
454 void start_rpn_engine(void)
459 void stop_rpn_engine(void)