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