1 /* expr.h -- part of aamath 2 * 3 * This program is copyright (C) 2005 Mauro Persano, and is free 4 * software which is freely distributable under the terms of the 5 * GNU public license, included as the file COPYING in this 6 * distribution. It is NOT public domain software, and any 7 * redistribution not permitted by the GNU General Public License is 8 * expressly forbidden without prior written permission from 9 * the author. 10 * 11 */ 12 13 #include <string> 14 #include <vector> 15 16 class Canvas; 17 class CanvasPtr; 18 19 // 20 // E x p r e s s i o n 21 // 22 23 enum ExpressionType { 24 ET_Constant, 25 ET_Symbol, 26 ET_UnaryOp, 27 ET_BinaryOp, 28 ET_OpOnFunction, 29 ET_Function, 30 ET_Matrix, 31 }; 32 33 class Expression { 34 public: 35 Expression(ExpressionType type_); 36 virtual ~Expression(); 37 38 virtual CanvasPtr render() const = 0; 39 virtual bool is_constant() const = 0; 40 virtual bool need_parens() const = 0; 41 virtual bool accept_expn() const = 0; 42 virtual void set_expn(Expression *expn_) = 0; 43 ExpressionType get_expr_type() const; 44 45 protected: 46 ExpressionType expr_type; 47 48 friend std::ostream& operator<<(std::ostream& o, Expression& e); 49 }; 50 51 typedef std::vector<Expression *> ExprVector; 52 53 54 // 55 // C o n s t a n t 56 // 57 58 enum ConstantType { 59 CT_Integer, 60 CT_Real, 61 CT_Ellipsis, 62 CT_Infinity, 63 CT_Pi, 64 CT_Nabla, 65 }; 66 67 class Constant : public Expression { 68 public: 69 Constant(ConstantType type_); 70 virtual ~Constant(); 71 ConstantType get_const_type() const; 72 virtual bool need_parens() const; 73 virtual bool is_constant() const; 74 virtual bool accept_expn() const; 75 virtual void set_expn(Expression *expn_); 76 77 protected: 78 ConstantType const_type; 79 }; 80 81 class Integer : public Constant { 82 public: 83 Integer(char *value_); 84 virtual ~Integer(); 85 86 virtual CanvasPtr render() const; 87 88 protected: 89 std::string value; 90 }; 91 92 class Real : public Constant { 93 public: 94 Real(char *value_); 95 virtual ~Real(); 96 97 virtual CanvasPtr render() const; 98 99 protected: 100 std::string value; 101 }; 102 103 class Ellipsis : public Constant { 104 public: 105 Ellipsis(); 106 virtual ~Ellipsis(); 107 108 virtual CanvasPtr render() const; 109 }; 110 111 class Infinity : public Constant { 112 public: 113 Infinity(); 114 virtual ~Infinity(); 115 116 virtual CanvasPtr render() const; 117 }; 118 119 class Pi : public Constant { 120 public: 121 Pi(); 122 virtual ~Pi(); 123 124 virtual bool accept_expn() const; 125 virtual void set_expn(Expression *expn_); 126 127 virtual CanvasPtr render() const; 128 129 protected: 130 Expression *expn; 131 }; 132 133 class Nabla : public Constant { 134 public: 135 Nabla(); 136 virtual ~Nabla(); 137 138 virtual bool accept_expn() const; 139 virtual void set_expn(Expression *expn_); 140 141 virtual CanvasPtr render() const; 142 143 protected: 144 Expression *expn; 145 }; 146 147 // 148 // S y m b o l 149 // 150 151 class Symbol : public Expression { 152 public: 153 Symbol(char *name_); 154 virtual ~Symbol(); 155 156 virtual CanvasPtr render() const; 157 virtual bool need_parens() const; 158 virtual bool is_constant() const; 159 virtual bool accept_expn() const; 160 161 void set_subscr(Expression *subscr_); 162 bool has_subscr() const; 163 void set_expn(Expression *expn_); 164 bool has_expn() const; 165 void switch_conj(); 166 void set_conj(bool is_conj_); 167 bool get_conj() const; 168 void set_bar(); 169 bool get_bar() const; 170 void add_tick(); 171 172 protected: 173 std::string name; 174 Expression *subscr; // subscript 175 Expression *expn; // exponent 176 int num_ticks; // # of ticks (e.g. f'(x)) 177 bool is_conj; // is conjugate (should render with * 178 // superscript) 179 bool has_bar; 180 }; 181 182 typedef std::vector<Symbol *> SymVector; 183 184 185 // 186 // U n a r y O p 187 // 188 189 enum UnaryOpType { 190 UT_Neg, 191 UT_Sqrt, 192 UT_Fact, 193 UT_Conj, 194 UT_Bar, 195 UT_Abs, 196 }; 197 198 class UnaryOp : public Expression { 199 public: 200 UnaryOp(UnaryOpType type_, Expression *down_); 201 virtual ~UnaryOp(); 202 UnaryOpType get_unop_type() const; 203 virtual bool is_constant() const; 204 virtual bool accept_expn() const; 205 virtual void set_expn(Expression *expn_); 206 207 protected: 208 UnaryOpType unop_type; 209 Expression *down; 210 }; 211 212 class Neg : public UnaryOp { 213 public: 214 Neg(Expression *down_); 215 virtual ~Neg(); 216 217 virtual CanvasPtr render() const; 218 virtual bool need_parens() const; 219 }; 220 221 class Sqrt : public UnaryOp { 222 public: 223 Sqrt(Expression *down_); 224 virtual ~Sqrt(); 225 226 virtual CanvasPtr render() const; 227 virtual bool need_parens() const; 228 }; 229 230 class Fact : public UnaryOp { 231 public: 232 Fact(Expression *down_); 233 virtual ~Fact(); 234 235 virtual CanvasPtr render() const; 236 virtual bool need_parens() const; 237 }; 238 239 class Conj : public UnaryOp { 240 public: 241 Conj(Expression *down_); 242 virtual ~Conj(); 243 244 virtual CanvasPtr render() const; 245 virtual bool need_parens() const; 246 }; 247 248 class Bar : public UnaryOp { 249 public: 250 Bar(Expression *down_); 251 virtual ~Bar(); 252 253 virtual CanvasPtr render() const; 254 virtual bool need_parens() const; 255 }; 256 257 class Abs : public UnaryOp { 258 public: 259 Abs(Expression *down_); 260 virtual ~Abs(); 261 262 virtual CanvasPtr render() const; 263 virtual bool need_parens() const; 264 }; 265 266 267 // 268 // B i n a r y O p 269 // 270 271 enum BinaryOpType { 272 BT_Add, 273 BT_Sub, 274 BT_Mul, 275 BT_Div, 276 BT_Pow, 277 BT_Root, 278 BT_Equal, 279 BT_Greater, 280 BT_Less, 281 BT_GreaterOrEqual, 282 BT_LessOrEqual, 283 }; 284 285 class BinaryOp : public Expression { 286 public: 287 BinaryOp(BinaryOpType type_, Expression *left_, Expression *right_); 288 virtual ~BinaryOp(); 289 BinaryOpType get_binop_type() const; 290 bool is_constant() const; 291 bool accept_expn() const; 292 void set_expn(Expression *expn_); 293 294 protected: 295 BinaryOpType binop_type; 296 Expression *left; 297 Expression *right; 298 }; 299 300 class SimpleBinaryOp : public BinaryOp { 301 public: 302 SimpleBinaryOp(BinaryOpType type_, Expression *left_, Expression *right_); 303 virtual ~SimpleBinaryOp(); 304 305 virtual bool need_parens() const; 306 virtual CanvasPtr render() const; 307 virtual char symbol() const = 0; 308 }; 309 310 class Add : public SimpleBinaryOp { 311 public: 312 Add(Expression *left_, Expression *right_); 313 virtual ~Add(); 314 315 virtual char symbol() const; 316 }; 317 318 class Sub : public SimpleBinaryOp { 319 public: 320 Sub(Expression *left_, Expression *right_); 321 virtual ~Sub(); 322 323 virtual CanvasPtr render() const; 324 virtual char symbol() const; 325 }; 326 327 class Equal : public SimpleBinaryOp { 328 public: 329 Equal(Expression *left_, Expression *right_); 330 virtual ~Equal(); 331 332 virtual char symbol() const; 333 }; 334 335 class Less : public SimpleBinaryOp { 336 public: 337 Less(Expression *left_, Expression *right_); 338 virtual ~Less(); 339 340 virtual char symbol() const; 341 }; 342 343 class Greater : public SimpleBinaryOp { 344 public: 345 Greater(Expression *left_, Expression *right_); 346 virtual ~Greater(); 347 348 virtual char symbol() const; 349 }; 350 351 class LessOrEqual : public BinaryOp { 352 public: 353 LessOrEqual(Expression *left_, Expression *right_); 354 virtual ~LessOrEqual(); 355 356 virtual CanvasPtr render() const; 357 virtual bool need_parens() const; 358 }; 359 360 class GreaterOrEqual : public BinaryOp { 361 public: 362 GreaterOrEqual(Expression *left_, Expression *right_); 363 virtual ~GreaterOrEqual(); 364 365 virtual CanvasPtr render() const; 366 virtual bool need_parens() const; 367 }; 368 369 class Mul : public BinaryOp { 370 public: 371 Mul(Expression *left_, Expression *right_); 372 virtual ~Mul(); 373 374 virtual CanvasPtr render() const; 375 virtual bool need_parens() const; 376 }; 377 378 class Div : public BinaryOp { 379 public: 380 Div(Expression *left_, Expression *right_); 381 virtual ~Div(); 382 383 virtual CanvasPtr render() const; 384 virtual bool need_parens() const; 385 }; 386 387 class Pow : public BinaryOp { 388 public: 389 Pow(Expression *left_, Expression *right_); 390 virtual ~Pow(); 391 392 virtual CanvasPtr render() const; 393 virtual bool need_parens() const; 394 }; 395 396 class Root : public BinaryOp { 397 public: 398 Root(Expression *left_, Expression *right_); 399 virtual ~Root(); 400 401 virtual CanvasPtr render() const; 402 virtual bool need_parens() const; 403 }; 404 405 406 407 // 408 // O p O n F u n c t i o n 409 // 410 411 enum OpOnFunctionType { 412 FT_Integral, 413 FT_Derivative, 414 FT_SumOrProduct, 415 FT_Limit, 416 }; 417 418 class OpOnFunction : public Expression { 419 public: 420 OpOnFunction(OpOnFunctionType type_, Expression *function_, 421 Expression *var_); 422 virtual ~OpOnFunction(); 423 OpOnFunctionType get_op_on_func_type() const; 424 virtual bool need_parens() const; 425 virtual bool is_constant() const; 426 virtual bool accept_expn() const; 427 virtual void set_expn(Expression *expn_); 428 429 protected: 430 OpOnFunctionType op_on_func_type; 431 Expression *function; 432 Expression *var; 433 }; 434 435 class OpOverInterval { 436 public: 437 OpOverInterval(Expression *from_, Expression *to_); 438 virtual ~OpOverInterval(); 439 440 protected: 441 Expression *from; 442 Expression *to; 443 }; 444 445 class Integral : public OpOnFunction { 446 public: 447 Integral(Expression *function_, Expression *var_); 448 virtual ~Integral(); 449 450 int get_rise() const; 451 452 virtual CanvasPtr render_head() const; 453 454 void render_symbol(Canvas& c, int r, int i, int h) const; 455 456 virtual CanvasPtr render() const; 457 }; 458 459 class IntegralOnInterval : public Integral, public OpOverInterval { 460 public: 461 IntegralOnInterval(Expression *function_, Expression *var_, 462 Expression *from_, Expression *to_); 463 virtual ~IntegralOnInterval(); 464 465 virtual CanvasPtr render_head() const; 466 }; 467 468 class OpSymbol { 469 public: 470 virtual void render(Canvas& c, int r, int i) const = 0; 471 }; 472 473 class SumOrProduct : public OpOnFunction { 474 public: 475 SumOrProduct(Expression *function_, Expression *var_); 476 virtual ~SumOrProduct(); 477 478 virtual CanvasPtr render1(const OpSymbol& os) const; 479 480 virtual CanvasPtr render_head(const OpSymbol& os) const; 481 }; 482 483 class SumOrProductOverInterval : public SumOrProduct, public OpOverInterval { 484 public: 485 SumOrProductOverInterval(Expression *function_, Expression *var_, 486 Expression *from_, Expression *to_); 487 virtual ~SumOrProductOverInterval(); 488 489 virtual CanvasPtr render_head(const OpSymbol& os) const; 490 }; 491 492 class Sum : public SumOrProduct { 493 public: 494 Sum(Expression *function_, Expression *var_); 495 virtual ~Sum(); 496 497 virtual CanvasPtr render() const; 498 }; 499 500 class SumOverInterval : public SumOrProductOverInterval { 501 public: 502 SumOverInterval(Expression *function_, Expression *var_, 503 Expression *from_, Expression *to_); 504 virtual ~SumOverInterval(); 505 506 virtual CanvasPtr render() const; 507 }; 508 509 class Product : public SumOrProduct { 510 public: 511 Product(Expression *function_, Expression *var_); 512 virtual ~Product(); 513 514 virtual CanvasPtr render() const; 515 }; 516 517 class ProductOverInterval : public SumOrProductOverInterval { 518 public: 519 ProductOverInterval(Expression *function_, Expression *var_, 520 Expression *from_, Expression *to_); 521 virtual ~ProductOverInterval(); 522 523 virtual CanvasPtr render() const; 524 }; 525 526 class Limit : public OpOnFunction { 527 public: 528 Limit(Expression *function_, Expression *var_, Expression *limit_); 529 virtual ~Limit(); 530 531 virtual CanvasPtr render() const; 532 533 protected: 534 Expression *limit; 535 }; 536 537 538 // 539 // F u n c t i o n 540 // 541 542 class FunctionArgs { 543 public: 544 FunctionArgs(); 545 virtual ~FunctionArgs(); 546 547 void add_arg(Expression *expr); 548 CanvasPtr render() const; 549 550 protected: 551 ExprVector args; 552 }; 553 554 class Function : public Expression { 555 public: 556 Function(Symbol *symbol_); 557 virtual ~Function(); 558 559 virtual bool need_parens() const; 560 virtual bool is_constant() const; 561 562 protected: 563 Symbol *symbol; 564 }; 565 566 class MultivarFunction : public Function { 567 public: 568 MultivarFunction(Symbol *symbol_, FunctionArgs *args_); 569 virtual ~MultivarFunction(); 570 571 virtual bool accept_expn() const; 572 virtual void set_expn(Expression *expn_); 573 virtual CanvasPtr render() const; 574 575 protected: 576 FunctionArgs *args; 577 }; 578 579 class TrigFunction : public Function { 580 public: 581 TrigFunction(Symbol *symbol_, Expression *arg_); 582 virtual ~TrigFunction(); 583 584 virtual bool accept_expn() const; 585 virtual CanvasPtr render() const; 586 587 void set_expn(Expression *expr); 588 bool has_expn() const; 589 590 protected: 591 Expression *arg; 592 }; 593 594 class Matrix : public Expression { 595 public: 596 Matrix(); 597 virtual ~Matrix(); 598 599 class Row; 600 601 void add_row(Row *row); 602 const Row& operator[](int i) const; 603 604 virtual CanvasPtr render() const; 605 virtual bool need_parens() const; 606 virtual bool is_constant() const; 607 virtual bool accept_expn() const; 608 virtual void set_expn(Expression *expn_); 609 610 void set_det(); 611 612 int num_rows() const; 613 int num_cols() const; 614 615 class Row { 616 public: 617 Row(); 618 virtual ~Row(); 619 620 void add_elem(Expression *expr); 621 int num_cols() const; 622 const Expression *operator[](int i) const; 623 624 protected: 625 ExprVector elems; 626 }; 627 628 protected: 629 std::vector<Row *> rows; 630 bool is_det; 631 }; 632 633 std::ostream& 634 operator<<(std::ostream& o, Expression& e); 635