ReactOS  0.4.10-dev-234-g15c29d0
rpn.c
Go to the documentation of this file.
1 #include "calc.h"
2 
3 typedef struct {
5  void *next;
7 
9 
10 typedef struct {
11  unsigned int prec;
16 
20 
33 
34 /* Integer mode calculations */
45 
46 /* Percentage mode calculations */
51 
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
68 };
69 
70 static stack_node_t *pop(void)
71 {
72  if (stack == NULL)
73  return NULL;
74 
75  temp = *stack;
76  free(stack);
77  stack = temp.next;
78 
79  return &temp;
80 }
81 
82 static int is_stack_empty(void)
83 {
84  return (stack == NULL);
85 }
86 
87 static void push(stack_node_t *op)
88 {
90 
91  *z = *op;
92  z->next = stack;
93  stack = z;
94 }
95 /*
96 static unsigned int get_prec(unsigned int opc)
97 {
98  unsigned int x;
99 
100  for (x=0; x<SIZEOF(operator_list); x++)
101  if (operator_list[x].opc == opc) break;
102  return operator_list[x].prec;
103 }
104 */
105 /* Real mode calculations */
107 {
108  r->f = a->f + b->f;
109 }
110 
112 {
113  r->f = a->f - b->f;
114 }
115 
117 {
118  r->f = a->f * b->f;
119 }
120 
122 {
123  if (b->f == 0)
124  calc.is_nan = TRUE;
125  else
126  r->f = a->f / b->f;
127 }
128 
130 {
131  double t;
132 
133  if (b->f == 0)
134  calc.is_nan = TRUE;
135  else {
136  modf(a->f/b->f, &t);
137  r->f = a->f - (t * b->f);
138  }
139 }
140 
142 {
143  calc_number_t ai, bi;
144 
145  ai.i = logic_dbl2int(a);
146  bi.i = logic_dbl2int(b);
147 
148  r->f = (long double)(ai.i & bi.i);
149 }
150 
152 {
153  calc_number_t ai, bi;
154 
155  ai.i = logic_dbl2int(a);
156  bi.i = logic_dbl2int(b);
157 
158  r->f = (long double)(ai.i | bi.i);
159 }
160 
162 {
163  calc_number_t ai, bi;
164 
165  ai.i = logic_dbl2int(a);
166  bi.i = logic_dbl2int(b);
167 
168  r->f = (long double)(ai.i ^ bi.i);
169 }
170 
172 {
174 
175  modf(b->f, &n.f);
176 
177  r->f = a->f * pow(2., n.f);
178 }
179 
181 {
183 
184  modf(b->f, &n.f);
185 
186  r->f = a->f / pow(2., n.f);
187 }
188 
190 {
191  r->f = pow(a->f, b->f);
192  if (_finite(r->f) == 0 || _isnan(r->f))
193  calc.is_nan = TRUE;
194 }
195 
197 {
198  if (b->f == 0)
199  calc.is_nan = TRUE;
200  else {
201  r->f = pow(a->f, 1./b->f);
202  if (_finite(r->f) == 0 || _isnan(r->f))
203  calc.is_nan = TRUE;
204  }
205 }
206 
207 /* Integer mode calculations */
209 {
210  r->i = a->i + b->i;
211 }
212 
214 {
215  r->i = a->i - b->i;
216 }
217 
219 {
220  r->i = a->i * b->i;
221 }
222 
224 {
225  if (b->i == 0)
226  calc.is_nan = TRUE;
227  else
228  r->i = a->i / b->i;
229 }
230 
232 {
233  if (b->i == 0)
234  calc.is_nan = TRUE;
235  else
236  r->i = a->i % b->i;
237 }
238 
240 {
241  r->i = a->i & b->i;
242 }
243 
245 {
246  r->i = a->i | b->i;
247 }
248 
250 {
251  r->i = a->i ^ b->i;
252 }
253 
255 {
256  r->i = a->i << b->i;
257 }
258 
260 {
261  r->i = a->i >> b->i;
262 }
263 
264 /* Percent mode calculations */
266 {
267  r->f = a->f * (1. + b->f/100.);
268 }
269 
271 {
272  r->f = a->f * (1. - b->f/100.);
273 }
274 
276 {
277  r->f = a->f * b->f / 100.;
278 }
279 
281 {
282  if (b->f == 0)
283  calc.is_nan = TRUE;
284  else
285  r->f = a->f * 100. / b->f;
286 }
287 
289  calc_node_t *a,
290  calc_node_t *b,
291  unsigned int operation)
292 {
293  calc_number_t da, db, dc;
294  DWORD base = calc.base;
295 
296  da = a->number;
297  db = b->number;
298  if (a->base == IDC_RADIO_DEC && b->base != IDC_RADIO_DEC) {
299  db.f = logic_int2dbl(&b->number);
300  base = IDC_RADIO_DEC;
301  } else
302  if (a->base != IDC_RADIO_DEC && b->base == IDC_RADIO_DEC) {
303  da.f = logic_int2dbl(&a->number);
304  base = IDC_RADIO_DEC;
305  }
306 
307  if (base == IDC_RADIO_DEC) {
308  if (percent_mode) {
310  operator_list[operation].op_p(&dc, &da, &db);
311  } else
312  operator_list[operation].op_f(&dc, &da, &db);
313  if (_finite(dc.f) == 0)
314  calc.is_nan = TRUE;
315  } else {
316  operator_list[operation].op_i(&dc, &da, &db);
317  /* apply final limiter to result */
318  apply_int_mask(&dc);
319  }
320 
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);
324  } else
325  if (a->base != IDC_RADIO_DEC && b->base == IDC_RADIO_DEC)
326  result->number.f = dc.f;
327  else
328  result->number = dc;
329 }
330 
332 {
333  stack_node_t *op, ip;
334  unsigned int prec;
335 
336  op = pop();
337  ip = *op;
338  prec = operator_list[ip.node.operation].prec;
339  while (!is_stack_empty()) {
340  op = pop();
341 
342  if (prec <= operator_list[op->node.operation].prec) {
343  if (op->node.operation == RPN_OPERATOR_PARENT) continue;
344 
345  calc.prev = ip.node.number;
346  run_operator(&ip.node, &op->node, &ip.node, op->node.operation);
347  if (calc.is_nan) {
348  flush_postfix();
349  return;
350  }
351  } else {
352  push(op);
353  break;
354  }
355  }
356 
358  push(&ip);
359 
361 
362  *number = ip.node.number;
363 }
364 
366 {
367  stack_node_t tmp;
368 
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 */
372  if (calc.sci_in)
373  return 1;
374  return 0;
375  }
376 
377  if (func == RPN_OPERATOR_PERCENT)
378  percent_mode = TRUE;
379 
380  tmp.node.number = *number;
381  tmp.node.base = calc.base;
382  tmp.node.operation = func;
383  tmp.next = NULL;
384 
385  push(&tmp);
386 
387  if (func == RPN_OPERATOR_NONE)
388  return 0;
389 
390  if (func != RPN_OPERATOR_PARENT) {
392  evalStack(number);
393  }
394  return 1;
395 }
396 
398 {
399  stack_node_t *op = stack;
400 
401  if (op == NULL)
402  return;
403  if (op->node.operation == RPN_OPERATOR_PARENT ||
406  return;
407  /* remove the head, it will be re-inserted with new operator */
408  pop();
409 }
410 
412 {
413  stack_node_t *op, ip;
414 
415  ip.node.number = *number;
416  ip.node.base = calc.base;
417  while (!is_stack_empty()) {
418  op = pop();
419 
421  break;
422 
423  run_operator(&ip.node, &op->node, &ip.node, op->node.operation);
424  if (calc.is_nan) {
425  flush_postfix();
426  return;
427  }
428  }
429  *number = ip.node.number;
430 }
431 
433 {
434  stack_node_t *s = stack;
435  int n = 0;
436 
437  while (s != NULL) {
439  n++;
440  s = (stack_node_t *)(s->next);
441  }
442  return n;
443 }
444 
446 {
447  while (!is_stack_empty())
448  pop();
449  /* clear prev and last typed operators */
451  calc.last_operator = 0;
452 }
453 
455 {
456  stack = NULL;
457 }
458 
459 void stop_rpn_engine(void)
460 {
461 }
462 
GLenum func
Definition: glext.h:6028
DWORD base
Definition: calc.h:138
int exec_infix2postfix(calc_number_t *number, unsigned int func)
Definition: rpn.c:365
#define TRUE
Definition: types.h:120
_Check_return_ __MINGW_NOTHROW _CRTIMP int __cdecl _isnan(_In_ double)
static void rpn_mul_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:275
static void rpn_add_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:106
#define IDC_RADIO_DEC
Definition: resource.h:17
static void rpn_or_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:151
static void rpn_sub_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:270
double f
Definition: calc.h:77
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define free
Definition: debug_ros.c:5
static void rpn_and_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:141
void flush_postfix()
Definition: rpn.c:445
GLdouble GLdouble t
Definition: gl.h:2047
static void rpn_sqr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:196
static void rpn_pow_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:189
static stack_node_t * pop(void)
Definition: rpn.c:70
HDC dc
Definition: cylfrac.c:34
static void rpn_and_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:239
double logic_int2dbl(calc_number_t *a)
Definition: function.c:253
static void rpn_or_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:244
BOOL is_nan
Definition: calc.h:132
int eval_parent_count(void)
Definition: rpn.c:432
static void rpn_mod_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:129
static void rpn_div_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:121
DWORD DWORD
Definition: winlogon.h:75
static void rpn_div_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:223
static void rpn_mod_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:231
static int is_stack_empty(void)
Definition: rpn.c:82
__int64 logic_dbl2int(calc_number_t *a)
Definition: function.c:240
static stack_node_t * stack
Definition: rpn.c:17
GLuint n
Definition: s_context.h:57
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:223
static void rpn_shr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:180
void(* operator_call)(calc_number_t *, calc_number_t *, calc_number_t *)
Definition: rpn.c:8
float pow(float __x, int __y)
Definition: _cmath.h:458
static size_t double number
Definition: printf.c:64
static void rpn_sub_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:213
int ip[4]
Definition: rtl.c:1176
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
GLdouble GLdouble z
Definition: glext.h:5874
smooth NULL
Definition: ftsmooth.c:416
unsigned int prec
Definition: rpn.c:11
static void rpn_shr_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:259
unsigned int prev_operator
Definition: calc.h:147
void run_operator(calc_node_t *result, calc_node_t *a, calc_node_t *b, unsigned int operation)
Definition: rpn.c:288
static void rpn_shl_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:171
static void rpn_add_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:208
static void push(stack_node_t *op)
Definition: rpn.c:87
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_ __MINGW_NOTHROW _CRTIMP int __cdecl _finite(_In_ double)
INT64 i
Definition: calc.h:78
BOOL sci_in
Definition: calc.h:134
unsigned int last_operator
Definition: calc.h:146
calc_number_t number
Definition: calc.h:84
void exec_closeparent(calc_number_t *number)
Definition: rpn.c:411
operator_call op_f
Definition: rpn.c:12
static void rpn_add_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:265
GLdouble s
Definition: gl.h:2039
void stop_rpn_engine(void)
Definition: rpn.c:459
static stack_node_t temp
Definition: rpn.c:18
calc_node_t node
Definition: rpn.c:4
static void evalStack(calc_number_t *number)
Definition: rpn.c:331
void exec_change_infix(void)
Definition: rpn.c:397
static void rpn_mul_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:116
static BOOL percent_mode
Definition: rpn.c:19
static void rpn_xor_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:161
DWORD base
Definition: calc.h:86
static const calc_operator_t operator_list[]
Definition: rpn.c:52
unsigned int operation
Definition: calc.h:85
operator_call op_i
Definition: rpn.c:13
static void rpn_xor_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:249
static void rpn_div_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:280
void start_rpn_engine(void)
Definition: rpn.c:454
#define malloc
Definition: debug_ros.c:4
static void rpn_sub_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:111
operator_call op_p
Definition: rpn.c:14
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
void * next
Definition: rpn.c:5
calc_t calc
Definition: winmain.c:226
GLuint64EXT * result
Definition: glext.h:11304
static void rpn_shl_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:254
calc_number_t prev
Definition: calc.h:128
void apply_int_mask(calc_number_t *a)
Definition: fun_mpfr.c:3
_Check_return_ _CRTIMP double __cdecl modf(_In_ double x, _Out_ double *y)
static void rpn_mul_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn.c:218