00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022
00023 #include "tools.h"
00024 #include "symmath.h"
00025
00026 #define ATOM_SYM_INT MAGICD("SMA\x00")
00027 #define ATOM_SYM_INT_SYMBOL MAGICD("SMA\x01")
00028 #define ATOM_SYM_INT_CONST MAGICD("SMA\x02")
00029
00030 #define ATOM_SYM_BOOL MAGICD("SMA\x10")
00031 #define ATOM_SYM_BOOL_SYMBOL MAGICD("SMA\x11")
00032 #define ATOM_SYM_BOOL_INTCMP MAGICD("SMA\x12")
00033
00034
00035
00036 b_op copp_mul[] = {
00037 b_mul,
00038 b_div,
00039 b_mod,
00040 b_invalid
00041 };
00042
00043 b_op copp_add[] = {
00044 b_add,
00045 b_sub,
00046 b_invalid
00047 };
00048
00049 b_op copp_bin[] = {
00050 b_and,
00051 b_or,
00052 b_xor,
00053 b_invalid
00054 };
00055
00056 b_op *c_op_prec[] = {
00057 copp_bin,
00058 copp_add,
00059 copp_mul,
00060 NULL
00061 };
00062
00063 UINT get_op_prec(b_op bop, b_op **op_prec)
00064 {
00065 UINT k = 0;
00066 while (*op_prec) {
00067 b_op *l = *op_prec;
00068 while (*l != b_invalid) {
00069 if (*l == bop) return k;
00070 l++;
00071 }
00072 op_prec++;
00073 k++;
00074 }
00075 return 0;
00076 }
00077
00078
00079
00080
00081
00082 bool sym_int_token::evaluate(UINT *i)
00083 {
00084 return false;
00085 }
00086
00087 void sym_int_token::simplify()
00088 {
00089 }
00090
00091
00092
00093
00094
00095 sym_int_symbol::sym_int_symbol(char *n)
00096 {
00097 name = strdup(n);
00098 }
00099
00100 sym_int_symbol::~sym_int_symbol()
00101 {
00102 free(name);
00103 }
00104
00105 bool sym_int_symbol::compare_eq(sym_int_token *t)
00106 {
00107 sym_int_symbol *s = (sym_int_symbol*)t;
00108 return (strcmp(name, s->name) == 0);
00109 }
00110
00111 Object *sym_int_symbol::duplicate()
00112 {
00113 sym_int_symbol *p = new sym_int_symbol(name);
00114 return p;
00115 }
00116
00117 bool sym_int_symbol::evaluate(UINT *i)
00118 {
00119 return false;
00120 }
00121
00122 int sym_int_symbol::nstrfy(char *buf, int n)
00123 {
00124 int q = strlen(name)+1;
00125 if (q > n) q = n;
00126 memmove(buf, name, q);
00127 return q-1;
00128 }
00129
00130 OBJECT_ID sym_int_symbol::object_id() const
00131 {
00132 return ATOM_SYM_INT_SYMBOL;
00133 }
00134
00135
00136
00137
00138
00139 sym_int_const::sym_int_const(UINT v)
00140 {
00141 value = v;
00142 }
00143
00144 bool sym_int_const::compare_eq(sym_int_token *t)
00145 {
00146 sym_int_const *s = (sym_int_const*)t;
00147 return (value == s->value);
00148 }
00149
00150 Object *sym_int_const::duplicate()
00151 {
00152 return new sym_int_const(value);
00153 }
00154
00155 bool sym_int_const::evaluate(UINT *i)
00156 {
00157 *i = value;
00158 return true;
00159 }
00160
00161 int sym_int_const::nstrfy(char *buf, int n)
00162 {
00163
00164 if (value < 16) return sprintf(buf, "%d", value);
00165 return sprintf(buf, "0x%x", value);
00166 }
00167
00168 OBJECT_ID sym_int_const::object_id() const
00169 {
00170 return ATOM_SYM_INT_CONST;
00171 }
00172
00173
00174
00175
00176
00177 class sym_int_token_rec: public Object {
00178 public:
00179 u_op uop;
00180 b_op bop;
00181 sym_int_token *token;
00182
00183 sym_int_token_rec(u_op u, b_op b, sym_int_token *t)
00184 {
00185 uop = u;
00186 bop = b;
00187 token = t;
00188 }
00189
00190 ~sym_int_token_rec()
00191 {
00192 token->done();
00193 delete token;
00194 }
00195
00196 Object *duplicate()
00197 {
00198 return new sym_int_token_rec(uop, bop, (sym_int_token*)token->duplicate());
00199 }
00200 };
00201
00202
00203
00204
00205
00206 static b_op **output_op_prec = c_op_prec;
00207
00208 struct op_int_prop {
00209 bool has_prop;
00210 UINT value;
00211 };
00212
00213 struct op_int_int_prop {
00214 bool has_prop;
00215 UINT value1;
00216 UINT value2;
00217 };
00218
00219 op_int_prop op_neutrals[NUM_VALID_BOPS] = {
00220
00221 {true, 1},
00222
00223 {true, 1},
00224
00225 {false},
00226
00227 {true, 0},
00228
00229 {true, 0},
00230
00231 {true, 0xffffffff},
00232
00233 {true, 0},
00234
00235 {true, 0}
00236 };
00237
00238 bool op_commutative[NUM_VALID_BOPS] = {
00239
00240 true,
00241
00242 false,
00243
00244 false,
00245
00246 true,
00247
00248 false,
00249
00250 true,
00251
00252 true,
00253
00254 true
00255 };
00256
00257 op_int_int_prop op_destructive[NUM_VALID_BOPS] = {
00258
00259 {true, 0, 0},
00260
00261 {false},
00262
00263 {true, 1, 0},
00264
00265 {false},
00266
00267 {false},
00268
00269 {true, 0, 0},
00270
00271 {true, 0xffffffff, 0xffffffff},
00272
00273 {false}
00274 };
00275
00276 sym_int::sym_int()
00277 {
00278 tokens = new ht_clist();
00279 ((ht_clist*)tokens)->init();
00280 }
00281
00282 sym_int::~sym_int()
00283 {
00284 tokens->destroy();
00285 delete tokens;
00286 }
00287
00288 void sym_int::b_operate(b_op bop, sym_int_token *t)
00289 {
00290 if (t->object_id() == ATOM_SYM_INT) {
00291 sym_int *i = (sym_int*)t;
00292 if (i->tokens->count() == 1) {
00293 sym_int_token_rec *r = (sym_int_token_rec*)i->tokens->get(0);
00294 b_operate(bop, r->token);
00295 return;
00296 }
00297 }
00298 tokens->insert(new sym_int_token_rec(u_null, bop, t));
00299 }
00300
00301 void sym_int::clear()
00302 {
00303 tokens->destroy();
00304 delete tokens;
00305
00306 tokens = new ht_clist();
00307 ((ht_clist*)tokens)->init();
00308 }
00309
00310 bool sym_int::compare_eq(sym_int_token *t)
00311 {
00312
00313 return false;
00314 }
00315
00316 bool sym_int::comp_eq(sym_int_token *a, sym_int_token *b)
00317 {
00318 if (a->object_id() == b->object_id()) {
00319 return a->compare_eq(b);
00320 }
00321 return false;
00322 }
00323
00324 Object *sym_int::duplicate()
00325 {
00326 sym_int *p = new sym_int();
00327 p->tokens = (ht_list*)tokens->duplicate();
00328 return p;
00329 }
00330
00331 bool sym_int::evaluate(UINT *i)
00332 {
00333 int c = tokens->count();
00334 UINT l;
00335 for (int j = 0; j < c; j++) {
00336 UINT k;
00337 sym_int_token_rec *r = (sym_int_token_rec*)tokens->get(j);
00338 if (!r->token->evaluate(&k)) return false;
00339 if (j == 0) l = k;
00340 switch (r->uop) {
00341 case u_null: break;
00342 case u_minus: k = -k; break;
00343 case u_not: k = ~k; break;
00344 }
00345 switch (r->bop) {
00346 case b_invalid: break;
00347 case b_mul: l *= k; break;
00348 case b_div: if (k) l /= k; else return false; break;
00349 case b_mod: if (k) l %= k; else return false; break;
00350 case b_add: l += k; break;
00351 case b_sub: l -= k; break;
00352 case b_and: l &= k; break;
00353 case b_or: l |= k; break;
00354 case b_xor: l ^= k; break;
00355 }
00356 }
00357 *i = l;
00358 return true;
00359 }
00360
00361 int sym_int::nstrfy(char *buf, int n)
00362 {
00363 b_op lbop;
00364 int l = 0;
00365 int c = tokens->count();
00366 lbop = b_invalid;
00367 UINT para_count = 0;
00368 for (int i = 0; i < c; i++) {
00369 sym_int_token_rec *r = (sym_int_token_rec*)tokens->get(i);
00370 bool para = ((lbop != b_invalid) && (r->bop != b_invalid) &&
00371 (get_op_prec(r->bop, output_op_prec) > get_op_prec(lbop,
00372 output_op_prec)));
00373 if (para) para_count++;
00374 lbop = r->bop;
00375 }
00376 for (UINT i = 0; i < para_count; i++) buf[l++] = '(';
00377 lbop = b_invalid;
00378 for (int i = 0; i < c; i++) {
00379 sym_int_token_rec *r = (sym_int_token_rec*)tokens->get(i);
00380 bool para = ((lbop != b_invalid) && (r->bop != b_invalid) &&
00381 (get_op_prec(r->bop, output_op_prec) > get_op_prec(lbop,
00382 output_op_prec)));
00383
00384 if (para) buf[l++] = ')';
00385
00386 switch (r->uop) {
00387 case u_null: break;
00388 case u_minus: buf[l++] = '-'; break;
00389 case u_not: buf[l++] = '~'; break;
00390 }
00391
00392 switch (r->bop) {
00393 case b_invalid: break;
00394 case b_mul: buf[l++] = '*'; break;
00395 case b_div: buf[l++] = '/'; break;
00396 case b_mod: buf[l++] = '%'; break;
00397 case b_add: buf[l++] = '+'; break;
00398 case b_sub: buf[l++] = '-'; break;
00399 case b_and: buf[l++] = '&'; break;
00400 case b_or: buf[l++] = '|'; break;
00401 case b_xor: buf[l++] = '^'; break;
00402 }
00403
00404 l += r->token->nstrfy(buf+l, n-l);
00405
00406
00407 lbop = r->bop;
00408 }
00409 buf[l] = 0;
00410 return l;
00411 }
00412
00413 OBJECT_ID sym_int::object_id() const
00414 {
00415 return ATOM_SYM_INT;
00416 }
00417
00418 void sym_int::replace(sym_int_token *token, sym_int_token *by)
00419 {
00420 int c = tokens->count();
00421 for (int i = 0; i < c; i++) {
00422 sym_int_token_rec *r = (sym_int_token_rec*)tokens->get(i);
00423 if (r->token->object_id() == object_id()) {
00424 ((sym_int*)r->token)->replace(token, by);
00425 } else if (comp_eq(r->token, token)) {
00426 r->token->done();
00427 delete r->token;
00428 r->token = (sym_int_token*)by->duplicate();
00429 }
00430 }
00431 }
00432
00433 void sym_int::set(sym_int_token *t)
00434 {
00435 clear();
00436 if (t->object_id() == ATOM_SYM_INT) {
00437 sym_int *i = (sym_int*)t;
00438 int c = i->tokens->count();
00439 for (int k=0; k<c; k++) {
00440 sym_int_token_rec *r = (sym_int_token_rec*)i->tokens->get(k);
00441 tokens->append(new sym_int_token_rec(r->uop, r->bop, (sym_int_token*)r->token->duplicate()));
00442 }
00443 t->done();
00444 delete t;
00445 return;
00446 }
00447 tokens->insert(new sym_int_token_rec(u_null, b_invalid, t));
00448 }
00449
00450 void sym_int::simplify()
00451 {
00452 UINT c = tokens->count();
00453 UINT d;
00454
00455 do {
00456 d = c;
00457
00458
00459
00460 while (c>=2) {
00461 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(0);
00462 sym_int_token_rec *b = (sym_int_token_rec*)tokens->get(1);
00463 b_op rop;
00464 sym_int_token *rtoken;
00465 if (!simplify_reduce_const(b_invalid, a->token, b->bop, b->token, &rop, &rtoken)) break;
00466 tokens->del(0);
00467 tokens->del(0);
00468 tokens->prepend(new sym_int_token_rec(u_null, b_invalid, rtoken));
00469 c--;
00470 }
00471
00472
00473
00474 for (UINT i=1; i<c-1; i++) {
00475 do {
00476 if (i >= c-1) break;
00477 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(i);
00478 sym_int_token_rec *b = (sym_int_token_rec*)tokens->get(i+1);
00479 b_op rop;
00480 sym_int_token *rtoken;
00481 if (!simplify_reduce_const(a->bop, a->token, b->bop, b->token, &rop, &rtoken)) break;
00482 tokens->del(i);
00483 tokens->del(i);
00484 tokens->insert_before(new sym_int_token_rec(u_null, rop, rtoken), i);
00485 c--;
00486 } while (c>=2);
00487 }
00488
00489
00490
00491
00492
00493
00494 while (c>=2) {
00495 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(0);
00496 sym_int_token_rec *b = (sym_int_token_rec*)tokens->get(1);
00497 if (!op_commutative[b->bop]) break;
00498 if (!simplify_reduce_neutral(b->bop, a->token)) break;
00499 tokens->del(0);
00500 tokens->remove(0);
00501 tokens->prepend(new sym_int_token_rec(u_null, b_invalid, b->token));
00502 c--;
00503 }
00504
00505
00506 for (UINT i=0; i<c-1; i++) {
00507 do {
00508 if (i >= c-1) break;
00509 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(i);
00510 sym_int_token_rec *b = (sym_int_token_rec*)tokens->get(i+1);
00511 if (!simplify_reduce_neutral(b->bop, b->token)) break;
00512 tokens->remove(i);
00513 tokens->del(i);
00514 tokens->insert_before(new sym_int_token_rec(a->uop, a->bop, a->token), i);
00515 c--;
00516 } while (c>=2);
00517 }
00518
00519
00520
00521
00522
00523 while (c>=2) {
00524 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(0);
00525 sym_int_token_rec *b = (sym_int_token_rec*)tokens->get(1);
00526 if (!op_commutative[b->bop]) break;
00527 sym_int_token *repl = simplify_reduce_destructive(b->bop, a->token);
00528 if (!repl) break;
00529 tokens->del(0);
00530 tokens->del(0);
00531 tokens->prepend(new sym_int_token_rec(u_null, b_invalid, repl));
00532 c--;
00533 }
00534
00535
00536 for (UINT i=1; i<c; i++) {
00537 do {
00538 if (i >= c) break;
00539 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(i);
00540 sym_int_token *repl = simplify_reduce_destructive(a->bop, a->token);
00541 if (!repl) break;
00542 UINT dc = i+1;
00543 tokens->del_multiple(0, dc);
00544 tokens->prepend(new sym_int_token_rec(u_null, b_invalid, repl));
00545 c -= dc-1;
00546 } while (c>=2);
00547 }
00548
00549
00550
00551
00552
00553 for (UINT i=0; i<c-1; i++) {
00554 do {
00555 if (i >= c-1) break;
00556 sym_int_token_rec *a = (sym_int_token_rec*)tokens->get(i);
00557 sym_int_token_rec *b = (sym_int_token_rec*)tokens->get(i+1);
00558 sym_int_token *repl;
00559 if (!simplify_reduce_inverse(a->bop, a->token, b->bop, b->token, &repl)) break;
00560 tokens->del(i);
00561 tokens->del(i);
00562 c-=2;
00563 if (repl) {
00564 tokens->insert_before(new sym_int_token_rec(a->uop, a->bop, repl), i);
00565 c++;
00566 }
00567 } while (c>=2);
00568 }
00569
00570 } while (d != c);
00571
00572 }
00573
00574 bool sym_int::simplify_reduce_inverse(b_op oa, sym_int_token *a, b_op ob, sym_int_token *b, sym_int_token **repl)
00575 {
00576 *repl = NULL;
00577 bool eq = (a->object_id() == b->object_id()) ? a->compare_eq(b) : false;
00578 if (eq) {
00579 if (oa == b_invalid) {
00580 if ((ob == b_sub) || (ob == b_xor)) {
00581
00582 *repl = new sym_int_const(0);
00583 return true;
00584 } else if ((ob == b_and) || (ob == b_or)) {
00585
00586 *repl = (sym_int_token*)a->duplicate();
00587 return true;
00588 }
00589 } else if ((oa == b_add) && (ob == b_sub)) {
00590
00591 return true;
00592 } else if ((oa == b_sub) && (ob == b_add)) {
00593
00594 return true;
00595 }
00596 }
00597 return false;
00598 }
00599
00600 sym_int_token *sym_int::simplify_reduce_destructive(b_op o, sym_int_token *x)
00601 {
00602
00603 op_int_int_prop *k = &op_destructive[o];
00604 if (k->has_prop) {
00605 UINT X;
00606 if ((x->evaluate(&X)) && (X == k->value1)) {
00607 return new sym_int_const(k->value2);
00608 }
00609 }
00610 return NULL;
00611 }
00612
00613 bool sym_int::simplify_reduce_neutral(b_op o, sym_int_token *x)
00614 {
00615
00616 op_int_prop *k = &op_neutrals[o];
00617 if (k->has_prop) {
00618 UINT i;
00619 if ((x->evaluate(&i)) && (k->value == i)) {
00620 return true;
00621 }
00622 }
00623 return false;
00624 }
00625
00626 bool sym_int::simplify_reduce_const(b_op oa, sym_int_token *a, b_op ob, sym_int_token *b, b_op *res_op, sym_int_token **res_token)
00627 {
00628 UINT A, B, C;
00629 if (!a->evaluate(&A)) return false;
00630 if (!b->evaluate(&B)) return false;
00631 if (oa == b_invalid) {
00632 switch (ob) {
00633 case b_add: C = A+B; break;
00634 case b_sub: C = A-B; break;
00635 case b_mul: C = A*B; break;
00636 case b_div: if (!B) return false; else C = A/B; break;
00637 case b_mod: if (!B) return false; else C = A%B; break;
00638 case b_and: C = A&B; break;
00639 case b_or: C = A|B; break;
00640 case b_xor: C = A^B; break;
00641 case b_invalid: break;
00642 }
00643 *res_op = b_invalid;
00644 } else if ((oa == b_add) && (ob == b_sub)) {
00645 C = A-B;
00646 *res_op = b_add;
00647 } else if ((oa == b_sub) && (ob == b_add)) {
00648 C = B-A;
00649 *res_op = b_add;
00650 } else if ((oa == b_add) && (ob == b_add)) {
00651 C = A+B;
00652 *res_op = b_add;
00653 } else if ((oa == b_sub) && (ob == b_sub)) {
00654 C = -A-B;
00655 *res_op = b_add;
00656 } else if ((oa == b_or) && (ob == b_or)) {
00657 C = A|B;
00658 *res_op = b_or;
00659 } else if ((oa == b_and) && (ob == b_and)) {
00660 C = A&B;
00661 *res_op = b_and;
00662 } else if ((oa == b_or) && (ob == b_and) && ((A&B) == 0)) {
00663 C = B;
00664 *res_op = b_and;
00665 } else return false;
00666
00667 if (((int)C<0) && (*res_op == b_add)) {
00668 *res_op = b_sub;
00669 C = -C;
00670 }
00671 *res_token = new sym_int_const(C);
00672 return true;
00673 }
00674
00675 void sym_int::u_operate(u_op uop)
00676 {
00677 }
00678
00679
00680
00681
00682
00683 sym_bool_symbol::sym_bool_symbol(char *n)
00684 {
00685 name = strdup(n);
00686 }
00687
00688 sym_bool_symbol::~sym_bool_symbol()
00689 {
00690 free(name);
00691 }
00692
00693 bool sym_bool_symbol::compare_eq(sym_bool_token *t)
00694 {
00695 sym_bool_symbol *s = (sym_bool_symbol*)t;
00696 return (strcmp(name, s->name) == 0);
00697 }
00698
00699 Object *sym_bool_symbol::duplicate()
00700 {
00701 sym_bool_symbol *p = new sym_bool_symbol(name);
00702 return p;
00703 }
00704
00705 bool sym_bool_symbol::evaluate(bool *i)
00706 {
00707 return false;
00708 }
00709
00710 int sym_bool_symbol::nstrfy(char *buf, int n)
00711 {
00712 int q = strlen(name)+1;
00713 if (q > n) q = n;
00714 memmove(buf, name, q);
00715 return q-1;
00716
00717
00718 }
00719
00720 OBJECT_ID sym_bool_symbol::object_id() const
00721 {
00722 return ATOM_SYM_BOOL_SYMBOL;
00723 }
00724
00725
00726
00727
00728
00729 bool sym_bool_token::evaluate(bool *i)
00730 {
00731 return false;
00732 }
00733
00734 void sym_bool_token::simplify()
00735 {
00736 }
00737
00738
00739
00740
00741
00742 sym_bool_const::sym_bool_const(bool v)
00743 {
00744 value = v;
00745 }
00746
00747 bool sym_bool_const::compare_eq(sym_bool_token *t)
00748 {
00749 sym_bool_const *s = (sym_bool_const*)t;
00750 return (value == s->value);
00751 }
00752
00753 bool sym_bool_const::evaluate(bool *i)
00754 {
00755 *i = value;
00756 return true;
00757 }
00758
00759 int sym_bool_const::nstrfy(char *buf, int n)
00760 {
00761 const char *name = value ? "true" : "false";
00762 int q = strlen(name)+1;
00763 if (q > n) q = n;
00764 memmove(buf, name, q);
00765 return q-1;
00766
00767 }
00768
00769
00770
00771
00772
00773 sym_bool_intcmp::sym_bool_intcmp(sym_int_token *i1, c_op c, sym_int_token *i2)
00774 {
00775 int1 = i1;
00776 cop = c;
00777 int2 = i2;
00778 }
00779
00780 bool sym_bool_intcmp::compare_eq(sym_bool_token *t)
00781 {
00782 sym_bool_intcmp *s = (sym_bool_intcmp*)t;
00783
00784 return (int1->compare_eq(s->int1) && int2->compare_eq(s->int2) && cop == s->cop);
00785 }
00786
00787 Object *sym_bool_intcmp::duplicate()
00788 {
00789 return new sym_bool_intcmp((sym_int_token*)int1->duplicate(), cop, (sym_int_token*)int2->duplicate());
00790 }
00791
00792 bool sym_bool_intcmp::evaluate(bool *i)
00793 {
00794 UINT e1, e2;
00795 bool e = false;
00796 if (!int1->evaluate(&e1)) return false;
00797 if (!int2->evaluate(&e2)) return false;
00798 switch (cop) {
00799 case c_invalid: break;
00800 case c_eq: e = (e1 == e2); break;
00801 case c_ne: e = (e1 != e2); break;
00802 case c_gt: e = (e1 > e2); break;
00803 case c_ge: e = (e1 >= e2); break;
00804 case c_lt: e = (e1 < e2); break;
00805 case c_le: e = (e1 <= e2); break;
00806 }
00807 *i = e;
00808 return true;
00809 }
00810
00811 int sym_bool_intcmp::nstrfy(char *buf, int n)
00812 {
00813 int i = 0;
00814 dword C1, C2;
00815 if (int1->evaluate(&C1) && int2->evaluate(&C2)) {
00816 bool r;
00817 bool handled = true;
00818 switch (cop) {
00819 case c_eq: r = (C1 == C2); break;
00820 case c_ne: r = (C1 != C2); break;
00821 case c_gt: r = (C1 > C2); break;
00822 case c_ge: r = (C1 >= C2); break;
00823 case c_lt: r = (C1 < C2); break;
00824 case c_le: r = (C1 <= C2); break;
00825 default: handled = false;
00826 }
00827 if (handled) {
00828 i += sprintf(buf, "%s", r ? "true" : "false");
00829 return i;
00830 }
00831 }
00832 i += int1->nstrfy(buf+i, n-i);
00833 switch (cop) {
00834 case c_invalid: break;
00835 case c_eq: strcpy(buf+i, "=="); i+=2; break;
00836 case c_ne: strcpy(buf+i, "!="); i+=2; break;
00837 case c_gt: buf[i++] = '>'; break;
00838 case c_ge: strcpy(buf+i, ">="); i+=2; break;
00839 case c_lt: buf[i++] = '<'; break;
00840 case c_le: strcpy(buf+i, "<="); i+=2; break;
00841 }
00842 i += int2->nstrfy(buf+i, n-i);
00843 return i;
00844 }
00845
00846 OBJECT_ID sym_bool_intcmp::object_id() const
00847 {
00848 return ATOM_SYM_BOOL_INTCMP;
00849 }
00850
00851 void sym_bool_intcmp::simplify()
00852 {
00853 int1->simplify();
00854 int2->simplify();
00855 }
00856
00857
00858
00859
00860
00861 class sym_bool_token_rec: public Object {
00862 public:
00863 n_op nop;
00864 l_op lop;
00865 sym_bool_token *token;
00866
00867 sym_bool_token_rec(n_op n, l_op l, sym_bool_token *t)
00868 {
00869 nop = n;
00870 lop = l;
00871 token = t;
00872 }
00873
00874 ~sym_bool_token_rec()
00875 {
00876 token->done();
00877 delete token;
00878 }
00879
00880 int nstrfy(char *buf, int n)
00881 {
00882 int i = 0;
00883 switch (nop) {
00884 case n_null: break;
00885 case n_not: buf[i++] = '!'; break;
00886 }
00887 switch (lop) {
00888 case l_invalid: break;
00889 case l_and: strcpy(buf+i, "&&"); i+=2; break;
00890 case l_or: strcpy(buf+i, "||"); i+=2; break;
00891 case l_eq: strcpy(buf+i, "=="); i+=2; break;
00892 case l_ne: strcpy(buf+i, "!="); i+=2; break;
00893 case l_gt: buf[i++] = '>'; break;
00894 case l_ge: strcpy(buf+i, ">="); i+=2; break;
00895 case l_lt: buf[i++] = '<'; break;
00896 case l_le: strcpy(buf+i, "<="); i+=2; break;
00897 }
00898 return i + token->nstrfy(buf+i, n-i);
00899 }
00900
00901 Object *duplicate()
00902 {
00903 return new sym_bool_token_rec(nop, lop, (sym_bool_token*)token->duplicate());
00904 }
00905 };
00906
00907
00908
00909
00910
00911 sym_bool::sym_bool()
00912 {
00913 tokens = new ht_clist();
00914 ((ht_clist*)tokens)->init();
00915 }
00916
00917 sym_bool::~sym_bool()
00918 {
00919 tokens->destroy();
00920 delete tokens;
00921 }
00922
00923 bool sym_bool::compare_eq(sym_bool_token *t)
00924 {
00925
00926 return false;
00927 }
00928
00929 Object *sym_bool::duplicate()
00930 {
00931 sym_bool *p = new sym_bool();
00932 p->tokens = (ht_list*)tokens->duplicate();
00933 return p;
00934 }
00935
00936 void sym_bool::clear()
00937 {
00938 tokens->destroy();
00939 delete tokens;
00940
00941 tokens = new ht_clist();
00942 ((ht_clist*)tokens)->init();
00943 }
00944
00945 bool sym_bool::evaluate(bool *i)
00946 {
00947 int c = tokens->count();
00948 bool l;
00949 for (int j = 0; j < c; j++) {
00950 bool k;
00951 sym_bool_token_rec *r = (sym_bool_token_rec*)tokens->get(j);
00952 if (!r->token->evaluate(&k)) return false;
00953 if (j == 0) l = k;
00954 switch (r->nop) {
00955 case n_null: break;
00956 case n_not: k = !k; break;
00957 }
00958 switch (r->lop) {
00959 case l_invalid: break;
00960 case l_and: l = (l && k); break;
00961 case l_or: l = (l || k); break;
00962 case l_eq: l = (l == k); break;
00963 case l_ne: l = (l != k); break;
00964 case l_gt: l = (l > k); break;
00965 case l_ge: l = (l >= k); break;
00966 case l_lt: l = (l < k); break;
00967 case l_le: l = (l <= k); break;
00968 }
00969 }
00970 *i = l;
00971 return true;
00972 }
00973
00974 void sym_bool::l_operate(l_op l, sym_bool_token *t)
00975 {
00976 tokens->insert(new sym_bool_token_rec(n_null, l, t));
00977 }
00978
00979 int sym_bool::nstrfy(char *buf, int n)
00980 {
00981 int l = 0;
00982 int c = tokens->count();
00983 for (int i = 0; i < c; i++) {
00984 sym_bool_token_rec *r = (sym_bool_token_rec*)tokens->get(i);
00985 l += r->nstrfy(buf+l, n-l);
00986 }
00987 return l;
00988 }
00989
00990 void sym_bool::set(sym_bool_token *t)
00991 {
00992 clear();
00993 tokens->insert(new sym_bool_token_rec(n_null, l_invalid, t));
00994 }
00995
00996 void sym_bool::simplify()
00997 {
00998 int c = tokens->count();
00999 for (int i = 0; i < c; i++) {
01000 sym_bool_token_rec *r = (sym_bool_token_rec*)tokens->get(i);
01001 r->token->simplify();
01002 }
01003 }
01004
01005 void sym_bool::n_operate(n_op n)
01006 {
01007 }
01008
01009 OBJECT_ID sym_bool::object_id() const
01010 {
01011 return ATOM_SYM_BOOL;
01012 }
01013