Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rpn.c

Go 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 doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.