Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrpn.cGo to the documentation of this file.00001 #include "calc.h" 00002 00003 typedef struct { 00004 calc_node_t node; 00005 void *next; 00006 } stack_node_t; 00007 00008 typedef void (*operator_call)(calc_number_t *, calc_number_t *, calc_number_t *); 00009 00010 typedef struct { 00011 unsigned int prec; 00012 operator_call op_f; 00013 operator_call op_i; 00014 operator_call op_p; 00015 } calc_operator_t; 00016 00017 static stack_node_t *stack; 00018 static stack_node_t temp; 00019 static BOOL percent_mode; 00020 00021 static void rpn_add_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00022 static void rpn_sub_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00023 static void rpn_mul_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00024 static void rpn_div_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00025 static void rpn_mod_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00026 static void rpn_pow_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00027 static void rpn_sqr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00028 static void rpn_and_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00029 static void rpn_or_f (calc_number_t *r, calc_number_t *a, calc_number_t *b); 00030 static void rpn_xor_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00031 static void rpn_shl_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00032 static void rpn_shr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00033 00034 /* Integer mode calculations */ 00035 static void rpn_add_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00036 static void rpn_sub_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00037 static void rpn_mul_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00038 static void rpn_div_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00039 static void rpn_mod_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00040 static void rpn_and_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00041 static void rpn_or_i (calc_number_t *r, calc_number_t *a, calc_number_t *b); 00042 static void rpn_xor_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00043 static void rpn_shl_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00044 static void rpn_shr_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00045 00046 /* Percentage mode calculations */ 00047 static void rpn_add_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00048 static void rpn_sub_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00049 static void rpn_mul_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00050 static void rpn_div_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00051 00052 static const calc_operator_t operator_list[] = { 00053 { 0, NULL, NULL, NULL, }, // RPN_OPERATOR_PARENT 00054 { 0, NULL, NULL, NULL, }, // RPN_OPERATOR_PERCENT 00055 { 0, NULL, NULL, NULL, }, // RPN_OPERATOR_EQUAL 00056 { 1, rpn_or_f, rpn_or_i, NULL, }, // RPN_OPERATOR_OR 00057 { 2, rpn_xor_f, rpn_xor_i, NULL, }, // RPN_OPERATOR_XOR 00058 { 3, rpn_and_f, rpn_and_i, NULL, }, // RPN_OPERATOR_AND 00059 { 4, rpn_shl_f, rpn_shl_i, NULL, }, // RPN_OPERATOR_LSH 00060 { 4, rpn_shr_f, rpn_shr_i, NULL, }, // RPN_OPERATOR_RSH 00061 { 5, rpn_add_f, rpn_add_i, rpn_add_p, }, // RPN_OPERATOR_ADD 00062 { 5, rpn_sub_f, rpn_sub_i, rpn_sub_p, }, // RPN_OPERATOR_SUB 00063 { 6, rpn_mul_f, rpn_mul_i, rpn_mul_p, }, // RPN_OPERATOR_MULT 00064 { 6, rpn_div_f, rpn_div_i, rpn_div_p, }, // RPN_OPERATOR_DIV 00065 { 6, rpn_mod_f, rpn_mod_i, NULL, }, // RPN_OPERATOR_MOD 00066 { 7, rpn_pow_f, NULL, NULL, }, // RPN_OPERATOR_POW 00067 { 7, rpn_sqr_f, NULL, NULL, }, // RPN_OPERATOR_SQR 00068 }; 00069 00070 static stack_node_t *pop(void) 00071 { 00072 if (stack == NULL) 00073 return NULL; 00074 00075 temp = *stack; 00076 free(stack); 00077 stack = temp.next; 00078 00079 return &temp; 00080 } 00081 00082 static int is_stack_empty(void) 00083 { 00084 return (stack == NULL); 00085 } 00086 00087 static void push(stack_node_t *op) 00088 { 00089 stack_node_t *z = (stack_node_t *)malloc(sizeof(stack_node_t)); 00090 00091 *z = *op; 00092 z->next = stack; 00093 stack = z; 00094 } 00095 /* 00096 static unsigned int get_prec(unsigned int opc) 00097 { 00098 unsigned int x; 00099 00100 for (x=0; x<SIZEOF(operator_list); x++) 00101 if (operator_list[x].opc == opc) break; 00102 return operator_list[x].prec; 00103 } 00104 */ 00105 /* Real mode calculations */ 00106 static void rpn_add_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00107 { 00108 r->f = a->f + b->f; 00109 } 00110 00111 static void rpn_sub_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00112 { 00113 r->f = a->f - b->f; 00114 } 00115 00116 static void rpn_mul_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00117 { 00118 r->f = a->f * b->f; 00119 } 00120 00121 static void rpn_div_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00122 { 00123 if (b->f == 0) 00124 calc.is_nan = TRUE; 00125 else 00126 r->f = a->f / b->f; 00127 } 00128 00129 static void rpn_mod_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00130 { 00131 double t; 00132 00133 if (b->f == 0) 00134 calc.is_nan = TRUE; 00135 else { 00136 modf(a->f/b->f, &t); 00137 r->f = a->f - (t * b->f); 00138 } 00139 } 00140 00141 static void rpn_and_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00142 { 00143 calc_number_t ai, bi; 00144 00145 ai.i = logic_dbl2int(a); 00146 bi.i = logic_dbl2int(b); 00147 00148 r->f = (long double)(ai.i & bi.i); 00149 } 00150 00151 static void rpn_or_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00152 { 00153 calc_number_t ai, bi; 00154 00155 ai.i = logic_dbl2int(a); 00156 bi.i = logic_dbl2int(b); 00157 00158 r->f = (long double)(ai.i | bi.i); 00159 } 00160 00161 static void rpn_xor_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00162 { 00163 calc_number_t ai, bi; 00164 00165 ai.i = logic_dbl2int(a); 00166 bi.i = logic_dbl2int(b); 00167 00168 r->f = (long double)(ai.i ^ bi.i); 00169 } 00170 00171 static void rpn_shl_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00172 { 00173 calc_number_t n; 00174 00175 modf(b->f, &n.f); 00176 00177 r->f = a->f * pow(2., n.f); 00178 } 00179 00180 static void rpn_shr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00181 { 00182 calc_number_t n; 00183 00184 modf(b->f, &n.f); 00185 00186 r->f = a->f / pow(2., n.f); 00187 } 00188 00189 static void rpn_pow_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00190 { 00191 r->f = pow(a->f, b->f); 00192 if (_finite(r->f) == 0 || _isnan(r->f)) 00193 calc.is_nan = TRUE; 00194 } 00195 00196 static void rpn_sqr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00197 { 00198 if (b->f == 0) 00199 calc.is_nan = TRUE; 00200 else { 00201 r->f = pow(a->f, 1./b->f); 00202 if (_finite(r->f) == 0 || _isnan(r->f)) 00203 calc.is_nan = TRUE; 00204 } 00205 } 00206 00207 /* Integer mode calculations */ 00208 static void rpn_add_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00209 { 00210 r->i = a->i + b->i; 00211 } 00212 00213 static void rpn_sub_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00214 { 00215 r->i = a->i - b->i; 00216 } 00217 00218 static void rpn_mul_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00219 { 00220 r->i = a->i * b->i; 00221 } 00222 00223 static void rpn_div_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00224 { 00225 if (b->i == 0) 00226 calc.is_nan = TRUE; 00227 else 00228 r->i = a->i / b->i; 00229 } 00230 00231 static void rpn_mod_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00232 { 00233 if (b->i == 0) 00234 calc.is_nan = TRUE; 00235 else 00236 r->i = a->i % b->i; 00237 } 00238 00239 static void rpn_and_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00240 { 00241 r->i = a->i & b->i; 00242 } 00243 00244 static void rpn_or_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00245 { 00246 r->i = a->i | b->i; 00247 } 00248 00249 static void rpn_xor_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00250 { 00251 r->i = a->i ^ b->i; 00252 } 00253 00254 static void rpn_shl_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00255 { 00256 r->i = a->i << b->i; 00257 } 00258 00259 static void rpn_shr_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00260 { 00261 r->i = a->i >> b->i; 00262 } 00263 00264 /* Percent mode calculations */ 00265 static void rpn_add_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00266 { 00267 r->f = a->f * (1. + b->f/100.); 00268 } 00269 00270 static void rpn_sub_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00271 { 00272 r->f = a->f * (1. - b->f/100.); 00273 } 00274 00275 static void rpn_mul_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00276 { 00277 r->f = a->f * b->f / 100.; 00278 } 00279 00280 static void rpn_div_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00281 { 00282 if (b->f == 0) 00283 calc.is_nan = TRUE; 00284 else 00285 r->f = a->f * 100. / b->f; 00286 } 00287 00288 void run_operator(calc_node_t *result, 00289 calc_node_t *a, 00290 calc_node_t *b, 00291 unsigned int operation) 00292 { 00293 calc_number_t da, db, dc; 00294 DWORD base = calc.base; 00295 00296 da = a->number; 00297 db = b->number; 00298 if (a->base == IDC_RADIO_DEC && b->base != IDC_RADIO_DEC) { 00299 db.f = logic_int2dbl(&b->number); 00300 base = IDC_RADIO_DEC; 00301 } else 00302 if (a->base != IDC_RADIO_DEC && b->base == IDC_RADIO_DEC) { 00303 da.f = logic_int2dbl(&a->number); 00304 base = IDC_RADIO_DEC; 00305 } 00306 00307 if (base == IDC_RADIO_DEC) { 00308 if (percent_mode) { 00309 percent_mode = FALSE; 00310 operator_list[operation].op_p(&dc, &da, &db); 00311 } else 00312 operator_list[operation].op_f(&dc, &da, &db); 00313 if (_finite(dc.f) == 0) 00314 calc.is_nan = TRUE; 00315 } else { 00316 operator_list[operation].op_i(&dc, &da, &db); 00317 /* apply final limitator to result */ 00318 apply_int_mask(&dc); 00319 } 00320 00321 if (a->base == IDC_RADIO_DEC && b->base != IDC_RADIO_DEC) { 00322 result->number.i = logic_dbl2int(&dc); 00323 apply_int_mask(&result->number); 00324 } else 00325 if (a->base != IDC_RADIO_DEC && b->base == IDC_RADIO_DEC) 00326 result->number.f = dc.f; 00327 else 00328 result->number = dc; 00329 } 00330 00331 static void evalStack(calc_number_t *number) 00332 { 00333 stack_node_t *op, ip; 00334 unsigned int prec; 00335 00336 op = pop(); 00337 ip = *op; 00338 prec = operator_list[ip.node.operation].prec; 00339 while (!is_stack_empty()) { 00340 op = pop(); 00341 00342 if (prec <= operator_list[op->node.operation].prec) { 00343 if (op->node.operation == RPN_OPERATOR_PARENT) continue; 00344 00345 calc.prev = ip.node.number; 00346 run_operator(&ip.node, &op->node, &ip.node, op->node.operation); 00347 if (calc.is_nan) { 00348 flush_postfix(); 00349 return; 00350 } 00351 } else { 00352 push(op); 00353 break; 00354 } 00355 } 00356 00357 if(ip.node.operation != RPN_OPERATOR_EQUAL && ip.node.operation != RPN_OPERATOR_PERCENT) 00358 push(&ip); 00359 00360 calc.prev_operator = op->node.operation; 00361 00362 *number = ip.node.number; 00363 } 00364 00365 int exec_infix2postfix(calc_number_t *number, unsigned int func) 00366 { 00367 stack_node_t tmp; 00368 00369 if (is_stack_empty() && func == RPN_OPERATOR_EQUAL) { 00370 /* if a number has been entered with exponential */ 00371 /* notation, I may update it with normal mode */ 00372 if (calc.sci_in) 00373 return 1; 00374 return 0; 00375 } 00376 00377 if (func == RPN_OPERATOR_PERCENT) 00378 percent_mode = TRUE; 00379 00380 tmp.node.number = *number; 00381 tmp.node.base = calc.base; 00382 tmp.node.operation = func; 00383 tmp.next = NULL; 00384 00385 push(&tmp); 00386 00387 if (func == RPN_OPERATOR_NONE) 00388 return 0; 00389 00390 if (func != RPN_OPERATOR_PARENT) { 00391 calc.last_operator = func; 00392 evalStack(number); 00393 } 00394 return 1; 00395 } 00396 00397 void exec_change_infix(void) 00398 { 00399 stack_node_t *op = stack; 00400 00401 if (op == NULL) 00402 return; 00403 if (op->node.operation == RPN_OPERATOR_PARENT || 00404 op->node.operation == RPN_OPERATOR_PERCENT || 00405 op->node.operation == RPN_OPERATOR_EQUAL) 00406 return; 00407 /* remove the head, it will be re-inserted with new operator */ 00408 pop(); 00409 } 00410 00411 void exec_closeparent(calc_number_t *number) 00412 { 00413 stack_node_t *op, ip; 00414 00415 ip.node.number = *number; 00416 ip.node.base = calc.base; 00417 while (!is_stack_empty()) { 00418 op = pop(); 00419 00420 if (op->node.operation == RPN_OPERATOR_PARENT) 00421 break; 00422 00423 run_operator(&ip.node, &op->node, &ip.node, op->node.operation); 00424 if (calc.is_nan) { 00425 flush_postfix(); 00426 return; 00427 } 00428 } 00429 *number = ip.node.number; 00430 } 00431 00432 int eval_parent_count(void) 00433 { 00434 stack_node_t *s = stack; 00435 int n = 0; 00436 00437 while (s != NULL) { 00438 if (s->node.operation == RPN_OPERATOR_PARENT) 00439 n++; 00440 s = (stack_node_t *)(s->next); 00441 } 00442 return n; 00443 } 00444 00445 void flush_postfix() 00446 { 00447 while (!is_stack_empty()) 00448 pop(); 00449 /* clear prev and last typed operators */ 00450 calc.prev_operator = 00451 calc.last_operator = 0; 00452 } 00453 00454 void start_rpn_engine(void) 00455 { 00456 stack = NULL; 00457 } 00458 00459 void stop_rpn_engine(void) 00460 { 00461 } 00462 Generated on Thu Feb 9 04:38:58 2012 for ReactOS by
1.6.3
|